From: Wietse Venema Date: Tue, 19 Dec 2023 05:00:00 +0000 (-0500) Subject: postfix-3.9-20231219 X-Git-Tag: v3.9.0~28 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=a41effbfcb42523874cba6c078a9ac075d565291;p=thirdparty%2Fpostfix.git postfix-3.9-20231219 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index d57557f5e..f4d925512 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -27630,3 +27630,13 @@ Apologies for any names omitted. cleanup/cleanup_milter.c, cleanup/Makefile.in, cleanup/test-queue-file18, cleanup/cleanup_milter.in18[a-d], cleanup/cleanup_milter.ref18[a-d][12]. + +20231219 + + Protocol enforcement: with "smtpd_forbid_bare_newline = + yes" (the default for Postfix 3.9), reply with "Error: bare + received" and disconnect when an SMTP client sends a + line ending in , violating the RFC 5321 requirement + that lines must end in . Files: mantools/postlink, + proto/postconf.proto, global/mail_params.h, global/smtp_stream.c, + global/smtp_stream.h, smtpd/smtpd.c. diff --git a/postfix/html/postconf.5.html b/postfix/html/postconf.5.html index 06553f229..ee933d66b 100644 --- a/postfix/html/postconf.5.html +++ b/postfix/html/postconf.5.html @@ -15919,6 +15919,23 @@ This feature is available in Postfix 2.0 and later.

+ + +
smtpd_forbid_bare_newline +(default: Postfix ≥ 3.9: yes)
+ +

Reply with "Error: bare <LF> received" and disconnect +when a remote SMTP client sends a line ending in <LF>, violating +the RFC 5321 requirement that lines must end in <CR><LF>. +This feature is enabled by default with Postfix ≥ 3.9 but may +not work with non-standard clients such as netcat. Specify +"smtpd_forbid_bare_newline = no" to disable (not recommended for +an Internet-connected MTA).

+ +

This feature is available in Postfix ≥ 3.9, 3.8.4, 3.7.9, +3.6.13, and 3.5.23.

+ +
smtpd_forbid_unauth_pipelining diff --git a/postfix/html/smtpd.8.html b/postfix/html/smtpd.8.html index a9d2b9a9a..084d34bc3 100644 --- a/postfix/html/smtpd.8.html +++ b/postfix/html/smtpd.8.html @@ -995,6 +995,13 @@ SMTPD(8) SMTPD(8) Disconnect remote SMTP clients that violate RFC 2920 (or 5321) command pipelining constraints. + Available in Postfix 3.9, 3.8.3, 3.7.9, 3.6.13, 3.5.23 and later: + + smtpd_forbid_bare_newline (Postfix >= 3.9: yes) + Reply with "Error: bare <LF> received" and disconnect when a + remote SMTP client sends a line ending in <LF>, violating the + RFC 5321 requirement that lines must end in <CR><LF>. + TARPIT CONTROLS When a remote SMTP client makes errors, the Postfix SMTP server can insert delays before responding. This can help to slow down run-away diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5 index 0ceea67ee..623ea49fd 100644 --- a/postfix/man/man5/postconf.5 +++ b/postfix/man/man5/postconf.5 @@ -11003,6 +11003,17 @@ The smtpd_expansion_filter value is not subject to Postfix configuration parameter $name expansion. .PP This feature is available in Postfix 2.0 and later. +.SH smtpd_forbid_bare_newline (default: Postfix >= 3.9: yes) +Reply with "Error: bare received" and disconnect +when a remote SMTP client sends a line ending in , violating +the RFC 5321 requirement that lines must end in . +This feature is enabled by default with Postfix >= 3.9 but may +not work with non\-standard clients such as netcat. Specify +"smtpd_forbid_bare_newline = no" to disable (not recommended for +an Internet\-connected MTA). +.PP +This feature is available in Postfix >= 3.9, 3.8.4, 3.7.9, +3.6.13, and 3.5.23. .SH smtpd_forbid_unauth_pipelining (default: Postfix >= 3.9: yes) Disconnect remote SMTP clients that violate RFC 2920 (or 5321) command pipelining constraints. The server replies with "554 5.5.0 diff --git a/postfix/man/man8/smtpd.8 b/postfix/man/man8/smtpd.8 index 6883ab107..56e22621c 100644 --- a/postfix/man/man8/smtpd.8 +++ b/postfix/man/man8/smtpd.8 @@ -868,6 +868,12 @@ Available in Postfix 3.9, 3.8.1, 3.7.6, 3.6.10, 3.5.20 and later: .IP "\fBsmtpd_forbid_unauth_pipelining (Postfix >= 3.9: yes)\fR" Disconnect remote SMTP clients that violate RFC 2920 (or 5321) command pipelining constraints. +.PP +Available in Postfix 3.9, 3.8.3, 3.7.9, 3.6.13, 3.5.23 and later: +.IP "\fBsmtpd_forbid_bare_newline (Postfix >= 3.9: yes)\fR" +Reply with "Error: bare received" and disconnect +when a remote SMTP client sends a line ending in , violating +the RFC 5321 requirement that lines must end in . .SH "TARPIT CONTROLS" .na .nf diff --git a/postfix/mantools/postlink b/postfix/mantools/postlink index 35337f5da..31f00be25 100755 --- a/postfix/mantools/postlink +++ b/postfix/mantools/postlink @@ -561,6 +561,7 @@ while (<>) { s;\bsmtpd_etrn_restrictions\b;$&;g; s;\bsmtpd_expansion_filter\b;$&;g; s;\bsmtpd_for[-]*\n*[ ]*bidden_commands\b;$&;g; + s;\bsmtpd_for[-]*\n*[ ]*bid_bare_newline\b;$&;g; s;\bsmtpd_for[-]*\n*[ ]*bid_unauth_pipelining\b;$&;g; s;\bsmtpd_hard_error_limit\b;$&;g; s;\bsmtpd_helo_required\b;$&;g; diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto index 8e014f690..1023c776e 100644 --- a/postfix/proto/postconf.proto +++ b/postfix/proto/postconf.proto @@ -19055,6 +19055,19 @@ MinProtocol = TLSv1

This feature is available in Postfix ≥ 3.9, 3.8.1, 3.7.6, 3.6.10, and 3.5.20.

+%PARAM smtpd_forbid_bare_newline Postfix ≥ 3.9: yes + +

Reply with "Error: bare <LF> received" and disconnect +when a remote SMTP client sends a line ending in <LF>, violating +the RFC 5321 requirement that lines must end in <CR><LF>. +This feature is enabled by default with Postfix ≥ 3.9 but may +not work with non-standard clients such as netcat. Specify +"smtpd_forbid_bare_newline = no" to disable (not recommended for +an Internet-connected MTA).

+ +

This feature is available in Postfix ≥ 3.9, 3.8.4, 3.7.9, +3.6.13, and 3.5.23.

+ %PARAM smtpd_forbid_unauth_pipelining Postfix ≥ 3.9: yes

Disconnect remote SMTP clients that violate RFC 2920 (or 5321) diff --git a/postfix/proto/stop b/postfix/proto/stop index 66dd2dab1..375597d29 100644 --- a/postfix/proto/stop +++ b/postfix/proto/stop @@ -1588,3 +1588,4 @@ sni Amawalk resychronization ENVID +netcat diff --git a/postfix/proto/stop.double-history b/postfix/proto/stop.double-history index 68d5bd80f..b75d9c7dc 100644 --- a/postfix/proto/stop.double-history +++ b/postfix/proto/stop.double-history @@ -81,3 +81,4 @@ proto proto aliases proto virtual proto ADDRESS_REWRITING_README html client process name File proxymap proxymap c available Files local command c local local c ID if available File pipe pipe c + global smtp_stream h smtpd smtpd c diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h index 11d58a6e7..244f05f51 100644 --- a/postfix/src/global/mail_params.h +++ b/postfix/src/global/mail_params.h @@ -4302,6 +4302,12 @@ extern char *var_smtp_dns_re_filter; #define DEF_SMTPD_DNS_RE_FILTER "" extern char *var_smtpd_dns_re_filter; + /* + * Backwards compatibility. + */ +#define VAR_SMTPD_FORBID_BARE_LF "smtpd_forbid_bare_newline" +#define DEF_SMTPD_FORBID_BARE_LF 1 + /* * Share TLS sessions through tlsproxy(8). */ diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 3f684bfb1..2bfce0ea5 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,7 +20,7 @@ * Patches change both the patchlevel and the release date. Snapshots have no * patchlevel; they change the release date only. */ -#define MAIL_RELEASE_DATE "20231213" +#define MAIL_RELEASE_DATE "20231219" #define MAIL_VERSION_NUMBER "3.9" #ifdef SNAPSHOT diff --git a/postfix/src/global/smtp_stream.c b/postfix/src/global/smtp_stream.c index 595a159f0..b7209009d 100644 --- a/postfix/src/global/smtp_stream.c +++ b/postfix/src/global/smtp_stream.c @@ -52,6 +52,8 @@ /* VSTREAM *stream; /* char *format; /* va_list ap; +/* +/* int smtp_forbid_bare_lf; /* AUXILIARY API /* int smtp_get_noexcept(vp, stream, maxlen, flags) /* VSTRING *vp; @@ -131,11 +133,16 @@ /* smtp_vprintf() is the machine underneath smtp_printf(). /* /* smtp_get_noexcept() implements the subset of smtp_get() -/* without timeouts and without making long jumps. Instead, +/* without long jumps for timeout or EOF errors. Instead, /* query the stream status with vstream_feof() etc. +/* This function will make a VSTREAM long jump (error code +/* SMTP_ERR_LF) when rejecting input with a bare newline byte. /* /* smtp_timeout_setup() is a backwards-compatibility interface /* for programs that don't require deadline or data-rate support. +/* +/* smtp_forbid_bare_lf controls whether smtp_get_noexcept() +/* will reject input with a bare newline byte. /* DIAGNOSTICS /* .fi /* .ad @@ -214,6 +221,7 @@ * the buffer. Such system calls would really hurt when receiving or sending * body content one line at a time. */ +int smtp_forbid_bare_lf; /* smtp_timeout_reset - reset per-stream error flags */ @@ -418,6 +426,9 @@ int smtp_get_noexcept(VSTRING *vp, VSTREAM *stream, ssize_t bound, int flags */ case '\n': vstring_truncate(vp, VSTRING_LEN(vp) - 1); + if (smtp_forbid_bare_lf + && (VSTRING_LEN(vp) == 0 || vstring_end(vp)[-1] != '\r')) + vstream_longjmp(stream, SMTP_ERR_LF); while (VSTRING_LEN(vp) > 0 && vstring_end(vp)[-1] == '\r') vstring_truncate(vp, VSTRING_LEN(vp) - 1); VSTRING_TERMINATE(vp); diff --git a/postfix/src/global/smtp_stream.h b/postfix/src/global/smtp_stream.h index 75700fed3..4bcd6b59b 100644 --- a/postfix/src/global/smtp_stream.h +++ b/postfix/src/global/smtp_stream.h @@ -32,6 +32,7 @@ #define SMTP_ERR_QUIET 3 /* silent cleanup (application) */ #define SMTP_ERR_NONE 4 /* non-error case */ #define SMTP_ERR_DATA 5 /* application data error */ +#define SMTP_ERR_LF 6 /* bare protocol error */ extern void smtp_stream_setup(VSTREAM *, int, int, int); extern void PRINTFLIKE(2, 3) smtp_printf(VSTREAM *, const char *,...); @@ -43,6 +44,7 @@ extern void smtp_fputs(const char *, ssize_t len, VSTREAM *); extern void smtp_fwrite(const char *, ssize_t len, VSTREAM *); extern void smtp_fread_buf(VSTRING *, ssize_t len, VSTREAM *); extern void smtp_fputc(int, VSTREAM *); +extern int smtp_forbid_bare_lf; extern void smtp_vprintf(VSTREAM *, const char *, va_list); diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index 2dbc8350b..8e91fc2f0 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -822,6 +822,12 @@ /* .IP "\fBsmtpd_forbid_unauth_pipelining (Postfix >= 3.9: yes)\fR" /* Disconnect remote SMTP clients that violate RFC 2920 (or 5321) /* command pipelining constraints. +/* .PP +/* Available in Postfix 3.9, 3.8.3, 3.7.9, 3.6.13, 3.5.23 and later: +/* .IP "\fBsmtpd_forbid_bare_newline (Postfix >= 3.9: yes)\fR" +/* Reply with "Error: bare received" and disconnect +/* when a remote SMTP client sends a line ending in , violating +/* the RFC 5321 requirement that lines must end in . /* TARPIT CONTROLS /* .ad /* .fi @@ -1608,6 +1614,7 @@ static void tls_reset(SMTPD_STATE *); #define REASON_TIMEOUT "timeout" #define REASON_LOST_CONNECTION "lost connection" #define REASON_ERROR_LIMIT "too many errors" +#define REASON_BARE_LF "bare received" #ifdef USE_TLS @@ -4066,6 +4073,7 @@ static int bdat_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) */ done = 0; do { + int payload_err; /* * Do not skip the smtp_fread_buf() call if read_len == 0. We still @@ -4079,6 +4087,11 @@ static int bdat_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) smtp_fread_buf(state->buffer, read_len, state->client); state->bdat_get_stream = vstream_memreopen( state->bdat_get_stream, state->buffer, O_RDONLY); + vstream_control(state->bdat_get_stream, CA_VSTREAM_CTL_EXCEPT, + CA_VSTREAM_CTL_END); + if ((payload_err = vstream_setjmp(state->bdat_get_stream)) + != SMTP_ERR_NONE) + vstream_longjmp(state->client, payload_err); /* * Read lines from the fragment. The last line may continue in the @@ -5576,6 +5589,13 @@ static void smtpd_proto(SMTPD_STATE *state) var_myhostname); break; + case SMTP_ERR_LF: + state->reason = REASON_BARE_LF; + if (vstream_setjmp(state->client) == 0) + smtpd_chat_reply(state, "521 5.5.2 %s Error: bare received", + var_myhostname); + break; + case 0: /* @@ -6570,6 +6590,7 @@ int main(int argc, char **argv) VAR_SMTPD_DELAY_OPEN, DEF_SMTPD_DELAY_OPEN, &var_smtpd_delay_open, VAR_SMTPD_CLIENT_PORT_LOG, DEF_SMTPD_CLIENT_PORT_LOG, &var_smtpd_client_port_log, VAR_SMTPD_FORBID_UNAUTH_PIPE, DEF_SMTPD_FORBID_UNAUTH_PIPE, &var_smtpd_forbid_unauth_pipe, + VAR_SMTPD_FORBID_BARE_LF, DEF_SMTPD_FORBID_BARE_LF, &smtp_forbid_bare_lf, 0, }; static const CONFIG_NBOOL_TABLE nbool_table[] = {