Files
bongo/docs/imap.md
T
2026-07-30 02:31:21 +02:00

8.1 KiB

IMAP compatibility and international mail

Bongo 0.7 advertises IMAP4rev2, IMAP4rev1, and the original IMAP4 capability. The compatibility capabilities are intentional: clients which do not understand rev2 can continue to use the older command and mailbox-name rules. Existing modified UTF-7 mailbox names therefore remain supported until the client explicitly enables UTF-8.

The original IMAP4 path does not require ENABLE. It retains the classic LIST/LSUB, CREATE/SUBSCRIBE, synchronized APPEND, SELECT/EXAMINE/CHECK/CLOSE, FAST/ALL/FULL and RFC822 FETCH forms, SEARCH, UID, STORE, COPY, and EXPUNGE workflow used by old clients. Bongo also implements RFC 1730 PARTIAL for a single message's complete RFC822 data, header, or text, including the equivalent top-level BODY and PEEK forms. Its position is one-based, returned data is truncated at the end of the selected part, and PEEK does not set \Seen. Nested MIME BODY sections are outside this compatibility subset and receive tagged NO; malformed syntax receives tagged BAD without losing the session.

Legacy protocol compatibility is independent from transport security. Bongo does not expose cleartext credentials before TLS merely because a client uses the old command set. Sites which must support a client unable to negotiate modern TLS must explicitly isolate and enable the corresponding legacy TLS policy.

The server also advertises the extensions it implements, including ENABLE, ID, IDLE, NAMESPACE, UIDPLUS, MOVE, SPECIAL-USE, CREATE-SPECIAL-USE, LIST-EXTENDED, LIST-STATUS, STATUS=SIZE, LITERAL+, APPENDLIMIT, and UTF8=ACCEPT. Capability tests keep this list in step with the command handlers; an extension must not be advertised merely because a client might expect it.

Modern clients can issue ENABLE UTF8=ACCEPT in the authenticated state. The untagged ENABLED response contains only capabilities newly enabled by that command; repeating one does not report it again, while an unknown-only request still receives an empty ENABLED response. After UTF-8 is enabled, Bongo accepts UTF-8 mailbox names and quoted strings, normalizes names to NFC, returns UTF-8 names from LIST, LSUB and STATUS, and rejects malformed UTF-8. Control, delete, line-separator and paragraph-separator code points are forbidden in mailbox names. SEARCH with an explicit CHARSET is rejected after UTF-8 has been enabled, as required by the extension.

Before UTF-8 is enabled, concrete mailbox names must use canonical modified UTF-7. LIST and LSUB patterns retain the established IMAP matching behavior: an invalid modified-UTF-7 pattern simply has no matches and does not terminate an otherwise valid LIST command. This distinction matches current Dovecot and Cyrus behavior while keeping CREATE, SELECT, RENAME, DELETE and other concrete mailbox operations strict.

Internationalized messages are appended with the RFC 6855 UTF8 (~{size}) data form. Bongo buffers at most the advertised APPENDLIMIT, validates the header before committing the message to the store, and rejects malformed UTF-8. A normal APPEND containing an eight-bit header receives NO [CANNOT]; the UTF8 data form is accepted only after ENABLE UTF8=ACCEPT and requires literal8 (~{size}) framing. In an IMAP4rev2 session UTF-8 acceptance is part of the base protocol, so a normal APPEND may contain a valid UTF-8 header. Opaque eight-bit body data remains valid with ASCII headers.

A legacy client never receives raw internationalized header fields in an IMAP response. Safe metadata such as UID, flags, internal date and message size remains available. A request that would expose a UTF-8 header receives NO [CANNOT] with an instruction to enable UTF-8. This explicit policy avoids silently corrupting addresses or invalidating DKIM signatures through an ad-hoc downgrade.

Mailbox roles follow RFC 6154 SPECIAL-USE. LIST reports stored roles, and extended LIST supports both SPECIAL-USE as a selection option and RETURN (SPECIAL-USE); selecting it also implies the corresponding return data. CREATE-SPECIAL-USE uses the standard CREATE mailbox (USE (...)) wrapper. An empty role list is valid. Bongo can create the ordinary \Archive, \Drafts, \Junk, \Sent, and \Trash roles, including multiple roles on one mailbox. Unsupported or duplicate attributes fail the complete CREATE atomically with NO [USEATTR].

\All and \Flagged remain valid response attributes but are not accepted for CREATE because Bongo 0.7 has no virtual aggregate or flagged view that could implement their required semantics. Roles survive RENAME. DELETE removes the role even when a subscribed mailbox must remain as a \Noselect hierarchy placeholder; recreating that ordinary mailbox does not silently restore the old role.

IDLE is available after authentication, with or without a selected mailbox. In selected state, Bongo sends unsolicited EXISTS, FETCH FLAGS, and EXPUNGE updates as Store changes become visible. The first event check happens immediately and subsequent checks are bounded; clients do not need to issue a NOOP to receive them. DONE is case-insensitive but must be the complete continuation line. Any other line completes the outstanding IDLE with tagged BAD while leaving the connection usable. Bongo also checks data already held in its application and GnuTLS input buffers before waiting on the network socket, so a client may safely pipeline DONE in the same TLS record. An IDLE session which reaches the server's 29-minute bound receives BYE and must reconnect; clients may end and renew IDLE sooner.

IMAP command lines are bounded to 64 KiB, matching the current Dovecot default. The server consumes an overlong line before returning an untagged BAD response, so it neither allocates attacker-controlled unbounded memory nor mistakes the remainder for another command. Command framing requires CRLF; bare CR/LF, embedded NUL, and tags too large for Bongo's protocol state are rejected while a correctly framed following command remains usable. Message literals have the separately advertised 999999-byte APPENDLIMIT. Oversized synchronizing literals are rejected before continuation; non-synchronizing literals are consumed without storing them so the stream can be resynchronized safely.

Mailbox state remains authoritative in the Store rather than in an IMAP process. Committed messages receive unique, monotonically increasing UIDs; UIDVALIDITY, UIDNEXT, flags, subscriptions, and message data survive client disconnects and complete Bongo service restarts. Simultaneous selected clients refresh their views through Store notifications or NOOP. On service shutdown Bongo closes active client and Store transports before waiting for the IMAP workers, so an idle TLS peer cannot delay restart until the command timeout.

AUTH capabilities are generated from the GNU GSASL mechanisms which Bongo has actually enabled. Password mechanisms are advertised only on a TLS connection; unencrypted connections offer STARTTLS and keep LOGIN disabled. STARTTLS rejects arguments and repeated or post-authentication use, discards already buffered cleartext before the TLS handshake, and closes the connection without attempting a plaintext IMAP response if negotiation fails. A client which ignores LOGINDISABLED receives a tagged NO without a password lookup.

The RFC 9208 QUOTA extension reports the authenticated user's optional mail-storage limit through GETQUOTA and GETQUOTAROOT. Bongo advertises QUOTA=RES-STORAGE, supports DELETED-STORAGE, and returns [OVERQUOTA] for APPEND, COPY, or MOVE growth rejected by the Store. It intentionally does not advertise QUOTASET; limits are administered with bongo-admin user quota. See Mail storage quotas.

Relevant standards are RFC 1730, RFC 9051, RFC 3501, RFC 2177, RFC 5161, RFC 5198, RFC 6154, RFC 6855, and RFC 9208.