from flask import Flask, request, jsonify import os import sqlite3 import bcrypt import base64 import hashlib from cryptography.fernet import Fernet # Configurazione db_file = "data/passwords.db" hash_file = "data/master_hash.txt" app = Flask(__name__) # Inizializza il database def init_db(): conn = sqlite3.connect(db_file) cursor = conn.cursor() cursor.execute(""" CREATE TABLE IF NOT EXISTS passwords ( id INTEGER PRIMARY KEY AUTOINCREMENT, site TEXT NOT NULL, username TEXT NOT NULL, password TEXT NOT NULL ) """) conn.commit() conn.close() # Salva l'hash della master password def save_master_hash(hash): with open(hash_file, "wb") as f: f.write(hash) # Carica l'hash della master password def load_master_hash(): if not os.path.exists(hash_file): return None with open(hash_file, "rb") as f: return f.read() # Deriva una chiave di crittografia dalla master password def derive_key(master_password): hash = hashlib.sha256(master_password.encode()).digest() return base64.urlsafe_b64encode(hash) # Autenticazione della master password def authenticate(master_password): master_hash = load_master_hash() if master_hash is None: hashed_password = bcrypt.hashpw(master_password.encode(), bcrypt.gensalt()) save_master_hash(hashed_password) return True return bcrypt.checkpw(master_password.encode(), master_hash) # Aggiungi una password al database def add_password(site, username, password, cipher): conn = sqlite3.connect(db_file) cursor = conn.cursor() encrypted_password = cipher.encrypt(password.encode()).decode() cursor.execute("INSERT INTO passwords (site, username, password) VALUES (?, ?, ?)", (site, username, encrypted_password)) conn.commit() conn.close() # Recupera una password dal database def get_password(site, cipher): conn = sqlite3.connect(db_file) cursor = conn.cursor() cursor.execute("SELECT username, password FROM passwords WHERE site = ?", (site,)) row = cursor.fetchone() conn.close() if row: username, encrypted_password = row decrypted_password = cipher.decrypt(encrypted_password.encode()).decode() return username, decrypted_password return None, None # Cancella una password dal database def delete_password(site): conn = sqlite3.connect(db_file) cursor = conn.cursor() cursor.execute("DELETE FROM passwords WHERE site = ?", (site,)) conn.commit() conn.close() # Ottieni la lista di tutti i siti def list_sites(): conn = sqlite3.connect(db_file) cursor = conn.cursor() cursor.execute("SELECT site FROM passwords") sites = [row[0] for row in cursor.fetchall()] conn.close() return sites # Endpoint per aggiungere una password @app.route('/add', methods=['POST']) def add_password_api(): master_password = request.json.get('master_password') site = request.json.get('site') username = request.json.get('username') password = request.json.get('password') if not authenticate(master_password): return jsonify({"error": "Master password errata"}), 403 key = derive_key(master_password) cipher = Fernet(key) add_password(site, username, password, cipher) return jsonify({"message": "Password aggiunta con successo"}) # Endpoint per recuperare una password @app.route('/get', methods=['POST']) def get_password_api(): master_password = request.json.get('master_password') site = request.json.get('site') if not authenticate(master_password): return jsonify({"error": "Master password errata"}), 403 key = derive_key(master_password) cipher = Fernet(key) username, password = get_password(site, cipher) if username is None: return jsonify({"error": "Sito non trovato"}), 404 return jsonify({"site": site, "username": username, "password": password}) # Endpoint per cancellare una password @app.route('/delete', methods=['POST']) def delete_password_api(): master_password = request.json.get('master_password') site = request.json.get('site') if not authenticate(master_password): return jsonify({"error": "Master password errata"}), 403 delete_password(site) return jsonify({"message": "Password cancellata con successo"}) # Endpoint per listare tutti i siti @app.route('/list', methods=['POST']) def list_sites_api(): master_password = request.json.get('master_password') if not authenticate(master_password): return jsonify({"error": "Master password errata"}), 403 sites = list_sites() return jsonify({"sites": sites}) # Avvio dell'app if __name__ == '__main__': init_db() app.run(host='0.0.0.0', port=5000)