Compare commits
3 Commits
bded598a6e
...
3b4939f9dc
Author | SHA1 | Date | |
---|---|---|---|
|
3b4939f9dc | ||
|
4727f389ed | ||
|
f0e613919a |
75
raps.py
Normal file → Executable file
75
raps.py
Normal file → Executable file
@ -1,54 +1,83 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import datetime
|
||||||
|
import hashlib
|
||||||
|
import os
|
||||||
import random
|
import random
|
||||||
import secrets
|
import secrets
|
||||||
import os
|
import string
|
||||||
import hashlib
|
import sys
|
||||||
|
|
||||||
SECRET_FILE = 'secret'
|
DEFAULT_SECRET_PATH = 'secret'
|
||||||
|
|
||||||
def create_secret():
|
def create_secret():
|
||||||
|
"""returns 128 bytes of randomness as hex bytes"""
|
||||||
return secrets.token_hex(128)
|
return secrets.token_hex(128)
|
||||||
|
|
||||||
def generate_password():
|
def generate_password():
|
||||||
import string
|
"""returns a random 24 char password"""
|
||||||
alphabet = string.ascii_letters + string.digits + '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}'
|
alphabet = string.ascii_letters + string.digits + '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}'
|
||||||
return ''.join(random.choice(alphabet) for i in range(24))
|
return ''.join(random.choice(alphabet) for i in range(24))
|
||||||
|
|
||||||
def month_timestamp():
|
def month_timestamp():
|
||||||
import datetime
|
"""returns the unix timestamp of the first of the current month"""
|
||||||
today = datetime.datetime.now()
|
today = datetime.datetime.now()
|
||||||
start_of_month = datetime.datetime(today.year, today.month, 1, 0, 0, 0, 0)
|
start_of_month = datetime.datetime(today.year, today.month, 1, 0, 0, 0, 0)
|
||||||
return int(start_of_month.timestamp())
|
return int(start_of_month.timestamp())
|
||||||
|
|
||||||
def generate_seed(secret):
|
def generate_seed(secret):
|
||||||
m = hashlib.sha256()
|
"""returns an rng seed based on the current date"""
|
||||||
m.update(bytes.fromhex(secret))
|
hash_object = hashlib.sha256()
|
||||||
m.update(str(month_timestamp()).encode())
|
hash_object.update(bytes.fromhex(secret))
|
||||||
return m.digest()
|
hash_object.update(str(month_timestamp()).encode())
|
||||||
|
return hash_object.digest()
|
||||||
|
|
||||||
|
def generate_secret(secret_path):
|
||||||
|
"""generates a secret and writes it as a file"""
|
||||||
|
print('Generating a new secret... ', end='')
|
||||||
|
secret = create_secret()
|
||||||
|
with open(secret_path, 'w') as file:
|
||||||
|
file.write(secret)
|
||||||
|
print('done. Send this to the other party:')
|
||||||
|
print(secret)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
import argparse
|
parser = argparse.ArgumentParser(
|
||||||
parser = argparse.ArgumentParser(prog='Remote Admin Password Solution', description='Generate rotating passwords based on a shared secret')
|
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')
|
parser.add_argument('--new-secret', action='store_true', help='generate a new secret')
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
secret = ''
|
if args.secret:
|
||||||
if not os.path.isfile(SECRET_FILE) or args.new_secret:
|
secret_path = os.path.realpath(args.secret)
|
||||||
print('Generating a new secret... ', end='')
|
|
||||||
secret = create_secret()
|
|
||||||
with open(SECRET_FILE, 'w') as f:
|
|
||||||
f.write(secret)
|
|
||||||
print('done. Send this to the other party:')
|
|
||||||
print(secret)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
secret = open(SECRET_FILE, 'r').read().strip()
|
secret_path = os.path.realpath(DEFAULT_SECRET_PATH)
|
||||||
print('Secret loaded.')
|
|
||||||
|
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))
|
random.seed(generate_seed(secret))
|
||||||
|
|
||||||
print('The password of the month is:')
|
print('The password of the month is:')
|
||||||
print(generate_password())
|
print(generate_password())
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user