85.1.57. pepsi-helper-mailbox-scan

list the addresses a mailbox’s owner has written to

Handbuchabschnitt:

1

85.1.57.1.1. Name

pepsi-helper-mailbox-scan - Korrespondentenadressen aus einem Postfach extrahieren.

85.1.57.1.2. Übersicht

pepsi-helper-mailbox-scan (–local-domain DOMAIN | –own-address ADDRESS)… [OPTIONS] PATH…

pepsi-helper-mailbox-scan (–local-domain DOMAIN | –own-address ADDRESS)… –imap URL –imap-password-stdin

pepsi-helper-mailbox-scan (–local-domain DOMAIN | –own-address ADDRESS)… –doveadm-stdin

85.1.57.1.3. Beschreibung

pepsi-helper-mailbox-scan liest ein Postfach und gibt, eine pro Zeile, die Adressen aus, an die ihr Eigentümer Mail gesendet hat. Es ist die scannende Hälfte des import-Unterbefehls von pepsi-whitelist(1), der es startet und seine Ausgabe in pepsi.whitelist-Datensätze umwandelt; es kann auch von Hand ausgeführt werden, da seine Ausgabe ein trivial parsebares, markiertes Zeilenprotokoll ist (siehe Ausgabe weiter unten), das für sich genommen lesbar ist.

Eine Nachricht zählt als „von uns gesendet“, wenn beide der folgenden Bedingungen gelten.

Ihr From: — oder Sender:, bei Mail, die im Auftrag eines anderen eingeliefert wurde — liegt bei einer der –local-domain-Domains; oder, wenn –own-address angegeben ist, ist es genau eine dieser Adressen. (Die beiden sind Alternativen, keine Vereinigung: Wird irgendeine eigene Adresse genannt, schaltet das den Absendertest vollständig auf diese Liste um, und die Domains dienen dann nur noch der Entscheidung, welche Empfänger als lokal verworfen werden.) Und ihr Header-Block trägt kein Received:-, Return-Path:-, Delivered-To:- oder X-Original-To:-Feld.

Die zweite Bedingung ist es, die der ersten überhaupt Bedeutung gibt. From: ist unauthentifiziert: Jeder darf Ihre Adresse hineinschreiben, und eine solche Nachricht liegt in Ihrer INBOX und sieht genau aus wie Mail, die Sie gesendet haben — ein Scan, der eine Inbox allein nach dem From:-Test durchgeht, lässt also einen Fremden die Adressen wählen, die in Ihrer weißen Liste landen. Diese vier Felder werden von einem empfangenden MTA oder MDA geschrieben und nie von einem Mail-Client, der eine Nachricht verfasst; ihr Vorhandensein beweist daher, dass die Nachricht hier angekommen ist, was auch immer ihr From: sagt. Übrig bleibt die Kopie, die Ihr Client nach dem Verfassen abgelegt hat, und genau die soll ein Scan lesen. Wo diese Kopie liegt, spielt keine Rolle: Ein Maildir-Scan durchläuft den ganzen Baum, sodass ~/Maildir .Sent und jeden Archivordner abdeckt. Ein einfaches /var/mail/-Spool, das nur empfangene Mail enthält, liefert nichts.

Die To:-, Cc:- und Bcc:-Adressen solcher Nachrichten sind die Korrespondenten; Adressen bei einer lokalen Domain werden ausgelassen, weil ein lokaler Absender nie die eingehende Schranke der weißen Liste durchläuft. Adressen werden dedupliziert, kleingeschrieben und syntaktisch geprüft, und jede wird höchstens einmal ausgegeben.

Nur der Header-Block jeder Nachricht wird gelesen: Jeder Leser hält an der Leerzeile an, die die Header beendet, und Nachrichtentexte werden nie berührt. Sowohl der Block als auch jede einzelne Zeile darin sind auf –max-header-bytes gedeckelt, sodass eine einzige absurde Nachricht den Scan nicht unbegrenzt allozieren lassen kann.

Zwei Dinge wachsen mit der Arbeit, statt konstant zu sein. Die Menge der verschiedenen Korrespondentenadressen wird im Speicher gehalten (das ist es, was Deduplizierung bedeutet), sie ist also proportional zur Zahl der angeschriebenen Personen — nicht zur Größe des Postfachs. Und –doveadm-stdin ist die eine Eingabe, die ihre gesamte Quelle puffern kann: Dovecot gibt sein Ergebnis unter Umständen als ein einziges JSON-Array auf oberster Ebene aus, das als ein Wert geparst wird.

85.1.57.1.3.1. Warum dies ein eigenes, unprivilegiertes Programm ist

Dies ist das einzige eigenständige pepsi-helper-*-Programm, das kein setuid- oder setgid-Bit trägt (Modus 0755). Die anderen drei eigenständigen — pepsi-helper-maildir-writer(1), pepsi-helper-dot-forward(1) und pepsi-helper-auto-pay(1) — werden setuid-root und gruppenbeschränkt installiert (Modus 4750). (pepsi-helper-token-refresh(1) hält ebenfalls keine Privilegien, ist aber in die vereinheitlichte pepsi-Binärdatei eingefaltet, statt als eigenes Programm installiert zu werden.)

Der Grund ist die Richtung des Privilegs. pepsi-whitelist(1) ist setuid, weil es eine Datenbank-Identität braucht, und ein setuid-Prozess behält seinen Eigentümer in der gespeicherten set-user-id und kann ihn jederzeit wiedererlangen. Das Parsen eines Postfachs ist die entgegengesetzte Art von Arbeit: Es verarbeitet Megabytes an angreiferkontrolliertem RFC 5322 — jede Nachricht, die dem Benutzer je irgendjemand gesendet hat — und es braucht kein Privileg über das des Benutzers hinaus. Also läuft das Parsen hier, in einem Prozess, den pepsi-whitelist mit setresuid startet, das die reale, effektive und gespeicherte ID auf den Zielbenutzer setzt. Da in seinen Prozesskennungen nirgends eine privilegierte ID übrig bleibt, kann dieses Programm nicht zum Konto der weißen Liste werden, kann die Datenbank nicht erreichen und kann nichts lesen, was der Benutzer nicht ohnehin lesen könnte.

85.1.57.1.4. Optionen

–local-domain DOMAIN

Eine Domain, deren Absender als „uns“ zählen. Wiederholbar. Mindestens ein –local-domain oder –own-address ist erforderlich — ohne eines kann keine Nachricht als von uns gesendet erkannt werden.

–own-address ADDRESS

Zählt nur Mail von genau dieser Adresse als unsere, statt jedes Absenders bei einer lokalen Domain. Wiederholbar.

–include-delivered

Lässt den Zustellspuren-Test weg und zählt eine Nachricht allein anhand ihres From: als unsere.

Das ist bei jedem Postfach unsicher, das empfangene Mail enthält: Ein gefälschtes From: genügt dann, damit eine eingehende Nachricht wie eine gesendete aussieht, und ihre To:-Adressen werden zu Einträgen der weißen Liste. Es existiert für den ungewöhnlichen Mail-Speicher, dessen gesendete Kopien tatsächlich die Zustellung durchlaufen haben — ein Anbieter, der seine eigene Received:-tragende Kopie in Sent ablegt — und sollte nur auf diesen Ordner gerichtet werden, nie auf eine Inbox.

–format auto|mbox|maildir

Format der angegebenen Pfade. auto (der Standardwert) behandelt ein Verzeichnis als Maildir-Baum und eine Datei als mbox.

Eine mbox wird an From ``-Zeilen aufgeteilt, die am Anfang der Datei oder direkt nach einer Leerzeile stehen. Ein Maildir wird aus ``cur/ und new/ gelesen (nie tmp/, dessen Dateien halb geschrieben sein können), und jedes Verzeichnis unterhalb des angegebenen, das selbst cur/ oder new/ enthält, wird ebenfalls gescannt — sodass das Maildir++-Layout (.Sent, .Archive.2025) abgedeckt ist, ohne jeden Ordner zu benennen.

–imap URL

Scannt einen fernen Mail-Speicher statt Dateien. imaps://user@host[:port]/[PATTERN] verwendet implizites TLS (Port 993), imap:// verwendet STARTTLS (Port 143), und imap+plain:// deaktiviert TLS vollständig (was das Passwort im Klartext sendet und nur gegen einen Loopback-Testserver sinnvoll ist). PATTERN ist ein IMAP-Postfach-Muster, standardmäßig *.

Das Serverzertifikat wird immer gegen den System-Vertrauensspeicher verifiziert. Postfächer werden mit EXAMINE (nur lesend) geöffnet und nur BODY.PEEK[HEADER] wird abgerufen, sodass ein Scan Nachrichten weder als \Seen markiert noch sonst etwas ändert.

–imap-user NAME

IMAP-Login, falls es nicht in der URL steht.

–imap-password-file FILE

Liest das Passwort aus der ersten Zeile von FILE, die ihrer Gruppe und anderen Benutzern keinerlei Zugriff gewähren darf (zum Beispiel Modus 0600).

–imap-password-stdin

Liest das Passwort aus der ersten Zeile der Standardeingabe. So übergibt es pepsi-whitelist(1), sodass es nie in einer Befehlszeile erscheint, wo andere Benutzer es aus ps auslesen könnten.

–doveadm-stdin

Liest einen doveadm -f json fetch -u LOGIN hdr mailbox '*' all-Strom von der Standardeingabe, statt Dateien zu öffnen. Wird für Dovecots eigene Mail-Formate (mdbox/sdbox) verwendet: Der Aufrufer führt das privilegierte doveadm aus, und nur dessen Ausgabe gelangt in diesen unprivilegierten Prozess. JSON ist erforderlich, weil ein Header-Block eigene Leerzeilen und Doppelpunkte enthält, die die menschenlesbaren Formate von doveadm nicht maskieren.

–max-header-bytes BYTES

Obergrenze für die pro Nachricht behaltenen Header-Bytes (Standardwert 65536).

–max-messages N

Untersucht höchstens N Nachrichten (0, der Standardwert, bedeutet keine Begrenzung).

Das ist eine Obergrenze dafür, wie viele Nachrichten geparst und klassifiziert werden, was der teure Teil pro Nachricht ist — es bricht den Durchlauf nicht ab. Die mbox-Datei wird weiterhin bis zum Ende gelesen, der Maildir-Baum weiterhin durchlaufen, und eine IMAP-Sitzung ruft weiterhin die Header jedes Postfachs ab. Verwenden Sie es, um die Arbeit eines Scans zu begrenzen, nicht die Zeit, die er auf einem sehr großen Mail-Speicher braucht.

-h, –help

Gibt eine Verwendungsübersicht aus und beendet sich.

-V, –version

Gibt die Version aus und beendet sich.

85.1.57.1.5. Ausgabe

Ein tabulatorgetrennter Datensatz pro Zeile auf der Standardausgabe:

a<TAB>ADDRESS

Eine Korrespondenzadresse, höchstens einmal ausgegeben.

m<TAB>COUNT

Wie viele Nachrichten untersucht wurden.

s<TAB>COUNT

Wie viele davon von uns gesendet wurden.

w<TAB>MESSAGE

Ein nicht-fatales Problem: ein unlesbarer Ordner, ein übersprungener Datensatz, ein Postfach ohne cur/new. Warnungen werden nach den Adressen ausgegeben und sind gedeckelt.

Ein Leser ignoriert Datensatztypen, die er nicht kennt, sodass spätere Versionen welche hinzufügen können.

85.1.57.1.6. Exit-Status

0

Der Scan wurde abgeschlossen. Etwaige w-Datensätze sind nicht fatal.

1

Ein fataler Fehler: ungültige Argumente, ein unlesbarer Postfach-Pfad, ein verweigertes IMAP-Login. Die Diagnose steht auf der Standardfehlerausgabe.

85.1.57.1.7. Beispiele

Scannen Sie Ihre eigene Mail:

pepsi-helper-mailbox-scan --local-domain example.com ~/Maildir /var/mail/alice

Nur Mail, die Sie von einer bestimmten Adresse gesendet haben:

pepsi-helper-mailbox-scan --own-address alice@example.com ~/Maildir

Ein fernes Konto über IMAP, mit dem Passwort in einer Datei:

pepsi-helper-mailbox-scan --local-domain example.com \
    --imap imaps://alice@mail.example.com/ --imap-password-file ~/.imap-pw

Ein Dovecot-Mail-Speicher, als root:

doveadm -f json fetch -u alice hdr mailbox '*' all \
  | pepsi-helper-mailbox-scan --local-domain example.com --doveadm-stdin

85.1.57.1.8. Siehe auch

pepsi-whitelist(1), pepsi-stage-check-whitelist(1), pepsi-stage-auto-whitelist(1), pepsi.conf(5)

85.1.57.1.9. Fehler

Melden Sie Fehler an den Pepsi-Issue-Tracker.