package aptrepo import ( "bytes" "encoding/json" "os" "path/filepath" "server-deploy/internal/installplan" "syscall" "testing" "time" ) func TestStagingRejectsLinksAndFIFO(t *testing.T) { dir := t.TempDir() for _, name := range []string{"docker.asc", "Release", "Release.gpg", "Packages"} { if err := os.WriteFile(filepath.Join(dir, name), []byte("metadata"), 0600); err != nil { t.Fatal(err) } } link := filepath.Join(t.TempDir(), "link") if err := os.Symlink(dir, link); err != nil { t.Fatal(err) } if _, err := readStaging(link + "/"); err == nil { t.Fatal("root symlink accepted") } if err := os.Remove(filepath.Join(dir, "Release")); err != nil { t.Fatal(err) } if err := os.Symlink(filepath.Join(dir, "Packages"), filepath.Join(dir, "Release")); err != nil { t.Fatal(err) } if _, err := readStaging(dir); err == nil { t.Fatal("file symlink accepted") } if err := os.Remove(filepath.Join(dir, "Release")); err != nil { t.Fatal(err) } if err := syscall.Mkfifo(filepath.Join(dir, "Release"), 0600); err != nil { t.Fatal(err) } if _, err := readStaging(dir); err == nil { t.Fatal("FIFO accepted") } } func TestGPGFailureRedactsDiagnostics(t *testing.T) { if _, err := runGPG(t.TempDir(), "/nonexistent/signature-tool-secret"); err == nil || err.Error() != "repository signature tool failed" { t.Fatal("unredacted or absent error", err) } } func TestOutputBound(t *testing.T) { var b cappedOutput if _, err := b.Write(make([]byte, 65536)); err != nil { t.Fatal(err) } if _, err := b.Write([]byte{1}); err == nil { t.Fatal("output limit missing") } if b.Len() != 65536 { t.Fatal("buffer grew beyond limit") } } func TestStagedSignatureIntegration(t *testing.T) { // Explicit opt-in public fixture, downloaded by the metadata-only probe. dir := os.Getenv("DEPLOYCTL_REPOSITORY_FIXTURE") if dir == "" { t.Skip("public signed fixture not supplied; run repository probe for real signature evidence") } files, err := readStaging(dir) if err != nil { t.Fatal(err) } if err := authenticate(files, time.Now()); err != nil { t.Fatal(err) } // Result comes from the successful real CLI invocation. Recheck the exact // fixture versions before making a semantically valid signature mutation. var response struct { Lock installplan.Lock `json:"lock"` } raw, err := os.ReadFile(filepath.Join(dir, "result.json")) if err != nil { t.Fatal(err) } if err = json.Unmarshal(raw, &response); err != nil { t.Fatal(err) } versions := make(map[string]string) for _, p := range response.Lock.Packages { versions[p.Name] = p.Version } // Unknown Release extension remains valid metadata; only its signature // should reject it. This catches a bypass hidden by syntax failures. files["Release"] = append(bytes.TrimRight(files["Release"], "\n"), []byte("\nX-Verification-Probe: changed\n")...) if _, err := Resolve(files["Release"], files["Packages"], response.Lock.Suite, response.Lock.Architecture, versions, time.Now()); err != nil { t.Fatal("mutation masked by metadata rejection", err) } if err := authenticate(files, time.Now()); err == nil { t.Fatal("tampered signature accepted") } }