diff --git a/gui/app.py b/gui/app.py index f6bfc64..1180ac3 100644 --- a/gui/app.py +++ b/gui/app.py @@ -87,6 +87,61 @@ def parse_kv(text): return out +def parse_wg_conf_peer_meta(): + path = f"/etc/wireguard/{WG_INTERFACE}.conf" + if not os.path.exists(path): + return {} + + by_pub = {} + pending_name = None + in_peer = False + current_pub = "" + current_allowed = "" + + def flush(): + nonlocal current_pub, current_allowed, pending_name + if not current_pub: + return + first = current_allowed.split(",", 1)[0].strip() if current_allowed else "" + routes = "" + if "," in current_allowed: + routes = current_allowed.split(",", 1)[1].strip() + by_pub[current_pub] = { + "name": pending_name or "(external)", + "client_address": first, + "routes": routes, + "allowed_ips": current_allowed, + } + pending_name = None + current_pub = "" + current_allowed = "" + + with open(path, "r", encoding="utf-8") as f: + for raw in f: + line = raw.strip() + if not line: + continue + if line.startswith("# managed-by=wg-peerctl"): + marker = "client=" + if marker in line: + pending_name = line.split(marker, 1)[1].split()[0].strip() + continue + if line == "[Peer]": + if in_peer: + flush() + in_peer = True + continue + if in_peer and line.startswith("PublicKey"): + current_pub = line.split("=", 1)[1].strip() + continue + if in_peer and line.startswith("AllowedIPs"): + current_allowed = line.split("=", 1)[1].strip() + continue + if in_peer: + flush() + return by_pub + + def wg_dump(): try: out = run(["wg", "show", WG_INTERFACE, "dump"]) @@ -171,6 +226,7 @@ def _schema(): def index(): meta = load_meta() runtime = {p["public_key"]: p for p in wg_dump()} + conf_meta = parse_wg_conf_peer_meta() with db_conn() as conn: cur = conn.cursor() cur.execute("SELECT * FROM peers ORDER BY id DESC") @@ -203,15 +259,33 @@ def index(): for pk, rt in runtime.items(): if pk in seen: continue + cm = conf_meta.get(pk, {}) + imported_name = cm.get("name", "(external)") + imported_addr = cm.get("client_address", rt.get("allowed_ips", "-").split(",", 1)[0]) + imported_routes = cm.get("routes", "-") or "-" + + ext_id = None + with db_conn() as conn: + cur = conn.cursor() + cur.execute( + "INSERT OR IGNORE INTO peers(name, public_key, client_address, advertised_routes, enabled) VALUES (?,?,?,?,1)", + (imported_name, pk, imported_addr, imported_routes if imported_routes != "-" else ""), + ) + cur.execute("SELECT id FROM peers WHERE public_key = ?", (pk,)) + got = cur.fetchone() + if got: + ext_id = got["id"] + conn.commit() + ts = int(rt.get("latest_handshake_ts", 0) or 0) is_online = ts > 0 and (now - ts) <= ONLINE_WINDOW_SEC items.append( { - "id": None, - "name": "(external)", + "id": ext_id, + "name": imported_name, "public_key": pk, - "client_address": rt.get("allowed_ips", "-").split(",", 1)[0], - "routes": "-", + "client_address": imported_addr, + "routes": imported_routes, "allowed_ips": rt.get("allowed_ips", "-"), "endpoint": rt.get("endpoint", "-"), "latest_handshake": rt.get("latest_handshake", "offline"),