package agent import ( "strings" "testing" ) // TestRestoreTargetGuardBlocksSystemDirectories ist der Kerntest der // Agenten-Wiederherstellung. // // Der Agent schreibt auf **sein eigenes** System. Ein Auftrag, der nach /etc // zurueckschreibt, ueberschriebe das laufende Betriebssystem des gesicherten // Rechners — und der Server kann das nicht verhindern: Er kennt die // Verzeichnisstruktur eines fremden Systems nicht, und ein Windows-Agent hat // andere Systempfade als ein Linux-Server. // // Die Pruefung gehoert deshalb auf das empfangende System, nicht nur auf den // Server (wo sie seit Phase 19 ebenfalls steht). func TestRestoreTargetGuardBlocksSystemDirectories(testInstance *testing.T) { forbiddenTargets := []string{ "/etc", "/etc/cron.d", "/usr/local/bin", "/bin", "/sbin", "/boot/grub", "/var/lib/postgresql", "/System/Library", "/private/etc/hosts", "/root/.ssh", "/", } for _, target := range forbiddenTargets { if guardError := validateRestoreTarget(target); guardError == nil { testInstance.Errorf("das Systemverzeichnis %q wurde als Wiederherstellungsziel "+ "zugelassen", target) } } } // TestRestoreTargetGuardAllowsOrdinaryTargets prueft die Gegenprobe. // // Ein Schutz, der auch die legitimen Ziele sperrt, macht die Wiederherstellung // unbrauchbar — und wer ihn deswegen abschaltet, hat gar keinen mehr. func TestRestoreTargetGuardAllowsOrdinaryTargets(testInstance *testing.T) { allowedTargets := []string{ "/srv/wiederherstellung", "/home/benutzer/daten", "/mnt/ziel", "/data/restore-2026", testInstance.TempDir(), } for _, target := range allowedTargets { if guardError := validateRestoreTarget(target); guardError != nil { testInstance.Errorf("das gewöhnliche Ziel %q wurde gesperrt: %v", target, guardError) } } } // TestRestoreTargetGuardIsNotFooledByPrefixes prueft den Pfadvergleich. // // Ein Vergleich ueber strings.HasPrefix haelt "/etchen" fuer einen Teil von // "/etc" — derselbe Fund wie beim TargetGuard des Servers (Phase 19). func TestRestoreTargetGuardIsNotFooledByPrefixes(testInstance *testing.T) { lookalikeTargets := []string{"/etchen", "/var/library", "/usrdaten", "/bindungen"} for _, target := range lookalikeTargets { if guardError := validateRestoreTarget(target); guardError != nil { testInstance.Errorf("das Ziel %q wurde fälschlich gesperrt: %v", target, guardError) } } } // TestRestoreTargetGuardResolvesEscapes prueft Rueckwaertsschritte. // // "/srv/../etc" ist "/etc". Ohne Bereinigung liefe der Vergleich gegen die // Zeichenkette statt gegen den tatsaechlichen Pfad. func TestRestoreTargetGuardResolvesEscapes(testInstance *testing.T) { escapeAttempts := []string{"/srv/../etc", "/tmp/../etc/cron.d", "/home/x/../../etc"} for _, target := range escapeAttempts { if guardError := validateRestoreTarget(target); guardError == nil { testInstance.Errorf("der Ausbruchsversuch %q wurde zugelassen", target) } } } // TestRestoreTargetErrorNamesTheReason prueft die Fehlermeldung. func TestRestoreTargetErrorNamesTheReason(testInstance *testing.T) { guardError := validateRestoreTarget("/etc/beliebig") if guardError == nil { testInstance.Fatal("das Systemverzeichnis wurde zugelassen") } if !strings.Contains(guardError.Error(), "systemverzeichnis") { testInstance.Errorf("die Meldung nennt den Grund nicht: %v", guardError) } } // TestCompressionLevelFallsBackSafely prueft die Auftragsdeutung. // // Ein neuerer Server koennte eine Stufe kennen, die dieser Agent nicht hat. // Die Sicherung deswegen ausfallen zu lassen waere unverhaeltnismaessig. func TestCompressionLevelFallsBackSafely(testInstance *testing.T) { if resolveCompressionLevel("eine-kuenftige-stufe") != resolveCompressionLevel("balanced") { testInstance.Error("eine unbekannte Kompressionsstufe ergibt nicht die ausgewogene") } if resolveCompressionLevel("off") == resolveCompressionLevel("maximum") { testInstance.Error("bekannte Stufen werden nicht unterschieden") } }