update
This commit is contained in:
@@ -5,7 +5,9 @@
|
|||||||
|
|
||||||
APP := wgsecure
|
APP := wgsecure
|
||||||
VERSION := 0.4.0
|
VERSION := 0.4.0
|
||||||
PYTHON := python3
|
VENV := .venv
|
||||||
|
PYTHON := $(VENV)/bin/python3
|
||||||
|
PIP := $(VENV)/bin/pip
|
||||||
SRC := main.py
|
SRC := main.py
|
||||||
DIST := dist
|
DIST := dist
|
||||||
BUILD := build
|
BUILD := build
|
||||||
@@ -25,11 +27,18 @@ PI_OPTS := \
|
|||||||
--hidden-import cryptography.hazmat.primitives.asymmetric.x25519 \
|
--hidden-import cryptography.hazmat.primitives.asymmetric.x25519 \
|
||||||
--collect-submodules PyQt6
|
--collect-submodules PyQt6
|
||||||
|
|
||||||
.PHONY: all linux windows release install install-gnome uninstall-gnome run run-admin icon reset-password clean help
|
.PHONY: all linux windows release install install-gnome uninstall-gnome run run-admin icon reset-password setup-sudoers clean clean-all help venv
|
||||||
|
|
||||||
# ── Cible par défaut ────────────────────────────────────────────────────────
|
# ── Cible par défaut ────────────────────────────────────────────────────────
|
||||||
all: linux
|
all: linux
|
||||||
|
|
||||||
|
# ── Environnement virtuel ────────────────────────────────────────────────────
|
||||||
|
venv: $(VENV)/bin/python3
|
||||||
|
|
||||||
|
$(VENV)/bin/python3:
|
||||||
|
python3 -m venv $(VENV)
|
||||||
|
$(PIP) install --upgrade pip --quiet
|
||||||
|
|
||||||
# ── Génération de l'icône PNG (utilisée par PyInstaller) ────────────────────
|
# ── Génération de l'icône PNG (utilisée par PyInstaller) ────────────────────
|
||||||
icon:
|
icon:
|
||||||
@$(PYTHON) -c "\
|
@$(PYTHON) -c "\
|
||||||
@@ -41,7 +50,7 @@ print(' Icône générée →', '$(ICON)')" 2>/dev/null
|
|||||||
@test -f $(ICON) || (echo " ❌ Génération icône échouée"; exit 1)
|
@test -f $(ICON) || (echo " ❌ Génération icône échouée"; exit 1)
|
||||||
|
|
||||||
# ── Binaire Linux ────────────────────────────────────────────────────────────
|
# ── Binaire Linux ────────────────────────────────────────────────────────────
|
||||||
linux: icon
|
linux: install icon
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo " 🐧 Compilation Linux (PyInstaller onefile)…"
|
@echo " 🐧 Compilation Linux (PyInstaller onefile)…"
|
||||||
@echo ""
|
@echo ""
|
||||||
@@ -60,7 +69,7 @@ windows: icon
|
|||||||
@echo ""
|
@echo ""
|
||||||
@which wine > /dev/null 2>&1 \
|
@which wine > /dev/null 2>&1 \
|
||||||
|| (echo " ❌ Wine non installé → sudo apt install wine"; exit 1)
|
|| (echo " ❌ Wine non installé → sudo apt install wine"; exit 1)
|
||||||
@wine python -m PyInstaller $(PI_OPTS) \
|
@wine $(WINE_PYTHON) -m PyInstaller $(PI_OPTS) \
|
||||||
--onefile \
|
--onefile \
|
||||||
--windowed \
|
--windowed \
|
||||||
--icon=$(ICON) \
|
--icon=$(ICON) \
|
||||||
@@ -74,11 +83,25 @@ windows: icon
|
|||||||
@echo ""
|
@echo ""
|
||||||
|
|
||||||
# ── Installation de Python dans Wine ─────────────────────────────────────────
|
# ── Installation de Python dans Wine ─────────────────────────────────────────
|
||||||
|
WINE_PY_VER := 3.11.9
|
||||||
|
WINE_PY_URL := https://www.python.org/ftp/python/$(WINE_PY_VER)/python-$(WINE_PY_VER)-amd64.exe
|
||||||
|
WINE_PY_EXE := /tmp/python-$(WINE_PY_VER)-amd64.exe
|
||||||
|
WINE_PYTHON := $(HOME)/.wine/drive_c/users/$(USER)/AppData/Local/Programs/Python/Python311/python.exe
|
||||||
|
|
||||||
setup-wine:
|
setup-wine:
|
||||||
@echo " 📦 Installation Python + pip dans Wine…"
|
@echo " 📦 Installation Python $(WINE_PY_VER) Windows dans Wine…"
|
||||||
winetricks python3
|
@which wine > /dev/null 2>&1 \
|
||||||
wine pip install -r requirements.txt
|
|| (echo " ❌ wine non installé → sudo apt install wine"; exit 1)
|
||||||
wine pip install pyinstaller
|
@test -f $(WINE_PY_EXE) \
|
||||||
|
|| (echo " ⬇️ Téléchargement Python Windows…" \
|
||||||
|
&& curl -L -o $(WINE_PY_EXE) $(WINE_PY_URL))
|
||||||
|
@echo " 🔧 Installation silencieuse…"
|
||||||
|
wine $(WINE_PY_EXE) /quiet InstallAllUsers=0 PrependPath=1
|
||||||
|
@echo " 📦 Installation des dépendances…"
|
||||||
|
wine $(WINE_PYTHON) -m pip install --upgrade pip
|
||||||
|
wine $(WINE_PYTHON) -m pip install -r requirements.txt
|
||||||
|
wine $(WINE_PYTHON) -m pip install pyinstaller
|
||||||
|
@echo " ✅ Python Windows prêt dans Wine"
|
||||||
|
|
||||||
# ── Release (Linux renommé avec version) ─────────────────────────────────────
|
# ── Release (Linux renommé avec version) ─────────────────────────────────────
|
||||||
release: clean linux
|
release: clean linux
|
||||||
@@ -119,10 +142,25 @@ uninstall-gnome:
|
|||||||
@echo " ✅ WGSecure désinstallé"
|
@echo " ✅ WGSecure désinstallé"
|
||||||
|
|
||||||
# ── Dépendances Python ────────────────────────────────────────────────────────
|
# ── Dépendances Python ────────────────────────────────────────────────────────
|
||||||
install:
|
install: venv
|
||||||
$(PYTHON) -m pip install -r requirements.txt
|
$(PIP) install -r requirements.txt
|
||||||
$(PYTHON) -m pip install pyinstaller
|
$(PIP) install pyinstaller
|
||||||
@echo " ✅ Dépendances installées"
|
@echo " ✅ Dépendances installées dans $(VENV)"
|
||||||
|
|
||||||
|
# ── Droits sudo wg-quick sans dialogue de mot de passe ───────────────────────
|
||||||
|
setup-sudoers:
|
||||||
|
@echo ""
|
||||||
|
@echo " 🔧 Configuration sudoers pour wg-quick (sans mot de passe)…"
|
||||||
|
@$(PYTHON) -c "\
|
||||||
|
import os, subprocess; \
|
||||||
|
user = os.environ.get('USER', os.path.basename(os.path.expanduser('~'))); \
|
||||||
|
rule = user + ' ALL=(ALL) NOPASSWD: /usr/bin/wg-quick\n'; \
|
||||||
|
tmp = '/tmp/wgsecure_sudoers_tmp'; \
|
||||||
|
open(tmp, 'w').write(rule); \
|
||||||
|
r = subprocess.run(['pkexec', 'bash', '-c', 'cp ' + tmp + ' /etc/sudoers.d/wgsecure && chmod 440 /etc/sudoers.d/wgsecure']); \
|
||||||
|
os.unlink(tmp); \
|
||||||
|
print(' ✅ /etc/sudoers.d/wgsecure configuré — WGSecure n\\'a plus besoin de dialogue admin.' if r.returncode == 0 else ' ❌ Échec. Exécutez manuellement : sudo bash -c \"echo ' + user + ' ALL=(ALL) NOPASSWD: /usr/bin/wg-quick > /etc/sudoers.d/wgsecure && chmod 440 /etc/sudoers.d/wgsecure\"')"
|
||||||
|
@echo ""
|
||||||
|
|
||||||
# ── Réinitialisation du mot de passe administrateur ──────────────────────────
|
# ── Réinitialisation du mot de passe administrateur ──────────────────────────
|
||||||
reset-password:
|
reset-password:
|
||||||
@@ -137,10 +175,10 @@ print(' ✅ Mot de passe supprimé — accès admin sans restriction au procha
|
|||||||
@echo ""
|
@echo ""
|
||||||
|
|
||||||
# ── Lancer l'application ─────────────────────────────────────────────────────
|
# ── Lancer l'application ─────────────────────────────────────────────────────
|
||||||
run:
|
run: venv
|
||||||
DISPLAY=:0 $(PYTHON) $(SRC)
|
DISPLAY=:0 $(PYTHON) $(SRC)
|
||||||
|
|
||||||
run-admin:
|
run-admin: venv
|
||||||
DISPLAY=:0 $(PYTHON) $(SRC) --admin
|
DISPLAY=:0 $(PYTHON) $(SRC) --admin
|
||||||
|
|
||||||
# ── Nettoyage ────────────────────────────────────────────────────────────────
|
# ── Nettoyage ────────────────────────────────────────────────────────────────
|
||||||
@@ -151,6 +189,10 @@ clean:
|
|||||||
@find . -name "*.pyc" -delete 2>/dev/null; true
|
@find . -name "*.pyc" -delete 2>/dev/null; true
|
||||||
@echo " ✅ Artefacts supprimés"
|
@echo " ✅ Artefacts supprimés"
|
||||||
|
|
||||||
|
clean-all: clean
|
||||||
|
@rm -rf $(VENV)
|
||||||
|
@echo " ✅ Venv supprimé"
|
||||||
|
|
||||||
# ── Aide ─────────────────────────────────────────────────────────────────────
|
# ── Aide ─────────────────────────────────────────────────────────────────────
|
||||||
help:
|
help:
|
||||||
@echo ""
|
@echo ""
|
||||||
@@ -164,6 +206,7 @@ help:
|
|||||||
@echo " ║ make setup-wine Python Windows dans Wine ║"
|
@echo " ║ make setup-wine Python Windows dans Wine ║"
|
||||||
@echo " ║ make install-gnome Installe dans GNOME ║"
|
@echo " ║ make install-gnome Installe dans GNOME ║"
|
||||||
@echo " ║ make uninstall-gnome Désinstalle de GNOME ║"
|
@echo " ║ make uninstall-gnome Désinstalle de GNOME ║"
|
||||||
|
@echo " ║ make setup-sudoers wg-quick sans sudo ║"
|
||||||
@echo " ║ make reset-password Supprime le MDP admin ║"
|
@echo " ║ make reset-password Supprime le MDP admin ║"
|
||||||
@echo " ║ make run Lance l'application ║"
|
@echo " ║ make run Lance l'application ║"
|
||||||
@echo " ║ make run-admin Lance en mode admin ║"
|
@echo " ║ make run-admin Lance en mode admin ║"
|
||||||
|
|||||||
+1
-1
@@ -19,7 +19,7 @@ _WG_DEFAULT: dict[str, Any] = {
|
|||||||
"client_public_key": "",
|
"client_public_key": "",
|
||||||
"client_address": "10.8.0.2/24",
|
"client_address": "10.8.0.2/24",
|
||||||
"dns": "1.1.1.1",
|
"dns": "1.1.1.1",
|
||||||
"allowed_ips": "0.0.0.0/0",
|
"allowed_ips": "10.8.0.0/24",
|
||||||
"keepalive": 25,
|
"keepalive": 25,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-18
@@ -48,11 +48,7 @@ def build_client_config(cfg: Config) -> str:
|
|||||||
|
|
||||||
def get_client_config_path(cfg: Config) -> str:
|
def get_client_config_path(cfg: Config) -> str:
|
||||||
name = cfg.wg.get("interface_name", "wgs0")
|
name = cfg.wg.get("interface_name", "wgs0")
|
||||||
if is_windows():
|
return os.path.join(get_config_dir(), f"{name}.conf")
|
||||||
config_dir = get_config_dir()
|
|
||||||
else:
|
|
||||||
config_dir = get_wg_config_dir()
|
|
||||||
return os.path.join(config_dir, f"{name}.conf")
|
|
||||||
|
|
||||||
|
|
||||||
def write_client_config(cfg: Config) -> tuple[bool, str]:
|
def write_client_config(cfg: Config) -> tuple[bool, str]:
|
||||||
@@ -65,18 +61,8 @@ def write_client_config(cfg: Config) -> tuple[bool, str]:
|
|||||||
if not is_windows():
|
if not is_windows():
|
||||||
os.chmod(path, 0o600)
|
os.chmod(path, 0o600)
|
||||||
return True, path
|
return True, path
|
||||||
except PermissionError:
|
except Exception as e:
|
||||||
# Écriture via sudo sur Linux
|
return False, str(e)
|
||||||
config_dir_path = get_config_dir()
|
|
||||||
tmp = os.path.join(config_dir_path, "wgs_tmp.conf")
|
|
||||||
with open(tmp, "w") as f:
|
|
||||||
f.write(content)
|
|
||||||
code, _, err = run_privileged(["cp", tmp, path])
|
|
||||||
os.unlink(tmp)
|
|
||||||
if code == 0:
|
|
||||||
run_privileged(["chmod", "600", path])
|
|
||||||
return True, path
|
|
||||||
return False, err
|
|
||||||
|
|
||||||
|
|
||||||
def is_connected(cfg: Config) -> bool:
|
def is_connected(cfg: Config) -> bool:
|
||||||
@@ -341,7 +327,7 @@ def generate_server_config(
|
|||||||
"[Peer]",
|
"[Peer]",
|
||||||
f"PublicKey = {srv_pub}",
|
f"PublicKey = {srv_pub}",
|
||||||
f"PresharedKey = {psk}",
|
f"PresharedKey = {psk}",
|
||||||
"AllowedIPs = 0.0.0.0/0",
|
"AllowedIPs = 10.8.0.0/24",
|
||||||
"Endpoint = <SERVER_IP>:" + str(server_port),
|
"Endpoint = <SERVER_IP>:" + str(server_port),
|
||||||
"PersistentKeepalive = 25",
|
"PersistentKeepalive = 25",
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -605,4 +605,14 @@ class MainWindow(QMainWindow):
|
|||||||
event.ignore()
|
event.ignore()
|
||||||
self.hide()
|
self.hide()
|
||||||
else:
|
else:
|
||||||
|
self._status_timer.stop()
|
||||||
|
self._clock_timer.stop()
|
||||||
|
self._bw_timer.stop()
|
||||||
|
self._ping_timer.stop()
|
||||||
|
self._reconnect_timer.stop()
|
||||||
|
try:
|
||||||
|
if wg_core.is_connected(self._cfg):
|
||||||
|
wg_core.disconnect(self._cfg)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
event.accept()
|
event.accept()
|
||||||
|
|||||||
@@ -108,4 +108,14 @@ class SystemTray(QSystemTrayIcon):
|
|||||||
|
|
||||||
def _quit(self):
|
def _quit(self):
|
||||||
self._poll.stop()
|
self._poll.stop()
|
||||||
|
try:
|
||||||
|
if wg_core.is_connected(self._cfg):
|
||||||
|
wg_core.disconnect(self._cfg)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
self._win._status_timer.stop()
|
||||||
|
self._win._clock_timer.stop()
|
||||||
|
self._win._bw_timer.stop()
|
||||||
|
self._win._ping_timer.stop()
|
||||||
|
self._win._reconnect_timer.stop()
|
||||||
QApplication.quit()
|
QApplication.quit()
|
||||||
|
|||||||
Reference in New Issue
Block a user