in otp.py [0:0]
def main():
cmd = os.path.basename(sys.argv[0])
if cmd in ALGOS:
# switch to USAGE:
# $ ALGO SEQUENCE SEED
# omit the prompt, and use argv
algo = cmd
seq = int(sys.argv[1])
seed = sys.argv[2].lower().encode()
# ignore any other argv
else:
parser = argparse.ArgumentParser(description='Compute OTP strings.')
parser.add_argument('--test', help='Run the test suite.', nargs=0,
action=RunTests)
parser.add_argument('--qr', help='Print a URL for a QR code',
action='store_true')
parser.add_argument('args', nargs=argparse.REMAINDER)
# Note: this may exit, if tests are run.
parsed = parser.parse_args()
parts = parsed.args
# We have two possible forms:
# $ CMD [ALGO] SEQUENCE SEED
# $ CMD totp SEED
# If the [ALGO] SEQUENCE SEED is not on the cmdline, then ask.
if len(parts) < 2:
line = input('Challenge? ')
parts = line.split()
if len(parts) == 2:
if parts[0] == ALGO_TOTP:
# form: totp SEED
algo = ALGO_TOTP
seq = None # unused
else:
# form: SEQUENCE SEED
algo = None
seq = int(parts[0])
seed = parts[1].lower().encode()
elif len(parts) >= 3:
algo = parts[0]
seq = int(parts[1])
seed = parts[2].lower().encode()
# ignore anything else on line (eg. "ext")
else:
print('ERROR: challenge must have: [ALGO] SEQUENCE SEED ...')
sys.exit(1)
# Load a dictionary mapping seeds to passwords.
pwds = load_passwords()
if seed not in pwds:
print('Creating new password for:', seed.decode())
if not algo:
algo = DEFAULT_ALGO
print('NOTE: using "%s" algorithm' % (algo,))
pwd = add_password(seed, algo)
else:
old_algo = algo
pwd, algo = pwds[seed]
if old_algo and algo != old_algo:
print('NOTE: switched to "%s" algorithm' % (algo,))
processor = ALGOS.get(algo)
assert processor, 'Unknown/unsupported algorithm: "%s"' % (algo,)
if algo == ALGO_TOTP:
if parsed.qr:
response = TOTP_QR_GEN % (pwd.decode(),)
else:
response = processor(pwd)
else:
value = processor(seed + pwd, seq)
response = ' '.join(to_words(value))
print('Response:', response)
osname = platform.system()
# Attempt to push this to the clipboard
if osname == 'Darwin':
result = subprocess.run(['pbcopy', '-pboard', 'general'], input=response.encode())
else:
result = subprocess.run(['xclip', '-selection', 'clipboard'], input=response.encode())
if result.returncode == 0:
print('NOTE: copied to clipboard')