imap

package
v0.783.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 29, 2026 License: AGPL-3.0 Imports: 3 Imported by: 0

Documentation

Overview

Package imap decodes IMAP4rev1 (Internet Message Access Protocol v4 revision 1) messages per RFC 3501, plus the RFC 2595 (STARTTLS), RFC 2087 (QUOTA), RFC 2342 (NAMESPACE), and RFC 4978 (COMPRESS) extensions. IMAP is the **dominant modern mail-access protocol** — TCP/143 (cleartext) or TCP/993 (implicit-TLS, "IMAPS"). It powers Exchange / Office 365 / Google Workspace IMAP / Dovecot / Cyrus IMAP / Courier IMAP / Zimbra / FastMail / SendGrid Inbound / Apple Mail / Thunderbird / iOS Mail / Outlook.

Operationally, IMAP is the canonical mail-server pentest target alongside POP3 and SMTP — but with a richer surface:

  • **Credential brute-force** — `LOGIN <user> <pass>` is the canonical cleartext-credentials command (sent before STARTTLS!); tagged responses are `OK` for success and `NO` for failure. Different `NO` error wording per implementation enables username enumeration (classic against older Dovecot configurations).
  • **STARTTLS downgrade audit** — `CAPABILITY` returns `STARTTLS` when the server supports opportunistic TLS upgrade; clients that don't enforce TLS can be stripped down to cleartext via mitm.
  • **SASL mechanism enumeration** — `CAPABILITY` lists `AUTH=LOGIN` / `AUTH=PLAIN` / `AUTH=CRAM-MD5` / `AUTH=DIGEST-MD5` / `AUTH=SCRAM-SHA-1` / `AUTH=SCRAM-SHA-256` / `AUTH=XOAUTH2` / `AUTH=GSSAPI`; the canonical pre-auth fingerprint.
  • **Banner fingerprinting** — the `* OK` greeting leaks IMAP server software + version (e.g. `* OK Dovecot ready.` / `* OK Microsoft Exchange Server 2019 IMAP4 service is ready` / `* OK Gimap ready`).
  • **CAPABILITY enumeration** — the per-server capability list (`IMAP4rev1 STARTTLS AUTH=PLAIN AUTH=LOGIN LOGINDISABLED IDLE NAMESPACE QUOTA UIDPLUS LITERAL+ COMPRESS=DEFLATE`) fingerprints the server's feature set + can reveal misconfigurations (e.g. `LOGINDISABLED` absent + `STARTTLS` absent = cleartext LOGIN accepted).
  • **FETCH-based content disclosure** — `1 UID FETCH 1:* BODY[]` retrieves every message in the selected mailbox in one round-trip (the canonical post-auth data- exfiltration command).
  • **IDLE / NOTIFY abuse** — `IDLE` keeps the connection open for server push of new messages; long-running IDLE sessions can be used to maintain persistent observer access.

Wrap-vs-native judgement

Native. RFC 3501 is publicly available; IMAP is a text-
based protocol with four message kinds — Client Command
(tagged), Untagged Response (`*`), Tagged Response
(matching the command's tag), and Continuation (`+`).
The wire format is richer than POP3 / SMTP because of
the tag-pairing mechanism, but the decoder discriminates
on the first character + the second whitespace-delimited
token. Literal strings (`{N}<CRLF>...<N bytes>`) and
multi-line FETCH bodies are surfaced as raw bytes for
caller-side processing — per-message-body MIME parsing
is a separate decoder. No crypto at the parse layer
(STARTTLS triggers a TLS upgrade — handle the post-
STARTTLS bytes through a TLS strip first).

What this package covers

  • **Four message kinds** discriminated by the first character of the first line:

  • **Continuation** — first character is `+`. Format: `+ <prompt-text>`. Used by the server during `AUTHENTICATE` SASL exchanges (server prompts the client for the next SASL step) and during `APPEND` literal uploads.

  • **Untagged Response** — first character is `*`. Format: `* <type> <data>`. The `<type>` is one of the documented untagged response types — either a status (`OK` / `NO` / `BAD` / `BYE` / `PREAUTH`) or a data response (`CAPABILITY` / `LIST` / `LSUB` / `STATUS` / `SEARCH` / `FLAGS` / `FETCH` / `EXISTS` / `RECENT` / `EXPUNGE` / `NAMESPACE` / `QUOTA` / `QUOTAROOT` / `ID`). The decoder surfaces the untagged type as `untagged_type` and the rest of the line as `untagged_data`.

  • **Command + Tagged Response** — first character is alphanumeric. Format: `<tag> <command> [args]` (Command) or `<tag> <status> [args]` (Tagged Response). To disambiguate, the decoder inspects the second whitespace-delimited token: if it is one of `OK` / `NO` / `BAD` / `BYE` / `PREAUTH` → Tagged Response; otherwise → Command.

  • **25+ entry Verb name table** (RFC 3501 §6 + extensions): `LOGIN` (cleartext credentials!) / `AUTHENTICATE` (SASL with continuation) / `SELECT` (open mailbox r/w) / `EXAMINE` (open mailbox read-only) / `CREATE` / `DELETE` / `RENAME` / `SUBSCRIBE` / `UNSUBSCRIBE` / `LIST` (list mailboxes — wildcard `*` / `%`) / `LSUB` (list subscribed mailboxes) / `STATUS` (query mailbox metadata without SELECT) / `APPEND` (push a message to a mailbox — literal upload) / `CHECK` / `CLOSE` (close mailbox without EXPUNGE) / `EXPUNGE` (permanently delete \Deleted messages) / `SEARCH` (search by criteria — `FROM` / `TO` / `SUBJECT` / `BEFORE` / `SINCE` / `HEADER` / `BODY` / `TEXT` / etc.) / `FETCH` (retrieve message data — the canonical content-disclosure command) / `STORE` (set message flags) / `COPY` / `UID` (UID variants of FETCH / STORE / SEARCH / COPY) / `NOOP` (keep-alive) / `LOGOUT` (close session) / `CAPABILITY` (list server features — the canonical enumeration step) / `STARTTLS` (TLS upgrade per RFC 2595) / `IDLE` (server push mode per RFC 2177) / `NAMESPACE` (list personal/shared/other namespaces per RFC 2342) / `ID` (client/server identification per RFC 2971).

  • **5-entry Status name table** (RFC 3501 §7.1): `OK` (success) / `NO` (failure) / `BAD` (malformed) / `BYE` (server closing connection) / `PREAUTH` (server pre-authenticated the client via Kerberos / IPsec / similar out-of-band trust).

  • **15+ entry Untagged Type name table** (data responses + the status responses above): `CAPABILITY` / `LIST` / `LSUB` / `STATUS` / `SEARCH` / `FLAGS` / `FETCH` / `EXISTS` / `RECENT` / `EXPUNGE` / `NAMESPACE` / `QUOTA` / `QUOTAROOT` / `ID` / `ESEARCH` (RFC 4731 extended SEARCH).

  • **Continuation prompt extraction** — the text after `+ ` on continuation responses is surfaced as `continuation_prompt` for caller-side SASL exchange analysis.

What this package does NOT cover (deliberately out of scope)

  • **Network framing** — feed IMAP bytes after the TCP- segment header strip (default TCP port 143 cleartext / 993 implicit-TLS IMAPS).
  • **STARTTLS / IMAPS transport** — after a successful STARTTLS handshake the connection upgrades to TLS; handle the TLS strip first before feeding the decrypted bytes back.
  • **Literal string body handling** — IMAP literals (`{N}<CRLF>...<N bytes>`) carry binary data inline (FETCH BODY[], APPEND uploads). The decoder surfaces the literal-length marker as part of the line but does not consume the following N bytes from a separate buffer; multi-line FETCH bodies are surfaced as the raw line content.
  • **FETCH attribute parser** — `FETCH (UID 12 FLAGS (\\Seen) BODY[HEADER] {142}\r\n...)` carries a nested attribute list; the decoder surfaces it as untagged_data for caller-side parsing.
  • **MIME / RFC 5322 message body parsing** — the bytes inside FETCH BODY[] / BODY[TEXT] / BODY.PEEK[] responses are the RFC 5322 mail body with optional MIME structure per RFC 2045; separate decoder.
  • **SASL mechanism decoding** — `AUTHENTICATE <mechanism>` is followed by a server `+` challenge then base64 responses; per-mechanism decoding (LOGIN, PLAIN, CRAM-MD5, SCRAM-SHA-256) is out of scope.
  • **IMAP4 commands beyond the IMAP4rev1 + common- extension set** — RFC 5267 (CONTEXT extension), RFC 5256 (SORT/THREAD), RFC 4467 (URLAUTH), RFC 4731 (ESEARCH), RFC 5464 (METADATA), RFC 6855 (UTF8) — verbs not in the name table surface as "uncatalogued verb <name>".

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type MessageKind

type MessageKind string

MessageKind enumerates the four IMAP message kinds.

const (
	KindCommand      MessageKind = "Command"
	KindUntaggedResp MessageKind = "Untagged_Response"
	KindTaggedResp   MessageKind = "Tagged_Response"
	KindContinuation MessageKind = "Continuation"
	KindUnknown      MessageKind = "uncatalogued"
)

type Result

type Result struct {
	TotalBytes int         `json:"total_bytes"`
	Kind       MessageKind `json:"kind"`

	// Command + Tagged Response only.
	Tag string `json:"tag,omitempty"`

	// Command only.
	Verb     string `json:"verb,omitempty"`
	VerbName string `json:"verb_name,omitempty"`
	Argument string `json:"argument,omitempty"`

	// Tagged Response only.
	Status     string `json:"status,omitempty"`
	StatusText string `json:"status_text,omitempty"`

	// Untagged Response only.
	UntaggedType     string `json:"untagged_type,omitempty"`
	UntaggedTypeName string `json:"untagged_type_name,omitempty"`
	UntaggedData     string `json:"untagged_data,omitempty"`

	// Continuation only.
	ContinuationPrompt string `json:"continuation_prompt,omitempty"`
}

Result is the structured decode of an IMAP message.

func Decode

func Decode(hexStr string) (*Result, error)

Decode parses an IMAP message from a hex string. Separators (':' '-' '_' whitespace) tolerated; '0x' prefix tolerated.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL