"""Fixed supervisor-side access capability. Embed alongside the C01 supervisor. Acquire before launch and retain on root Supervisor through complete retirement. Never inherit this connection into role children; they do not own admission. The existing runtime broker uses runtime-access-v1; this client owns the distinct exclusive supervisor-access-v1 lifetime bound to the protected launch digest. """ import json import os from pathlib import Path import select import socket import stat import struct SOCKET = Path('/run/archipelago-c01/runtime-access.sock') class AccessLease: def __init__(self, launch_sha256): if not (type(launch_sha256) is str and len(launch_sha256) == 64 and all(c in '0123456789abcdef' for c in launch_sha256)): raise ValueError('protected launch digest required') self.channel = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET | socket.SOCK_CLOEXEC) self.pidfd = None try: for path in reversed(SOCKET.parents): meta = path.lstat() if not stat.S_ISDIR(meta.st_mode) or meta.st_uid != 0 or meta.st_mode & 0o022: raise ValueError('unprotected access socket ancestry') meta = SOCKET.lstat() if not stat.S_ISSOCK(meta.st_mode) or (meta.st_uid, meta.st_gid) != (0, 0) or meta.st_mode & 0o077: raise ValueError('unprotected access socket') # Candidate admission waits for an in-flight obsolete scan and a # new generation check; the owner's absolute evidence fence is 5s. self.channel.settimeout(6) self.channel.connect(str(SOCKET)) pid, uid, gid = struct.unpack('3i', self.channel.getsockopt(socket.SOL_SOCKET, socket.SO_PEERCRED, 12)) if pid <= 1 or (uid, gid) != (0, 0): raise ValueError('access owner credentials refused') self.pidfd = os.pidfd_open(pid) request = {'protocol': 'supervisor-access-v1', 'configuration_sha256': launch_sha256, 'nonce': os.urandom(32).hex()} raw = json.dumps(request, separators=(',', ':')).encode() if self.channel.send(raw) != len(raw): raise ValueError('access challenge delivery failed') # Exact bytes are unnecessary (provider JSON formatting can differ), # but fields, nonce and digest must match exactly. No FD transfer. response, ancillary, flags, _ = self.channel.recvmsg(1025, 0) if flags or ancillary or len(response) > 1024 or json.loads(response) != request: raise ValueError('access capability refused') self.channel.setblocking(False) self.check() except BaseException: self.close() raise def check(self): if self.pidfd is None or select.select([self.channel, self.pidfd], [], [], 0)[0]: raise ValueError('access enforcement ownership lost') def close(self): self.channel.close() if self.pidfd is not None: os.close(self.pidfd) self.pidfd = None