Files
chimera-gfx-Public/tools/phase10w_shsrv_client_policy.py
Chimera GFX release export a6037502d7
phase0-ci / build-and-audit (push) Successful in 2m14s
Publish Chimera GFX source
2026-09-03 03:27:14 +02:00

181 lines
6.8 KiB
Python

#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-3.0-or-later
"""Offline policy model for a future one-shot shsrv client.
There is intentionally no transport, CLI, socket, DNS lookup, file output or
clock acquisition. Tests supply synthetic records and an explicit host time.
"""
from __future__ import annotations
from dataclasses import dataclass
from datetime import datetime, timedelta
import re
from typing import Any
from phase10v_shsrv_collector_model import (
CollectorError as CollectorModelError,
OfflineCollector,
)
COLLECTOR_SHA256 = \
"f8a306dafee5d135919bec5afda789dd741e57f39803b7683fb8747c186db25c"
SOURCE_BOUND_PORT = 2323
MAX_DEADLINE_SECONDS = 10
MAX_APPROVAL_LIFETIME = timedelta(minutes=15)
WINDOW_COMMANDS = {
"T2_GREETING_AND_HELP": ("help",),
"T3_ONE_EXACT_PATH": ("stat", "sum"),
}
ACTIVATION_FIELDS = {
"active", "policy_sha256", "collector_sha256", "run_id",
"target_address", "target_port", "window", "exact_literal_path",
"commands", "deadline_seconds", "expires_at",
}
REQUIRED_TRUE_FIELDS = {
"ps5_connection_authorized", "device_request_authorized",
"result_receive_authorized", "spawned_shell_effects_accepted",
"automatic_serial_query_accepted", "automatic_telemetry_query_accepted",
"sanitized_output_only_accepted",
"physical_memory_erasure_unproven_accepted",
}
REQUIRED_FALSE_FIELDS = {
"target_build_authorized", "device_transfer_authorized",
"device_execution_authorized", "installation_authorized",
"autoload_authorized", "device_write_authorized", "automatic_retry",
"reconnect_authorized", "resume_authorized", "fallback_authorized",
}
APPROVAL_FIELDS = ACTIVATION_FIELDS | REQUIRED_TRUE_FIELDS | \
REQUIRED_FALSE_FIELDS | {"attested", "listener_already_running_attested"}
class PolicyError(RuntimeError):
"""Fail-closed policy error without record values."""
@dataclass(frozen=True)
class SessionPlan:
"""Immutable plan only; it has no method capable of network I/O."""
run_id: str
target_address: str
target_port: int
window: str
exact_literal_path: str | None
commands: tuple[str, ...]
deadline_seconds: int
expires_at: datetime
def inactive_record_is_inert(record: dict[str, Any]) -> bool:
return record == {
"active": False,
"policy_sha256": None,
"collector_sha256": None,
"run_id": None,
"target_address": None,
"target_port": None,
"window": None,
"exact_literal_path": None,
"commands": [],
"deadline_seconds": None,
"expires_at": None,
}
def _parse_expiry(value: Any, now: datetime) -> datetime:
if not isinstance(value, str):
raise PolicyError("expiry is missing")
try:
expiry = datetime.fromisoformat(value.replace("Z", "+00:00"))
except ValueError as error:
raise PolicyError("expiry format is invalid") from error
if now.tzinfo is None or expiry.tzinfo is None:
raise PolicyError("expiry must be timezone aware")
if not now < expiry <= now + MAX_APPROVAL_LIFETIME:
raise PolicyError("approval is expired or too long")
return expiry
def _validate_target(value: Any) -> str:
if not isinstance(value, str) or not re.fullmatch(
r"[A-Za-z0-9](?:[A-Za-z0-9.-]{0,251}[A-Za-z0-9])?", value):
raise PolicyError("target syntax is invalid")
if ".." in value:
raise PolicyError("target syntax is invalid")
return value
def _validate_authority(record: dict[str, Any]) -> None:
if not all(record.get(field) is True for field in REQUIRED_TRUE_FIELDS):
raise PolicyError("required authority or effect acceptance is missing")
if not all(record.get(field) is False for field in REQUIRED_FALSE_FIELDS):
raise PolicyError("forbidden authority is active")
def build_session_plan(
activation: dict[str, Any], approval: dict[str, Any], now: datetime,
) -> SessionPlan:
"""Validate dual synthetic records and return an immutable offline plan."""
if set(activation) != ACTIVATION_FIELDS or set(approval) != APPROVAL_FIELDS:
raise PolicyError("record shape is not exact")
if activation.get("active") is not True or approval.get("active") is not True:
raise PolicyError("activation is inactive")
if approval.get("attested") is not True:
raise PolicyError("operator attestation is missing")
if approval.get("listener_already_running_attested") is not True:
raise PolicyError("listener attestation is missing")
_validate_authority(approval)
matching_fields = (
"policy_sha256", "collector_sha256", "run_id", "target_address", "target_port",
"window", "exact_literal_path", "commands", "deadline_seconds",
"expires_at",
)
if any(activation.get(field) != approval.get(field)
for field in matching_fields):
raise PolicyError("activation and approval do not match")
if activation.get("collector_sha256") != COLLECTOR_SHA256:
raise PolicyError("collector identity mismatch")
if not isinstance(activation.get("policy_sha256"), str) or \
not re.fullmatch(r"[0-9a-f]{64}", activation["policy_sha256"]):
raise PolicyError("policy identity syntax is invalid")
run_id = activation.get("run_id")
if not isinstance(run_id, str) or not re.fullmatch(
r"[A-Za-z0-9_-]{8,64}", run_id):
raise PolicyError("run identifier is invalid")
target = _validate_target(activation.get("target_address"))
if activation.get("target_port") != SOURCE_BOUND_PORT:
raise PolicyError("target port mismatch")
window = activation.get("window")
if window not in WINDOW_COMMANDS:
raise PolicyError("window is not allowlisted")
commands = activation.get("commands")
if commands != list(WINDOW_COMMANDS[window]):
raise PolicyError("command sequence mismatch")
path = activation.get("exact_literal_path")
if window == "T2_GREETING_AND_HELP" and path is not None:
raise PolicyError("help window cannot include a path")
if window == "T3_ONE_EXACT_PATH":
if not isinstance(path, str):
raise PolicyError("exact path is missing")
try:
OfflineCollector._validate_expected_paths({path})
except CollectorModelError as error:
raise PolicyError("exact path is invalid") from error
deadline = activation.get("deadline_seconds")
if not isinstance(deadline, int) or isinstance(deadline, bool) or \
not 1 <= deadline <= MAX_DEADLINE_SECONDS:
raise PolicyError("deadline is invalid")
expiry = _parse_expiry(activation.get("expires_at"), now)
return SessionPlan(
run_id=run_id,
target_address=target,
target_port=SOURCE_BOUND_PORT,
window=window,
exact_literal_path=path,
commands=WINDOW_COMMANDS[window],
deadline_seconds=deadline,
expires_at=expiry,
)