ISO-Build: root_password_hash fuer Diagnosezugang, Geheimnisse per stdin statt Argument (ADR-0035)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 5.5 committed 2026-10-02 14:18:26 +02:00
1 parent e0e60ef828
commit cec4dcb2d6
1 file changed
+25 -3
+25 -3
View File
@@ -286,6 +286,9 @@ class CreateIsoBuildRequest(BaseModel):
activation_code: str
wifi_ssid: str | None = None
wifi_psk: str | None = None
# Diagnosezugang (02.10.2026): nur der SHA-512-crypt-Hash, nie das
# Passwort selbst - das kennt allein die Kundenplattform (Root-Admin).
root_password_hash: str | None = None
class CreateOrganisationseinheitRequest(BaseModel):
@@ -3721,7 +3724,13 @@ def compute_file_sha256(path) -> str:
return hasher.hexdigest()
def run_iso_build(build_id, organization_id: str, activation_code: str, wifi_ssid: str | None, wifi_psk: str | None) -> None:
ROOT_PASSWORD_HASH_PATTERN = re.compile(r"^\$6\$[./A-Za-z0-9]{1,16}\$[./A-Za-z0-9]{86}$")
def run_iso_build(
build_id, organization_id: str, activation_code: str, wifi_ssid: str | None, wifi_psk: str | None,
root_password_hash: str | None = None,
) -> None:
output_path = ISO_BUILD_OUTPUT_DIR / f"{build_id}.iso"
update_iso_build(build_id, status="running", mark_started=True)
@@ -3745,9 +3754,13 @@ def run_iso_build(build_id, organization_id: str, activation_code: str, wifi_ssi
str(output_path),
activation_code,
wifi_ssid or "",
wifi_psk or "",
# Geheimnisse per stdin statt als Argument (Kunden-ISO-Test
# 02.10.2026, Befund B6): Argumente landen ueber sudo im
# Klartext im Journal - siehe build_customer_iso.sh.
"-",
volid,
],
input=f"WIFI_PSK={wifi_psk or ''}\nROOT_PASSWORD_HASH={root_password_hash or ''}\n",
cwd=TUXFLOTTE_INSTALLER_DIR,
capture_output=True,
text=True,
@@ -5000,13 +5013,22 @@ def create_iso_build_endpoint(
if not payload.activation_code.strip():
return {"success": False, "error": "invalid_request", "message": "activation_code darf nicht leer sein."}
if payload.root_password_hash and not ROOT_PASSWORD_HASH_PATTERN.match(payload.root_password_hash):
return {"success": False, "error": "invalid_request", "message": "root_password_hash ist kein gültiger SHA-512-crypt-Hash."}
if payload.wifi_psk and "\n" in payload.wifi_psk:
return {"success": False, "error": "invalid_request", "message": "wifi_psk darf keinen Zeilenumbruch enthalten."}
ISO_BUILD_OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
iso_build = create_iso_build(organization_id)
thread = threading.Thread(
target=run_iso_build,
args=(UUID(iso_build["id"]), organization_id, payload.activation_code, payload.wifi_ssid, payload.wifi_psk),
args=(
UUID(iso_build["id"]), organization_id, payload.activation_code, payload.wifi_ssid, payload.wifi_psk,
payload.root_password_hash,
),
daemon=True,
)
thread.start()