diff --git a/CHANGELOG.md b/CHANGELOG.md index 50e37dd..3a5780e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ Ce projet suit le [Versionnage Sémantique](https://semver.org/lang/fr/). --- +## [0.7.5] — 2026-09-04 + +### Corrigé +- **Connexion Windows en échec silencieux sur « Accès refusé ».** `wireguard.exe /installtunnelservice` et `/uninstalltunnelservice` étaient lancés sans élévation en misant sur le manifeste UAC natif de `wireguard.exe` — qui ne s'auto-déclenche que lancé depuis l'explorateur ou via ShellExecute, jamais via l'appel process-à-process utilisé ici. Sans les ACLs du service accordées, la connexion échouait donc directement, sans jamais afficher la moindre invite. L'appel tente maintenant d'abord sans élévation (aucune UAC si les ACLs ont été accordées via le bouton dédié), puis retente avec une véritable élévation UAC (`ShellExecuteEx "runas"`) si le premier essai échoue. +- **Diagnostic d'élévation Windows trompeur.** Le panneau Tests & diagnostic annonçait qu'une invite UAC apparaîtrait à chaque connexion sans mentionner que les ACLs accordées au service l'évitent — corrigé pour refléter les deux cas. + +--- + ## [0.7.4] — 2026-09-04 ### Ajouté diff --git a/Makefile b/Makefile index 5cb411e..287c1c8 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ ## ────────────────────────────────────────────── APP := wgsecure -VERSION := 0.7.4 +VERSION := 0.7.5 VENV := .venv PYTHON := $(VENV)/bin/python3 PIP := $(VENV)/bin/pip diff --git a/README.md b/README.md index 370eb84..028983b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # 🛡️ WGSecure (WGS) -🚀 v0.7.4 · 🐍 · 🪟🐧 · 🔐 MFA TOTP · 🛡️ WireGuard +🚀 v0.7.5 · 🐍 · 🪟🐧 · 🔐 MFA TOTP · 🛡️ WireGuard **WGSecure** est une interface graphique multiplateforme (Windows & Linux) pour gérer une connexion WireGuard avec une surcouche MFA (authentification à deux facteurs TOTP). @@ -210,4 +210,4 @@ WGSecure/ ## 👤 Auteur Développé par **Johnny** — [JT-Tools](https://github.com/JT-Tools) -Version : ![v0.7.4](https://img.shields.io/badge/v0.7.4-septembre%202026-2980b9?style=flat-square) — Septembre 2026 +Version : ![v0.7.5](https://img.shields.io/badge/v0.7.5-septembre%202026-2980b9?style=flat-square) — Septembre 2026 diff --git a/app/__init__.py b/app/__init__.py index addc5cb..065db2c 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,3 +1,3 @@ -__version__ = "0.7.4" +__version__ = "0.7.5" APP_NAME = "WGSecure" APP_SHORT = "WGS" diff --git a/app/core/wireguard.py b/app/core/wireguard.py index 1bdc34e..fa18fcc 100644 --- a/app/core/wireguard.py +++ b/app/core/wireguard.py @@ -213,6 +213,27 @@ def interface_exists(cfg: Config) -> bool: return dns_util.interface_exists(cfg.wg.get("interface_name", "wgs0")) +def _run_wireguard_service_cmd(cmd: list[str], timeout: int) -> tuple[int, str, str]: + """Lance `wireguard.exe /install…` ou `/uninstall…tunnelservice`. + + Un utilisateur dont les ACLs du service ont été accordées (bouton + « Configurer les permissions » du panneau Admin) peut créer/supprimer ses + tunnels sans élévation : l'appel non privilégié est donc tenté en premier, + pour ne jamais déclencher d'UAC inutile dans ce cas. + + Sans ACL accordée, cet appel échoue sur « Accès refusé » — le manifeste + UAC de wireguard.exe ne s'applique que lancé depuis l'explorateur ou via + ShellExecute, jamais via CreateProcess (`run_command`) — et échouait donc + silencieusement plutôt que de demander l'élévation. On retente alors via + `run_privileged`, seul à passer par ShellExecuteEx "runas" pour obtenir une + vraie invite UAC. + """ + code, out, err = run_command(cmd, timeout) + if code == 0: + return code, out, err + return run_privileged(cmd, timeout) + + def force_cleanup(cfg: Config) -> list[str]: """Démonte tout résidu du tunnel : entrée DNS orpheline + interface morte. @@ -229,10 +250,9 @@ def force_cleanup(cfg: Config) -> list[str]: if is_windows(): # Le service du tunnel restaure routes et DNS en s'arrêtant. - # Sous Windows, wireguard.exe gère lui-même l'élévation via son manifeste UAC. if dns_util.interface_exists(name): cmd = [wireguard_exe(), "/uninstalltunnelservice", name] - run_command(cmd, timeout=60) + _run_wireguard_service_cmd(cmd, timeout=60) # Nettoyer les règles split-DNS dns_util.cleanup_split_dns(cfg) actions += dns_util.cleanup(name) @@ -305,13 +325,8 @@ def connect(cfg: Config) -> tuple[bool, str]: return True, "Tunnel WireGuard déjà actif" if dns_util.interface_exists(name): force_cleanup(cfg) - # Sous Windows, wireguard.exe gère lui-même l'élévation via son manifeste UAC. - # Sous Linux, wg-quick nécessite sudo. cmd = [wireguard_exe(), "/installtunnelservice", result] - if is_windows(): - code, _, err = run_command(cmd, timeout=90) - else: - code, _, err = run_privileged(cmd, timeout=90) + code, _, err = _run_wireguard_service_cmd(cmd, timeout=90) # /installtunnelservice enregistre le service et rend la main : le # démarrage effectif du tunnel est asynchrone. Tester l'état # immédiatement conclurait « échec » sur un tunnel qui monte. diff --git a/app/ui/admin_window.py b/app/ui/admin_window.py index 70afe8e..8ec10cf 100644 --- a/app/ui/admin_window.py +++ b/app/ui/admin_window.py @@ -1776,14 +1776,16 @@ class AdminWindow(QDialog): "fenêtre UAC à la connexion.") state = "ok" else: - lines.append("⚠️ Processus non élevé : Windows demandera une " - "confirmation UAC à chaque") - lines.append(" connexion et déconnexion du tunnel.") + lines.append("⚠️ Processus non élevé : si les permissions ACL du " + "service n'ont pas été") + lines.append(" accordées (bouton ci-dessous), Windows " + "demandera une confirmation UAC") + lines.append(" à chaque connexion et déconnexion du tunnel.") lines.append("") - lines.append("Pour l'éviter : lancez WGSecure via un raccourci " - "coché « Exécuter en tant") - lines.append("qu'administrateur », ou une tâche planifiée avec " - "les privilèges les plus élevés.") + lines.append("Pour l'éviter : accordez les permissions ACL, ou " + "lancez WGSecure via un") + lines.append("raccourci coché « Exécuter en tant " + "qu'administrateur ».") state = "warn" lines.append("") diff --git a/wgsecure.iss b/wgsecure.iss index d111819..44fd8bb 100644 --- a/wgsecure.iss +++ b/wgsecure.iss @@ -5,7 +5,7 @@ ; ────────────────────────────────────────────── #define MyAppName "WGSecure" -#define MyAppVersion "0.7.4" +#define MyAppVersion "0.7.5" #define MyAppPublisher "WGSecure" #define MyAppExeName "wgsecure.exe"