Initial server source import

This commit is contained in:
sashatrask
2026-09-30 20:30:56 +03:00
commit 170dd941b9
498 changed files with 261563 additions and 0 deletions
+131
View File
@@ -0,0 +1,131 @@
import os
import socket
import stat
import struct
import time
from host_agent_protocol import (
CLIENT_CONNECT_TIMEOUT_SECONDS,
EXCHANGE_TIMEOUT_SECONDS,
HOST_AGENT_SOCKET_PATH,
MAX_RESPONSE_PAYLOAD_BYTES,
HostAgentAction,
HostAgentProtocolError,
HostAgentRequest,
HostAgentStatus,
decode_response_frame,
encode_request_frame,
receive_frame,
require_eof,
send_frame,
)
class HostAgentClientError(RuntimeError):
def __init__(self, category):
self.category = category
super().__init__('host operations agent request failed')
class HostAgentUnavailableError(HostAgentClientError):
pass
class HostAgentRejectedError(HostAgentClientError):
pass
def _fixed_socket_is_safe():
try:
details = os.lstat(HOST_AGENT_SOCKET_PATH)
except OSError:
return False
return stat.S_ISSOCK(details.st_mode) and details.st_uid == 0
def _peer_credentials(sock):
if not hasattr(socket, 'SO_PEERCRED'):
raise HostAgentUnavailableError('peer_credentials_unavailable')
try:
raw = sock.getsockopt(
socket.SOL_SOCKET, socket.SO_PEERCRED, struct.calcsize('3i'),
)
pid, uid, gid = struct.unpack('3i', raw)
except (OSError, struct.error) as exc:
raise HostAgentUnavailableError('peer_credentials_unavailable') from exc
# A peer outside the client's PID namespace is reported as PID 0 even
# though its UID/GID remain authoritative through SO_PEERCRED.
if pid < 0:
raise HostAgentUnavailableError('peer_identity_invalid')
return pid, uid, gid
class HostAgentClient:
def __init__(self):
pass
@staticmethod
def is_available():
return _fixed_socket_is_safe()
def dispatch(
self, *, operation_id, action, active_config_sha256,
active_secrets_sha256, candidate_config_sha256,
candidate_secrets_sha256,
):
try:
request = HostAgentRequest(
operation_id=operation_id,
action=HostAgentAction(action),
active_config_sha256=active_config_sha256,
active_secrets_sha256=active_secrets_sha256,
candidate_config_sha256=candidate_config_sha256,
candidate_secrets_sha256=candidate_secrets_sha256,
)
frame = encode_request_frame(request)
except (HostAgentProtocolError, TypeError, ValueError) as exc:
raise HostAgentRejectedError('request_invalid') from exc
if not _fixed_socket_is_safe():
raise HostAgentUnavailableError('socket_unavailable')
deadline = time.monotonic() + EXCHANGE_TIMEOUT_SECONDS
connection = None
response = None
try:
family = getattr(socket, 'AF_UNIX', None)
if family is None:
raise HostAgentUnavailableError('unix_socket_unavailable')
connection = socket.socket(family, socket.SOCK_STREAM)
connection.settimeout(min(
CLIENT_CONNECT_TIMEOUT_SECONDS,
max(0.001, deadline - time.monotonic()),
))
connection.connect(HOST_AGENT_SOCKET_PATH)
_pid, peer_uid, _gid = _peer_credentials(connection)
if peer_uid != 0:
raise HostAgentUnavailableError('server_identity_invalid')
send_frame(connection, frame, deadline=deadline)
connection.shutdown(socket.SHUT_WR)
response = decode_response_frame(receive_frame(
connection, maximum=MAX_RESPONSE_PAYLOAD_BYTES, deadline=deadline,
))
require_eof(connection, deadline=deadline)
except HostAgentClientError:
raise
except HostAgentProtocolError as exc:
raise HostAgentUnavailableError('response_invalid') from exc
except (OSError, TimeoutError) as exc:
raise HostAgentUnavailableError('transport_unavailable') from exc
finally:
if connection is not None:
try:
connection.close()
except OSError:
pass
connection = frame = request = family = None
if response.operation_id != operation_id:
raise HostAgentUnavailableError('response_identity_invalid')
if response.status is HostAgentStatus.ACCEPTED:
return response
if response.status is HostAgentStatus.REJECTED:
raise HostAgentRejectedError('request_rejected')
raise HostAgentUnavailableError('request_unavailable')