Add isolated WireGuard module with guarded access modes and server setup

This commit is contained in:
Mikei386
2026-09-28 14:50:02 +02:00
parent b7b2506272
commit e86e540ae4
21 changed files with 1278 additions and 8 deletions
+53
View File
@@ -0,0 +1,53 @@
"""Access policy: persisted confirmed mode, monotonic trial deadline."""
import secrets
import time
class Policy:
MODES = ('lan', 'tunnel', 'both')
def __init__(self, mode='lan', clock=time.monotonic, persist=lambda mode: None):
self.mode = mode if mode in self.MODES else 'lan'
self.clock = clock
self.persist = persist
self.pending = None
def expire(self):
if self.pending and self.clock() >= self.pending['deadline']:
self.mode = self.pending['previous']
self.pending = None
def allowed(self, ingress):
self.expire()
return self.mode == 'both' or self.mode == ingress
def propose(self, mode, connected):
self.expire()
if mode not in self.MODES:
raise ValueError('Ungültiger Zugriffsmodus.')
if self.pending:
raise ValueError('Zuerst den laufenden Zugriffsversuch bestätigen oder zurücknehmen.')
if mode == self.mode:
return
if mode in ('tunnel', 'both') and not connected:
raise ValueError('Zuerst WireGuard verbinden und einen aktuellen Handshake abwarten.')
self.pending = dict(previous=self.mode, target=mode, deadline=self.clock()+120, id=secrets.token_urlsafe(24))
self.mode = mode
def confirm(self, trial_id, ingress):
self.expire()
if not self.pending or not secrets.compare_digest(self.pending['id'], str(trial_id)):
raise ValueError('Kein passender laufender Zugriffsversuch.')
needed = 'tunnel' if self.mode in ('tunnel', 'both') else 'lan'
if ingress != needed:
raise ValueError('Bestätigung muss über den ausgewählten Netzwerkzugang erfolgen.')
self.persist(self.mode)
self.pending = None
def cancel(self):
if self.pending:
self.mode = self.pending['previous']
self.pending = None
def status(self):
self.expire()
return dict(mode=self.mode, pending=None if not self.pending else dict(id=self.pending['id'], target=self.pending['target'], previous=self.pending['previous'], seconds_remaining=max(0, int(self.pending['deadline']-self.clock()))))