diff --git a/app/services/realtime_audit_service.py b/app/services/realtime_audit_service.py index 8a3b823..23ee232 100644 --- a/app/services/realtime_audit_service.py +++ b/app/services/realtime_audit_service.py @@ -125,11 +125,62 @@ def _resolve(hostname): return None -def _connect(target): +def _connect_via_psmp(target): + """Connexion via PSMP CyberArk (auth_interactive avec Vault Password).""" + if not PARAMIKO_OK: + return None + try: + from .secrets_service import get_secret + from ..database import SessionLocal + db = SessionLocal() + psmp_host = get_secret(db, "psmp_host") or "psmp.sanef.fr" + psmp_port = int(get_secret(db, "psmp_port") or "22") + cyber_user = get_secret(db, "psmp_cyberark_user") or "CYBP01336" + target_user = get_secret(db, "psmp_target_user") or "cybsecope" + password = get_secret(db, "ssh_pwd_default_pass") or "" + db.close() + if not password: + return None + username = f"{cyber_user}@{target_user}@{target}" + transport = paramiko.Transport((psmp_host, psmp_port)) + transport.start_client(timeout=SSH_TIMEOUT) + transport.auth_interactive(username, lambda t, i, p: [password] * len(p)) + if not transport.is_authenticated(): + return None + client = paramiko.SSHClient() + client._transport = transport + return client + except Exception: + return None + + +def _resolve_ssh_method(hostname): + """Retourne ssh_method configure pour le serveur (ssh_psmp / ssh_key / ssh_password / None).""" + try: + from ..database import SessionLocal + db = SessionLocal() + row = db.execute(text( + "SELECT ssh_method FROM servers WHERE LOWER(hostname)=LOWER(:h)" + ), {"h": hostname.split(".")[0]}).fetchone() + db.close() + return row.ssh_method if row else None + except Exception: + return None + + +def _connect(target, hostname=None): if not PARAMIKO_OK: return None import os + # Routage PSMP si ssh_method='ssh_psmp' pour ce serveur + method = _resolve_ssh_method(hostname or target) + if method == "ssh_psmp": + client = _connect_via_psmp(target) + if client: + return client + # fallback SSH direct si PSMP KO + ssh_key, ssh_user = _get_ssh_settings() # 1. Essai clé SSH depuis settings (contenu PEM ou chemin legacy) @@ -216,7 +267,7 @@ def audit_single_server(hostname): return result result["resolved_fqdn"] = target - client = _connect(target) + client = _connect(target, hostname) if not client: result["status"] = "CONNECTION_FAILED" result["connection_method"] = f"SSH: connexion refusée ({target})" @@ -321,7 +372,7 @@ def _audit_one(job, hostname): job["servers"][hostname]["stage"] = "connecting" job["servers"][hostname]["detail"] = f"Connexion SSH → {target}" - client = _connect(target) + client = _connect(target, hostname) if not client: job["servers"][hostname]["stage"] = "failed" job["servers"][hostname]["detail"] = f"SSH refusé ({target})"