diff --git a/postfix/HISTORY b/postfix/HISTORY index b16cdc2ed..d6e357af4 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -27644,11 +27644,31 @@ Apologies for any names omitted. mantools/postlink, proto/postconf.proto, global/mail_params.h, global/smtp_stream.c, global/smtp_stream.h, smtpd/smtpd.c. -20231226 +20240104 - Cleanup: a nicer implementation of smtpd_forbid_bare_newline - that does not hang up the the middle of a BDAT or DATA - command, and that optionally includes the offending command - sequence in a postmaster 'protocol' notification. Files: - smtpd/smtpd.c, global/stp_stream.[hc], global/cleanup_user.h, - global/cleanup_strerror.c. + Cleanup: when the Postfix SMTP server rejects bare , + log the helo, mail and rcpt information if available. Files: + smtpd/smtpd.c, smtpd/smtpd_check.c. + + Cleanup: when the Postfix SMTP server rejects bare , + keep reading message content after an unexpected . + or ., before responding. This increases the + likelihood that the client will actually see the Postfix + response and remove the attack from their mail queue. Files: + smtpd/smtpd.c, global/smtp_stream.[hc], global/cleanup_user.h. + + Cleanup: added smtpd_forbid_bare_newline settings "reject" + and "normalize". The default setting "normalize" (and "yes") + will accept bare newlines from local or remote SMTP clients, + but if any DATA content line ends in , require the + standard End-of-DATA form . and skip plus + log non-standard End-of-DATA forms. This may fail to receive + email from legitimate clients that send a mix of lines + ending in and . If such clients exist, they + need to be excluded with smtpd_forbid_bare_newline_exclusions. + Files: proto/postconf.proto, global/mail_params.h, + smtpd/smtpd.c. + + Tooling: mantools/dehtml was breaking words in code examples, + causing false spellchecker errors. File: mantools/dehtml, + proto/stop.double-proto-html. diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES index 70d611ee3..d5b101140 100644 --- a/postfix/RELEASE_NOTES +++ b/postfix/RELEASE_NOTES @@ -26,6 +26,56 @@ now also distributed with the more recent Eclipse Public License license of their choice. Those who are more comfortable with the IPL can continue with that license. +Major changes with snapshot 20240102 +==================================== + +This updates Postfix fixes for SMTP smuggling attacks, For background, +see https://www.postfix.org/smtp-smuggling.html + +This release improves configuration (see below) and logging (it now +includes helo, mail, and rcpt information if available). + +- The new setting "smtpd_forbid_bare_newline = normalize" allows + bare newlines from local and remote SMTP clients that send bare + newlines consistently, and maintains more compatibility with + infrastructure tools such as probers and surveys. + +- The new setting "smtpd_forbid_bare_newline = reject" rejects a + command or message that contains a bare newline. To disconnect + the client, specify "smtpd_forbid_bare_newline_reject_code = 521". + +- The old setting "yes" has become an alias for "normalize". + +- The old setting "no" has not changed, and allows SMTP smuggling. + +The recommended Postfix 3.9 settings (i.e. the defaults) are now: + + # Allow bare newlines from local and remote SMTP clients. If any DATA + # content line ends in , require the standard End-of-DATA form + # . and skip non-standard End-of-DATA forms with + # logging that looks like: + # + # skipping unexpected . in DATA from... + # skipping unexpected . in DATA from... + # + # This may fail to receive email from legitimate clients that send a + # mix of lines ending in and . If such clients exist, + # they need to be excluded with smtpd_forbid_bare_newline_exclusions. + # + smtpd_forbid_bare_newline = normalize + smtpd_forbid_bare_newline_exclusions = $mynetworks + +Alternative settings: + + # Reject bare newlines from remote SMTP clients, but allow them from + # local non-standard clients such as netcat, fax machines, or load + # balancer health checks. + # + smtpd_forbid_bare_newline = reject + smtpd_forbid_bare_newline_exclusions = $mynetworks + +This will be back ported to Postfix 3.8.5, 3.7.10, 3.6.14, and 3.5.24. + Incompatible changes with snapshot 20231221 =========================================== diff --git a/postfix/html/postconf.5.html b/postfix/html/postconf.5.html index c6b76a48c..449e10ba3 100644 --- a/postfix/html/postconf.5.html +++ b/postfix/html/postconf.5.html @@ -15922,31 +15922,86 @@ This feature is available in Postfix 2.0 and later.
smtpd_forbid_bare_newline -(default: Postfix ≥ 3.9: yes)
+(default: Postfix ≥ 3.9: normalize)
-

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. Use -smtpd_forbid_bare_newline_exclusions to exclude non-standard clients -such as netcat. Specify "smtpd_forbid_bare_newline = no" to disable -(not recommended for an Internet-connected MTA).

+

Disconnect, reject, or normalize commands and email message +content when a remote SMTP client sends lines ending in <LF>. +Such line endings are commonly allowed with UNIX-based SMTP servers, +but they violate the RFC 5321 requirement that lines must end in +<CR><LF>. <.p> -

Example:

+

Specify one of the following values (case does not matter):

+ +
+ +
normalize
Maintain compatibility with legacy +SMTP clients that send lines ending in the non-standard <LF>, +and treat those line endings as if the client sent the standard +<CR><LF>. However, if an SMTP client sends any DATA +content line ending in the standard <CR><LF>, support +only the standard End-of-DATA form +<CR><LF>.<CR><LF>, and skip non-standard +End-of-DATA forms after logging them as: +
+
+skipping unexpected <LF>.<LF> in DATA from...
+skipping unexpected <LF>.<CR><LF> in DATA from...
+
+
+This may fail to receive email from legitimate SMTP clients that +send DATA content with a mix of line endings. Such clients need +to be excluded with smtpd_forbid_bare_newline_exclusions.
+ +
yes
Alias for "normalize".
+ +
reject
When an SMTP client sends a command +or message content line ending in <LF>, log a "bare <LF> +received" error, and reject the command or message content with +smtpd_forbid_bare_newline_reject_code. This will fail to receive +email from legitimate SMTP clients that send command or message +content with lines ending in <LF>. Such clients need to be +excluded with smtpd_forbid_bare_newline_exclusions.
+ +
no
Treat all lines ending in <LF> +as if the client sent <CR><LF>. This option is fully +backwards compatible, but is not recommended for an Internet-facing +SMTP server, because it is vulnerable to SMTP smuggling. +
+ +
+ +

Examples:

-# Disconnect remote SMTP clients that send bare newlines, but allow
-# local clients with non-standard SMTP implementations such as netcat,
-# fax machines, or load balancer health checks.
+# Allow bare newlines from local and remote SMTP clients. If any
+# DATA content line ends in <CR><LF>, require the standard End-of-DATA
+# form <CR><LF>.<CR><LF> and skip plus log non-standard forms.
+# This may fail to receive email from legitimate clients that send a
+# mix of lines ending in <LF> and <CR><LF>. If such clients exist,
+# they need to be excluded with smtpd_forbid_bare_newline_exclusions.
 #
-smtpd_forbid_bare_newline = yes
+smtpd_forbid_bare_newline = normalize
 smtpd_forbid_bare_newline_exclusions = $mynetworks
 
-

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

+
+
+# Reject bare newlines from remote SMTP clients, but allow them from
+# local non-standard clients such as netcat, fax machines, or load
+# balancer health checks.
+#
+smtpd_forbid_bare_newline = reject
+smtpd_forbid_bare_newline_exclusions = $mynetworks
+
+
+ +

This feature with settings 'yes' and 'no' is available in Postfix +≥ 3.9, 3.8.4, 3.7.9, 3.6.13, and 3.5.23. The settings 'reject' +and 'normalize' are available with Postfix ≥ 3.9, 3.8.5, 3.7.10, +3.6.14, and 3.5.24.

@@ -15958,23 +16013,25 @@ such as netcat. Specify "smt enforcement. It uses the same syntax and parent-domain matching behavior as mynetworks.

-

Example:

- -
-
-# Disconnect remote SMTP clients that send bare newlines, but allow
-# local clients with non-standard SMTP implementations such as netcat,
-# fax machines, or load balancer health checks.
-#
-smtpd_forbid_bare_newline = yes
-smtpd_forbid_bare_newline_exclusions = $mynetworks
-
-
-

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

+ + +
smtpd_forbid_bare_newline_reject_code +(default: 550)
+ +

+The numerical Postfix SMTP server response code when a request +is rejected by the smtpd_forbid_bare_newline feature. +Specify a 5XX status code (521 to disconnect). +

+ +

This feature is available in Postfix ≥ 3.9, 3.8.5, 3.7.10, +3.6.14, and 3.5.24.

+ +
smtpd_forbid_unauth_pipelining diff --git a/postfix/html/smtpd.8.html b/postfix/html/smtpd.8.html index 26ea40b95..c48c494c3 100644 --- a/postfix/html/smtpd.8.html +++ b/postfix/html/smtpd.8.html @@ -997,15 +997,20 @@ SMTPD(8) SMTPD(8) Available in Postfix 3.9, 3.8.4, 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>. + smtpd_forbid_bare_newline (Postfix >= 3.9: normalize) + Disconnect, reject, or normalize commands and email message con- + tent when a remote SMTP client sends lines ending in <LF>. smtpd_forbid_bare_newline_exclusions ($mynetworks) - Exclude the specified clients from smtpd_forbid_bare_newline + Exclude the specified clients from smtpd_forbid_bare_newline enforcement. + Available in Postfix 3.9, 3.8.5, 3.7.10, 3.6.14, 3.5.24 and later: + + smtpd_forbid_bare_newline_reject_code (550) + The numerical Postfix SMTP server response code when a request + is rejected by the smtpd_forbid_bare_newline feature. + 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 e1280475f..6d7d45177 100644 --- a/postfix/man/man5/postconf.5 +++ b/postfix/man/man5/postconf.5 @@ -11003,58 +11003,111 @@ 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. Use -smtpd_forbid_bare_newline_exclusions to exclude non\-standard clients -such as netcat. Specify "smtpd_forbid_bare_newline = no" to disable -(not recommended for an Internet\-connected MTA). +.SH smtpd_forbid_bare_newline (default: Postfix >= 3.9: normalize) +Disconnect, reject, or normalize commands and email message +content when a remote SMTP client sends lines ending in . +Such line endings are commonly allowed with UNIX\-based SMTP servers, +but they violate the RFC 5321 requirement that lines must end in +. <.p> .PP -Example: +Specify one of the following values (case does not matter): +.IP "\fBnormalize\fR" +Maintain compatibility with legacy +SMTP clients that send lines ending in the non\-standard , +and treat those line endings as if the client sent the standard +. However, if an SMTP client sends any DATA +content line ending in the standard , support +only the standard End\-of\-DATA form +., and skip non\-standard +End\-of\-DATA forms after logging them as: .sp .in +4 .nf .na .ft C -# Disconnect remote SMTP clients that send bare newlines, but allow -# local clients with non\-standard SMTP implementations such as netcat, -# fax machines, or load balancer health checks. +skipping unexpected . in DATA from... +skipping unexpected . in DATA from... +.fi +.ad +.ft R +.in -4 +This may fail to receive email from legitimate SMTP clients that +send DATA content with a mix of line endings. Such clients need +to be excluded with smtpd_forbid_bare_newline_exclusions. +.br +.IP "\fByes\fR" +Alias for "normalize". +.br +.IP "\fBreject\fR" +When an SMTP client sends a command +or message content line ending in , log a "bare +received" error, and reject the command or message content with +smtpd_forbid_bare_newline_reject_code. This will fail to receive +email from legitimate SMTP clients that send command or message +content with lines ending in . Such clients need to be +excluded with smtpd_forbid_bare_newline_exclusions. +.br +.IP "\fBno\fR" +Treat all lines ending in +as if the client sent . This option is fully +backwards compatible, but is not recommended for an Internet\-facing +SMTP server, because it is vulnerable to SMTP smuggling. +.br +.br +.PP +Examples: +.sp +.in +4 +.nf +.na +.ft C +# Allow bare newlines from local and remote SMTP clients. If any +# DATA content line ends in , require the standard End\-of\-DATA +# form . and skip plus log non\-standard forms. +# This may fail to receive email from legitimate clients that send a +# mix of lines ending in and . If such clients exist, +# they need to be excluded with smtpd_forbid_bare_newline_exclusions. # -smtpd_forbid_bare_newline = yes +smtpd_forbid_bare_newline = normalize +smtpd_forbid_bare_newline_exclusions = $mynetworks +.fi +.ad +.ft R +.in -4 +.sp +.in +4 +.nf +.na +.ft C +# Reject bare newlines from remote SMTP clients, but allow them from +# local non\-standard clients such as netcat, fax machines, or load +# balancer health checks. +# +smtpd_forbid_bare_newline = reject smtpd_forbid_bare_newline_exclusions = $mynetworks .fi .ad .ft R .in -4 .PP -This feature is available in Postfix >= 3.9, 3.8.4, 3.7.9, -3.6.13, and 3.5.23. +This feature with settings 'yes' and 'no' is available in Postfix +>= 3.9, 3.8.4, 3.7.9, 3.6.13, and 3.5.23. The settings 'reject' +and 'normalize' are available with Postfix >= 3.9, 3.8.5, 3.7.10, +3.6.14, and 3.5.24. .SH smtpd_forbid_bare_newline_exclusions (default: $mynetworks) Exclude the specified clients from smtpd_forbid_bare_newline enforcement. It uses the same syntax and parent\-domain matching behavior as mynetworks. .PP -Example: -.sp -.in +4 -.nf -.na -.ft C -# Disconnect remote SMTP clients that send bare newlines, but allow -# local clients with non\-standard SMTP implementations such as netcat, -# fax machines, or load balancer health checks. -# -smtpd_forbid_bare_newline = yes -smtpd_forbid_bare_newline_exclusions = $mynetworks -.fi -.ad -.ft R -.in -4 -.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_bare_newline_reject_code (default: 550) +The numerical Postfix SMTP server response code when a request +is rejected by the \fBsmtpd_forbid_bare_newline\fR feature. +Specify a 5XX status code (521 to disconnect). +.PP +This feature is available in Postfix >= 3.9, 3.8.5, 3.7.10, +3.6.14, and 3.5.24. .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 17b19695d..25b1f48a4 100644 --- a/postfix/man/man8/smtpd.8 +++ b/postfix/man/man8/smtpd.8 @@ -870,13 +870,18 @@ Disconnect remote SMTP clients that violate RFC 2920 (or 5321) command pipelining constraints. .PP Available in Postfix 3.9, 3.8.4, 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 . +.IP "\fBsmtpd_forbid_bare_newline (Postfix >= 3.9: normalize)\fR" +Disconnect, reject, or normalize commands and email message +content when a remote SMTP client sends lines ending in . .IP "\fBsmtpd_forbid_bare_newline_exclusions ($mynetworks)\fR" Exclude the specified clients from smtpd_forbid_bare_newline enforcement. +.PP +Available in Postfix 3.9, 3.8.5, 3.7.10, 3.6.14, 3.5.24 and +later: +.IP "\fBsmtpd_forbid_bare_newline_reject_code (550)\fR" +The numerical Postfix SMTP server response code when a request +is rejected by the \fBsmtpd_forbid_bare_newline\fR feature. .SH "TARPIT CONTROLS" .na .nf diff --git a/postfix/mantools/dehtml b/postfix/mantools/dehtml index 69f66b7b1..9a3be6f3f 100755 --- a/postfix/mantools/dehtml +++ b/postfix/mantools/dehtml @@ -3,7 +3,7 @@ for i do case $i in - /*) lynx -dump file://localhost$i;; - *) lynx -dump file://localhost`pwd`/$i;; + /*) lynx -width=256 -dump file://localhost$i;; + *) lynx -width=256 -dump file://localhost`pwd`/$i;; esac done | grep -v 'file://localhost/' diff --git a/postfix/mantools/postlink b/postfix/mantools/postlink index d49217e86..85f6b68c4 100755 --- a/postfix/mantools/postlink +++ b/postfix/mantools/postlink @@ -562,6 +562,7 @@ while (<>) { 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_bare_newline_reject_code\b;$&;g; s;\bsmtpd_for[-]*\n*[ ]*bid_bare_newline_exclusions\b;$&;g; s;\bsmtpd_for[-]*\n*[ ]*bid_unauth_pipelining\b;$&;g; s;\bsmtpd_hard_error_limit\b;$&;g; diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto index 537e02af4..f0b835099 100644 --- a/postfix/proto/postconf.proto +++ b/postfix/proto/postconf.proto @@ -11240,6 +11240,17 @@ is rejected by the reject_plaintext_session restriction.

This feature is available in Postfix 2.3 and later.

+%PARAM smtpd_forbid_bare_newline_reject_code 550 + +

+The numerical Postfix SMTP server response code when a request +is rejected by the smtpd_forbid_bare_newline feature. +Specify a 5XX status code (521 to disconnect). +

+ +

This feature is available in Postfix ≥ 3.9, 3.8.5, 3.7.10, +3.6.14, and 3.5.24.

+ %PARAM resolve_numeric_domain no

Resolve "user@ipaddress" as "user@[ipaddress]", instead of @@ -19055,31 +19066,86 @@ 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 +%PARAM smtpd_forbid_bare_newline Postfix ≥ 3.9: normalize -

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. Use -smtpd_forbid_bare_newline_exclusions to exclude non-standard clients -such as netcat. Specify "smtpd_forbid_bare_newline = no" to disable -(not recommended for an Internet-connected MTA).

+

Disconnect, reject, or normalize commands and email message +content when a remote SMTP client sends lines ending in <LF>. +Such line endings are commonly allowed with UNIX-based SMTP servers, +but they violate the RFC 5321 requirement that lines must end in +<CR><LF>. <.p> -

Example:

+

Specify one of the following values (case does not matter):

+ +
+ +
normalize
Maintain compatibility with legacy +SMTP clients that send lines ending in the non-standard <LF>, +and treat those line endings as if the client sent the standard +<CR><LF>. However, if an SMTP client sends any DATA +content line ending in the standard <CR><LF>, support +only the standard End-of-DATA form +<CR><LF>.<CR><LF>, and skip non-standard +End-of-DATA forms after logging them as: +
+
+skipping unexpected <LF>.<LF> in DATA from...
+skipping unexpected <LF>.<CR><LF> in DATA from...
+
+
+This may fail to receive email from legitimate SMTP clients that +send DATA content with a mix of line endings. Such clients need +to be excluded with smtpd_forbid_bare_newline_exclusions.
+ +
yes
Alias for "normalize".
+ +
reject
When an SMTP client sends a command +or message content line ending in <LF>, log a "bare <LF> +received" error, and reject the command or message content with +smtpd_forbid_bare_newline_reject_code. This will fail to receive +email from legitimate SMTP clients that send command or message +content with lines ending in <LF>. Such clients need to be +excluded with smtpd_forbid_bare_newline_exclusions.
+ +
no
Treat all lines ending in <LF> +as if the client sent <CR><LF>. This option is fully +backwards compatible, but is not recommended for an Internet-facing +SMTP server, because it is vulnerable to SMTP smuggling. +
+ +
+ +

Examples:

-# Disconnect remote SMTP clients that send bare newlines, but allow
-# local clients with non-standard SMTP implementations such as netcat,
-# fax machines, or load balancer health checks.
+# Allow bare newlines from local and remote SMTP clients. If any
+# DATA content line ends in <CR><LF>, require the standard End-of-DATA
+# form <CR><LF>.<CR><LF> and skip plus log non-standard forms.
+# This may fail to receive email from legitimate clients that send a
+# mix of lines ending in <LF> and <CR><LF>. If such clients exist,
+# they need to be excluded with smtpd_forbid_bare_newline_exclusions.
 #
-smtpd_forbid_bare_newline = yes
+smtpd_forbid_bare_newline = normalize
 smtpd_forbid_bare_newline_exclusions = $mynetworks
 
-

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

+
+
+# Reject bare newlines from remote SMTP clients, but allow them from
+# local non-standard clients such as netcat, fax machines, or load
+# balancer health checks.
+#
+smtpd_forbid_bare_newline = reject
+smtpd_forbid_bare_newline_exclusions = $mynetworks
+
+
+ +

This feature with settings 'yes' and 'no' is available in Postfix +≥ 3.9, 3.8.4, 3.7.9, 3.6.13, and 3.5.23. The settings 'reject' +and 'normalize' are available with Postfix ≥ 3.9, 3.8.5, 3.7.10, +3.6.14, and 3.5.24.

%PARAM smtpd_forbid_bare_newline_exclusions $mynetworks @@ -19087,19 +19153,6 @@ smtpd_forbid_bare_newline_exclusions = $mynetworks enforcement. It uses the same syntax and parent-domain matching behavior as mynetworks.

-

Example:

- -
-
-# Disconnect remote SMTP clients that send bare newlines, but allow
-# local clients with non-standard SMTP implementations such as netcat,
-# fax machines, or load balancer health checks.
-#
-smtpd_forbid_bare_newline = yes
-smtpd_forbid_bare_newline_exclusions = $mynetworks
-
-
-

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

diff --git a/postfix/proto/stop b/postfix/proto/stop index 375597d29..13a4b3d63 100644 --- a/postfix/proto/stop +++ b/postfix/proto/stop @@ -1589,3 +1589,4 @@ Amawalk resychronization ENVID netcat +probers diff --git a/postfix/proto/stop.double-history b/postfix/proto/stop.double-history index b75d9c7dc..7b32c1fda 100644 --- a/postfix/proto/stop.double-history +++ b/postfix/proto/stop.double-history @@ -82,3 +82,9 @@ proto proto aliases proto virtual proto ADDRESS_REWRITING_README html available Files local command c local local c ID if available File pipe pipe c global smtp_stream h smtpd smtpd c + global smtp_stream c global smtp_stream h smtpd smtpd c + log the helo mail and rcpt information Files smtpd smtpd c + LF LF or LF CR LF before responding This increases + smtpd smtpd c global smtp_stream hc global cleanup_user h + smtpd smtpd c smtpd smtpd_check c + keep reading message content after an unexpected LF LF diff --git a/postfix/proto/stop.double-install-proto-text b/postfix/proto/stop.double-install-proto-text index 338286eb8..edccb2498 100644 --- a/postfix/proto/stop.double-install-proto-text +++ b/postfix/proto/stop.double-install-proto-text @@ -39,3 +39,4 @@ root root you shlib_directory shlib_directory user foo domain user domain domain virtual virtual alias domain anything right hand content does not matter + skipping unexpected LF LF in DATA from diff --git a/postfix/proto/stop.double-proto-html b/postfix/proto/stop.double-proto-html index 3d69cd0a6..78f8eed9d 100644 --- a/postfix/proto/stop.double-proto-html +++ b/postfix/proto/stop.double-proto-html @@ -252,3 +252,96 @@ postfix_ssl_settings postfix_ssl_settings baseline_postfix_settings baseline_postfix_settings The and match and literally Without the the The matches literally Without the the would + The example is simplified for educational purposes In reality my patterns list multiple domain names as domain domain + The matches literally Without the the would match any character + The and match and literally Without the the and would be grouping operators + The matches literally Without the the would match any character + pipeline all commands following EHLO for example MAIL RCPT BDAT BDAT MAIL RCPT BDAT without ever having to wait for a server response This means that with BDAT the Postfix SMTP server cannot distinguish between a well behaved client and a + NOTE Postfix 3 6 also introduces support for the level level and other operators to compare compatibility levels With the standard operators etc compatibility level 3 10 would be smaller than 3 9 which is undesirable + Otherwise the benefits of SMTP connection caching are minor it eliminates the latency of the TCP handshake SYN SYN ACK ACK plus the latency of the SMTP initial handshake 220 greeting EHLO command EHLO response With TLS encrypted + Otherwise the benefits of SMTP connection caching are minor it eliminates the latency of the TCP handshake SYN SYN ACK ACK plus the latency of the SMTP initial handshake 220 greeting EHLO command EHLO response With TLS encrypted + 3 Reject the mail by sending a suitable status code back to Postfix Postfix will send the mail back to the sender address + Line 8 NEVER NEVER NEVER use the t command line option here It will mis deliver mail like sending messages from a mailing list back to the mailing list + Line 8 NEVER NEVER NEVER use the t command line option here It will mis deliver mail like sending messages from a mailing list back to the mailing list +Documentation Documentation is available as README files start with the file README_FILES AAAREADME as HTML web pages point your browser to html index html and as UNIX style manual pages + Parameters whose defaults can be specified in this way are listed below See the postconf 5 manpage for a description command nroff man man man5 postconf 5 less + Parameters whose defaults can be specified in this way are listed below See the postconf 5 manpage for a description command nroff man man man5 postconf 5 less +mynetworks mynetworks 127 0 0 0 8 168 100 189 0 28 1 128 fe80 10 2001 240 587 64 +Postfix Postfix can use an LDAP directory as a source for any of its lookups aliases 5 virtual 5 canonical 5 etc This allows you to keep information for your mail service in a replicated network database with fine grained access controls By not + If you re using the libraries from the UM distribution http www umich edu dirsvcs ldap ldap html or OpenLDAP http www openldap org something like this in the top level of your Postfix source tree should work +query_filter mailacceptinggeneralid s maildrop maildrop maildrop +query_filter mailacceptinggeneralid s maildrop maildrop maildrop +query_filter mailacceptinggeneralid s maildrop maildrop maildrop owner cn root dc your dc com +query_filter mailacceptinggeneralid s maildrop maildrop maildrop owner cn root dc your dc com + As of Postfix version 2 0 the Postfix SMTP server rejects mail for unknown recipients in local domains domains that match mydestination or the IP addresses in inet_interfaces or proxy_interfaces with User unknown in local recipient table + Postfix emulates a limited number of Sendmail macros as shown in the table Some macro values depend on whether a recipient is rejected rejected recipients are available on request by the Milter application Different macros are available at + Postfix has TWO sets of mail filters filters that are used for SMTP mail only specified with the smtpd_milters parameter and filters for non SMTP mail specified with the non_smtpd_milters parameter The non SMTP filters are primarily for + etc usr usr bin var var spool and so on This is especially an issue if you executed postfix install see above as an unprivileged user + etc usr usr bin var var spool and so on This is especially an issue if you executed postfix install see above as an unprivileged user + parametername stress something stress something or parametername stress something something Other parameters always evaluate as if the stress value is the empty string + parametername stress something stress something or parametername stress something something Other parameters always evaluate as if the stress value is the empty string + more CPU faster disks and more network bandwidth can deal with larger deferred queues but as a rule of thumb the deferred queue scales to somewhere between 100 000 and 1 000 000 messages with good performance unlikely above that limit + 31 sasldb Accounts are stored stored in a Cyrus SASL Berkeley DB database + assigned to the delivery slots might look like this 12131415 Hmm fine for sneaking in the single recipient mail but how do we sneak in the mail with more than one recipient Say if we have one four recipient mail followed by two two recipient + we see the hundred recipient job can accumulate ten free delivery slots and then we could preempt it and sneak in the ten recipient mail Wait wait wait Could we Aren t we overinflating the original one thousand recipient mail + The truth is that it turns out that it is not really necessary to wait until the jobs counter accumulates all the delivery slots in advance Say we have ten recipient mail followed by two two recipient mails If the preemption happened when enough + Disallowing RFC 822 address syntax example MAIL FROM the dude dude example com + 3 Reject the mail by sending a suitable SMTP status code back to Postfix Postfix passes the status back to the remote SMTP client This way Postfix does not have to send a bounce message + Lines 14 18 Define the list of valid addresses in the the backed up domain tld domain This prevents your mail queue from filling up with undeliverable MAILER DAEMON messages If you can t maintain a list of valid recipients then you must + The syntax of name value value name value and name value is explained at the beginning of the postconf 5 manual page + Use 521 SMTP reply codes Postfix 2 6 and later or 421 Postfix 2 3 2 5 to hang up on clients that that match botnet related RBLs see next bullet or that match selected non RBL restrictions such as SMTP access maps The Postfix SMTP + the next hop destination can have the Postfix specific form name name port name or name port + dt b a name no_unknown_recipient_checks no_unknown_recipient_checks a b dt + dt b a name check_ccert_access check_ccert_access a i a href DATABASE_README html type table a i b dt + dt b a name check_client_access check_client_access a i a href DATABASE_README html type table a i b dt + dt b a name check_client_a_access check_client_a_access a i a href DATABASE_README html type table a i b dt + dt b a name check_client_mx_access check_client_mx_access a i a href DATABASE_README html type table a i b dt + dt b a name check_client_ns_access check_client_ns_access a i a href DATABASE_README html type table a i b dt + dt b a name check_reverse_client_hostname_access check_reverse_client_hostname_access a i a href DATABASE_README html type table a i b dt + dt b a name check_reverse_client_hostname_a_access check_reverse_client_hostname_a_access a i a href DATABASE_README html type table a i b dt + dt b a name check_reverse_client_hostname_mx_access check_reverse_client_hostname_mx_access a i a href DATABASE_README html type table a i b dt + dt b a name check_reverse_client_hostname_ns_access check_reverse_client_hostname_ns_access a i a href DATABASE_README html type table a i b dt + dt b a name check_sasl_access check_sasl_access a i a href DATABASE_README html type table a i b dt + dt b a name permit_sasl_authenticated permit_sasl_authenticated a b dt + dt b a name permit_tls_all_clientcerts permit_tls_all_clientcerts a b dt + dt b a name reject_rbl_client reject_rbl_client i rbl_domain d d d d i a b dt + dt b a name permit_dnswl_client permit_dnswl_client i dnswl_domain d d d d i a b dt + dt b a name reject_rhsbl_client reject_rhsbl_client i rbl_domain d d d d i a b dt + dt b a name permit_rhswl_client permit_rhswl_client i rhswl_domain d d d d i a b dt + dt b a name reject_rhsbl_reverse_client reject_rhsbl_reverse_client i rbl_domain d d d d i a b dt + dt b a name reject_unknown_client_hostname reject_unknown_client_hostname a b with Postfix lt 2 3 reject_unknown_client dt + dt b a name reject_unknown_reverse_client_hostname reject_unknown_reverse_client_hostname a b dt + dt b a name reject_unknown_forward_client_hostname reject_unknown_forward_client_hostname a b dt + dt b a name check_policy_service check_policy_service i servername i a b dt + dt b a name reject_multi_recipient_bounce reject_multi_recipient_bounce a b dt + dt b a name check_etrn_access check_etrn_access a i a href DATABASE_README html type table a i b dt + dt b a name check_helo_access check_helo_access a i a href DATABASE_README html type table a i b dt + dt b a name check_helo_a_access check_helo_a_access a i a href DATABASE_README html type table a i b dt + dt b a name check_helo_mx_access check_helo_mx_access a i a href DATABASE_README html type table a i b dt + dt b a name check_helo_ns_access check_helo_ns_access a i a href DATABASE_README html type table a i b dt + dt b a name reject_invalid_helo_hostname reject_invalid_helo_hostname a b with Postfix lt 2 3 reject_invalid_hostname dt + dt b a name reject_non_fqdn_helo_hostname reject_non_fqdn_helo_hostname a b with Postfix lt 2 3 reject_non_fqdn_hostname dt + dt b a name reject_rhsbl_helo reject_rhsbl_helo i rbl_domain d d d d i a b dt + dt b a name reject_unknown_helo_hostname reject_unknown_helo_hostname a b with Postfix lt 2 3 reject_unknown_hostname dt + dt b a name check_recipient_access check_recipient_access a i a href DATABASE_README html type table a i b dt + dt b a name check_recipient_a_access check_recipient_a_access a i a href DATABASE_README html type table a i b dt + dt b a name check_recipient_mx_access check_recipient_mx_access a i a href DATABASE_README html type table a i b dt + dt b a name check_recipient_ns_access check_recipient_ns_access a i a href DATABASE_README html type table a i b dt + dt b a name reject_non_fqdn_recipient reject_non_fqdn_recipient a b dt + dt b a name reject_rhsbl_recipient reject_rhsbl_recipient i rbl_domain d d d d i a b dt + dt b a name reject_unauth_destination reject_unauth_destination a b dt + dt b a name reject_unknown_recipient_domain reject_unknown_recipient_domain a b dt + dt b a name reject_unlisted_recipient reject_unlisted_recipient a b with Postfix version 2 0 check_recipient_maps dt + dt b a name reject_unverified_recipient reject_unverified_recipient a b dt + dt b a name check_sender_access check_sender_access a i a href DATABASE_README html type table a i b dt + dt b a name check_sender_a_access check_sender_a_access a i a href DATABASE_README html type table a i b dt + dt b a name check_sender_mx_access check_sender_mx_access a i a href DATABASE_README html type table a i b dt + dt b a name check_sender_ns_access check_sender_ns_access a i a href DATABASE_README html type table a i b dt + dt b a name reject_authenticated_sender_login_mismatch reject_authenticated_sender_login_mismatch a b dt + dt b a name reject_known_sender_login_mismatch reject_known_sender_login_mismatch a b dt + dt b a name reject_rhsbl_sender reject_rhsbl_sender i rbl_domain d d d d i a b dt + dt b a name reject_sender_login_mismatch reject_sender_login_mismatch a b dt + dt b a name reject_unauthenticated_sender_login_mismatch reject_unauthenticated_sender_login_mismatch a b dt + dt b a name reject_unknown_sender_domain reject_unknown_sender_domain a b dt + dt b a name check_address_map check_address_map a i a href DATABASE_README html type table a i b dt + PARAM postscreen_dnsbl_max_ttl postscreen_dnsbl_ttl postscreen_dnsbl_ttl 1 h diff --git a/postfix/proto/stop.spell-history b/postfix/proto/stop.spell-history index 8a4685797..912bffcec 100644 --- a/postfix/proto/stop.spell-history +++ b/postfix/proto/stop.spell-history @@ -66,3 +66,4 @@ spammy Birta Levente MariaDB +dehtml diff --git a/postfix/src/global/cleanup_user.h b/postfix/src/global/cleanup_user.h index 9bc0b9db4..74815bed3 100644 --- a/postfix/src/global/cleanup_user.h +++ b/postfix/src/global/cleanup_user.h @@ -68,7 +68,7 @@ * Non-cleanup errors that live in the same bitmask space, to centralize * error handling. */ -#define CLEANUP_STAT_BARE_LF (1<<16) /* Bare received */ +#define CLEANUP_STAT_BARE_LF (1<<16) /* Bare received */ /* * These are set when we can't bounce even if we were asked to. diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h index 338dc667d..d21e5bfe0 100644 --- a/postfix/src/global/mail_params.h +++ b/postfix/src/global/mail_params.h @@ -4306,11 +4306,14 @@ 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 +#define DEF_SMTPD_FORBID_BARE_LF "normalize" #define VAR_SMTPD_FORBID_BARE_LF_EXCL "smtpd_forbid_bare_newline_exclusions" #define DEF_SMTPD_FORBID_BARE_LF_EXCL "$" VAR_MYNETWORKS +#define VAR_SMTPD_FORBID_BARE_LF_CODE "smtpd_forbid_bare_newline_reject_code" +#define DEF_SMTPD_FORBID_BARE_LF_CODE 550 + /* * Share TLS sessions through tlsproxy(8). */ diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 013508eac..b2f0c7999 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 "20231226" +#define MAIL_RELEASE_DATE "20240104" #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 dccf279a7..b22d245a1 100644 --- a/postfix/src/global/smtp_stream.c +++ b/postfix/src/global/smtp_stream.c @@ -134,9 +134,9 @@ /* 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 timeouts and without making long jumps. Instead, /* query the stream status with vstream_feof() etc. -/* This function will set smtp_forbid_bare_lf when flagging +/* This function will set smtp_seen_bare_lf when flagging /* input with a bare newline byte. /* /* smtp_timeout_setup() is a backwards-compatibility interface @@ -433,7 +433,7 @@ int smtp_get_noexcept(VSTRING *vp, VSTREAM *stream, ssize_t bound, int flags vstring_truncate(vp, VSTRING_LEN(vp) - 1); if (smtp_forbid_bare_lf && (VSTRING_LEN(vp) == 0 || vstring_end(vp)[-1] != '\r')) - smtp_seen_bare_lf = 1; + smtp_seen_bare_lf = smtp_forbid_bare_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/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index f3ab0305d..1fe3b003c 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -824,13 +824,18 @@ /* command pipelining constraints. /* .PP /* Available in Postfix 3.9, 3.8.4, 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 . +/* .IP "\fBsmtpd_forbid_bare_newline (Postfix >= 3.9: normalize)\fR" +/* Disconnect, reject, or normalize commands and email message +/* content when a remote SMTP client sends lines ending in . /* .IP "\fBsmtpd_forbid_bare_newline_exclusions ($mynetworks)\fR" /* Exclude the specified clients from smtpd_forbid_bare_newline /* enforcement. +/* .PP +/* Available in Postfix 3.9, 3.8.5, 3.7.10, 3.6.14, 3.5.24 and +/* later: +/* .IP "\fBsmtpd_forbid_bare_newline_reject_code (550)\fR" +/* The numerical Postfix SMTP server response code when a request +/* is rejected by the \fBsmtpd_forbid_bare_newline\fR feature. /* TARPIT CONTROLS /* .ad /* .fi @@ -1542,8 +1547,10 @@ bool var_relay_before_rcpt_checks; bool var_smtpd_req_deadline; int var_smtpd_min_data_rate; char *var_hfrom_format; -bool var_smtpd_forbid_bare_lf; +char *var_smtpd_forbid_bare_lf; char *var_smtpd_forbid_bare_lf_excl; +int var_smtpd_forbid_bare_lf_code; +static int bare_lf_mask; static NAMADR_LIST *bare_lf_excl; /* @@ -1643,6 +1650,23 @@ static DICT *smtpd_cmd_filter; */ int smtpd_hfrom_format; + /* + * Bare newline handling. + */ +#define BARE_LF_FLAG_NORMALIZE (1<<0) /* Best effort */ +#define BARE_LF_FLAG_REJECT (1<<1) /* Purist */ + +#define IS_BARE_LF_NORMALIZE(m) ((m) & BARE_LF_FLAG_NORMALIZE) +#define IS_BARE_LF_REJECT(m) ((m) & BARE_LF_FLAG_REJECT) + +static const NAME_CODE bare_lf_masks[] = { + "normalize", BARE_LF_FLAG_NORMALIZE, + "yes", BARE_LF_FLAG_NORMALIZE, + "reject", BARE_LF_FLAG_REJECT, + "no", 0, + 0, -1, /* error */ +}; + #ifdef USE_SASL_AUTH /* @@ -3598,6 +3622,8 @@ static void receive_data_message(SMTPD_STATE *state, int curr_rec_type; int prev_rec_type; int first = 1; + int prev_seen_bare_lf = 0; + int expect_crlf_dot = 0; /* * If deadlines are enabled, increase the time budget as message content @@ -3618,13 +3644,15 @@ static void receive_data_message(SMTPD_STATE *state, * XXX Deal with UNIX-style From_ lines at the start of message content * because sendmail permits it. */ - for (prev_rec_type = 0; /* void */ ; prev_rec_type = curr_rec_type) { + for (prev_rec_type = 0; /* void */ ; prev_rec_type = curr_rec_type, + expect_crlf_dot = (expect_crlf_dot || smtp_seen_bare_lf == 0), + prev_seen_bare_lf = smtp_seen_bare_lf) { if (smtp_get(state->buffer, state->client, var_line_limit, SMTP_GET_FLAG_NONE) == '\n') curr_rec_type = REC_TYPE_NORM; else curr_rec_type = REC_TYPE_CONT; - if (smtp_seen_bare_lf) + if (IS_BARE_LF_REJECT(smtp_seen_bare_lf)) state->err |= CLEANUP_STAT_BARE_LF; start = vstring_str(state->buffer); len = VSTRING_LEN(state->buffer); @@ -3638,9 +3666,18 @@ static void receive_data_message(SMTPD_STATE *state, if (len > 0 && IS_SPACE_TAB(start[0])) out_record(out_stream, REC_TYPE_NORM, "", 0); } - if (prev_rec_type != REC_TYPE_CONT && *start == '.' - && (proxy == 0 ? (++start, --len) == 0 : len == 1)) - break; + if (prev_rec_type != REC_TYPE_CONT && *start == '.') { + if (len == 1 && prev_seen_bare_lf && expect_crlf_dot) { + if (IS_BARE_LF_NORMALIZE(prev_seen_bare_lf)) + msg_info("%s: skipping unexpected .%s in DATA from %s", + state->queue_id ? state->queue_id : "NOQUEUE", + smtp_seen_bare_lf ? "" : "", + state->namaddr); + continue; + } + if (proxy == 0 ? (++start, --len) == 0 : len == 1) + break; + } if (state->err == CLEANUP_STAT_OK) { if (ENFORCING_SIZE_LIMIT(var_message_limit) && var_message_limit - state->act_size < len + 2) { @@ -3794,11 +3831,10 @@ static int common_post_message_handling(SMTPD_STATE *state) smtpd_chat_reply(state, "250 2.0.0 Ok: queued as %s", state->queue_id); } else if ((state->err & CLEANUP_STAT_BARE_LF) != 0) { - /* Disconnect immediately. */ state->error_mask |= MAIL_ERROR_PROTOCOL; - msg_info("disconnect: bare received from %s", state->namaddr); - smtpd_chat_reply(state, "521 5.5.2 %s Error: bare received", - var_myhostname); + log_whatsup(state, "reject", "bare received"); + smtpd_chat_reply(state, "%d 5.5.2 %s Error: bare received", + var_smtpd_forbid_bare_lf_code, var_myhostname); } else if (why && IS_SMTP_REJECT(STR(why))) { state->error_mask |= MAIL_ERROR_POLICY; smtpd_chat_reply(state, "%s", STR(why)); @@ -4123,7 +4159,7 @@ static int bdat_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) /* Skip the out_record() and VSTRING_RESET() calls below. */ break; } - if (smtp_seen_bare_lf) + if (IS_BARE_LF_REJECT(smtp_seen_bare_lf)) state->err |= CLEANUP_STAT_BARE_LF; start = vstring_str(state->bdat_get_buffer); len = VSTRING_LEN(state->bdat_get_buffer); @@ -4776,9 +4812,9 @@ static int xclient_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) */ xclient_allowed = namadr_list_match(xclient_hosts, state->name, state->addr); - smtp_forbid_bare_lf = SMTPD_STAND_ALONE((state)) == 0 - && var_smtpd_forbid_bare_lf - && !namadr_list_match(bare_lf_excl, state->name, state->addr); + smtp_forbid_bare_lf = (SMTPD_STAND_ALONE((state)) == 0 && bare_lf_mask + && !namadr_list_match(bare_lf_excl, state->name, state->addr)) ? + bare_lf_mask : 0; /* NOT: tls_reset() */ if (got_helo == 0) helo_reset(state); @@ -5820,13 +5856,11 @@ static void smtpd_proto(SMTPD_STATE *state) } watchdog_pat(); smtpd_chat_query(state); - if (smtp_seen_bare_lf) { - msg_info("disconnect: bare received from %s", - state->namaddr); + if (IS_BARE_LF_REJECT(smtp_seen_bare_lf)) { + log_whatsup(state, "reject", "bare received"); state->error_mask |= MAIL_ERROR_PROTOCOL; - smtpd_chat_reply(state, - "521 5.5.2 %s Error: bare received", - var_myhostname); + smtpd_chat_reply(state, "%d 5.5.2 %s Error: bare received", + var_smtpd_forbid_bare_lf_code, var_myhostname); break; } /* Safety: protect internal interfaces against malformed UTF-8. */ @@ -6180,9 +6214,9 @@ static void smtpd_service(VSTREAM *stream, char *service, char **argv) /* * Enforce strict SMTP line endings, with compatibility exclusions. */ - smtp_forbid_bare_lf = SMTPD_STAND_ALONE((&state)) == 0 - && var_smtpd_forbid_bare_lf - && !namadr_list_match(bare_lf_excl, state.name, state.addr); + smtp_forbid_bare_lf = (SMTPD_STAND_ALONE((&state)) == 0 && bare_lf_mask + && !namadr_list_match(bare_lf_excl, state.name, state.addr)) ? + bare_lf_mask : 0; /* * See if we need to turn on verbose logging for this client. @@ -6249,6 +6283,10 @@ static void pre_jail_init(char *unused_name, char **unused_argv) MATCH_FLAG_RETURN | match_parent_style(VAR_MYNETWORKS), var_smtpd_forbid_bare_lf_excl); + if ((bare_lf_mask = name_code(bare_lf_masks, NAME_CODE_FLAG_NONE, + var_smtpd_forbid_bare_lf)) < 0) + msg_fatal("bad parameter value: '%s = %s'", + VAR_SMTPD_FORBID_BARE_LF, var_smtpd_forbid_bare_lf); /* * Open maps before dropping privileges so we can read passwords etc. @@ -6548,6 +6586,7 @@ int main(int argc, char **argv) VAR_VIRT_MAILBOX_CODE, DEF_VIRT_MAILBOX_CODE, &var_virt_mailbox_code, 0, 0, VAR_RELAY_RCPT_CODE, DEF_RELAY_RCPT_CODE, &var_relay_rcpt_code, 0, 0, VAR_PLAINTEXT_CODE, DEF_PLAINTEXT_CODE, &var_plaintext_code, 0, 0, + VAR_SMTPD_FORBID_BARE_LF_CODE, DEF_SMTPD_FORBID_BARE_LF_CODE, &var_smtpd_forbid_bare_lf_code, 500, 599, VAR_SMTPD_CRATE_LIMIT, DEF_SMTPD_CRATE_LIMIT, &var_smtpd_crate_limit, 0, 0, VAR_SMTPD_CCONN_LIMIT, DEF_SMTPD_CCONN_LIMIT, &var_smtpd_cconn_limit, 0, 0, VAR_SMTPD_CMAIL_LIMIT, DEF_SMTPD_CMAIL_LIMIT, &var_smtpd_cmail_limit, 0, 0, @@ -6615,7 +6654,6 @@ 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, &var_smtpd_forbid_bare_lf, 0, }; static const CONFIG_NBOOL_TABLE nbool_table[] = { @@ -6733,6 +6771,7 @@ int main(int argc, char **argv) VAR_SMTPD_REJ_FTR_MAPS, DEF_SMTPD_REJ_FTR_MAPS, &var_smtpd_rej_ftr_maps, 0, 0, VAR_HFROM_FORMAT, DEF_HFROM_FORMAT, &var_hfrom_format, 1, 0, VAR_SMTPD_FORBID_BARE_LF_EXCL, DEF_SMTPD_FORBID_BARE_LF_EXCL, &var_smtpd_forbid_bare_lf_excl, 0, 0, + VAR_SMTPD_FORBID_BARE_LF, DEF_SMTPD_FORBID_BARE_LF, &var_smtpd_forbid_bare_lf, 1, 0, 0, }; static const CONFIG_RAW_TABLE raw_table[] = { diff --git a/postfix/src/smtpd/smtpd_check.c b/postfix/src/smtpd/smtpd_check.c index 560cd0b2e..975fcbe79 100644 --- a/postfix/src/smtpd/smtpd_check.c +++ b/postfix/src/smtpd/smtpd_check.c @@ -48,6 +48,11 @@ /* /* char *smtpd_check_queue(state) /* SMTPD_STATE *state; +/* AUXILIARY FUNCTIONS +/* void log_whatsup(state, action, text) +/* SMTPD_STATE *state; +/* const char *action; +/* const char *text; /* DESCRIPTION /* This module implements additional checks on SMTP client requests. /* A client request is validated in the context of the session state. @@ -146,6 +151,11 @@ /* The recipient address given with the RCPT TO or VRFY command. /* .IP size /* The message size given with the MAIL FROM command (zero if unknown). +/* .PP +/* log_whatsup() logs ": : +/* from: : " plus the protocol +/* (SMTP or ESMTP), and if available, EHLO, MAIL FROM, or RCPT +/* TO. /* BUGS /* Policies like these should not be hard-coded in C, but should /* be user-programmable instead. @@ -988,8 +998,8 @@ void smtpd_check_init(void) /* log_whatsup - log as much context as we have */ -static void log_whatsup(SMTPD_STATE *state, const char *whatsup, - const char *text) +void log_whatsup(SMTPD_STATE *state, const char *whatsup, + const char *text) { VSTRING *buf = vstring_alloc(100); @@ -5853,7 +5863,7 @@ char *var_smtpd_dns_re_filter; bool var_smtpd_tls_ask_ccert; int var_smtpd_cipv4_prefix; int var_smtpd_cipv6_prefix; -bool var_smtpd_tls_enable_rpk; +bool var_smtpd_tls_enable_rpk; #define int_table test_int_table diff --git a/postfix/src/smtpd/smtpd_check.h b/postfix/src/smtpd/smtpd_check.h index ce24498e2..bf0fe001a 100644 --- a/postfix/src/smtpd/smtpd_check.h +++ b/postfix/src/smtpd/smtpd_check.h @@ -25,6 +25,7 @@ extern char *smtpd_check_etrn(SMTPD_STATE *, char *); extern char *smtpd_check_data(SMTPD_STATE *); extern char *smtpd_check_eod(SMTPD_STATE *); extern char *smtpd_check_policy(SMTPD_STATE *, char *); +extern void log_whatsup(SMTPD_STATE *, const char *, const char *); /* LICENSE /* .ad