import sys import os import subprocess import platform def is_windows() -> bool: return sys.platform == "win32" def is_linux() -> bool: return sys.platform.startswith("linux") def get_config_dir() -> str: if is_windows(): base = os.environ.get("APPDATA", os.path.expanduser("~")) path = os.path.join(base, "WGSecure") else: path = os.path.join(os.path.expanduser("~"), ".wgsecure") os.makedirs(path, exist_ok=True) return path def get_wg_config_dir() -> str: if is_windows(): base = os.environ.get("PROGRAMDATA", r"C:\ProgramData") return os.path.join(base, "WireGuard") return "/etc/wireguard" def has_root_privileges() -> bool: if is_windows(): try: import ctypes return ctypes.windll.shell32.IsUserAnAdmin() != 0 except Exception: return False return os.geteuid() == 0 def run_command(cmd: list[str], timeout: int = 10) -> tuple[int, str, str]: try: result = subprocess.run( cmd, capture_output=True, text=True, timeout=timeout, ) return result.returncode, result.stdout.strip(), result.stderr.strip() except subprocess.TimeoutExpired: return -1, "", "Timeout" except FileNotFoundError: return -1, "", f"Commande introuvable : {cmd[0]}" except Exception as e: return -1, "", str(e) def run_privileged(cmd: list[str], timeout: int = 10) -> tuple[int, str, str]: if is_windows(): return run_command(cmd, timeout) if has_root_privileges(): return run_command(cmd, timeout) # Tente pkexec puis sudo for elevator in ("pkexec", "sudo"): code, out, err = run_command([elevator] + cmd, timeout) if code != -1 or "introuvable" not in err: return code, out, err return -1, "", "Élévation de privilèges impossible" def wg_available() -> bool: code, _, _ = run_command(["wg", "--version"]) return code == 0 def wg_quick_available() -> bool: if is_windows(): code, _, _ = run_command(["wireguard", "--help"]) return code == 0 code, _, _ = run_command(["wg-quick", "--help"]) return code == 0 def install_desktop_entry(icon_png_path: str) -> None: """Installe l'entrée .desktop et l'icône PNG pour la barre des tâches GNOME/KDE. Appelé une fois au démarrage ; sans effet sur Windows.""" if is_windows(): return try: # Icône dans le thème hicolor icon_dir = os.path.expanduser("~/.local/share/icons/hicolor/256x256/apps") os.makedirs(icon_dir, exist_ok=True) dest_icon = os.path.join(icon_dir, "wgsecure.png") import shutil shutil.copy2(icon_png_path, dest_icon) # Fichier .desktop app_dir = os.path.expanduser("~/.local/share/applications") os.makedirs(app_dir, exist_ok=True) script = os.path.abspath( os.path.join(os.path.dirname(__file__), "..", "..", "main.py") ) desktop = os.path.join(app_dir, "wgsecure.desktop") content = ( "[Desktop Entry]\n" "Type=Application\n" "Name=WGSecure\n" "Comment=WireGuard GUI avec MFA TOTP\n" f"Exec=python3 {script}\n" "Icon=wgsecure\n" "Categories=Network;Security;\n" "StartupWMClass=main\n" "Terminal=false\n" ) with open(desktop, "w") as f: f.write(content) # Mettre à jour le cache d'icônes si disponible run_command(["gtk-update-icon-cache", "-f", "-t", os.path.expanduser("~/.local/share/icons/hicolor")]) except Exception: pass