# ING-01 – Prüfprotokoll: IMAP-Server-Grundgerüst Keine Vorbedingungen im Mail-Board (sofort startbar). ## Umsetzung - `mail/internal/imap/state.go` — `State` (`NotAuthenticated`, `Authenticated`, `Selected`, RFC 3501 §3). - `mail/internal/imap/parser.go` — `parseCommandLine`/`tokenize`: Tag + Kommando + Argumente (Atome und doppelt zitierte Zeichenketten), keine IMAP-Literalsyntax (`{n}CRLF...` — bewusst nicht Bestandteil der kleinsten Lösung, LOGIN/SELECT/FETCH kommen ohne Literale aus). - `mail/internal/imap/response.go` — `sanitizeResponseText`: Bekannten Fehler vermieden (archivmail: Header-/Zeilen-Injection durch Stringkonkatenation ohne CRLF-Prüfung) — jede Antwortzeile entfernt eingebettete CR/LF, bevor sie geschrieben wird, keine direkte Interpolation von Nutzereingaben in eine Rohantwort. - `mail/internal/imap/session.go`/`commands.go` — Session- Zustandsmaschine mit `CAPABILITY`/`LOGIN`/`SELECT`/`FETCH`/`LOGOUT`, strikte Zustandsprüfung je Kommando (Akzeptanzkriterium 1), fehlerhafte Zeilen/unbekannte Kommandos/verbotene Zustandsübergänge liefern eine `BAD`/`NO`-Antwort statt eines Verbindungsabbruchs (Akzeptanzkriterium 3). `maxCommandLineBytes` begrenzt die Puffergröße defensiv (Vorbild Dovecot: defensive Fehlerbehandlung statt optimistischem Parsing). - `mail/internal/imap/server.go` — `Server.Serve`: TCP-Accept-Schleife, eine Goroutine je Verbindung. - `Authenticator`/`MailboxStore` sind schmale Schnittstellen — echte Benutzerverwaltungs-/Postfach-Anbindung ist Sache von IMP-01 u. a. („Nicht Bestandteil dieser Kachel"), dieses Paket kennt weder Core-IAM noch `mail/internal/storage`. - Kein Umbau: alle bestehenden Pakete unverändert — ING-01 fügt ausschließlich das neue `mail/internal/imap`-Paket hinzu. ## Prüfungen | # | Prüfung | Ergebnis | |---|---|---| | 1 | Manuelle Session mit Standard-IMAP-Client durchgespielt und protokolliert | **bestanden** – echte Session mit Pythons Standardbibliothek `imaplib` gegen den real laufenden Server auf 192.168.1.131 (Port 14300): CAPABILITY→OK, LOGIN→OK, SELECT INBOX→OK (`2` Nachrichten), FETCH 1:2 (FLAGS)→OK mit realen Flags, SELECT eines nicht existierenden Postfachs→NO OHNE Verbindungsabbruch, danach CAPABILITY erneut→OK, LOGOUT→BYE. Vollständiges Protokoll siehe unten | | 2 | Automatisierter Test deckt alle drei Zustandsübergänge und deren verbotene Übergänge ab | **bestanden** – `TestSession_StateTransitionsAndForbiddenTransitions`: SELECT/FETCH in NotAuthenticated→BAD, LOGIN→Authenticated, erneutes LOGIN/FETCH in Authenticated→BAD, SELECT→Selected, FETCH in Selected→OK — alle real über echte TCP-Verbindung gegen den echten Server geprüft | | 3 | Lasttest mit 50 parallelen Sessions ohne Ressourcenleck | **bestanden** – `TestServer_50ParallelSessionsNoLeak`: 50 reale, gleichzeitige TCP-Verbindungen, je vollständiger LOGIN→SELECT→FETCH→LOGOUT-Durchlauf, 0 Fehler | ### Manuelles Sitzungsprotokoll (Pflichtprüfung 1, real erzeugt) ``` CAPABILITY -> OK [b'IMAP4rev1'] LOGIN -> OK [b'LOGIN completed'] SELECT INBOX -> OK [b'2'] FETCH 1:2 (FLAGS) -> OK [b'1 (FLAGS (\\Seen))', b'2 (FLAGS ())'] SELECT NICHT_VORHANDEN (erwartet NO) -> NO [b'SELECT failed: no such mailbox'] CAPABILITY nach Fehler (Verbindung noch offen) -> OK [b'IMAP4rev1'] LOGOUT -> BYE [b'IMAP4rev1 Server logging out'] ``` Testserver und Testskript wurden nach der Prüfung wieder entfernt (Wegwerf-`cmd/imap-manual-test`, nicht Teil des Produktcodes). Zusätzlich (AC2/AC3, ergänzend real geprüft): `TestCommands_AllBaseCommandsAnswered` (alle fünf Grundbefehle real beantwortet) und `TestSession_MalformedLineDoesNotDisconnect` (syntaktisch fehlerhafte Zeile → `* BAD`, Verbindung bleibt real funktionsfähig). ## Build/Test-Ergebnis (192.168.1.131) ``` go build ./... -> clean go vet ./... -> clean golangci-lint run ./... -> 0 issues go test ./internal/imap/... -v -timeout 60s -> 5/5 bestanden TEST_TENANT_DSN=... TEST_MANTICORE_URL=... go test ./... -p 1 -> alle 12 Pakete bestanden, keine Regression ``` ## Gesamtergebnis **Bestanden.** Alle drei Akzeptanzkriterien und alle drei Pflichtprüfungen real erfüllt. Entsperrt IMP-01, ING-02, ING-05, ING-06, ING-07, ING-08, ING-10, QA-07.