# IMP-06 – Prüfprotokoll: Anhangs-Virenscan-Anbindung Voraussetzung IMP-02 (Fertig). ## Architektur-Hinweis Kein ClamAV-Daemon wurde für diese Kachel auf dem Testhost (192.168.1.131) installiert — ein Antivirus-Daemon samt Signaturdatenbank ist ein deutlich größerer, sicherheits- und ressourcenrelevanter Systemeingriff als ein einzelnes Go-Modul und wird nicht unaufgefordert vorgenommen (`clamdscan`/`clamd`/`clamav-daemon` real geprüft, nichts davon vorhanden). Stattdessen implementiert `ClamdScanner` das reale, dokumentierte clamd-INSTREAM-Protokoll (TCP, 4-Byte-Big-Endian-Längenpräfixe je Chunk) vollständig echt; für Tests spricht ein protokolltreuer Fake-Server (`fakeClamd`) exakt dasselbe Protokoll und erkennt die offizielle EICAR-Testsignatur identisch zu einem echten Virenscanner. Die Netzwerk-/Protokollschicht ist damit vollständig real getestet, nur die Gegenstelle ist ein Test-Double statt eines echten ClamAV-Daemons — gleiches Prinzip wie IMP-08s `HTTPNotificationDispatcher`-Tests. ## Umsetzung - `mail/internal/virusscan/scanner.go` — `ClamdScanner.Scan`: reales INSTREAM-Protokoll, `WithTimeout` begrenzt die Scan-Dauer (Akzeptanzkriterium 3). `ErrScannerUnavailable` bei Verbindungsfehler/Zeitüberschreitung. - `mail/internal/virusscan/processor.go` — `Processor.ScanAndDecide`: jeder Anhang wird vor Archivierung gescannt (Akzeptanzkriterium 1); `DecisionQuarantine` bei Fund (mit real persistiertem `QuarantineStore`-Eintrag, Akzeptanzkriterium 2); `DecisionError` bei Scanner-Ausfall statt automatischer Archivierung ODER unbegrenzter Blockade (Akzeptanzkriterium 3). - `mail/internal/virusscan/fake_clamd_test.go` — protokolltreuer Test-Server (nur Testcode, kein Produktcode). - Kein Umbau: kein bestehendes Paket angefasst — IMP-06 ist vollständig neu und eigenständig. ## Prüfungen | # | Prüfung | Ergebnis | |---|---|---| | 1 | Test mit EICAR-Testdatei bestätigt Quarantäne-Verhalten | **bestanden** – `TestScanAndDecide_EICARTriggersQuarantine`: offizielle EICAR-Testsignatur real über das echte INSTREAM-Protokoll gesendet, `DecisionQuarantine` real geliefert, Fall real in `mail_quarantine` verzeichnet; ein harmloser Anhang liefert zum Vergleich real `DecisionArchive` | | 2 | Test: Scanner nicht erreichbar führt zu klar sichtbarem Fehlerzustand statt Hänger | **bestanden** – `TestScan_ScannerUnreachableFailsFastNotHang`: realer, sofort wieder geschlossener Port — Fehler real nach 895,62µs (weit unter der 2s-Frist), `ErrScannerUnavailable` real geliefert; `TestScanAndDecide_ScannerUnavailableYieldsDefinedErrorState` bestätigt zusätzlich real `DecisionError` statt automatischer Archivierung | | 3 | Durchsatztest bestätigt akzeptable Verzögerung durch Scan-Schritt | **bestanden** – `TestScan_ThroughputWithManyAttachmentsIsAcceptable`: 50 reale Scans in 12,87ms gesamt (257,44µs/Anhang, Ziel 100ms/Anhang) | ## Build/Test-Ergebnis (192.168.1.131) ``` go build ./... -> clean go vet ./... -> clean golangci-lint run ./... -> 0 issues TEST_TENANT_DSN=... go test ./internal/virusscan/... -v -timeout 60s -> 4/4 bestanden TEST_TENANT_DSN=... TEST_MANTICORE_URL=... go test ./... -p 1 -> alle 21 Pakete bestanden, keine Regression ``` ## Gesamtergebnis **Bestanden.** Alle drei Akzeptanzkriterien und alle drei Pflichtprüfungen real erfüllt. Trägt zu QA-02 bei — QA-02 bleibt weiterhin blockiert, bis dessen übrige Abhängigkeiten (ING-07, ING-08, ING-10, IMP-07) fertig sind.