]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
submission-login: submission-proxy - Handle multi-line backend AUTH reply
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Fri, 26 Jun 2026 05:50:10 +0000 (05:50 +0000)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Thu, 2 Jul 2026 21:15:41 +0000 (21:15 +0000)
In the SUBMISSION_PROXY_AUTHENTICATE state a non-334 reply line that is
not an invalid line ran i_assert(proxy_reply == NULL) and then created
proxy_reply, returning early (return 0) for a non-final line without
clearing it. proxy_reply is only reset on connection reset, so a backend
answering the proxied AUTH with a multi-line reply (e.g. a two-line
'535-...' / '535 ...' rejection) re-entered this state with proxy_reply
already set and tripped the assert, i_panic()ing the submission-login
process - a deterministic DoS triggerable by a malicious/compromised
backend.

Create proxy_reply only on the first line and append each subsequent
line's text to it.

src/submission-login/submission-proxy.c

index 3a2e1f84e0a8db97f847d870c6ed37d021c00b82..296e7a585ff5a052f5b8243c2416f78469fa856e 100644 (file)
@@ -651,9 +651,15 @@ int submission_proxy_parse_line(struct client *client, const char *line)
                        return 0;
                }
 
-               i_assert(subm_client->proxy_reply == NULL);
-               subm_client->proxy_reply = smtp_server_reply_create(
-                       command, status, enh_code);
+               /* The backend may answer the proxied AUTH with a multi-line
+                  reply, in which case this callback is invoked once per line
+                  with the reply still pending (!last_line). Create the reply
+                  on the first line and append the text of each subsequent
+                  line. */
+               if (subm_client->proxy_reply == NULL) {
+                       subm_client->proxy_reply = smtp_server_reply_create(
+                               command, status, enh_code);
+               }
                smtp_server_reply_add_text(subm_client->proxy_reply, text);
 
                if (!last_line)