Добавить manager.py
This commit is contained in:
commit
2ac2bc8390
|
|
@ -0,0 +1,105 @@
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
from getpass import getpass
|
||||||
|
from hashlib import md5, sha256
|
||||||
|
from base64 import b64encode
|
||||||
|
from os.path import expanduser
|
||||||
|
import pyperclip
|
||||||
|
import nacl.secret
|
||||||
|
|
||||||
|
def show_usage_error(error_message):
|
||||||
|
raise Exception(f"""Invalid usage: {error_message}
|
||||||
|
|
||||||
|
Syntax: python3 manager.py <command> <args>
|
||||||
|
|
||||||
|
Commands:
|
||||||
|
save <name>
|
||||||
|
read
|
||||||
|
readv1
|
||||||
|
auth
|
||||||
|
del <name>
|
||||||
|
list""")
|
||||||
|
|
||||||
|
def read_passwords_list():
|
||||||
|
passwords_list_path = '.ps_list'
|
||||||
|
if not os.path.exists(passwords_list_path):
|
||||||
|
save_passwords_list([])
|
||||||
|
with open(passwords_list_path, 'r') as file:
|
||||||
|
return file.read().splitlines()
|
||||||
|
|
||||||
|
def save_passwords_list(passwords_list):
|
||||||
|
with open('.ps_list', 'w') as file:
|
||||||
|
file.writelines('\n'.join(passwords_list))
|
||||||
|
|
||||||
|
def append_to_passwords_list(new_entries):
|
||||||
|
current_list = read_passwords_list()
|
||||||
|
updated_list = current_list + new_entries
|
||||||
|
save_passwords_list(list(set(updated_list)))
|
||||||
|
|
||||||
|
def decrypt_master_password(protect_pass=None):
|
||||||
|
master_pass_path = f'{expanduser("~")}/.master_pass'
|
||||||
|
with open(master_pass_path, 'rb') as file:
|
||||||
|
encrypted_data = file.read()
|
||||||
|
if not protect_pass:
|
||||||
|
protect_pass = getpass("Protect password: ")
|
||||||
|
protect_hash = sha256(protect_pass.encode('utf-8')).digest()
|
||||||
|
box = nacl.secret.SecretBox(protect_hash)
|
||||||
|
nonce = encrypted_data[:nacl.secret.SecretBox.NONCE_SIZE]
|
||||||
|
encrypted = encrypted_data[nacl.secret.SecretBox.NONCE_SIZE:]
|
||||||
|
return box.decrypt(encrypted, nonce)
|
||||||
|
|
||||||
|
def process_command(args):
|
||||||
|
if len(args) < 2:
|
||||||
|
show_usage_error("No command provided.")
|
||||||
|
|
||||||
|
command = args[1]
|
||||||
|
if command in ['save', 'del'] and len(args) < 3:
|
||||||
|
show_usage_error("Missing arguments for command.")
|
||||||
|
|
||||||
|
if command == 'save':
|
||||||
|
entry_name = args[2]
|
||||||
|
comment = input("Enter comment for this password: ")
|
||||||
|
entry = f"{entry_name} – {comment}" if comment else entry_name
|
||||||
|
append_to_passwords_list([entry])
|
||||||
|
print("Entry saved.")
|
||||||
|
elif command == 'auth':
|
||||||
|
master_pass = getpass("Master-password: ").encode('utf-8')
|
||||||
|
protect_pass = getpass("Protect password: ")
|
||||||
|
protect_hash = sha256(protect_pass.encode('utf-8')).digest()
|
||||||
|
box = nacl.secret.SecretBox(protect_hash)
|
||||||
|
encrypted = box.encrypt(master_pass)
|
||||||
|
with open(f'{expanduser("~")}/.master_pass', 'wb') as file:
|
||||||
|
file.write(encrypted)
|
||||||
|
print("Master-password saved.")
|
||||||
|
elif command == 'read':
|
||||||
|
master_pass = decrypt_master_password()
|
||||||
|
postfix = getpass("Password postfix: ")
|
||||||
|
hash_digest = sha256(master_pass + postfix.encode('utf-8')).digest()
|
||||||
|
password = b64encode(hash_digest).decode().replace('=', '.').replace('+', '-').replace('/', '_')
|
||||||
|
pyperclip.copy(password)
|
||||||
|
print("Password copied to clipboard.")
|
||||||
|
elif command == 'readv1':
|
||||||
|
master_pass = decrypt_master_password()
|
||||||
|
postfix = getpass("Password postfix: ")
|
||||||
|
hash_digest = md5(master_pass + postfix.encode('utf-8')).digest()
|
||||||
|
password = b64encode(hash_digest).decode().replace('=', '')
|
||||||
|
pyperclip.copy(password)
|
||||||
|
print("Password (v1) copied to clipboard.")
|
||||||
|
elif command == 'del':
|
||||||
|
entry_name = args[2]
|
||||||
|
updated_list = [entry for entry in read_passwords_list() if not entry.startswith(entry_name)]
|
||||||
|
save_passwords_list(updated_list)
|
||||||
|
print("Entry deleted.")
|
||||||
|
elif command == 'list':
|
||||||
|
print("Known passwords:")
|
||||||
|
for entry in read_passwords_list():
|
||||||
|
print(entry)
|
||||||
|
else:
|
||||||
|
show_usage_error("Unknown command.")
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
try:
|
||||||
|
process_command(sys.argv)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error: {e}")
|
||||||
|
sys.exit(1)
|
||||||
Loading…
Reference in New Issue