"""Restreint l'acces a une cle privee au seul utilisateur courant. Sous Windows, `chmod(0o600)` n'a aucun effet sur les permissions NTFS reelles : on verrouille donc l'ACL du fichier via `icacls` (outil Windows standard), plutot que d'ajouter une dependance pywin32 - plus lourde a empaqueter avec PyInstaller pour un simple changement de permissions. Sous Linux/macOS, chmod suffit. `icacls fichier /inheritance:r` retire les entrees heritees du dossier parent (qui donnent en general acces a "Users"/"Authenticated Users"), puis `/grant:r :F` accorde le controle total au seul utilisateur courant. Le proprietaire d'un fichier NTFS garde toujours le droit de modifier son ACL meme quand celle-ci est vide entre les deux commandes : il n'y a pas de risque de se retrouver bloque hors de son propre fichier. """ from __future__ import annotations import os import subprocess from pathlib import Path _NO_WINDOW = getattr(subprocess, "CREATE_NO_WINDOW", 0) def protect_private_key(path: Path) -> None: """Ne rend jamais une cle plus accessible qu'elle ne l'etait ; peut echouer silencieusement (systeme de fichiers sans ACL/permissions, icacls absent...), comme le faisait deja l'appel chmod qu'elle remplace.""" if os.name == "nt": _protect_windows(Path(path)) else: try: Path(path).chmod(0o600) except OSError: pass def _current_user_account() -> str: domain = os.environ.get("USERDOMAIN", "") name = os.environ.get("USERNAME", "") return f"{domain}\\{name}" if domain else name def _protect_windows(path: Path) -> None: account = _current_user_account() if not account.strip("\\"): return try: subprocess.run( ["icacls", str(path), "/inheritance:r"], capture_output=True, check=True, creationflags=_NO_WINDOW, ) subprocess.run( ["icacls", str(path), "/grant:r", f"{account}:F"], capture_output=True, check=True, creationflags=_NO_WINDOW, ) except (subprocess.CalledProcessError, OSError, FileNotFoundError): pass