Добавить manager.py

This commit is contained in:
oscux 2024-03-20 18:48:55 +00:00
commit 2ac2bc8390
1 changed files with 105 additions and 0 deletions

105
manager.py Normal file
View File

@ -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)