Gumdrop provides a complete IMAP server implementation following RFC 9051 (IMAP4rev2). Like all Gumdrop protocol implementations, the IMAP server uses the event-driven, non-blocking architecture that enables high concurrency with minimal resource consumption.
The IMAP server implements the IMAP4rev2 protocol as defined in RFC 9051, the modernised successor to RFC 3501. IMAP4rev2 incorporates lessons learned from two decades of IMAP deployment and mandates several previously optional features.
IMAP sessions progress through four states:
All standard IMAP4rev2 commands are implemented:
* N EXISTS responses if the message count
has changed since the last check.The server supports several IMAP extensions that enhance functionality:
Push notifications for mailbox changes. When a client issues the IDLE command, the server holds the connection open and sends unsolicited responses when new messages arrive or flags change. This eliminates the need for polling.
C: A001 IDLE S: + idling ... (server sends updates as mailbox changes) S: * 4 EXISTS C: DONE S: A001 OK IDLE terminated
Exposes the mailbox hierarchy structure, including personal, shared, and
other-users' namespaces when configured. The MailboxStore can
return shared and other-users namespace prefixes via
getSharedNamespace() and getOtherUsersNamespace().
Helps clients discover the hierarchy delimiter and namespace prefixes.
Atomic move operation combining COPY and STORE \Deleted + EXPUNGE. More efficient than the three-command sequence and avoids race conditions.
Storage quota reporting. Clients can query quota roots and current usage, enabling display of storage limits in mail client interfaces.
setServerIdFields()
Authentication uses Gumdrop's centralised Realm interface, which
provides a unified credential store across all servers. The IMAP server supports
multiple SASL mechanisms.
A Realm represents a collection of authenticatable principals with
associated passwords and roles. The interface supports both plaintext password
verification and pre-computed credential hashes for secure storage:
passwordMatch(username, password) - verifies credentials without
exposing the stored passwordgetDigestHA1(username, realmName) - returns H(A1) for Digest
authenticationgetCramMD5Response(username, challenge) - computes CRAM-MD5
responsegetScramCredentials(username) - returns SCRAM-SHA-256 derived
keysvalidateBearerToken(token) - validates OAuth/Bearer tokensisMember(username, role) - checks role membership
The built-in BasicRealm reads users from an XML file:
<realm> <user name="alice" password="secret" roles="user,admin"/> <user name="bob" password="password123" roles="user"/> </realm>
Custom realm implementations can integrate with LDAP, databases, or external identity providers.
The server advertises available mechanisms in the CAPABILITY response:
SCRAM-SHA-256 is the recommended mechanism as it provides mutual authentication and does not transmit the password in any form. The realm can store only the derived keys (StoredKey, ServerKey) without keeping the plaintext password.
By default, the LOGIN command is disabled over unencrypted connections. The
server advertises LOGINDISABLED in capabilities until TLS is
established via STARTTLS or implicit IMAPS. This prevents credential exposure
over plaintext connections.
The IMAP server accesses mail storage through the Mailbox
API. A MailboxFactory is configured to provide
MailboxStore instances for authenticated users.
When a user authenticates successfully:
mailboxFactory.createStore()store.open(username)See the Mailbox API documentation for details on each format's characteristics and configuration.
org.bluezoo.gumdrop.imap.IMAPServer supports:
port - listening port (default: 143, or 993 for secure)secure - enable implicit TLS (IMAPS)keystoreFile - keystore for TLS/STARTTLSkeystorePass - keystore passwordrealm - reference to a Realm for authenticationmailboxFactory - reference to a MailboxFactorygssapiServer - reference to a GSSAPIServer for Kerberos auth (optional)enableIDLE - enable IDLE extension (default: true)enableNAMESPACE - enable NAMESPACE extension (default: true)enableQUOTA - enable QUOTA extension (default: true)enableMOVE - enable MOVE extension (default: true)serverIdFields - map of key/value pairs returned by the ID
command (RFC 2971). Default: name=gumdrop, version from package manifest.loginTimeout - maximum time for authentication (default: 60000ms)idleTimeout - connection idle timeout (default: 1800000ms / 30 min)commandTimeout - maximum time per command (default: 300000ms)maxLineLength - maximum command line length (default: 8192)maxLiteralSize - maximum literal size for APPEND (default: 25MB)allowPlaintextLogin - allow LOGIN over non-TLS (default: false;
testing only)
<!-- Authentication realm -->
<realm id="mailRealm" class="org.bluezoo.gumdrop.auth.BasicRealm">
<property name="href">mail-users.xml</property>
</realm>
<!-- Maildir storage -->
<mailboxFactory id="maildir"
class="org.bluezoo.gumdrop.mailbox.maildir.MaildirMailboxFactory">
<property name="basedir">/var/mail</property>
</mailbox-factory>
<!-- IMAP server (port 143 with STARTTLS) -->
<server id="imap" class="org.bluezoo.gumdrop.imap.IMAPServer">
<property name="port">143</property>
<property name="keystore-file">keystore.p12</property>
<property name="keystore-pass">secret</property>
<property name="realm" ref="#mailRealm"/>
<property name="mailbox-factory" ref="#maildir"/>
<property name="idle-timeout">1800000</property>
</server>
<!-- IMAPS server (port 993 with implicit TLS) -->
<server id="imaps" class="org.bluezoo.gumdrop.imap.IMAPServer">
<property name="port">993</property>
<property name="secure">true</property>
<property name="keystore-file">keystore.p12</property>
<property name="keystore-pass">secret</property>
<property name="realm" ref="#mailRealm"/>
<property name="mailbox-factory" ref="#maildir"/>
</server>
TLS is required before credentials are transmitted. The server advertises
LOGINDISABLED until encryption is established.
Challenge-response mechanisms (CRAM-MD5, SCRAM-SHA-256) never transmit the password, even over TLS. SCRAM additionally protects against server compromise by using derived keys.
The maxLiteralSize setting prevents denial-of-service attacks via
oversized APPEND commands. The default 25MB limit can be adjusted based on
expected message sizes.
Timeouts prevent resource exhaustion from idle or slow connections. The 30-minute idle timeout follows RFC 9051 recommendations while allowing reasonable IDLE sessions.
The IMAP server supports storage quotas via the QUOTA extension (RFC 9208). Users can query their quota status, and administrators can set per-user storage limits.
Three commands provide quota functionality:
C: A001 GETQUOTAROOT INBOX S: * QUOTAROOT INBOX user/alice S: * QUOTA user/alice (STORAGE 52428 102400) S: A001 OK GETQUOTAROOT completed C: A002 GETQUOTA user/alice S: * QUOTA user/alice (STORAGE 52428 102400) S: A002 OK GETQUOTA completed
The STORAGE resource reports usage and limits in kilobytes.
Quotas are enforced through a QuotaManager configured on the
IMAP server. The RoleBasedQuotaManager supports user-specific
overrides, role-based policies, and a system default:
<!-- Quota manager with role-based policies -->
<component id="mailQuota"
class="org.bluezoo.gumdrop.quota.RoleBasedQuotaManager">
<property name="realm" ref="#mailRealm"/>
<property name="storage-dir">/var/mail/quota</property>
<property name="default-quota">100MB</property>
<property name="role-quota.premium">10GB</property>
<property name="role-quota.enterprise">unlimited</property>
</component>
<!-- Link to IMAP server -->
<server id="imap" class="org.bluezoo.gumdrop.imap.IMAPServer">
<property name="quota-manager" ref="#mailQuota"/>
<!-- ... other properties ... -->
</server>
When determining a user's quota, the manager checks in order:
Sizes can be specified with standard suffixes: KB, MB, GB, TB. Use
unlimited or -1 for no limit.
When a client issues an APPEND command, the server checks whether adding the
message would exceed the user's quota. If so, the server returns an
[OVERQUOTA] response code:
C: A003 APPEND INBOX {1048576}
S: A003 NO [OVERQUOTA] Quota exceeded
Quota operations are integrated with Gumdrop's telemetry. Events include:
QUOTA_CHECK - GETQUOTA/GETQUOTAROOT queriesQUOTA_SET - administrator quota changesQUOTA_EXCEEDED - APPEND denied due to quotaGumdrop includes a fully asynchronous IMAP client supporting IMAPS, STARTTLS, and the full range of RFC 9051 commands. The client uses a callback-driven design with typed reply handler interfaces for each command category.
The client provides getQuota() and getQuotaRoot()
commands via the ClientAuthenticatedState interface. Responses
are delivered through the ServerQuotaReplyHandler callback:
handleQuota(quotaRoot, resourceName, usage, limit) —
called for each resource triplet in a QUOTA responsehandleQuotaRoot(mailbox, quotaRoots) — called for
QUOTAROOT untagged responseshandleQuotaComplete() / handleQuotaError(msg)
— completion callbacks← Back to Main Page | POP3 Server | SMTP Server & Client | DNS Server | Telemetry
Gumdrop IMAP Server