IMAP-Server-Grundgerüst: TCP-Listener, Command-Parser, Session- Zustandsmaschine (Not Authenticated/Authenticated/Selected), Grundbefehle CAPABILITY/LOGIN/SELECT/FETCH/LOGOUT. - parser.go: Tag+Kommando+Argumente (Atome, zitierte Zeichenketten), keine IMAP-Literalsyntax (kleinste Lösung). - response.go: sanitizeResponseText entfernt eingebettete CR/LF vor jeder Antwortzeile — bekannten archivmail-Fehler (Header-/Zeilen-Injection durch Stringkonkatenation ohne CRLF-Prüfung) strukturell vermieden. - session.go/commands.go: strikte Zustandsprüfung je Kommando, verbotene Übergänge und fehlerhafte Zeilen liefern BAD/NO statt Verbindungsabbruch. maxCommandLineBytes begrenzt Pufferwachstum defensiv. - server.go: TCP-Accept-Schleife, eine Goroutine je Verbindung. - Authenticator/MailboxStore als schmale Schnittstellen — echte Benutzerverwaltungs-/Postfach-Anbindung ist Sache von IMP-01 u. a. Prüfungen (alle real durchgeführt, siehe mail/docs/ING-01-PRUEFPROTOKOLL.md): 1. Manuelle Session mit Pythons imaplib gegen den echten laufenden Server: alle Grundbefehle real beantwortet, ungültiges SELECT liefert real NO ohne Verbindungsabbruch. 2. TestSession_StateTransitionsAndForbiddenTransitions: alle drei Zustandsübergänge und deren verbotene Übergänge real über TCP geprüft. 3. TestServer_50ParallelSessionsNoLeak: 50 reale parallele Sessions, 0 Fehler. Kein Umbau: alle bestehenden Pakete unverändert. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HhgFcLS8tYMhDJpP74C6AQ
4.2 KiB
4.2 KiB
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 mitCAPABILITY/LOGIN/SELECT/FETCH/LOGOUT, strikte Zustandsprüfung je Kommando (Akzeptanzkriterium 1), fehlerhafte Zeilen/unbekannte Kommandos/verbotene Zustandsübergänge liefern eineBAD/NO-Antwort statt eines Verbindungsabbruchs (Akzeptanzkriterium 3).maxCommandLineBytesbegrenzt 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/MailboxStoresind schmale Schnittstellen — echte Benutzerverwaltungs-/Postfach-Anbindung ist Sache von IMP-01 u. a. („Nicht Bestandteil dieser Kachel"), dieses Paket kennt weder Core-IAM nochmail/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.