Skip to content

Instantly share code, notes, and snippets.

@gen0cide
Forked from davehughes/README.md
Created September 16, 2016 19:01
Show Gist options
  • Save gen0cide/c3af6c55877c3f3da8740e4d1c1755ca to your computer and use it in GitHub Desktop.
Save gen0cide/c3af6c55877c3f3da8740e4d1c1755ca to your computer and use it in GitHub Desktop.
.mfa

Setup:

  • Add TOTP keys to a yaml file in ~/.mfa. For example:
aws: k4ur lrri br6f mbzo l6dv gyx5 u2yg cd7n
google: 25gq xtax hzoz wsxe c7pd 34pf 44dq abzl
  • Copy the mfa.py script to ~/bin (or elsewhere, adjusting your alias appropriately).
  • Create the alias alias mfa="~/bin/mfa.py --config=~/.mfa" in ~/.bashrc, ~/.zshrc, or wherever it can be sourced conveniently.
  • Test usage:
> mfa list
aws
google

> mfa token aws
869723
#!/usr/local/bin/python
from __future__ import print_function
import argparse
import os
import re
import subprocess
import sys
import yaml
def load_login_map(filepath):
'''
Load a yaml file of the format:
| <login>: <key>
| ...
'''
return yaml.load(open(filepath))
def get_token(filepath, login):
if not is_oathtool_installed():
print("Couldn't find an installation of oathtool. You can install it "
"with your system package manager ('brew install oath-toolkit' or "
"'apt install oathtool').")
login_map = load_login_map(filepath)
login_key = login_map.get(login)
if not login_key:
print("No key found for login '{}'".format(login))
return
proc = subprocess.Popen(['oathtool', '--totp', '-b', login_key], stdout=subprocess.PIPE)
out, err = proc.communicate()
return out.strip()
def is_oathtool_installed():
proc = subprocess.Popen(['sh', '-c', 'which oathtool'], stdout=subprocess.PIPE)
proc.communicate()
return proc.returncode == 0
def parse_opts(argv=None):
argv = argv or sys.argv[1:]
parser = argparse.ArgumentParser(description="Manage multi-factor auth from the command line")
subparsers = parser.add_subparsers()
parser.add_argument('--config', default=os.environ.get('MFA_CONFIG'))
# mfa.py list
def cmd_list_logins(opts):
login_map = load_login_map(opts.config)
print('\n'.join(sorted(login_map.keys())))
list_cmd = subparsers.add_parser('list')
list_cmd.set_defaults(func=cmd_list_logins)
# mfa.py token
def cmd_get_token(opts):
print(get_token(opts.config, opts.login[0]))
token_cmd = subparsers.add_parser('token')
token_cmd.add_argument('login', nargs=1)
token_cmd.set_defaults(func=cmd_get_token)
return parser.parse_args(argv)
def main():
opts = parse_opts()
opts.func(opts)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment