#!/usr/bin/python3 """GERAMEG CUA-TTY with the explicitly selected local-user input policy. Reuse the installed LocalServer and Manager without changing their source, socket protocol, existing demos and PTY handling, or input/session limits for demos. Remote callers must still enter through authenticated FrameBridge. This process authenticates LOCAL peers by the original LocalServer's SO_PEERCRED check. It cannot distinguish an authenticated FBEXEC process from another process running as gerabh (UID 1000). Both have the same local authority. The legacy owner_assertion RPC field remains mandatory for wire compatibility but must be an empty object. It is not a grant, signature, or approval flag. No Owner R12 signing code, private keys, or FBAUTH state is loaded. """ from __future__ import annotations import argparse import os from pathlib import Path import re import signal import stat EXPECTED_UID = 1000 EXPECTED_HOST = "GERAMEG" DEFAULT_SOCKET = "/run/user/1000/framebridge-alpha01-cua/agent.sock" _SESSION_ID = re.compile(r"[a-f0-9]{32}\Z") _PAYLOAD_HASH = re.compile(r"[a-f0-9]{64}\Z") _CONTEXT_FIELDS = frozenset( {"session_id", "program", "operation", "payload_sha256", "owner_assertion"} ) def require_local_identity() -> None: if ( os.getuid() != EXPECTED_UID or os.geteuid() != EXPECTED_UID or os.uname().nodename.upper() != EXPECTED_HOST ): raise RuntimeError("CUA_LOCAL_UID_OR_HOST_INVALID") class LocalUidVerifier: """Apply the selected UID policy after LocalServer checks the peer UID. Manager constructs this context after resolving its own live session and validating the input. No caller-provided boolean or assertion grants access. """ def __call__(self, context: object) -> bool: try: require_local_identity() if type(context) is not dict or set(context) != _CONTEXT_FIELDS: return False if context.get("program") not in ("demo-readonly", "bash"): return False if context.get("operation") not in ("key.send", "text.type"): return False session_id = context.get("session_id") payload_hash = context.get("payload_sha256") if type(session_id) is not str or _SESSION_ID.fullmatch(session_id) is None: return False if type(payload_hash) is not str or _PAYLOAD_HASH.fullmatch(payload_hash) is None: return False assertion = context.get("owner_assertion") return type(assertion) is dict and not assertion except (AttributeError, OSError, RuntimeError, TypeError, ValueError): return False def _stop(_signum: int, _frame: object) -> None: # Exiting the LocalServer context closes only this runtime's own sessions # and socket. Do not leave a stale socket after a normal systemd stop. raise SystemExit(0) def main(argv: list[str] | None = None) -> None: parser = argparse.ArgumentParser(description="GERAMEG CUA-TTY local UID policy") parser.add_argument("--socket", default=DEFAULT_SOCKET) args = parser.parse_args(argv) require_local_identity() if args.socket != DEFAULT_SOCKET: raise RuntimeError("CUA_LOCAL_SOCKET_INVALID") parent = Path(args.socket).parent try: parent_state = parent.lstat() except FileNotFoundError: # LocalServer creates its own private directory with mode 0700. pass else: if ( not stat.S_ISDIR(parent_state.st_mode) or parent_state.st_uid != EXPECTED_UID or stat.S_IMODE(parent_state.st_mode) != 0o700 ): raise RuntimeError("CUA_LOCAL_SOCKET_PARENT_UNTRUSTED") # Keep imports on the existing service's installed PYTHONPATH. This file # does not copy, patch, or replace the original CUA-TTY package. from framebridge_cua_tty.core import Manager from framebridge_cua_tty.server import LocalServer from real_tty_manager import RealTerminalMixin class LocalPolicyManager(RealTerminalMixin, Manager): def status(self): value = super().status() # A callable verifier is not evidence of an Owner device. Report # the selected authority honestly while retaining session status. value["owner_device_connected"] = False value["input_enabled"] = "same-uid-1000" value["input_policy"] = "local-uid-1000" value["owner_signature_required"] = False return value manager = LocalPolicyManager( owner_verifier=LocalUidVerifier(), max_sessions=2, idle_timeout_s=600 ) signal.signal(signal.SIGTERM, _stop) with LocalServer(args.socket, manager=manager) as server: print("CUA_TTY_READY POLICY=LOCAL_UID_1000 OWNER_SIGNATURE_REQUIRED=NO", flush=True) try: server.serve_forever(poll_interval=0.2) except KeyboardInterrupt: pass if __name__ == "__main__": main()