Document current-server IMAP source audit
This commit is contained in:
@@ -174,7 +174,7 @@ review does not mark an open live test as passed.
|
||||
| IMAP-05 | LIST, LSUB, extended LIST, LIST-STATUS, hierarchy quoting | [PASS](test-evidence/0.7-r1.md#imap-0506) | | |
|
||||
| IMAP-06 | CREATE, DELETE, RENAME, SUBSCRIBE, UNSUBSCRIBE | [PASS](test-evidence/0.7-r1.md#imap-0506) | | |
|
||||
| IMAP-07 | SELECT, EXAMINE, STATUS/SIZE, CHECK, CLOSE, UNSELECT | [PASS](test-evidence/0.7-r1.md#imap-07) | | |
|
||||
| IMAP-08 | APPEND, LITERAL+, APPENDLIMIT, flags/date, oversized literals | | | |
|
||||
| IMAP-08 | APPEND, LITERAL+, APPENDLIMIT, flags/date, oversized literals | [PASS](test-evidence/0.7-r1.md#imap-08) | | |
|
||||
| IMAP-09 | FETCH/UID FETCH body, headers, partials, flags, envelope, binary | | | |
|
||||
| IMAP-10 | STORE/UID STORE add/remove/replace flags and silent variants | | | |
|
||||
| IMAP-11 | COPY/UID COPY/MOVE/UID MOVE and UIDPLUS response codes | | | |
|
||||
|
||||
@@ -3367,7 +3367,7 @@ document, and left `bongo.service` active.
|
||||
|
||||
Result: **PASS**
|
||||
|
||||
The installed `865c632d` GCC 15.3.0 debug build was exercised on 2026-07-29
|
||||
The installed `834c9322` GCC 15.3.0 debug build was exercised on 2026-07-29
|
||||
with the reusable `smtp-tlsrpt-delivery-check.py --live` fixture. It delivered
|
||||
one RFC 8460 report as a DKIM-signed, gzip-compressed MIME attachment and one
|
||||
gzip-compressed report through HTTPS with validated TLS. Reports with a
|
||||
@@ -3447,15 +3447,21 @@ GSASL PLAIN and LOGIN mechanisms. The TLS capability response contained
|
||||
an RFC 2971 client ID with name and version, the RFC 2342 personal namespace,
|
||||
and LOGOUT with an untagged BYE followed by tagged completion.
|
||||
|
||||
This state model was compared with current Cyrus IMAP `imap/imapd.c`. Cyrus
|
||||
likewise limits STARTTLS and SASL-IR to pre-authentication state, advertises
|
||||
`LOGINDISABLED` from connection state, starts TLS immediately for IMAPS, and
|
||||
explicitly discards input pipelined after STARTTLS. Bongo's focused
|
||||
This state model was compared with Cyrus IMAP 3.12.3 `imap/imapd.c` and
|
||||
Dovecot 2.4.4 `src/imap/imap-commands.c`,
|
||||
`src/imap-login/client-authenticate.c`,
|
||||
`src/login-common/client-common-auth.c`, and `src/imap/cmd-id.c`. The source
|
||||
comparison added checks for AUTHENTICATE cancellation, malformed base64,
|
||||
unknown mechanisms, trailing arguments, continued session usability, ID
|
||||
field limits, NIL keys, literals, and commands which take no arguments.
|
||||
Cyrus and Dovecot likewise limit STARTTLS and SASL-IR to pre-authentication
|
||||
state, derive `LOGINDISABLED` from connection state, and discard input
|
||||
pipelined after STARTTLS. Bongo's focused
|
||||
`imap-capabilities`, `imap-protocol`, and `sasl-password-mechanisms` native
|
||||
tests all passed before the live run.
|
||||
|
||||
```text
|
||||
IMAP-01/02/03/04 PASS host=127.0.0.1 starttls=143/TLSv1.3 imaps=993/TLSv1.3 protocols=IMAP4rev2,IMAP4rev1,IMAP4 pre-tls=LOGINDISABLED login=LOGIN,PLAIN,LOGIN-SASL commands=CAPABILITY,NOOP,ID,NAMESPACE,LOGOUT repeated-starttls=rejected pipeline=discarded
|
||||
IMAP-01/02/03/04 PASS host=127.0.0.1 starttls=143/TLSv1.3 imaps=993/TLSv1.3 protocols=IMAP4rev2,IMAP4rev1,IMAP4 pre-tls=LOGINDISABLED login=LOGIN,PLAIN,LOGIN-SASL commands=CAPABILITY,NOOP,ID,NAMESPACE,LOGOUT id=literal+,limits,nil-key-rejected auth=cancel/unknown/base64/trailing/session-alive noarg-syntax=capability/noop/namespace/logout repeated-starttls=rejected pipeline=discarded
|
||||
```
|
||||
|
||||
The test only authenticates and logs out. It does not create, alter, or
|
||||
@@ -3465,7 +3471,7 @@ delete any mailbox or message and leaves the service configuration unchanged.
|
||||
|
||||
Result: **PASS**
|
||||
|
||||
The installed `9bb5eb8e` GCC 15.3.0 debug build was exercised on 2026-07-29
|
||||
The installed `834c9322` GCC 15.3.0 debug build was exercised on 2026-07-29
|
||||
with the reusable `imap-mailbox-check.py`. The test used disposable mailbox
|
||||
names containing spaces and multiple hierarchy levels. It verified the
|
||||
reported hierarchy delimiter, LIST with both `%` and `*`, exact and recursive
|
||||
@@ -3474,26 +3480,37 @@ LIST-STATUS responses.
|
||||
|
||||
CREATE left new mailboxes unsubscribed until an explicit SUBSCRIBE. RENAME
|
||||
moved the complete hierarchy without changing any child or grandchild suffix.
|
||||
UNSUBSCRIBE removed only the subscription. DELETE removed an empty leaf, and
|
||||
deleting a parent with inferiors retained its children while converting the
|
||||
parent into a `\NoSelect` hierarchy placeholder. The test then removed all
|
||||
disposable objects depth-first and verified that none remained.
|
||||
UNSUBSCRIBE removed only the subscription. DELETE retained subscriptions
|
||||
independently of mailbox existence: obsolete LSUB continued to return the
|
||||
deleted name, extended LIST returned `\Subscribed \NonExistent`, basic LIST
|
||||
returned `\NoSelect`, and CREATE restored the selectable mailbox without
|
||||
dropping its subscription. Deleting a parent with inferiors retained its
|
||||
children. A final UNSUBSCRIBE removed an unused non-existent placeholder.
|
||||
The test then removed all disposable objects depth-first and verified that
|
||||
none remained.
|
||||
|
||||
The live pass exposed and fixed three issues before succeeding: CREATE had
|
||||
The live pass exposed and fixed several issues before succeeding: CREATE had
|
||||
implicitly subscribed folders, recursive Store rename truncated hierarchy
|
||||
suffixes, and Store commands did not quote paths containing spaces when
|
||||
converting a deleted parent to hierarchy-only state. Focused native coverage
|
||||
now exercises SPECIAL-USE creation, LIST-EXTENDED parsing, and the exact SQL
|
||||
rename boundary for children, grandchildren, and similarly prefixed
|
||||
mailboxes.
|
||||
suffixes, LSUB overwrote a syntax error with a path-length error, wildcard and
|
||||
reference handling were incomplete, INBOX was not canonicalized
|
||||
case-insensitively, subscriptions disappeared with a deleted mailbox, and
|
||||
several Store commands did not quote paths containing spaces. The missing
|
||||
quotes also caused the old CREATE error path to return without a tagged IMAP
|
||||
response. Focused native coverage now exercises SPECIAL-USE creation,
|
||||
LIST-EXTENDED parsing, and the exact SQL rename boundary for children,
|
||||
grandchildren, and similarly prefixed mailboxes.
|
||||
|
||||
The behavior was also compared directly with current Cyrus IMAP source:
|
||||
subscription is independent of mailbox creation, hierarchy rename preserves
|
||||
descendants, and deleting a mailbox with inferiors leaves the hierarchy
|
||||
available for those descendants.
|
||||
The behavior was compared directly with Cyrus IMAP 3.12.3
|
||||
`imap/imapd.c` (`cmd_changesub`, LIST processing, rename and delete paths) and
|
||||
Dovecot 2.4.4 `src/imap/cmd-list.c`, `src/imap/cmd-subscribe.c`, and
|
||||
`src/lib-storage/mailbox-list.c`. Both implementations keep subscriptions
|
||||
separate from mailbox existence. Dovecot's `used_listext` distinction was
|
||||
also used to preserve the RFC difference between basic `\NoSelect` and
|
||||
extended `\NonExistent` responses. RFC 9051 sections 6.3.7 through 6.3.9 were
|
||||
checked alongside both implementations.
|
||||
|
||||
```text
|
||||
IMAP-05/06 PASS host=127.0.0.1:993 delimiter=/ hierarchy=quoted list=percent/star lsub=subscribed-only extended=subscribed/children/list-status lifecycle=create/rename/sub/unsub/delete delete-with-inferiors=noselect/preserved cleanup=yes
|
||||
IMAP-05/06 PASS host=127.0.0.1:993 delimiter=/ hierarchy=quoted list=percent/star/literal-pattern-list/reference/inbox-case lsub=subscribed-only lsub=mid-wildcard/no-match/delimiter extended=subscribed/children/list-status lifecycle=create/rename/sub/unsub/delete syntax=trailing-arguments-rejected delete-subscription=retained/nonexistent/recreated delete-with-inferiors=noselect/preserved cleanup=yes
|
||||
```
|
||||
|
||||
The test creates only uniquely named disposable mailboxes for `test1`, removes
|
||||
@@ -3503,7 +3520,7 @@ them before exit, and does not alter service configuration or existing mail.
|
||||
|
||||
Result: **PASS**
|
||||
|
||||
The installed `0c0d281b` GCC 15.3.0 debug build was exercised on 2026-07-29
|
||||
The installed `834c9322` GCC 15.3.0 debug build was exercised on 2026-07-29
|
||||
with the reusable `imap-selected-state-check.py`. The test created two
|
||||
disposable mailboxes and appended one disposable message using a synchronizing
|
||||
IMAP literal. Rev1 SELECT returned EXISTS, RECENT, UIDVALIDITY, UIDNEXT, FLAGS,
|
||||
@@ -3519,10 +3536,12 @@ After `ENABLE IMAP4rev2`, STATUS accepted DELETED and DELETED-STORAGE but
|
||||
rejected RECENT; SELECT omitted RECENT, emitted the required LIST response,
|
||||
and selecting a second mailbox emitted the CLOSED response code.
|
||||
|
||||
The source audit used current Cyrus IMAP `imap/imapd.c` as the implementation
|
||||
comparison. Cyrus likewise separates EXAMINE read-only state, expunges on
|
||||
CLOSE but not UNSELECT, emits CLOSED when rev2 selection replaces an open
|
||||
mailbox, and refreshes selected-mailbox state before STATUS.
|
||||
The source audit used Cyrus IMAP 3.12.3 `imap/imapd.c` and Dovecot 2.4.4
|
||||
`src/imap/cmd-select.c`, `cmd-examine.c`, `cmd-status.c`, `cmd-close.c`,
|
||||
`cmd-unselect.c`, and the command registration table as implementation
|
||||
comparisons. Both separate EXAMINE read-only state, expunge on CLOSE but not
|
||||
UNSELECT, reject arguments on CHECK/CLOSE/UNSELECT, and implement the rev2
|
||||
CLOSED transition when a selected mailbox is replaced.
|
||||
|
||||
The first live attempt found a real APPEND deadlock: the IMAP agent buffered
|
||||
the message sent to Store and waited for Store's completion without flushing
|
||||
@@ -3533,9 +3552,57 @@ returns only its payload. The corrected payload parser is covered by the
|
||||
native `imap-uidplus` test and also fixes the later COPY/MOVE UIDPLUS paths.
|
||||
|
||||
```text
|
||||
IMAP-07 PASS host=127.0.0.1:993 select=read-write examine=read-only status=rev1/rev2/size check=selected-only close=deselect/expunge-semantics unselect=no-expunge rev2=closed/list/no-recent cleanup=yes
|
||||
IMAP-07 PASS host=127.0.0.1:993 select=read-write examine=read-only status=rev1/rev2/size check=selected-only noarg-syntax=check/close/unselect close=deselect/expunge-semantics unselect=no-expunge rev2=closed/list/no-recent cleanup=yes
|
||||
```
|
||||
|
||||
The successful run removed its disposable message and mailboxes. The three
|
||||
mailboxes left by deliberately interrupted diagnostic runs were separately
|
||||
listed, matched by their unique test names, and removed afterward.
|
||||
|
||||
## IMAP-08
|
||||
|
||||
Result: **PASS**
|
||||
|
||||
The installed `834c9322` GCC 15.3.0 debug build was exercised on 2026-07-29
|
||||
with the reusable `imap-append-check.py`. Synchronizing literals and
|
||||
non-synchronizing LITERAL+ both committed messages and returned UIDPLUS
|
||||
APPENDUID data. Supplied system flags and INTERNALDATE survived the append.
|
||||
APPEND to a missing mailbox returned TRYCREATE. The advertised global
|
||||
APPENDLIMIT and per-mailbox STATUS APPENDLIMIT agreed, an oversized
|
||||
non-synchronizing literal returned TOOBIG without accepting its body, and the
|
||||
next command proved that the parser stream remained synchronized.
|
||||
|
||||
The implementation was compared with Cyrus IMAP 3.12.3 `imap/imapd.c` append
|
||||
handling and Dovecot 2.4.4 `src/imap/cmd-append.c` plus its command/literal
|
||||
reader. The comparison covered literal continuation timing, LITERAL+,
|
||||
mailbox lookup before data acceptance, bounded literal sizes, flag/date
|
||||
parsing, failure stream recovery, and UIDPLUS completion. RFC 9051 and the
|
||||
advertised APPENDLIMIT/LITERAL+ extension contracts were checked at the same
|
||||
time.
|
||||
|
||||
The native `imap-append-message`, `imap-literal`, and `imap-uidplus` tests
|
||||
passed as part of the complete 101-test native run before the live matrix.
|
||||
|
||||
```text
|
||||
IMAP-08 PASS host=127.0.0.1:993 append=sync/literal+ appendlimit=capability/status/toobig metadata=flags/date missing=trycreate stream=resynchronized cleanup=yes
|
||||
```
|
||||
|
||||
The test removed all disposable messages and mailboxes and did not change
|
||||
service configuration.
|
||||
|
||||
## IMAP retrospective source audit
|
||||
|
||||
Result: **PASS for IMAP-01 through IMAP-08**
|
||||
|
||||
The already completed IMAP blocks were re-audited against actual current
|
||||
server source, not only documentation: Cyrus IMAP 3.12.3 and Dovecot 2.4.4.
|
||||
The comparison found and fixed authentication cancellation/error handling,
|
||||
ID and no-argument syntax validation, LIST/LSUB parsing and wildcard
|
||||
semantics, case-insensitive INBOX handling, independent subscription
|
||||
lifetime, basic-versus-extended LIST attributes, missing Store path quoting,
|
||||
and several error paths which could otherwise omit a tagged response.
|
||||
|
||||
After the fixes, all 101 native tests passed and the four reusable live
|
||||
scripts for IMAP-01 through IMAP-08 passed consecutively against the
|
||||
installed debug build. The same Cyrus/Dovecot source-comparison requirement
|
||||
applies to every remaining IMAP and POP3 row as it is reached in the matrix.
|
||||
|
||||
Reference in New Issue
Block a user