From b3c0515244f9429aa610149d0e7e77154dd73ed1 Mon Sep 17 00:00:00 2001 From: tuxgyver Date: Tue, 8 Sep 2026 10:02:11 +0200 Subject: [PATCH] chore(release): v0.9.0 --- CHANGELOG.md | 26 ++++++++++++++++++++++++++ Makefile | 2 +- README.md | 4 ++-- app/__init__.py | 2 +- wgsecure.iss | 2 +- 5 files changed, 31 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b2bc02..126f41f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,32 @@ Ce projet suit le [Versionnage Sémantique](https://semver.org/lang/fr/). --- +## [0.9.0] — 2026-09-08 + +### Corrigé +- **L'adresse du serveur d'authentification était devinée de travers dès que le client n'était pas en /24.** Elle se déduisait en retranchant le dernier octet de l'adresse du client, ce qui suppose un réseau /24 et ignore les IPs autorisées. Or une adresse client en /32 est la forme la plus courante et ne décrit aucun réseau : un poste en 10.6.1.7/32 sur un 10.6.0.0/16 était expédié vers 10.6.1.1, qui n'existe pas. Sondage et validation échouaient tous deux, sans autre issue que de renseigner `api_url` à la main. La déduction passe désormais par la même fonction que le diagnostic (`tunnel_gateway`), qui gère le /32, l'IPv6 et le repli sur les IPs autorisées. Une adresse IPv6 est encadrée de crochets, sans quoi son « : » se confondait avec celui du port. +- **Une révocation décidée par le serveur restait invisible.** Le client ne demandait l'état de l'accès qu'au retour du tunnel : un redémarrage du serveur, une purge de sa table de sessions ou une décision d'administrateur n'étaient annoncés par rien. L'application affichait « Ouvert ✓ » devant un réseau muet, bouton et entrée de systray masqués, jusqu'à la chute du tunnel — et indéfiniment face à un serveur qui n'annonce pas d'échéance. L'accès est reconfirmé chaque minute tant qu'il est cru ouvert. +- **Fermer la fenêtre de saisie pendant la vérification perdait une authentification réussie.** « Plus tard », la touche Échap et la croix restaient actifs le temps de la requête, qui peut durer dix secondes. Fermer là rendait la main sur un refus alors que le serveur pouvait encore accepter : sa réponse arrivait après coup et n'était lue par personne. L'accès était ouvert côté serveur, l'application affichait la quarantaine, et le code saisi était consommé pour rien. La fenêtre ne se ferme plus tant qu'une requête est en vol. +- **Le repli pour serveurs anciens, introduit en 0.8.7, pouvait déclarer l'accès ouvert alors qu'il ne l'était pas.** Il tenait pour preuve toute réponse du serveur DNS du split-DNS, sans vérifier que celui-ci était joint *par le tunnel*. Une adresse d'entreprise également routée par le réseau local du poste — télétravail depuis un site jumeau, autre VPN déjà monté — répondait donc hors tunnel : accès déclaré ouvert, sans échéance donc sans fin, bouton masqué. Le repli censé éviter le blocage le provoquait. La route est vérifiée d'abord, sans émettre le moindre paquet. +- **Sur un poste derrière un proxy d'entreprise, la requête d'authentification partait au proxy.** `urllib` lit `http_proxy` dans l'environnement : la requête vers l'adresse privée du tunnel était détournée, et la réponse du proxy — souvent un 404 — prise pour celle du serveur, déclenchant justement le repli ci-dessus. Panne parfaitement intermittente : selon l'environnement de lancement, cela passait ou non. Le serveur d'authentification n'étant joignable que par l'intérieur du tunnel, tout proxy est désormais ignoré. +- **Un serveur momentanément muet était traité comme un refus.** Un hoquet réseau au montage du tunnel faisait surgir la fenêtre de saisie et brûler un code, alors que l'accès était peut-être déjà ouvert. Le client distingue maintenant « le serveur refuse » de « le serveur n'a rien dit » : un refus fait autorité et referme du premier coup, un silence déclenche un second sondage trois secondes plus tard avant de déranger l'utilisateur, et n'entame un accès établi qu'après trois minutes sans réponse. +- **Renoncer à saisir un code refermait un accès pourtant ouvert.** L'état était réécrit à la fermeture de la fenêtre quoi qu'il arrive : un sondage abouti pendant qu'elle était ouverte — les minuteries tournent — pouvait établir que l'accès l'était, que « Plus tard » remettait aussitôt à fermé. Renoncer à saisir un code ne referme rien côté serveur ; plus rien côté poste non plus. +- La fenêtre de saisie est détruite après usage. Ni sa validation ni son abandon ne passaient par la fermeture attendue par Qt : son minuteur continuait à battre indéfiniment, et la fenêtre survivait à sa propre disparition, son thread n'étant plus attendu à l'arrêt de l'application. + +### Ajouté +- **Trois sous-onglets dans la page « À propos »** : Mode d'emploi, Prérequis et Sécurité, aux côtés de Fonctions, Garanties, Technique, Journal et Auteur. Le mode d'emploi couvre la première configuration pas à pas, les gestes du quotidien et les pannes courantes ; les prérequis listent paquets, ports et privilèges par plateforme ; la page Sécurité détaille l'authentification, la cryptographie, la protection des secrets au repos et la réduction de la surface d'attaque. + +### Sécurité +- L'URL de l'API n'est plus reprise telle quelle : seuls les schémas `http` et `https` sont acceptés. Identifiant et code d'accès partent dans cette URL, et une valeur saisie de travers les aurait envoyés ailleurs que prévu, ou aurait échoué sans dire pourquoi. +- Rappel, inchangé et hors de portée du client : l'API par défaut est en clair et le serveur n'est pas authentifié. La confidentialité vient du tunnel seul. Si le serveur laisse les pairs en quarantaine se joindre entre eux, un pair malveillant peut usurper l'adresse de l'API et moissonner identifiants et codes. Filtrer le trafic intra-tunnel côté serveur, ou exposer l'API en TLS et renseigner `api_url` en `https://` — le client le gère déjà. + +### Technique +- `AuthResult` porte un champ `authoritative`, qui dit si le serveur a réellement répondu. C'est lui qui permet de ne plus confondre refus et silence. +- `_tunnel_gateway` devient `tunnel_gateway` : la déduction de l'adresse du serveur dans le tunnel avait deux implémentations divergentes, il n'en reste qu'une. +- **Nouvelle cible `make windows-release`**, qui enchaîne les quatre gestes manuels de la production des artefacts Windows dans le seul ordre qui fonctionne, et vérifie d'emblée que la version du `Makefile` et celle de `wgsecure.iss` concordent — les bumper séparément produisait un installeur au mauvais numéro, que `publish` ne retrouvait pas. + +--- + ## [0.8.7] — 2026-09-07 ### Corrigé diff --git a/Makefile b/Makefile index 646baff..3953a70 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ ## ────────────────────────────────────────────── APP := wgsecure -VERSION := 0.8.7 +VERSION := 0.9.0 VENV := .venv PYTHON := $(VENV)/bin/python3 PIP := $(VENV)/bin/pip diff --git a/README.md b/README.md index d3ebc45..88306a0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # 🛡️ WGSecure (WGS) -🚀 v0.8.7 · 🐍 · 🪟🐧 · 🔐 Accès validé par le serveur · 🛡️ WireGuard +🚀 v0.9.0 · 🐍 · 🪟🐧 · 🔐 Accès validé par le serveur · 🛡️ WireGuard **WGSecure** est une interface graphique multiplateforme (Windows & Linux) pour gérer une connexion WireGuard dont l'accès aux ressources distantes est ouvert par un code à 6 chiffres validé **par le serveur**. @@ -210,4 +210,4 @@ WGSecure/ ## 👤 Auteur Développé par **Johnny** — [JT-Tools](https://github.com/JT-Tools) -Version : ![v0.8.0](https://img.shields.io/badge/v0.8.0-septembre%202026-2980b9?style=flat-square) — Septembre 2026 +Version : ![v0.9.0](https://img.shields.io/badge/v0.9.0-septembre%202026-2980b9?style=flat-square) — Septembre 2026 diff --git a/app/__init__.py b/app/__init__.py index 4e16936..65f2971 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,3 +1,3 @@ -__version__ = "0.8.7" +__version__ = "0.9.0" APP_NAME = "WGSecure" APP_SHORT = "WGS" diff --git a/wgsecure.iss b/wgsecure.iss index c0d6bdc..7e42fc4 100644 --- a/wgsecure.iss +++ b/wgsecure.iss @@ -5,7 +5,7 @@ ; ────────────────────────────────────────────── #define MyAppName "WGSecure" -#define MyAppVersion "0.8.7" +#define MyAppVersion "0.9.0" #define MyAppPublisher "WGSecure" #define MyAppExeName "wgsecure.exe"