chore(release): v0.7.9
Corrige la SDDL invalide (erreur 1804) produite par le fix précédent quand le service porte une clause S: (SACL/étiquette d'intégrité), et les accents corrompus dans les messages d'erreur Windows (mauvais codepage/encodage lors de la capture de sortie). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,14 @@ Ce projet suit le [Versionnage Sémantique](https://semver.org/lang/fr/).
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## [0.7.9] — 2026-09-04
|
||||||
|
|
||||||
|
### Corrigé
|
||||||
|
- **`sc sdset` échouait toujours (erreur 1804, SDDL invalide).** Le correctif précédent ajoutait l'ACE en fin de chaîne SDDL, mais la sécurité d'un service porte souvent aussi une clause `S:` (SACL — étiquette d'intégrité obligatoire, ex. `S:(ML;;NW;;;LW)`) : l'ACE se retrouvait alors insérée après le `S:`, produisant une SDDL syntaxiquement invalide. L'ACE est désormais insérée à l'intérieur de la clause `D:`, avant tout `S:` éventuel.
|
||||||
|
- **Caractères accentués corrompus dans les messages d'erreur Windows** (« échoué » affiché « ‚chou‚ »). Les outils console natifs (`sc.exe`, PowerShell non-Core) écrivent dans le codepage OEM de la console (CP850 en français), pas en UTF-8 ni en ANSI : `run_command()` décode désormais explicitement avec ce codepage. Le fichier de capture d'une commande élevée (v0.7.7) utilisait quant à lui la redirection `*>` brute, qui écrit en UTF-16LE par défaut sous Windows PowerShell — remplacée par `Out-File -Encoding utf8` explicite, lu en UTF-8.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## [0.7.8] — 2026-09-04
|
## [0.7.8] — 2026-09-04
|
||||||
|
|
||||||
### Corrigé
|
### Corrigé
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
## ──────────────────────────────────────────────
|
## ──────────────────────────────────────────────
|
||||||
|
|
||||||
APP := wgsecure
|
APP := wgsecure
|
||||||
VERSION := 0.7.8
|
VERSION := 0.7.9
|
||||||
VENV := .venv
|
VENV := .venv
|
||||||
PYTHON := $(VENV)/bin/python3
|
PYTHON := $(VENV)/bin/python3
|
||||||
PIP := $(VENV)/bin/pip
|
PIP := $(VENV)/bin/pip
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# 🛡️ WGSecure (WGS)
|
# 🛡️ WGSecure (WGS)
|
||||||
|
|
||||||
🚀 v0.7.8 · 🐍 · 🪟🐧 · 🔐 MFA TOTP · 🛡️ WireGuard
|
🚀 v0.7.9 · 🐍 · 🪟🐧 · 🔐 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).
|
**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
|
## 👤 Auteur
|
||||||
|
|
||||||
Développé par **Johnny** — [JT-Tools](https://github.com/JT-Tools)
|
Développé par **Johnny** — [JT-Tools](https://github.com/JT-Tools)
|
||||||
Version :  — Septembre 2026
|
Version :  — Septembre 2026
|
||||||
|
|||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
__version__ = "0.7.8"
|
__version__ = "0.7.9"
|
||||||
APP_NAME = "WGSecure"
|
APP_NAME = "WGSecure"
|
||||||
APP_SHORT = "WGS"
|
APP_SHORT = "WGS"
|
||||||
|
|||||||
+12
-4
@@ -1927,15 +1927,23 @@ if (-not $currentSddl) {
|
|||||||
}
|
}
|
||||||
$currentSddl = $currentSddl.Trim()
|
$currentSddl = $currentSddl.Trim()
|
||||||
|
|
||||||
# Ajouter l'utilisateur actuel avec les permissions nécessaires, à
|
# Insérer l'ACE de l'utilisateur actuel à l'intérieur de la clause D:
|
||||||
# l'intérieur de la clause D: existante (jamais en concaténant deux
|
# existante, jamais en l'ajoutant après toute la chaîne : la SDDL d'un
|
||||||
# préfixes "D:" distincts, ce qui produit une SDDL invalide) :
|
# service porte souvent aussi une clause S: (SACL — étiquette d'intégrité
|
||||||
|
# obligatoire notamment, ex. "S:(ML;;NW;;;LW)"). Un simple "+" à la fin
|
||||||
|
# insérait alors l'ACE *après* le S:, produisant une SDDL syntaxiquement
|
||||||
|
# invalide (erreur 1804, ConvertStringSecurityDescriptorToSecurityDescriptor)
|
||||||
|
# — d'où l'échec systématique constaté malgré une lecture correcte de la
|
||||||
|
# SDDL actuelle.
|
||||||
# CC = Create Child (créer des services enfants)
|
# CC = Create Child (créer des services enfants)
|
||||||
# LC = List Child (lister les services enfants)
|
# LC = List Child (lister les services enfants)
|
||||||
# SW = Self Write (modifier ses propres services)
|
# SW = Self Write (modifier ses propres services)
|
||||||
# LO = List Object (lister)
|
# LO = List Object (lister)
|
||||||
# CR = Control (contrôle)
|
# CR = Control (contrôle)
|
||||||
$fullSddl = $currentSddl + "(A;;CCLCSWLOCRRC;;;$currentUserSid)"
|
if ($currentSddl -notmatch '^(D:[A-Z]*)((?:\([^)]*\))*)(S:.*)?$') {
|
||||||
|
throw "Format de SDDL inattendu pour '$serviceName' : $currentSddl"
|
||||||
|
}
|
||||||
|
$fullSddl = $matches[1] + $matches[2] + "(A;;CCLCSWLOCRRC;;;$currentUserSid)" + $matches[3]
|
||||||
|
|
||||||
$setOutput = & sc.exe sdset $serviceName $fullSddl
|
$setOutput = & sc.exe sdset $serviceName $fullSddl
|
||||||
if ($LASTEXITCODE -ne 0) {
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
|||||||
@@ -102,12 +102,20 @@ def _no_window_kwargs() -> dict:
|
|||||||
def run_command(cmd: list[str], timeout: int = 10,
|
def run_command(cmd: list[str], timeout: int = 10,
|
||||||
env: dict | None = None) -> tuple[int, str, str]:
|
env: dict | None = None) -> tuple[int, str, str]:
|
||||||
try:
|
try:
|
||||||
|
text_kwargs = {"text": True}
|
||||||
|
if is_windows():
|
||||||
|
# Les outils console natifs (sc.exe, PowerShell non-Core, ping…)
|
||||||
|
# écrivent dans le codepage OEM de la console (ex. CP850 en
|
||||||
|
# français), pas en UTF-8 : sans préciser l'encodage, Python
|
||||||
|
# décode avec le codepage ANSI par défaut et tout caractère
|
||||||
|
# accentué remonte corrompu ("échoué" → "‚chou‚").
|
||||||
|
text_kwargs = {"encoding": "oem", "errors": "replace"}
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
cmd,
|
cmd,
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
text=True,
|
|
||||||
timeout=timeout,
|
timeout=timeout,
|
||||||
env=env,
|
env=env,
|
||||||
|
**text_kwargs,
|
||||||
**_no_window_kwargs(),
|
**_no_window_kwargs(),
|
||||||
)
|
)
|
||||||
return result.returncode, result.stdout.strip(), result.stderr.strip()
|
return result.returncode, result.stdout.strip(), result.stderr.strip()
|
||||||
@@ -215,10 +223,18 @@ def _run_elevated_windows(cmd: list[str], timeout: int = 60) -> tuple[int, str,
|
|||||||
]
|
]
|
||||||
|
|
||||||
out_path = os.path.join(tempfile.gettempdir(), f"wgsecure-elev-{uuid.uuid4().hex}.log")
|
out_path = os.path.join(tempfile.gettempdir(), f"wgsecure-elev-{uuid.uuid4().hex}.log")
|
||||||
# `*>` fusionne tous les flux (succès, erreur, avertissement…) — cohérent
|
# `*>&1 | Out-File -Encoding utf8` plutôt que la redirection `*>` brute :
|
||||||
# avec l'usage existant qui traite `err or out` indifféremment.
|
# cette dernière écrit en UTF-16LE (encodage par défaut de PowerShell
|
||||||
|
# Windows pour `>`/`*>`), que la lecture Python en UTF-8 corromprait
|
||||||
|
# (accents illisibles). `*>&1` fusionne tous les flux (succès, erreur,
|
||||||
|
# avertissement…) dans le flux de sortie avant le pipe, comme le faisait
|
||||||
|
# `*>` seul — cohérent avec l'usage existant qui traite `err or out`
|
||||||
|
# indifféremment.
|
||||||
call_expr = "& " + " ".join(_ps_quote(a) for a in cmd)
|
call_expr = "& " + " ".join(_ps_quote(a) for a in cmd)
|
||||||
wrapped_script = f"{call_expr} *> {_ps_quote(out_path)}; exit $LASTEXITCODE"
|
wrapped_script = (
|
||||||
|
f"{call_expr} *>&1 | Out-File -FilePath {_ps_quote(out_path)} -Encoding utf8; "
|
||||||
|
f"exit $LASTEXITCODE"
|
||||||
|
)
|
||||||
elevated_cmd = ["powershell", "-NoProfile", "-NonInteractive", "-Command", wrapped_script]
|
elevated_cmd = ["powershell", "-NoProfile", "-NonInteractive", "-Command", wrapped_script]
|
||||||
|
|
||||||
info = SHELLEXECUTEINFOW()
|
info = SHELLEXECUTEINFOW()
|
||||||
@@ -239,7 +255,9 @@ def _run_elevated_windows(cmd: list[str], timeout: int = 60) -> tuple[int, str,
|
|||||||
|
|
||||||
def _read_output() -> str:
|
def _read_output() -> str:
|
||||||
try:
|
try:
|
||||||
with open(out_path, encoding="utf-8", errors="replace") as f:
|
# utf-8-sig : Out-File -Encoding utf8 (Windows PowerShell)
|
||||||
|
# ajoute un BOM ; -sig l'ignore silencieusement s'il est présent.
|
||||||
|
with open(out_path, encoding="utf-8-sig", errors="replace") as f:
|
||||||
return f.read().strip()
|
return f.read().strip()
|
||||||
except OSError:
|
except OSError:
|
||||||
return ""
|
return ""
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@
|
|||||||
; ──────────────────────────────────────────────
|
; ──────────────────────────────────────────────
|
||||||
|
|
||||||
#define MyAppName "WGSecure"
|
#define MyAppName "WGSecure"
|
||||||
#define MyAppVersion "0.7.8"
|
#define MyAppVersion "0.7.9"
|
||||||
#define MyAppPublisher "WGSecure"
|
#define MyAppPublisher "WGSecure"
|
||||||
#define MyAppExeName "wgsecure.exe"
|
#define MyAppExeName "wgsecure.exe"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user