diff --git a/red-queen-architecture/control-plane/cp2a2_2b/rq-historical b/red-queen-architecture/control-plane/cp2a2_2b/rq-historical index 6263937..3ce344f 100755 --- a/red-queen-architecture/control-plane/cp2a2_2b/rq-historical +++ b/red-queen-architecture/control-plane/cp2a2_2b/rq-historical @@ -2553,13 +2553,54 @@ remediation_archive_classification() { # echo: NO|PARTIAL|VALID|INVALID|UNKNOWN echo "INVALID"; return fi # --- PARTIAL vs UNKNOWN (RAIN Hotfix: fail-closed-Semantik) --- - # PARTIAL nur wenn klar unvollstaendig/orphan: image.tar fehlt oder ist leer. - # (NICHT bei blosser Anomalie — Symlink/widerspruechliche Metadata ist UNKNOWN.) - if [ ! -f "$img" ] || [ ! -s "$img" ]; then + # PARTIAL nur wenn sicher erkennbar unvollstaendig UND alle Safety-Gates PASS: + # - kontrollierter candidates-Pfad (base = $sdir/$sid, gebunden an aktive Session) + # - mindestens ein Archive-Artefakt vorhanden + # - vollstaendige VALID-Struktur fehlt + # - kein widerspruechliches/unerwartetes Fremdartefakt + # - keine Symlinks, keine Mountpoints, keine falsche Image-ID + # - kein anderes Session-/Image-Metadata-Binding + # - kein valides vollstaendiges Archive + # UNKNOWN wenn Zustand nicht sicher klassifizierbar (fail closed). + local has_any=0 + [ -e "$base/image.tar" ] && has_any=1 + [ -e "$base/session.meta" ] && has_any=1 + [ -e "$base/app.manifest" ] && has_any=1 + [ -e "$base/runtime-config.txt" ] && has_any=1 + [ -e "$base/image.tar.sha256" ] && has_any=1 + [ "$has_any" = "0" ] && { echo "NO"; return; } # kein Artefakt -> NO + # Safety: keine Symlinks im Ziel (Datei ODER Verzeichnis) + if [ -L "$base" ] || [ -L "$base/image.tar" ] || [ -L "$base/session.meta" ] || \ + [ -L "$base/app.manifest" ] || [ -L "$base/runtime-config.txt" ] || [ -L "$base/image.tar.sha256" ]; then + echo "UNKNOWN"; return + fi + # Safety: kein Mountpoint / Bind-Mount + if mountpoint -q "$base" 2>/dev/null || grep -qE " $base( |$)" /proc/mounts 2>/dev/null; then + echo "UNKNOWN"; return + fi + # Safety: keine unerwarteten Extrafiles (nur die 5 bekannten Artefakte erlaubt) + local extra="" + for f in "$base"/*; do + [ -e "$f" ] || continue + local bn; bn="${f##*/}" + case "$bn" in + image.tar|session.meta|app.manifest|runtime-config.txt|image.tar.sha256) : ;; + *) extra="$extra $bn" ;; + esac + done + [ -n "$extra" ] && { echo "UNKNOWN"; return; } # Fremdartefakt -> UNKNOWN + # PARTIAL: image.tar valide vorhanden, aber Metadaten-Struktur unvollstaendig + # (session.meta/app.manifest/runtime-config.txt/image.tar.sha256 fehlt mind. eines) + if [ -f "$base/image.tar" ] && [ -s "$base/image.tar" ] && \ + { [ ! -f "$base/session.meta" ] || [ ! -f "$base/app.manifest" ] || \ + [ ! -f "$base/runtime-config.txt" ] || [ ! -f "$base/image.tar.sha256" ]; }; then echo "PARTIAL"; return fi - # Sonst: image.tar vorhanden+valide, aber Metadata/Manifest/Runtime unvollstaendig - # oder widerspruechlich -> nicht sicher klassifizierbar -> UNKNOWN (fail closed). + # PARTIAL: image.tar fehlt/leer, aber andere Artefakte vorhanden (orphan) + if [ ! -f "$base/image.tar" ] || [ ! -s "$base/image.tar" ]; then + echo "PARTIAL"; return + fi + # Sonst: nicht sicher klassifizierbar -> UNKNOWN (fail closed) echo "UNKNOWN"; return }