Download raw body.
smtpd: ehlo MUST reset the transaction
quoting RFC5321 ยง4.1.4:
> An EHLO command MAY be issued by a client later in the session. If it
> is issued after the session begins and the EHLO command is acceptable to
> the SMTP server, the SMTP server MUST clear all buffers and reset the
> state exactly as if a RSET command had been issued. [...]
This was brought to my attention a few times over the last release
cycle, we even had an issue on the -portable repository, as there are
some clients that actually rely on this behaviour.
I've tested a simpler variation of the diff below for several months
(been procrastinating on cleaning it up) on my mx and at a customer's
site.
To ease the review, take a look at smtp_proceed_rset() in the same file
as well too, it's exactly what i'm adding in smtp_proceed_ehlo.
smtp_tx_free() could feel a bit awkward to use like this, but it will
actually set session->tx back to NULL internally.
okay?
diff /home/op/w/smtpd
path + /home/op/w/smtpd
commit - 90063ccc4246e9d74e7fc619f8817b9f18458a99
blob - 00bac7ede042aa5378e6476b5173d3f6932a7d91
file + smtp_session.c
--- smtp_session.c
+++ smtp_session.c
@@ -1422,13 +1422,6 @@ smtp_check_ehlo(struct smtp_session *s, const char *ar
return 0;
}
- if (s->helo[0]) {
- smtp_reply(s, "503 %s %s: Already identified",
- esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
- esc_description(ESC_INVALID_COMMAND));
- return 0;
- }
-
if (args == NULL) {
smtp_reply(s, "501 %s %s: EHLO requires domain name",
esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
@@ -1770,6 +1763,12 @@ smtp_proceed_ehlo(struct smtp_session *s, const char *
s->flags |= SF_EHLO;
s->flags |= SF_8BITMIME;
+ if (s->tx) {
+ if (s->tx->msgid)
+ smtp_tx_rollback(s->tx);
+ smtp_tx_free(s->tx);
+ }
+
smtp_report_link_identify(s, "EHLO", s->helo);
smtp_enter_state(s, STATE_HELO);
smtpd: ehlo MUST reset the transaction