#!/usr/bin/env python from __future__ import print_function import base64 import hashlib import hmac import struct import sys import time import json from pprint import pprint import argparse # laddar filen with open('/home/fredrik/otp_accounts.json') as filen: data = json.load(filen) class TOTP(): class TOTPException(Exception): def __init__(self, msg): self.msg = msg def __str__(self): return repr(self.msg) def __init__(self, secret): if not secret: raise TOTP.TOTPException('Invalid secret') self.secret = secret def generate(self): try: key = base64.b32decode(self.secret) num = int(time.time()) // 30 msg = struct.pack('>Q', num) # Take a SHA1 HMAC of key and binary-packed time value digest = hmac.new(key, msg, hashlib.sha1).digest() # Last 4 bits of the digest tells which 4 bytes to use offset = ord(digest[19]) & 15 token_base = digest[offset : offset+4] # Unpack that into an integer and strip it down token_val = struct.unpack('>I', token_base)[0] & 0x7fffffff token_num = token_val % 1000000 # Pad with leading zeroes token = '{0:06d}'.format(token_num) return token except: raise TOTP.TOTPException('Invalid secret') def showme(args): if len(args): token = sys.stdin.readline().strip() if args[0] == '-' else args[0] elif not sys.stdin.isatty(): token = sys.stdin.readline().strip() else: return 'Usage: totp ' try: print(TOTP(token).generate()) except TOTP.TOTPException as e: return 'Error: ' + e.msg def main(): for p in data: print (TOTP(data["secret"]).generate()) if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument("site") args = parser.parse_args() for p in data: if p["label"].strip().lower() == args.site.lower(): print(TOTP(p["secret"]).generate()) # try: # sys.exit(main(sys.argv[1:])) # except KeyboardInterrupt: # sys.exit(1)