#!/usr/bin/env python3 import random import secrets import os import sys import hashlib DEFAULT_SECRET_PATH = 'secret' def create_secret(): return secrets.token_hex(128) def generate_password(): import string alphabet = string.ascii_letters + string.digits + '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}' return ''.join(random.choice(alphabet) for i in range(24)) def month_timestamp(): import datetime today = datetime.datetime.now() start_of_month = datetime.datetime(today.year, today.month, 1, 0, 0, 0, 0) return int(start_of_month.timestamp()) def generate_seed(secret): m = hashlib.sha256() m.update(bytes.fromhex(secret)) m.update(str(month_timestamp()).encode()) return m.digest() def generate_secret(secret_path): print('Generating a new secret... ', end='') secret = create_secret() with open(secret_path, 'w') as f: f.write(secret) print('done. Send this to the other party:') print(secret) def main(): import argparse parser = argparse.ArgumentParser( prog='Remote Admin Password Solution', description='Generate rotating passwords based on a shared secret' ) parser.add_argument('--secret', action='store', help='path to secret file') parser.add_argument('--new-secret', action='store_true', help='generate a new secret') args = parser.parse_args() secret_path = args.secret if args.secret else DEFAULT_SECRET_PATH secret = '' if args.new_secret: if os.path.isfile(secret_path): choice = '' while choice.lower() != 'y' and choice.lower() != 'n': choice = input(f'Secret {secret_path} exists! Overwrite? [y/n]: ') if choice.lower() == 'y': generate_secret(secret_path) else: generate_secret(secret_path) try: secret = open(secret_path, 'r').read().strip() except FileNotFoundError: print(f'ERROR: Secret file {secret_path} could not be found.') sys.exit(1) print(f'Secret {secret_path} loaded.') random.seed(generate_seed(secret)) print('The password of the month is:') print(generate_password()) if __name__ == '__main__': main()