From 8d41bf32e3efa5842cb791e47e0727df068a5f8e Mon Sep 17 00:00:00 2001 From: alex Date: Sun, 22 Dec 2024 20:19:25 +0100 Subject: [PATCH] gestione errori wallet + fix --- control_mqtt.py | 4 +- password_wallet_api.py | 89 +++++++++++++++++++++++------- services/mqtt_ase_receiver.service | 3 +- 3 files changed, 71 insertions(+), 25 deletions(-) diff --git a/control_mqtt.py b/control_mqtt.py index a88f60b..57b960e 100755 --- a/control_mqtt.py +++ b/control_mqtt.py @@ -35,7 +35,7 @@ class CurrentClients: def start_client(self, client, args): process = subprocess.Popen( - [f'{self.venv_path}/bin/python3 {args.ase_receiver} {client}'], + [f'{self.venv_path}/bin/python3', args.ase_receiver, client], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True @@ -87,7 +87,7 @@ def get_credentials(args): } response = requests.post(url, json=data) if response.status_code != 200: - logging.error("Error to get pwd from wallet") + logging.error(f"Error to get pwd from wallet.") exit(1) return response.json().get('password') diff --git a/password_wallet_api.py b/password_wallet_api.py index ed265a0..20c50e2 100644 --- a/password_wallet_api.py +++ b/password_wallet_api.py @@ -4,6 +4,7 @@ import sqlite3 import bcrypt import base64 import hashlib +import logging from cryptography.fernet import Fernet # Configurazione @@ -11,6 +12,12 @@ db_file = "data/passwords.db" hash_file = "data/master_hash.txt" app = Flask(__name__) +# Configura il logging +logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[ + logging.FileHandler("/var/log/mosquitto/password_wallet.log"), + logging.StreamHandler() +]) + # Inizializza il database def init_db(): conn = sqlite3.connect(db_file) @@ -25,17 +32,21 @@ def init_db(): """) conn.commit() conn.close() + logging.info("Database inizializzato.") # Salva l'hash della master password def save_master_hash(hash): with open(hash_file, "wb") as f: f.write(hash) + logging.info("Hash della master password salvato.") # Carica l'hash della master password def load_master_hash(): if not os.path.exists(hash_file): + logging.warning("Hash della master password non trovato.") return None with open(hash_file, "rb") as f: + logging.info("Hash della master password caricato.") return f.read() # Deriva una chiave di crittografia dalla master password @@ -49,48 +60,80 @@ def authenticate(master_password): if master_hash is None: hashed_password = bcrypt.hashpw(master_password.encode(), bcrypt.gensalt()) save_master_hash(hashed_password) + logging.info("Master password impostata per la prima volta.") return True - return bcrypt.checkpw(master_password.encode(), master_hash) + auth_success = bcrypt.checkpw(master_password.encode(), master_hash) + if auth_success: + logging.info("Autenticazione riuscita.") + else: + logging.warning("Autenticazione fallita.") + return auth_success # 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() + try: + cursor.execute("INSERT INTO passwords (site, username, password) VALUES (?, ?, ?)", + (site, username, encrypted_password)) + conn.commit() + logging.info(f"Password aggiunta per il sito: {site}.") + except sqlite3.Error as e: + logging.error(f"Errore durante l'aggiunta della password: {e}") + finally: + 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 + try: + cursor.execute("SELECT username, password FROM passwords WHERE site = ?", (site,)) + row = cursor.fetchone() + if row: + username, encrypted_password = row + decrypted_password = cipher.decrypt(encrypted_password.encode()).decode() + logging.info(f"Password recuperata per il sito: {site}.") + return username, decrypted_password + logging.warning(f"Sito non trovato: {site}.") + return None, None + except sqlite3.Error as e: + logging.error(f"Errore durante il recupero della password: {e}") + return None, None + finally: + conn.close() # 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() + try: + cursor.execute("DELETE FROM passwords WHERE site = ?", (site,)) + if cursor.rowcount > 0: + logging.info(f"Password cancellata per il sito: {site}.") + else: + logging.warning(f"Nessuna password trovata per il sito: {site}.") + conn.commit() + except sqlite3.Error as e: + logging.error(f"Errore durante la cancellazione della password: {e}") + finally: + 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 + try: + cursor.execute("SELECT site FROM passwords") + sites = [row[0] for row in cursor.fetchall()] + logging.info("Elenco dei siti recuperato.") + return sites + except sqlite3.Error as e: + logging.error(f"Errore durante il recupero dell'elenco dei siti: {e}") + return [] + finally: + conn.close() # Endpoint per aggiungere una password @app.route('/add', methods=['POST']) @@ -101,6 +144,7 @@ def add_password_api(): password = request.json.get('password') if not authenticate(master_password): + logging.warning("Tentativo di aggiungere una password con master password errata.") return jsonify({"error": "Master password errata"}), 403 key = derive_key(master_password) @@ -115,6 +159,7 @@ def get_password_api(): site = request.json.get('site') if not authenticate(master_password): + logging.warning("Tentativo di recuperare una password con master password errata.") return jsonify({"error": "Master password errata"}), 403 key = derive_key(master_password) @@ -133,6 +178,7 @@ def delete_password_api(): site = request.json.get('site') if not authenticate(master_password): + logging.warning("Tentativo di cancellare una password con master password errata.") return jsonify({"error": "Master password errata"}), 403 delete_password(site) @@ -144,6 +190,7 @@ def list_sites_api(): master_password = request.json.get('master_password') if not authenticate(master_password): + logging.warning("Tentativo di recuperare l'elenco dei siti con master password errata.") return jsonify({"error": "Master password errata"}), 403 sites = list_sites() @@ -152,4 +199,4 @@ def list_sites_api(): # Avvio dell'app if __name__ == '__main__': init_db() - app.run(host='0.0.0.0', port=5000) \ No newline at end of file + app.run(host='0.0.0.0', port=5000) diff --git a/services/mqtt_ase_receiver.service b/services/mqtt_ase_receiver.service index 97958d1..4e759fa 100644 --- a/services/mqtt_ase_receiver.service +++ b/services/mqtt_ase_receiver.service @@ -4,11 +4,10 @@ After=network.target [Service] WorkingDirectory=/var/lib/mosquitto -ExecStart=/var/lib/mosquitto/.venv/bin/python3 ./control_mqtt.py +ExecStart=/var/lib/mosquitto/.venv/bin/python3 /var/lib/mosquitto/control_mqtt.py EnvironmentFile=/var/lib/mosquitto/data/.env Restart=always [Install] WantedBy=multi-user.target -Alias=DynSecBackup.service