fix(ssh): puttygen multi-syntaxe (private-openssh / private-openssh-new) + message GUI explicite si aucune syntaxe ne marche

This commit is contained in:
Pierre & Lumière 2026-04-29 14:52:42 +02:00
parent e5ce3b2ec9
commit 5fc0c41df5

View File

@ -691,33 +691,53 @@ def load_key(keyfile):
is_ppk = first_line.startswith("PuTTY-User-Key-File-") is_ppk = first_line.startswith("PuTTY-User-Key-File-")
if is_ppk: if is_ppk:
# Paramiko ne lit pas .ppk nativement → tenter conversion auto via puttygen # Paramiko ne lit pas .ppk nativement → tenter conversion auto via puttygen.
# Ordre des syntaxes (de la plus moderne à la plus large) :
# PuTTY 0.74+ : -O private-openssh
# PuTTY 0.75+ : -O private-openssh-new
# Avant 0.74 : pas de CLI export → conversion GUI obligatoire.
converted = keyfile + ".openssh" converted = keyfile + ".openssh"
puttygen_paths = [ puttygen_paths = [
r"C:\Program Files\PuTTY\puttygen.exe", r"C:\Program Files\PuTTY\puttygen.exe",
r"C:\Program Files (x86)\PuTTY\puttygen.exe", r"C:\Program Files (x86)\PuTTY\puttygen.exe",
"puttygen", # si dans PATH "puttygen",
"puttygen.exe", "puttygen.exe",
] ]
export_syntaxes = [
["-O", "private-openssh", "-o", converted],
["-O", "private-openssh-new", "-o", converted],
]
import subprocess import subprocess
converted_ok = False converted_ok = False
last_stderr = ""
for pg in puttygen_paths: for pg in puttygen_paths:
for syntax in export_syntaxes:
try: try:
subprocess.run( proc = subprocess.run(
[pg, keyfile, "-O", "private-openssh", "-o", converted], [pg, keyfile] + syntax,
check=True, capture_output=True, timeout=10, capture_output=True, timeout=10, text=True,
) )
if proc.returncode == 0 and os.path.exists(converted):
converted_ok = True converted_ok = True
break break
except (FileNotFoundError, subprocess.SubprocessError, OSError): last_stderr = (proc.stderr or proc.stdout or "").strip()
except (FileNotFoundError, subprocess.SubprocessError, OSError) as ex:
last_stderr = str(ex)
continue continue
if converted_ok:
break
if not converted_ok: if not converted_ok:
load_key.last_error = ( load_key.last_error = (
f"Format PuTTY (.ppk) détecté pour {os.path.basename(keyfile)}. " f"Format PuTTY (.ppk) détecté pour {os.path.basename(keyfile)}.\n"
f"Paramiko ne lit pas ce format nativement et puttygen.exe est introuvable. " f"Paramiko ne lit pas ce format. La conversion automatique via puttygen a échoué "
f"Convertir manuellement : " f"(version ancienne ou puttygen absent).\n\n"
f'puttygen "{keyfile}" -O private-openssh -o "{keyfile}.openssh" ' f"Détail dernière tentative : {last_stderr or 'aucun'}\n\n"
f"puis pointer la conf vers le fichier converti." f"CONVERSION MANUELLE (PuTTYgen GUI, ~30s) :\n"
f" 1. Ouvrir puttygen.exe (sans arguments, en GUI)\n"
f" 2. Bouton 'Load' → choisir {keyfile}\n"
f" 3. Menu 'Conversions''Export OpenSSH key'\n"
f" 4. Enregistrer sous '{keyfile.rsplit('.', 1)[0]}' (sans .ppk)\n"
f" 5. Dans les paramètres ci-dessous, pointer la clé vers le fichier converti"
) )
return None return None
keyfile = converted keyfile = converted