Client SSH/SFTP personnel pour Windows

Reunit en un seul outil les fonctions utiles de MobaXterm, Termius et Bitvise,
sans compte ni service tiers, avec toutes les donnees en local.

- Terminaux multi-onglets : sessions SSH et terminaux Windows locaux
  (PowerShell / cmd) via la pseudo-console native ConPTY
- Gestionnaire de fichiers SFTP facon WinSCP : double panneau, colonnes
  triables, glisser-deposer, renommage, permissions, file de transferts.
  Ouvrable sur une connexion en cours sans creer de favori
- Gestion des cles SSH : generation Ed25519/RSA, import, export
- Gestion du fichier known_hosts, avec remplacement guide d'une cle d'hote
  modifiee (cas frequent des serveurs en DHCP)
- Trois themes (clair, bleu nuit, noir), commutables a chaud
- Authentification automatique reprenant le comportement de la commande ssh
  (agent SSH et cles ~/.ssh), mot de passe demande seulement en secours

Aucun mot de passe n'est stocke sur le disque.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
snoopy
2026-09-04 06:50:10 +02:00
commit b977842186
28 changed files with 3946 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
"""Dialogues utilises au moment de la connexion : saisie de secret et confirmation de cle d'hote."""
from __future__ import annotations
from PySide6.QtWidgets import QInputDialog, QLineEdit, QMessageBox, QWidget
def ask_secret(parent: QWidget, title: str, label: str) -> tuple[str, bool]:
text, ok = QInputDialog.getText(parent, title, label, QLineEdit.Password)
return text, ok
def confirm_host_key(parent: QWidget, hostname: str, key_type: str, fingerprint: str) -> bool:
msg = (
f"L'empreinte de la cle du serveur '{hostname}' n'est pas connue.\n\n"
f"Type : {key_type}\n"
f"Empreinte : {fingerprint}\n\n"
"Verifiez cette empreinte aupres de l'administrateur du serveur si vous n'etes pas certain.\n"
"Faire confiance a cette cle et se connecter ?"
)
answer = QMessageBox.question(
parent, "Nouvelle cle d'hote detectee", msg,
QMessageBox.Yes | QMessageBox.No, QMessageBox.No,
)
return answer == QMessageBox.Yes
def confirm_host_key_change(parent: QWidget, hostname: str, key_type: str, old_fingerprint: str, new_fingerprint: str) -> bool:
msg = (
f"La cle presentee par le serveur '{hostname}' ne correspond plus a celle enregistree.\n\n"
f"Ancienne empreinte : {old_fingerprint}\n"
f"Nouvelle empreinte : {new_fingerprint}\n\n"
"C'est generalement normal si ce serveur a une adresse IP attribuee par DHCP et "
"qu'elle a ete reutilisee par une autre machine, ou si le serveur a ete reinstalle. "
"Mais cela peut aussi indiquer une interception de la connexion (attaque de type "
"'man-in-the-middle') : verifiez la nouvelle empreinte si vous avez un doute.\n\n"
"Remplacer l'ancienne cle enregistree et se connecter ?"
)
answer = QMessageBox.warning(
parent, "Cle d'hote modifiee", msg,
QMessageBox.Yes | QMessageBox.No, QMessageBox.No,
)
return answer == QMessageBox.Yes