diff --git a/CHANGELOG.md b/CHANGELOG.md index a785fa8..5da9451 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ Ce projet suit le [Versionnage Sémantique](https://semver.org/lang/fr/). --- +## [0.7.16] — 2026-09-04 + +### Corrigé +- **Le service `wgsecure-helper` répondait au premier appel puis devenait injoignable** (connexion automatique au démarrage sans prompt, puis retour aux invites UAC ensuite). La boucle principale ne capturait que `pywintypes.error` et ne protégeait pas `CloseHandle` individuellement dans son nettoyage — une exception non prévue sur une requête, ou un échec de fermeture de handle, pouvait faire sortir de la boucle et arrêter tout le service. Chaque étape (création du pipe, connexion, traitement, fermeture) est désormais individuellement protégée par une capture large, avec un filet de sécurité final qui journalise toute erreur inattendue au lieu de laisser le service disparaître en silence. Gère aussi correctement `ERROR_PIPE_CONNECTED` (client connecté entre la création du pipe et l'appel `ConnectNamedPipe` — un cas normal, pas rare, qui faisait auparavant rater la requête). + +--- + ## [0.7.15] — 2026-09-04 ### Corrigé diff --git a/Makefile b/Makefile index d71fdf8..f1ba4df 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ ## ────────────────────────────────────────────── APP := wgsecure -VERSION := 0.7.15 +VERSION := 0.7.16 VENV := .venv PYTHON := $(VENV)/bin/python3 PIP := $(VENV)/bin/pip diff --git a/README.md b/README.md index 2a2317d..4edb5fd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # 🛡️ WGSecure (WGS) -🚀 v0.7.15 · 🐍 · 🪟🐧 · 🔐 MFA TOTP · 🛡️ WireGuard +🚀 v0.7.16 · 🐍 · 🪟🐧 · 🔐 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.15](https://img.shields.io/badge/v0.7.15-septembre%202026-2980b9?style=flat-square) — Septembre 2026 +Version : ![v0.7.16](https://img.shields.io/badge/v0.7.16-septembre%202026-2980b9?style=flat-square) — Septembre 2026 diff --git a/app/__init__.py b/app/__init__.py index acff5e0..d6fdecc 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,3 +1,3 @@ -__version__ = "0.7.15" +__version__ = "0.7.16" APP_NAME = "WGSecure" APP_SHORT = "WGS" diff --git a/app/service/helper_service.py b/app/service/helper_service.py index c726edb..45dc84a 100644 --- a/app/service/helper_service.py +++ b/app/service/helper_service.py @@ -226,12 +226,12 @@ def _handle_connection(handle, logger: logging.Logger) -> None: except ValidationError as e: resp = {"ok": False, "message": str(e)} logger.info("%s -> ok=%s", cmd, resp.get("ok")) - except (pywintypes.error, ValueError, OSError) as e: + except Exception as e: logger.exception("Requête invalide ou erreur pipe") resp = {"ok": False, "message": f"Erreur interne : {e}"} try: win32file.WriteFile(handle, (json.dumps(resp) + "\n").encode("utf-8")) - except pywintypes.error: + except Exception: pass @@ -273,26 +273,57 @@ class WGSecureHelperService(win32serviceutil.ServiceFramework): ) logger = _get_logger() logger.info("Service démarré") + try: + self._serve_forever(logger) + except Exception: + # Filet de sécurité final : si malgré tout ce qui suit une + # exception s'échappe encore, elle laisse au moins une trace + # exploitable ici plutôt qu'un service qui disparaît en + # silence sans rien dans le log. + logger.exception("Arrêt inattendu de la boucle principale") + finally: + logger.info("Service arrêté") + + def _serve_forever(self, logger: logging.Logger) -> None: + # Chaque étape est individuellement protégée et ne peut donc jamais + # faire sortir la boucle sur une exception non prévue : un service + # censé tourner indéfiniment sans surveillance ne doit jamais + # s'arrêter à cause d'un incident sur UNE requête. Une version + # antérieure ne capturait que pywintypes.error (pas Exception en + # général) et ne protégeait pas CloseHandle individuellement dans + # le `finally` : une erreur non prévue là pouvait remonter et + # arrêter tout le service — expliquant un premier échange réussi + # (juste après le démarrage du service) puis silence total ensuite. + ERROR_PIPE_CONNECTED = 535 while self._running: + handle = None try: handle = _create_pipe_instance() - except pywintypes.error: - logger.exception("Création du pipe impossible") - break - try: - win32pipe.ConnectNamedPipe(handle, None) + try: + win32pipe.ConnectNamedPipe(handle, None) + except pywintypes.error as e: + # Le client s'est connecté entre CreateNamedPipe et + # ConnectNamedPipe : cas normal (pas une erreur), pas + # rare vu la fréquence des appels — sans ce cas + # particulier, la requête était silencieusement ratée + # à chaque fois qu'il se produisait. + if e.winerror != ERROR_PIPE_CONNECTED: + raise if not self._running: break _handle_connection(handle, logger) - except pywintypes.error: + except Exception: logger.exception("Erreur sur une connexion cliente") finally: - try: - win32pipe.DisconnectNamedPipe(handle) - except pywintypes.error: - pass - win32file.CloseHandle(handle) - logger.info("Service arrêté") + if handle: + try: + win32pipe.DisconnectNamedPipe(handle) + except Exception: + pass + try: + win32file.CloseHandle(handle) + except Exception: + pass if __name__ == "__main__": diff --git a/wgsecure.iss b/wgsecure.iss index 595b1f9..ec46eb8 100644 --- a/wgsecure.iss +++ b/wgsecure.iss @@ -5,7 +5,7 @@ ; ────────────────────────────────────────────── #define MyAppName "WGSecure" -#define MyAppVersion "0.7.15" +#define MyAppVersion "0.7.16" #define MyAppPublisher "WGSecure" #define MyAppExeName "wgsecure.exe"