Skip to content
API Documentation
BastionGuard™
fake_ui.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2"""
3Fake UI per BastionGuard Secure Connection.
4
5Simula la UI reale sul protocollo wire (Unix socket + JSON length-prefixed):
6 - accetta una connessione dal daemon sul socket default /tmp/bsd-daemon.sock
7 - logga tutti i messaggi ricevuti
8 - risponde automaticamente ai messaggi ask_rule con "allow once"
9
10Uso: python3 fake_ui.py [SOCKET_PATH]
11
12Utile per:
13 - testare il daemon senza compilare la UI gtkmm
14 - debuggare modifiche al protocollo
15 - smoke test di CI
16"""
17import json
18import os
19import socket
20import struct
21import sys
22
23
24def read_exact(conn: socket.socket, n: int) -> bytes | None:
25 buf = b""
26 while len(buf) < n:
27 chunk = conn.recv(n - len(buf))
28 if not chunk:
29 return None
30 buf += chunk
31 return buf
32
33
34def send_frame(conn: socket.socket, msg: dict) -> None:
35 data = json.dumps(msg).encode("utf-8")
36 conn.sendall(struct.pack("<I", len(data)) + data)
37
38
39def handle_client(conn: socket.socket) -> None:
40 while True:
41 hdr = read_exact(conn, 4)
42 if not hdr:
43 return
44 length = struct.unpack("<I", hdr)[0]
45 if length > 4 * 1024 * 1024:
46 print(f"[fake-ui] frame troppo grande ({length}), chiudo", flush=True)
47 return
48 payload = read_exact(conn, length)
49 if not payload:
50 return
51 try:
52 msg = json.loads(payload.decode("utf-8"))
53 except Exception as e:
54 print(f"[fake-ui] JSON invalido: {e}", flush=True)
55 continue
56
57 t = msg.get("type", "?")
58 mid = msg.get("id", 0)
59 print(f"[fake-ui] recv type={t} id={mid}", flush=True)
60
61 if t == "ask_rule":
62 conn_info = msg.get("connection", {})
63 print(f"[fake-ui] app={conn_info.get('process_path')} "
64 f"dst={conn_info.get('dst_host') or conn_info.get('dst_ip')}"
65 f":{conn_info.get('dst_port')}", flush=True)
66 send_frame(conn, {
67 "type": "ask_rule_reply",
68 "id": mid,
69 "action": "allow",
70 "duration": "once",
71 "rule_name": "fake-ui-auto-allow",
72 })
73 print(f"[fake-ui] sent ask_rule_reply id={mid} action=allow", flush=True)
74 elif t == "alert":
75 text = msg.get("text", "")
76 if text:
77 print(f"[fake-ui] alert: {text}", flush=True)
78
79
80def main() -> int:
81 sock_path = sys.argv[1] if len(sys.argv) > 1 else "/tmp/bsd-daemon.sock"
82 if os.path.exists(sock_path):
83 os.remove(sock_path)
84
85 srv = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
86 srv.bind(sock_path)
87 os.chmod(sock_path, 0o666)
88 srv.listen(1)
89 print(f"[fake-ui] in ascolto su {sock_path} (Ctrl-C per uscire)", flush=True)
90
91 try:
92 while True:
93 conn, _ = srv.accept()
94 print("[fake-ui] daemon connesso", flush=True)
95 try:
96 handle_client(conn)
97 finally:
98 conn.close()
99 print("[fake-ui] daemon disconnesso, aspetto nuova connessione", flush=True)
100 except KeyboardInterrupt:
101 print("\n[fake-ui] stop", flush=True)
102 finally:
103 try:
104 os.remove(sock_path)
105 except FileNotFoundError:
106 pass
107 return 0
108
109
110if __name__ == "__main__":
111 sys.exit(main())
int main()
Definition fake_ui.py:80
None send_frame(socket.socket conn, dict msg)
Definition fake_ui.py:34
bytes|None read_exact(socket.socket conn, int n)
Definition fake_ui.py:24
None handle_client(socket.socket conn)
Definition fake_ui.py:39