chore(release): v0.7.19

Sécurité : la clé privée ne subsiste plus en clair dans %APPDATA%.
Le .conf généré est écrasé puis supprimé dès que wireguard.exe l'a
consommé (il en garde sa propre copie chiffrée DPAPI), et l'import
propose d'effacer le fichier source. Windows uniquement : sous Linux
/etc/wireguard/<iface>.conf reste requis par wg-quick down.

Corrige aussi ImpersonateNamedPipeClient, qui appartient à
win32security et non à win32pipe (vérifié par introspection).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-05 08:36:16 +02:00
co-authored by Claude Sonnet 5
parent e96f829f8b
commit e272b9397e
9 changed files with 100 additions and 15 deletions
+31 -1
View File
@@ -15,7 +15,9 @@ from app.core import dns as dns_util
from app.core import mfa as mfa_core
from app.ui import theme
from app.ui.worker import ValueWorker
from app.utils.platform_utils import is_windows, run_command, run_privileged
from app.utils.platform_utils import (
is_windows, run_command, run_privileged, secure_delete,
)
class AdminWindow(QDialog):
def __init__(self, config: Config, parent=None):
@@ -1404,6 +1406,34 @@ class AdminWindow(QDialog):
"accidentelle — déverrouillez-les dans l'onglet Tunnel pour les "
"éditer."
)
self._offer_source_shred(path)
def _offer_source_shred(self, path: str):
"""Propose d'effacer le .conf source une fois importé.
Ce fichier porte la clé privée en clair : le laisser traîner dans
Téléchargements ou sur le Bureau annule une bonne part de l'intérêt
de l'application. La suppression est proposée plutôt qu'imposée —
c'est un fichier que l'utilisateur a choisi lui-même, et le détruire
sans demander serait irrattrapable si l'import s'avérait incorrect.
"""
reply = QMessageBox.question(
self, "Effacer le fichier source ?",
f"Le fichier importé contient votre clé privée en clair :\n{path}\n\n"
"Il n'est plus nécessaire : la configuration est enregistrée dans "
"le profil.\n\nL'effacer maintenant ?",
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
)
if reply != QMessageBox.StandardButton.Yes:
return
if secure_delete(path):
QMessageBox.information(self, "Fichier effacé",
f"Fichier source supprimé :\n{path}")
else:
QMessageBox.warning(
self, "Suppression impossible",
f"Le fichier n'a pas pu être supprimé :\n{path}\n\n"
"Supprimez-le manuellement : il contient votre clé privée.")
def _export_conf(self):
self._save_values()