# Lokaler Mailversand auf Hostsharing Read-only geprüft am 2026-09-09 auf `mih04-werkjournal@mih04.hostsharing.net`, dem tatsächlichen Deploymentkonto. ## Befund - `/usr/sbin/sendmail` gehört zu Postfix, installierte Version `3.7.11-0+deb12u1`. - `sendmail_path = /usr/sbin/sendmail`; das Programm liegt nicht im normalen PATH dieses SSH-Kontos. Die Anwendung muss den absoluten Pfad verwenden. - `authorized_submit_users = static:anyone` erlaubt lokale Einlieferung durch das Anwendungskonto. - `/usr/sbin/postdrop` ist mit Setgid-Gruppe `postdrop` installiert. Direkter Benutzerzugriff auf den geschützten Pickup-Socket ist nicht erforderlich; dessen Inspektion wurde vom Dateisystem erwartungsgemäß verweigert. - Postfix verwendet `myhostname = h68.hostsharing.net` und `myorigin = $myhostname`. Ohne explizite Absenderadresse würde nicht automatisch die Werkjournal-Domain verwendet. - Der systemd-User-Service hat `PrivateNetwork=no`, `NoNewPrivileges=no` und keine einschränkenden Adressfamilien-/Systemaufruffilter. - `mail`, `mailx` und `msmtp` sind zusätzlich installiert; für direkte Postfix-Einlieferung sind sie nicht notwendig. Damit ist eine lokale Sendmail-Schnittstelle vorhanden und laut Konfiguration für den App-User zugelassen. Es wurde keine E-Mail versendet, keine Queue verändert und keine Serverkonfiguration geändert. Annahme und tatsächliche externe Zustellung einschließlich Spam-Einstufung und Absenderauthentifizierung sind noch nicht bewiesen. ## Geplanter Anschluss Die Anwendung kann vollständige MIME-Nachrichten über die Standardeingabe an `/usr/sbin/sendmail` übergeben. Prozessargumente getrennt übergeben, keine Shell-Auswertung; expliziter Envelope-Absender und geprüfter Empfänger, begrenzte Laufzeit und Fehlerauswertung. Keine Login-Codes oder Links in Logs. SMTP-Zugangsdaten werden für diesen lokalen Weg nicht benötigt. Eine erfolgreiche Queue-Einlieferung ist keine Zustellbestätigung. Absender am 2026-09-09 bestätigt: `Werkjournal `. Die Anwendung verarbeitet keine Antworten und setzt kein Reply-To auf eine betreute Adresse. Deutsche und englische Login-Mails erhalten den Hinweis „Bitte nicht auf diese E-Mail antworten; Antworten werden nicht gelesen.“ beziehungsweise „Please do not reply to this email; replies are not monitored.“ Ein Antwort-Button im Mailprogramm kann dadurch nicht entfernt werden. Postfächer, Aliase und serverseitige Regeln für eingehende Antworten wurden nicht geändert. Eine ausdrücklich autorisierte Testmail an einen bestätigten Empfänger zur Zustellprüfung steht noch aus. CI nutzt einen kontrollierten Mailtransport ohne externen Versand. ## Autorisierte Einlieferungsprobe Am 2026-09-09 eine einzelne Testnachricht mit dem bestätigten Absender an den vom Betreiber ausdrücklich genannten Empfänger über `/usr/sbin/sendmail -i -f … -- …` eingeliefert. Exitcode 0: lokale Annahme erfolgreich. Kein Login-Code enthalten. Der Empfänger hat den Eingang dieser Testnachricht anschließend ausdrücklich bestätigt. Damit sind lokale Einlieferung und tatsächliche Zustellung für diese Probe nachgewiesen. Eine generelle Zustellgarantie oder Aussage zur Spam-Einstufung anderer Nachrichten folgt daraus nicht. ## Anwendungsadapter `SendmailLoginMail` implementiert `LoginMail` mit UTF-8-MIME-Nachrichten, deutschen/englischen Texten und gemeinsam dargestelltem Code/Link. Konfigurierbar über `werkjournal.mail.sendmail` und `werkjournal.mail.sender`, standardmäßig der geprüfte lokale Pfad und bestätigte Absender. Prozessausführung ohne Shell, begrenzte Wartezeit, keine Kindprozessausgabe in Logs. `LoginMailTest` prüft über lokale Ersatzprogramme MIME-Inhalt, Empfängerargumente, manipulierte Adressen, Fehler und Timeout. Gezielter Gradle-Testlauf erfolgreich; keine reale E-Mail durch diese Tests. Noch nicht an einen Login-Endpunkt angeschlossen. ## Gemeinsame Login-Freigabe `EmailLoginChallenges` und Migration `email-login-challenge` implementieren eine pro E-Mail gespeicherte Freigabe mit gehashtem Code und Linktoken. Zehn zufällige Zeichen (ohne leicht verwechselbare Zeichen), zwei Stunden Gültigkeit, fünf Fehlversuche, 60 Sekunden Abstand zwischen Anforderungen. Code und Link verbrauchen denselben Datensatz unter einer Datenbanksperre; ein neuer Code ersetzt die alte Freigabe. Einlösung setzt keinen anfordernden Browser voraus. `EmailLoginChallengesTest` prüft auch gleichzeitige Einlösung über getrennte Verbindungen. Gezielte Tests einschließlich Mailadapter bestanden. Noch nicht öffentlich angeschlossen: Aufrufberechtigung zur Erzeugung, verifizierte E-Mail-Zuordnung zum Konto, Einladung/Bootstrap, zusätzliche Begrenzung öffentlicher Mailanforderungen, frische Bestätigung für sensible Aktionen und Login-Oberfläche folgen. Fehlversuche werden durch normales Rückgeben von null festgeschrieben; aufrufende Transaktionen dürfen diesen Zustand nicht durch nachträgliche Exceptions zurückrollen. ## Kontoanbindung `EmailAccounts` verknüpft bestätigte E-Mail-Adressen mit lokalen Konten. Eine gültige Einladung oder der konfigurierte einmalige Bootstrap-Code erlaubt die Anforderung einer E-Mail zur Kontoanlage. Erst die erfolgreiche Einlösung legt das Konto an und erstellt eine widerrufbare Geräteanmeldung. Einladung/Bootstrap werden unmittelbar vor Kontoanlage erneut unter der gemeinsamen Datenbanksperre geprüft. Bestehende aktive Konten können ohne neue Einladung wieder angemeldet werden; unbekannte und gesperrte Konten erhalten keine Login-Mail. Fehlversuche bleiben auch im äußeren Ablauf gespeichert. Gezielte Tests prüfen Kontoanlage nach E-Mail-Nachweis, Wiederanmeldung, Einmaligkeit, widerrufene Einladungen, Bootstrap, Kontosperren und konkurrierende Empfänger derselben Einladung. Der Mailtransport ist in diesen Tests kontrolliert; keine externen Nachrichten. HTTP-Anbindung, öffentliche Anforderungsbegrenzung und OIDC-Rückbau bleiben offen. ## Öffentliche Anforderungsbegrenzung `EmailRequestLimits` begrenzt vor der Kontoabfrage fünf Anforderungen je normalisierter E-Mail-Adresse in 15 Minuten, zwanzig je Clientadresse in 15 Minuten und hundert insgesamt pro Stunde. Auch unbekannte Adressen zählen. Hashes statt Klartext-Adressen in den Zählern; abgelaufene Einträge werden entfernt. Datenbanksperre und persistente Zähler sichern Parallelität und Neustarts ab. Der HTTP-Adapter muss eine aus der vertrauenswürdigen Proxy-Konfiguration ermittelte Clientadresse übergeben; keine vom Formular gelieferte Adresse. `EmailRequestLimitsTest` und die angepassten Kontotests bestanden. Die Grenzen sind technische Startwerte für die kleine Nutzergruppe. HTTP-Anschluss bleibt offen. ## Loginoberfläche und HTTP-Anbindung `LoginController` bietet unter `/login` Codeanforderung für bestehende Konten, Einladungen und Bootstrap sowie geräteübergreifende Codeeingabe. Der Linktoken bleibt im URL-Fragment, wird aus dem Verlauf entfernt und über das vorhandene CSRF-Formular per POST eingelöst. Erfolgreiche Einlösung invalidiert die kurzlebige HTTP-Sitzung und setzt das sichere, widerrufbare Gerätecookie. Keine OIDC-Clientkonfiguration wird mehr benötigt. `EmailLoginHttpTest` prüft ohne externen Versand CSRF, Kontoanlage, geräteunabhängige Einlösung und Replay-Abweisung über Spring Security sowie den anschließenden Zugriff auf `/settings` über einen echten lokalen HTTP-Server. Frontendtests prüfen zusätzlich Fragmententfernung und Formularübergabe. Öffentliche Aktivierung und visuelle Browserabnahme stehen noch aus; der Gastmodus bleibt aktiv. Historische Provider-Hilfsklassen und -Abhängigkeiten werden im eigenen Rückbauknoten entfernt.