diff -ur --exclude=README_FILES /var/tmp/postfix-3.0.15/HISTORY ./HISTORY
--- /var/tmp/postfix-3.0.15/HISTORY 2018-12-27 18:35:10.000000000 -0500
+++ ./HISTORY 2024-01-22 16:17:09.000000000 -0500
@@ -21982,3 +21982,37 @@
a lookup table that does not use fixed-string keys (regexp,
pcre, tcp, etc.). Historically, Postfix would not case-fold
the search string with such tables. File: util/dict_utf8.c.
+
+20240109
+
+ Security (outbound SMTP smuggling): with the default setting
+ "cleanup_replace_stray_cr_lf = yes" Postfix will replace
+ stray or characters in message content with a
+ space character. This prevents Postfix from enabling
+ outbound (remote) SMTP smuggling, and it also makes evaluation
+ of Postfix-added DKIM etc. signatures independent from how
+ a remote mail server handles stray or characters.
+ Files: global/mail_params.h, cleanup/cleanup.c,
+ cleanup/cleanup_message.c, mantools/postlink, proto/postconf.proto.
+
+20240112
+
+ Security (inbound SMTP smuggling): with "smtpd_forbid_bare_newline
+ = normalize" (default "no" for Postfix < 3.9), the Postfix
+ SMTP server requires the standard End-of-DATA sequence
+ ., and otherwise allows command or message
+ content lines ending in the non-standard , processing
+ them as if the client sent the standard .
+
+ The alternative setting, "smtpd_forbid_bare_newline = reject"
+ will reject any command or message that contains a bare
+ , and is more likely to cause problems with legitimate
+ clients.
+
+ For backwards compatibility, local clients are excluded by
+ default with "smtpd_forbid_bare_newline_exclusions =
+ $mynetworks".
+
+ Files: mantools/postlink, proto/postconf.proto,
+ global/mail_params.h, global/smtp_stream.c, global/smtp_stream.h,
+ smtpd/smtpd.c, smtpd/smtpd_check.[hc].
diff -ur --exclude=README_FILES /var/tmp/postfix-3.0.15/RELEASE_NOTES ./RELEASE_NOTES
--- /var/tmp/postfix-3.0.15/RELEASE_NOTES 2016-10-01 19:36:19.000000000 -0400
+++ ./RELEASE_NOTES 2024-01-22 16:26:31.000000000 -0500
@@ -16,6 +16,90 @@
If you upgrade from Postfix 2.10 or earlier, read RELEASE_NOTES-2.11
before proceeding.
+Incompatibility with Postfix 3.8.5, 3.7.10, 3.6.14, and 3.5.24
+==============================================================
+
+Improvements for outbound SMTP smuggling defense:
+
+- With "cleanup_replace_stray_cr_lf = yes" (the default), the cleanup
+ daemon replaces each stray or character in message
+ content with a space character. The replacement happens before
+ any other content management (header/body_checks, Milters, etc).
+
+ This prevents outbound SMTP smuggling, where an attacker uses
+ Postfix to send email containing a non-standard End-of-DATA
+ sequence, to exploit inbound SMTP smuggling at a vulnerable remote
+ SMTP server.
+
+ This also improves the remote evaluation of Postfix-added DKIM
+ and other signatures, as the evaluation result will not depend
+ on how a remote email server handles stray or characters.
+
+This feature applies to all email that Postfix locally or remotely
+sends out. It is not allowlisted based on client identity.
+
+Major changes with Postfix 3.8.5, 3.7.10, 3.6.14, and 3.5.24
+============================================================
+
+Improvements for inbound SMTP smuggling defense:
+
+- Better compatibility: the recommended setting "smtpd_forbid_bare_newline
+ = normalize" requires the standard End-of-DATA sequence
+ ., but allows bare newlines from SMTP clients,
+ maintaining more compatibility with existing infrastructure.
+
+- Improved logging for rejected input (it now includes queue ID,
+ helo, mail, and rcpt, if available).
+
+- The setting "smtpd_forbid_bare_newline = reject" requires
+ that input lines end in , requires the standard End-of-DATA
+ sequence ., and rejects a command or message that
+ contains a bare newline. To disconnect the client, specify
+ "smtpd_forbid_bare_newline_reject_code = 521".
+
+- The Postfix SMTP server no longer strips extra as in
+ ., to silence false alarms from test tools
+ that send attack sequences that real mail servers cannot send.
+ Details at https://www.postfix.org/false-smuggling-claims.html
+
+- The old setting "yes" has become an alias for "normalize".
+
+- The old setting "no" has not changed, and allows SMTP smuggling.
+
+The recommended settings are now:
+
+ # Require the standard End-of-DATA sequence ..
+ # Otherwise, allow bare and process it as if the client sent
+ # .
+ #
+ # This maintains compatibility with many legitimate SMTP client
+ # applications that send a mix of standard and non-standard line
+ # endings, but will fail to receive email from client implementations
+ # that do not terminate DATA content with the standard End-of-DATA
+ # sequence ..
+ #
+ # Such clients can be allowlisted with smtpd_forbid_bare_newline_exclusions.
+ # The example below allowlists SMTP clients in trusted networks.
+ #
+ smtpd_forbid_bare_newline = normalize
+ smtpd_forbid_bare_newline_exclusions = $mynetworks
+
+Alternative settings:
+
+ # Reject input lines that contain and log a "bare received"
+ # error. Require that input lines end in , and require the
+ # standard End-of-DATA sequence ..
+ #
+ # This will reject email from SMTP clients that send any non-standard
+ # line endings such as web applications, netcat, or load balancer
+ # health checks.
+ #
+ # Such clients can be allowlisted with smtpd_forbid_bare_newline_exclusions.
+ # The example below allowlists SMTP clients in trusted networks.
+ #
+ smtpd_forbid_bare_newline = reject
+ smtpd_forbid_bare_newline_exclusions = $mynetworks
+
Workaround - UTF8 support in Postfix MySQL queries
--------------------------------------------------
diff -ur --exclude=README_FILES /var/tmp/postfix-3.0.15/html/cleanup.8.html ./html/cleanup.8.html
--- /var/tmp/postfix-3.0.15/html/cleanup.8.html 2015-10-10 09:33:46.000000000 -0400
+++ ./html/cleanup.8.html 2024-01-22 16:16:48.000000000 -0500
@@ -146,6 +146,16 @@
The set of characters that Postfix will remove from message con-
tent.
+ Available in Postfix version 3.9, 3.8.5, 3.7.10, 3.6.14, 3.5.24, and
+ later:
+
+ cleanup_replace_stray_cr_lf (yes)
+ Replace each stray <CR> or <LF> character in message content
+ with a space character, to prevent outbound SMTP smuggling, and
+ to make the evaluation of Postfix-added DKIM or other signatures
+ independent from how a remote mail server handles such charac-
+ ters.
+
BEFORE QUEUE MILTER CONTROLS
As of version 2.3, Postfix supports the Sendmail version 8 Milter (mail
filter) protocol. When mail is not received via the smtpd(8) server,
diff -ur --exclude=README_FILES /var/tmp/postfix-3.0.15/html/postconf.5.html ./html/postconf.5.html
--- /var/tmp/postfix-3.0.15/html/postconf.5.html 2018-11-10 18:54:17.000000000 -0500
+++ ./html/postconf.5.html 2024-01-22 16:16:48.000000000 -0500
@@ -1416,6 +1416,40 @@
+cleanup_replace_stray_cr_lf
+(default: yes)
+
+ Replace each stray <CR> or <LF> character in message
+content with a space character, to prevent outbound SMTP smuggling,
+and to make the evaluation of Postfix-added DKIM or other signatures
+independent from how a remote mail server handles such characters.
+
+
+ SMTP does not allow such characters unless they are part of a
+<CR><LF> sequence, and different mail systems handle
+such stray characters in an implementation-dependent manner. Stray
+<CR> or <LF> characters could be used for outbound
+SMTP smuggling, where an attacker uses a Postfix server to send
+message content with a non-standard End-of-DATA sequence that
+triggers inbound SMTP smuggling at a remote SMTP server.
+
+ The replacement happens before all other content management,
+and before Postfix may add a DKIM etc. signature; if the signature
+were created first, the replacement could invalidate the signature.
+
+
+ In addition to preventing SMTP smuggling, replacing stray
+<CR> or <LF> characters ensures that the result of
+signature validation by later mail system will not depend on how
+that mail system handles those stray characters in an
+implementation-dependent manner.
+
+ This feature is available in Postfix ≥ 3.9, 3.8.5, 3.7.10,
+3.6.14, and 3.5.24.
+
+
+
+
cleanup_service_name
(default: cleanup)
@@ -14114,6 +14148,133 @@
+smtpd_forbid_bare_newline
+(default: Postfix < 3.9: no)
+
+ Reject or restrict input lines from an SMTP client that end in
+<LF> instead of the standard <CR><LF>. Such line
+endings are commonly allowed with UNIX-based SMTP servers, but they
+violate RFC 5321, and allowing such line endings can make a server
+vulnerable to
+SMTP smuggling.
+
+ Specify one of the following values (case does not matter):
+
+
+
+- normalize
- Require the standard
+End-of-DATA sequence <CR><LF>.<CR><LF>.
+Otherwise, allow command or message content lines ending in the
+non-standard <LF>, and process them as if the client sent the
+standard <CR><LF>.
This maintains compatibility
+with many legitimate SMTP client applications that send a mix of
+standard and non-standard line endings, but will fail to receive
+email from client implementations that do not terminate DATA content
+with the standard End-of-DATA sequence
+<CR><LF>.<CR><LF>.
Such clients
+can be excluded with smtpd_forbid_bare_newline_exclusions.
+
+- yes
- Compatibility alias for normalize.
+
+- reject
- Require the standard End-of-DATA
+sequence <CR><LF>.<CR><LF>. Reject a command
+or message content when a line contains bare <LF>, log a "bare
+<LF> received" error, and reply with the SMTP status code in
+$smtpd_forbid_bare_newline_reject_code.
This will reject
+email from SMTP clients that send any non-standard line endings
+such as web applications, netcat, or load balancer health checks.
+
Such clients can be
+excluded with smtpd_forbid_bare_newline_exclusions.
+
+- no (default)
- Do not require the standard
+End-of-DATA
+sequence <CR><LF>.<CR><LF>. Always process
+a bare <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.
+
+
+
+
+ Recommended settings:
+
+
+
+# Require the standard End-of-DATA sequence <CR><LF>.<CR><LF>.
+# Otherwise, allow bare <LF> and process it as if the client sent
+# <CR><LF>.
+#
+# This maintains compatibility with many legitimate SMTP client
+# applications that send a mix of standard and non-standard line
+# endings, but will fail to receive email from client implementations
+# that do not terminate DATA content with the standard End-of-DATA
+# sequence <CR><LF>.<CR><LF>.
+#
+# Such clients can be allowlisted with smtpd_forbid_bare_newline_exclusions.
+# The example below allowlists SMTP clients in trusted networks.
+#
+smtpd_forbid_bare_newline = normalize
+smtpd_forbid_bare_newline_exclusions = $mynetworks
+
+
+
+ Alternative:
+
+
+
+# Reject input lines that contain <LF> and log a "bare <LF> received"
+# error. Require that input lines end in <CR><LF>, and require the
+# standard End-of-DATA sequence <CR><LF>.<CR><LF>.
+#
+# This will reject email from SMTP clients that send any non-standard
+# line endings such as web applications, netcat, or load balancer
+# health checks.
+#
+# Such clients can be allowlisted with smtpd_forbid_bare_newline_exclusions.
+# The example below allowlists SMTP clients in trusted networks.
+#
+smtpd_forbid_bare_newline = reject
+smtpd_forbid_bare_newline_exclusions = $mynetworks
+
+
+
+ This feature with settings yes and no is available
+in Postfix 3.8.4, 3.7.9, 3.6.13, and 3.5.23. Additionally, the
+settings reject, and normalize are available with
+Postfix ≥ 3.9, 3.8.5, 3.7.10, 3.6.14, and 3.5.24.
+
+
+
+
+smtpd_forbid_bare_newline_exclusions
+(default: $mynetworks)
+
+ Exclude the specified clients from smtpd_forbid_bare_newline
+enforcement. This setting uses the same syntax and parent-domain
+matching behavior as 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 rejecting a
+request with "smtpd_forbid_bare_newline = reject".
+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_forbidden_commands
(default: CONNECT, GET, POST)
diff -ur --exclude=README_FILES /var/tmp/postfix-3.0.15/html/smtpd.8.html ./html/smtpd.8.html
--- /var/tmp/postfix-3.0.15/html/smtpd.8.html 2018-11-17 18:25:20.000000000 -0500
+++ ./html/smtpd.8.html 2024-01-22 16:16:48.000000000 -0500
@@ -833,6 +833,22 @@
record (an SMTP command line, SMTP response line, SMTP message
content line, or TLS protocol message).
+ 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: no)
+ Reject or restrict input lines from an SMTP client that end in
+ <LF> instead of the standard <CR><LF>.
+
+ smtpd_forbid_bare_newline_exclusions ($mynetworks)
+ 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 rejecting a
+ request with "smtpd_forbid_bare_newline = reject".
+
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 -ur --exclude=README_FILES /var/tmp/postfix-3.0.15/man/man5/postconf.5 ./man/man5/postconf.5
--- /var/tmp/postfix-3.0.15/man/man5/postconf.5 2018-11-10 18:54:17.000000000 -0500
+++ ./man/man5/postconf.5 2024-01-22 16:16:48.000000000 -0500
@@ -826,6 +826,32 @@
.fi
.ad
.ft R
+.SH cleanup_replace_stray_cr_lf (default: yes)
+Replace each stray or character in message
+content with a space character, to prevent outbound SMTP smuggling,
+and to make the evaluation of Postfix\-added DKIM or other signatures
+independent from how a remote mail server handles such characters.
+.PP
+SMTP does not allow such characters unless they are part of a
+ sequence, and different mail systems handle
+such stray characters in an implementation\-dependent manner. Stray
+ or characters could be used for outbound
+SMTP smuggling, where an attacker uses a Postfix server to send
+message content with a non\-standard End\-of\-DATA sequence that
+triggers inbound SMTP smuggling at a remote SMTP server.
+.PP
+The replacement happens before all other content management,
+and before Postfix may add a DKIM etc. signature; if the signature
+were created first, the replacement could invalidate the signature.
+.PP
+In addition to preventing SMTP smuggling, replacing stray
+ or characters ensures that the result of
+signature validation by later mail system will not depend on how
+that mail system handles those stray characters in an
+implementation\-dependent manner.
+.PP
+This feature is available in Postfix >= 3.9, 3.8.5, 3.7.10,
+3.6.14, and 3.5.24.
.SH cleanup_service_name (default: cleanup)
The name of the \fBcleanup\fR(8) service. This service rewrites addresses
into the standard form, and performs \fBcanonical\fR(5) address mapping
@@ -9446,6 +9472,131 @@
This parameter is not subjected to $parameter expansion.
.PP
This feature is available in Postfix 2.0 and later.
+.SH smtpd_forbid_bare_newline (default: Postfix < 3.9: no)
+Reject or restrict input lines from an SMTP client that end in
+ instead of the standard . Such line
+endings are commonly allowed with UNIX\-based SMTP servers, but they
+violate RFC 5321, and allowing such line endings can make a server
+vulnerable to
+SMTP smuggling.
+.PP
+Specify one of the following values (case does not matter):
+.IP "\fBnormalize\fR"
+Require the standard
+End\-of\-DATA sequence ..
+Otherwise, allow command or message content lines ending in the
+non\-standard , and process them as if the client sent the
+standard .
+.br
+.br
+This maintains compatibility
+with many legitimate SMTP client applications that send a mix of
+standard and non\-standard line endings, but will fail to receive
+email from client implementations that do not terminate DATA content
+with the standard End\-of\-DATA sequence
+..
+.br
+.br
+Such clients
+can be excluded with smtpd_forbid_bare_newline_exclusions.
+.br
+.IP "\fByes\fR"
+Compatibility alias for \fBnormalize\fR.
+.br
+.IP "\fBreject\fR"
+Require the standard End\-of\-DATA
+sequence .. Reject a command
+or message content when a line contains bare , log a "bare
+ received" error, and reply with the SMTP status code in
+$smtpd_forbid_bare_newline_reject_code.
+.br
+.br
+This will reject
+email from SMTP clients that send any non\-standard line endings
+such as web applications, netcat, or load balancer health checks.
+.br
+.br
+Such clients can be
+excluded with smtpd_forbid_bare_newline_exclusions.
+.br
+.IP "\fBno\fR (default)"
+Do not require the standard
+End\-of\-DATA
+sequence .. Always process
+a bare 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
+Recommended settings:
+.sp
+.in +4
+.nf
+.na
+.ft C
+# Require the standard End\-of\-DATA sequence ..
+# Otherwise, allow bare and process it as if the client sent
+# .
+#
+# This maintains compatibility with many legitimate SMTP client
+# applications that send a mix of standard and non\-standard line
+# endings, but will fail to receive email from client implementations
+# that do not terminate DATA content with the standard End\-of\-DATA
+# sequence ..
+#
+# Such clients can be allowlisted with smtpd_forbid_bare_newline_exclusions.
+# The example below allowlists SMTP clients in trusted networks.
+#
+smtpd_forbid_bare_newline = normalize
+smtpd_forbid_bare_newline_exclusions = $mynetworks
+.fi
+.ad
+.ft R
+.in -4
+.PP
+Alternative:
+.sp
+.in +4
+.nf
+.na
+.ft C
+# Reject input lines that contain and log a "bare received"
+# error. Require that input lines end in , and require the
+# standard End\-of\-DATA sequence ..
+#
+# This will reject email from SMTP clients that send any non\-standard
+# line endings such as web applications, netcat, or load balancer
+# health checks.
+#
+# Such clients can be allowlisted with smtpd_forbid_bare_newline_exclusions.
+# The example below allowlists SMTP clients in trusted networks.
+#
+smtpd_forbid_bare_newline = reject
+smtpd_forbid_bare_newline_exclusions = $mynetworks
+.fi
+.ad
+.ft R
+.in -4
+.PP
+This feature with settings \fByes\fR and \fBno\fR is available
+in Postfix 3.8.4, 3.7.9, 3.6.13, and 3.5.23. Additionally, the
+settings \fBreject\fR, and \fBnormalize\fR 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. This setting uses the same syntax and parent\-domain
+matching behavior as mynetworks.
+.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 rejecting a
+request with "smtpd_forbid_bare_newline = reject".
+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_forbidden_commands (default: CONNECT, GET, POST)
List of commands that cause the Postfix SMTP server to immediately
terminate the session with a 221 code. This can be used to disconnect
diff -ur --exclude=README_FILES /var/tmp/postfix-3.0.15/man/man8/cleanup.8 ./man/man8/cleanup.8
--- /var/tmp/postfix-3.0.15/man/man8/cleanup.8 2015-10-10 09:33:46.000000000 -0400
+++ ./man/man8/cleanup.8 2024-01-22 16:16:48.000000000 -0500
@@ -145,6 +145,14 @@
.IP "\fBmessage_strip_characters (empty)\fR"
The set of characters that Postfix will remove from message
content.
+.PP
+Available in Postfix version 3.9, 3.8.5, 3.7.10, 3.6.14,
+3.5.24, and later:
+.IP "\fBcleanup_replace_stray_cr_lf (yes)\fR"
+Replace each stray or character in message
+content with a space character, to prevent outbound SMTP smuggling,
+and to make the evaluation of Postfix\-added DKIM or other signatures
+independent from how a remote mail server handles such characters.
.SH "BEFORE QUEUE MILTER CONTROLS"
.na
.nf
diff -ur --exclude=README_FILES /var/tmp/postfix-3.0.15/man/man8/smtpd.8 ./man/man8/smtpd.8
--- /var/tmp/postfix-3.0.15/man/man8/smtpd.8 2018-11-17 18:25:19.000000000 -0500
+++ ./man/man8/smtpd.8 2024-01-22 16:22:26.000000000 -0500
@@ -739,6 +739,20 @@
time limit per read or write system call, to a time limit to send
or receive a complete record (an SMTP command line, SMTP response
line, SMTP message content line, or TLS protocol message).
+.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: no)\fR"
+Reject or restrict input lines from an SMTP client that end in
+ instead of the standard .
+.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 rejecting a
+request with "smtpd_forbid_bare_newline = reject".
.SH "TARPIT CONTROLS"
.na
.nf
diff -ur --exclude=README_FILES /var/tmp/postfix-3.0.15/mantools/postlink ./mantools/postlink
--- /var/tmp/postfix-3.0.15/mantools/postlink 2015-01-17 19:06:00.000000000 -0500
+++ ./mantools/postlink 2024-01-22 16:16:48.000000000 -0500
@@ -539,6 +539,10 @@
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_new[-]*\n*[ ]*line\b;$&;g;
+ s;\bsmtpd_for[-]*\n*[ ]*bid_bare_new[-]*\n*[ ]*line_reject_code\b;$&;g;
+ s;\bsmtpd_for[-]*\n*[ ]*bid_bare_new[-]*\n*[ ]*line_exclusions\b;$&;g;
+ s;\bcleanup_replace_stray_cr_lf\b;$&;g;
s;\bsmtpd_hard_error_limit\b;$&;g;
s;\bsmtpd_helo_required\b;$&;g;
s;\bsmtpd_helo_restrictions\b;$&;g;
diff -ur --exclude=README_FILES /var/tmp/postfix-3.0.15/proto/postconf.proto ./proto/postconf.proto
--- /var/tmp/postfix-3.0.15/proto/postconf.proto 2018-11-10 18:53:43.000000000 -0500
+++ ./proto/postconf.proto 2024-01-22 16:27:32.000000000 -0500
@@ -16473,4 +16473,148 @@
This feature is available in Postfix 3.0 and later.
+%PARAM smtpd_forbid_bare_newline Postfix < 3.9: no
+
+ Reject or restrict input lines from an SMTP client that end in
+<LF> instead of the standard <CR><LF>. Such line
+endings are commonly allowed with UNIX-based SMTP servers, but they
+violate RFC 5321, and allowing such line endings can make a server
+vulnerable to
+SMTP smuggling.
+
+ Specify one of the following values (case does not matter):
+
+
+
+- normalize
- Require the standard
+End-of-DATA sequence <CR><LF>.<CR><LF>.
+Otherwise, allow command or message content lines ending in the
+non-standard <LF>, and process them as if the client sent the
+standard <CR><LF>.
This maintains compatibility
+with many legitimate SMTP client applications that send a mix of
+standard and non-standard line endings, but will fail to receive
+email from client implementations that do not terminate DATA content
+with the standard End-of-DATA sequence
+<CR><LF>.<CR><LF>.
Such clients
+can be excluded with smtpd_forbid_bare_newline_exclusions.
+
+- yes
- Compatibility alias for normalize.
+
+- reject
- Require the standard End-of-DATA
+sequence <CR><LF>.<CR><LF>. Reject a command
+or message content when a line contains bare <LF>, log a "bare
+<LF> received" error, and reply with the SMTP status code in
+$smtpd_forbid_bare_newline_reject_code.
This will reject
+email from SMTP clients that send any non-standard line endings
+such as web applications, netcat, or load balancer health checks.
+
Such clients can be
+excluded with smtpd_forbid_bare_newline_exclusions.
+
+- no (default)
- Do not require the standard
+End-of-DATA
+sequence <CR><LF>.<CR><LF>. Always process
+a bare <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.
+
+
+
+
+ Recommended settings:
+
+
+
+# Require the standard End-of-DATA sequence <CR><LF>.<CR><LF>.
+# Otherwise, allow bare <LF> and process it as if the client sent
+# <CR><LF>.
+#
+# This maintains compatibility with many legitimate SMTP client
+# applications that send a mix of standard and non-standard line
+# endings, but will fail to receive email from client implementations
+# that do not terminate DATA content with the standard End-of-DATA
+# sequence <CR><LF>.<CR><LF>.
+#
+# Such clients can be allowlisted with smtpd_forbid_bare_newline_exclusions.
+# The example below allowlists SMTP clients in trusted networks.
+#
+smtpd_forbid_bare_newline = normalize
+smtpd_forbid_bare_newline_exclusions = $mynetworks
+
+
+
+ Alternative:
+
+
+
+# Reject input lines that contain <LF> and log a "bare <LF> received"
+# error. Require that input lines end in <CR><LF>, and require the
+# standard End-of-DATA sequence <CR><LF>.<CR><LF>.
+#
+# This will reject email from SMTP clients that send any non-standard
+# line endings such as web applications, netcat, or load balancer
+# health checks.
+#
+# Such clients can be allowlisted with smtpd_forbid_bare_newline_exclusions.
+# The example below allowlists SMTP clients in trusted networks.
+#
+smtpd_forbid_bare_newline = reject
+smtpd_forbid_bare_newline_exclusions = $mynetworks
+
+
+
+ This feature with settings yes and no is available
+in Postfix 3.8.4, 3.7.9, 3.6.13, and 3.5.23. Additionally, 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
+
+ Exclude the specified clients from smtpd_forbid_bare_newline
+enforcement. This setting uses the same syntax and parent-domain
+matching behavior as mynetworks.
+
+ This feature is available in Postfix ≥ 3.9, 3.8.4, 3.7.9,
+3.6.13, and 3.5.23.
+
+%PARAM smtpd_forbid_bare_newline_reject_code 550
+
+
+The numerical Postfix SMTP server response code when rejecting a
+request with "smtpd_forbid_bare_newline = reject".
+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 cleanup_replace_stray_cr_lf yes
+
+ Replace each stray <CR> or <LF> character in message
+content with a space character, to prevent outbound SMTP smuggling,
+and to make the evaluation of Postfix-added DKIM or other signatures
+independent from how a remote mail server handles such characters.
+
+
+ SMTP does not allow such characters unless they are part of a
+<CR><LF> sequence, and different mail systems handle
+such stray characters in an implementation-dependent manner. Stray
+<CR> or <LF> characters could be used for outbound
+SMTP smuggling, where an attacker uses a Postfix server to send
+message content with a non-standard End-of-DATA sequence that
+triggers inbound SMTP smuggling at a remote SMTP server.
+
+ The replacement happens before all other content management,
+and before Postfix may add a DKIM etc. signature; if the signature
+were created first, the replacement could invalidate the signature.
+
+
+ In addition to preventing SMTP smuggling, replacing stray
+<CR> or <LF> characters ensures that the result of
+signature validation by later mail system will not depend on how
+that mail system handles those stray characters in an
+implementation-dependent manner.
+
+ This feature is available in Postfix ≥ 3.9, 3.8.5, 3.7.10,
+3.6.14, and 3.5.24.
diff -ur --exclude=README_FILES /var/tmp/postfix-3.0.15/src/cleanup/cleanup.c ./src/cleanup/cleanup.c
--- /var/tmp/postfix-3.0.15/src/cleanup/cleanup.c 2015-10-04 08:13:28.000000000 -0400
+++ ./src/cleanup/cleanup.c 2024-01-22 16:16:48.000000000 -0500
@@ -127,6 +127,14 @@
/* .IP "\fBmessage_strip_characters (empty)\fR"
/* The set of characters that Postfix will remove from message
/* content.
+/* .PP
+/* Available in Postfix version 3.9, 3.8.5, 3.7.10, 3.6.14,
+/* 3.5.24, and later:
+/* .IP "\fBcleanup_replace_stray_cr_lf (yes)\fR"
+/* Replace each stray or character in message
+/* content with a space character, to prevent outbound SMTP smuggling,
+/* and to make the evaluation of Postfix-added DKIM or other signatures
+/* independent from how a remote mail server handles such characters.
/* BEFORE QUEUE MILTER CONTROLS
/* .ad
/* .fi
diff -ur --exclude=README_FILES /var/tmp/postfix-3.0.15/src/cleanup/cleanup_init.c ./src/cleanup/cleanup_init.c
--- /var/tmp/postfix-3.0.15/src/cleanup/cleanup_init.c 2015-01-17 18:34:37.000000000 -0500
+++ ./src/cleanup/cleanup_init.c 2024-01-22 16:16:48.000000000 -0500
@@ -165,6 +165,7 @@
int var_auto_8bit_enc_hdr; /* auto-detect 8bit encoding header */
int var_always_add_hdrs; /* always add missing headers */
int var_virt_addrlen_limit; /* stop exponential growth */
+int var_cleanup_mask_stray_cr_lf; /* replace stray CR or LF with space */
const CONFIG_INT_TABLE cleanup_int_table[] = {
VAR_HOPCOUNT_LIMIT, DEF_HOPCOUNT_LIMIT, &var_hopcount_limit, 1, 0,
@@ -182,6 +183,7 @@
VAR_VERP_BOUNCE_OFF, DEF_VERP_BOUNCE_OFF, &var_verp_bounce_off,
VAR_AUTO_8BIT_ENC_HDR, DEF_AUTO_8BIT_ENC_HDR, &var_auto_8bit_enc_hdr,
VAR_ALWAYS_ADD_HDRS, DEF_ALWAYS_ADD_HDRS, &var_always_add_hdrs,
+ VAR_CLEANUP_MASK_STRAY_CR_LF, DEF_CLEANUP_MASK_STRAY_CR_LF, &var_cleanup_mask_stray_cr_lf,
0,
};
diff -ur --exclude=README_FILES /var/tmp/postfix-3.0.15/src/cleanup/cleanup_message.c ./src/cleanup/cleanup_message.c
--- /var/tmp/postfix-3.0.15/src/cleanup/cleanup_message.c 2015-10-04 18:29:37.000000000 -0400
+++ ./src/cleanup/cleanup_message.c 2024-01-22 16:16:48.000000000 -0500
@@ -856,6 +856,23 @@
char *dst;
/*
+ * Replace each stray CR or LF with one space. These are not allowed in
+ * SMTP, and can be used to enable outbound (remote) SMTP smuggling.
+ * Replacing these early ensures that our later DKIM etc. signature will
+ * not be invalidated. Besides preventing SMTP smuggling, replacing stray
+ * or ensures that the result of signature validation by a
+ * later mail system will not depend on how that mail system handles
+ * those stray characters in an implementation-dependent manner.
+ *
+ * The input length is not changed, therefore it is safe to overwrite the
+ * input.
+ */
+ if (var_cleanup_mask_stray_cr_lf)
+ for (dst = (char *) buf; dst < buf + len; dst++)
+ if (*dst == '\r' || *dst == '\n')
+ *dst = ' ';
+
+ /*
* Reject unwanted characters.
*
* XXX Possible optimization: simplify the loop when the "reject" set
diff -ur --exclude=README_FILES /var/tmp/postfix-3.0.15/src/global/cleanup_strerror.c ./src/global/cleanup_strerror.c
--- /var/tmp/postfix-3.0.15/src/global/cleanup_strerror.c 2008-01-08 16:07:47.000000000 -0500
+++ ./src/global/cleanup_strerror.c 2024-01-22 16:16:48.000000000 -0500
@@ -67,6 +67,7 @@
CLEANUP_STAT_SIZE, 552, "5.3.4", "message file too big",
CLEANUP_STAT_CONT, 550, "5.7.1", "message content rejected",
CLEANUP_STAT_WRITE, 451, "4.3.0", "queue file write error",
+ CLEANUP_STAT_BARE_LF, 521, "5.5.2", "bare received",
};
static CLEANUP_STAT_DETAIL cleanup_stat_success = {
diff -ur --exclude=README_FILES /var/tmp/postfix-3.0.15/src/global/cleanup_user.h ./src/global/cleanup_user.h
--- /var/tmp/postfix-3.0.15/src/global/cleanup_user.h 2014-07-13 11:15:53.000000000 -0400
+++ ./src/global/cleanup_user.h 2024-01-22 16:16:48.000000000 -0500
@@ -64,6 +64,12 @@
#define CLEANUP_STAT_DEFER (1<<8) /* Temporary reject */
/*
+ * Non-cleanup errors that live in the same bitmask space, to centralize
+ * error handling.
+ */
+#define CLEANUP_STAT_BARE_LF (1<<16) /* Bare received */
+
+ /*
* These are set when we can't bounce even if we were asked to.
*/
#define CLEANUP_STAT_MASK_CANT_BOUNCE \
diff -ur --exclude=README_FILES /var/tmp/postfix-3.0.15/src/global/mail_params.h ./src/global/mail_params.h
--- /var/tmp/postfix-3.0.15/src/global/mail_params.h 2018-02-18 10:53:29.000000000 -0500
+++ ./src/global/mail_params.h 2024-01-22 16:16:48.000000000 -0500
@@ -3891,6 +3891,22 @@
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 "no"
+
+#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
+
+#define VAR_CLEANUP_MASK_STRAY_CR_LF "cleanup_replace_stray_cr_lf"
+#define DEF_CLEANUP_MASK_STRAY_CR_LF 1
+extern int var_cleanup_mask_stray_cr_lf;
+
+ /*
* Location of shared-library files.
*
* If the files will be installed into a known directory, such as a directory
diff -ur --exclude=README_FILES /var/tmp/postfix-3.0.15/src/global/smtp_stream.c ./src/global/smtp_stream.c
--- /var/tmp/postfix-3.0.15/src/global/smtp_stream.c 2014-12-25 11:47:17.000000000 -0500
+++ ./src/global/smtp_stream.c 2024-01-22 16:16:48.000000000 -0500
@@ -45,6 +45,9 @@
/* VSTREAM *stream;
/* char *format;
/* va_list ap;
+/*
+/* int smtp_detect_bare_lf;
+/* int smtp_got_bare_lf;
/* LEGACY API
/* void smtp_timeout_setup(stream, timeout)
/* VSTREAM *stream;
@@ -100,6 +103,11 @@
/*
/* smtp_vprintf() is the machine underneath smtp_printf().
/*
+/* This function assigns smtp_got_bare_lf = smtp_detect_bare_lf,
+/* if smtp_detect_bare_lf is non-zero and the last read line
+/* was terminated with a bare newline. Otherwise, this function
+/* sets smtp_got_bare_lf to zero.
+/*
/* smtp_timeout_setup() is a backwards-compatibility interface
/* for programs that don't require per-record deadline support.
/* DIAGNOSTICS
@@ -169,6 +177,9 @@
#include "smtp_stream.h"
+int smtp_detect_bare_lf;
+int smtp_got_bare_lf;
+
/* smtp_timeout_reset - reset per-stream error flags, restart deadline timer */
static void smtp_timeout_reset(VSTREAM *stream)
@@ -307,6 +318,8 @@
int last_char;
int next_char;
+ smtp_got_bare_lf = 0;
+
/*
* It's painful to do I/O with records that may span multiple buffers.
* Allow for partial long lines (we will read the remainder later) and
@@ -345,8 +358,15 @@
*/
case '\n':
vstring_truncate(vp, VSTRING_LEN(vp) - 1);
- while (VSTRING_LEN(vp) > 0 && vstring_end(vp)[-1] == '\r')
- vstring_truncate(vp, VSTRING_LEN(vp) - 1);
+ if (smtp_detect_bare_lf) {
+ if (VSTRING_LEN(vp) == 0 || vstring_end(vp)[-1] != '\r')
+ smtp_got_bare_lf = smtp_detect_bare_lf;
+ else
+ vstring_truncate(vp, VSTRING_LEN(vp) - 1);
+ } else {
+ while (VSTRING_LEN(vp) > 0 && vstring_end(vp)[-1] == '\r')
+ vstring_truncate(vp, VSTRING_LEN(vp) - 1);
+ }
VSTRING_TERMINATE(vp);
/* FALLTRHOUGH */
diff -ur --exclude=README_FILES /var/tmp/postfix-3.0.15/src/global/smtp_stream.h ./src/global/smtp_stream.h
--- /var/tmp/postfix-3.0.15/src/global/smtp_stream.h 2012-01-14 19:40:55.000000000 -0500
+++ ./src/global/smtp_stream.h 2024-01-22 16:16:48.000000000 -0500
@@ -41,6 +41,8 @@
extern void smtp_fputs(const char *, ssize_t len, VSTREAM *);
extern void smtp_fwrite(const char *, ssize_t len, VSTREAM *);
extern void smtp_fputc(int, VSTREAM *);
+extern int smtp_detect_bare_lf;
+extern int smtp_got_bare_lf;
extern void smtp_vprintf(VSTREAM *, const char *, va_list);
diff -ur --exclude=README_FILES /var/tmp/postfix-3.0.15/src/smtpd/smtpd.c ./src/smtpd/smtpd.c
--- /var/tmp/postfix-3.0.15/src/smtpd/smtpd.c 2018-11-17 18:25:09.000000000 -0500
+++ ./src/smtpd/smtpd.c 2024-01-22 16:19:57.000000000 -0500
@@ -693,6 +693,20 @@
/* time limit per read or write system call, to a time limit to send
/* or receive a complete record (an SMTP command line, SMTP response
/* line, SMTP message content line, or TLS protocol message).
+/* .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: no)\fR"
+/* Reject or restrict input lines from an SMTP client that end in
+/* instead of the standard .
+/* .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 rejecting a
+/* request with "smtpd_forbid_bare_newline = reject".
/* TARPIT CONTROLS
/* .ad
/* .fi
@@ -1364,6 +1378,12 @@
char *var_smtpd_uproxy_proto;
int var_smtpd_uproxy_tmout;
+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;
+
/*
* Silly little macros.
*/
@@ -1452,6 +1472,40 @@
*/
static DICT *smtpd_cmd_filter;
+ /*
+ * Bare LF and End-of-DATA controls (bare CR is handled elsewhere).
+ *
+ * At the smtp_get*() line reader level, setting any of these flags in the
+ * smtp_detect_bare_lf variable enables the detection of bare newlines. The
+ * line reader will set the same flags in the smtp_got_bare_lf variable
+ * after it detects a bare newline, otherwise it clears smtp_got_bare_lf.
+ *
+ * At the SMTP command level, the flags in smtp_got_bare_lf control whether
+ * commands ending in a bare newline are rejected.
+ *
+ * At the DATA and BDAT content level, the flags in smtp_got_bare_lf control
+ * whether the standard End-of-DATA sequence CRLF.CRLF is required, and
+ * whether lines ending in bare newlines are rejected.
+ *
+ * Postfix implements "delayed reject" after detecting a bare newline in BDAT
+ * or DATA content. The SMTP server delays a REJECT response until the
+ * command is finished, instead of replying and hanging up immediately. The
+ * End-of-DATA detection is secured with BARE_LF_FLAG_WANT_STD_EOD.
+ */
+#define BARE_LF_FLAG_WANT_STD_EOD (1<<0) /* Require CRLF.CRLF */
+#define BARE_LF_FLAG_REPLY_REJECT (1<<1) /* Reject bare newline */
+
+#define IS_BARE_LF_WANT_STD_EOD(m) ((m) & BARE_LF_FLAG_WANT_STD_EOD)
+#define IS_BARE_LF_REPLY_REJECT(m) ((m) & BARE_LF_FLAG_REPLY_REJECT)
+
+static const NAME_CODE bare_lf_mask_table[] = {
+ "normalize", BARE_LF_FLAG_WANT_STD_EOD, /* Default */
+ "yes", BARE_LF_FLAG_WANT_STD_EOD, /* Migration aid */
+ "reject", BARE_LF_FLAG_WANT_STD_EOD | BARE_LF_FLAG_REPLY_REJECT,
+ "no", 0,
+ 0, -1, /* error */
+};
+
#ifdef USE_SASL_AUTH
/*
@@ -3028,6 +3082,7 @@
int curr_rec_type;
int prev_rec_type;
int first = 1;
+ int prev_got_bare_lf = 0;
VSTRING *why = 0;
int saved_err;
int (*out_record) (VSTREAM *, int, const char *, ssize_t);
@@ -3297,12 +3352,15 @@
* 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,
+ prev_got_bare_lf = smtp_got_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 (IS_BARE_LF_REPLY_REJECT(smtp_got_bare_lf))
+ state->err |= CLEANUP_STAT_BARE_LF;
start = vstring_str(state->buffer);
len = VSTRING_LEN(state->buffer);
if (first) {
@@ -3315,9 +3373,14 @@
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 && IS_BARE_LF_WANT_STD_EOD(smtp_detect_bare_lf)
+ && (smtp_got_bare_lf || prev_got_bare_lf))
+ /* Do not store or send to proxy filter. */
+ continue;
+ if (proxy == 0 ? (++start, --len) == 0 : len == 1)
+ break;
+ }
if (state->err == CLEANUP_STAT_OK) {
if (var_message_limit > 0 && var_message_limit - state->act_size < len + 2) {
state->err = CLEANUP_STAT_SIZE;
@@ -3446,6 +3509,11 @@
else
smtpd_chat_reply(state,
"250 2.0.0 Ok: queued as %s", state->queue_id);
+ } else if ((state->err & CLEANUP_STAT_BARE_LF) != 0) {
+ state->error_mask |= MAIL_ERROR_PROTOCOL;
+ 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));
@@ -4078,6 +4146,9 @@
*/
xclient_allowed =
namadr_list_match(xclient_hosts, state->name, state->addr);
+ smtp_detect_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);
@@ -5052,6 +5123,13 @@
}
watchdog_pat();
smtpd_chat_query(state);
+ if (IS_BARE_LF_REPLY_REJECT(smtp_got_bare_lf)) {
+ log_whatsup(state, "reject", "bare received");
+ state->error_mask |= MAIL_ERROR_PROTOCOL;
+ 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. */
if (var_smtputf8_enable && valid_utf8_string(STR(state->buffer),
LEN(state->buffer)) == 0) {
@@ -5326,6 +5404,13 @@
namadr_list_match(xforward_hosts, state.name, state.addr);
/*
+ * Reject or normalize bare LF, with compatibility exclusions.
+ */
+ smtp_detect_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.
*/
debug_peer_check(state.name, state.addr);
@@ -5381,6 +5466,14 @@
hogger_list = namadr_list_init(VAR_SMTPD_HOGGERS, MATCH_FLAG_RETURN
| match_parent_style(VAR_SMTPD_HOGGERS),
var_smtpd_hoggers);
+ bare_lf_excl = namadr_list_init(VAR_SMTPD_FORBID_BARE_LF_EXCL,
+ MATCH_FLAG_RETURN
+ | match_parent_style(VAR_MYNETWORKS),
+ var_smtpd_forbid_bare_lf_excl);
+ if ((bare_lf_mask = name_code(bare_lf_mask_table, 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.
@@ -5672,6 +5765,7 @@
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,
@@ -5835,6 +5929,8 @@
VAR_SMTPD_UPROXY_PROTO, DEF_SMTPD_UPROXY_PROTO, &var_smtpd_uproxy_proto, 0, 0,
VAR_SMTPD_POLICY_DEF_ACTION, DEF_SMTPD_POLICY_DEF_ACTION, &var_smtpd_policy_def_action, 1, 0,
VAR_SMTPD_DNS_RE_FILTER, DEF_SMTPD_DNS_RE_FILTER, &var_smtpd_dns_re_filter, 0, 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 -ur --exclude=README_FILES /var/tmp/postfix-3.0.15/src/smtpd/smtpd_check.c ./src/smtpd/smtpd_check.c
--- /var/tmp/postfix-3.0.15/src/smtpd/smtpd_check.c 2017-12-20 20:27:08.000000000 -0500
+++ ./src/smtpd/smtpd_check.c 2024-01-22 16:16:48.000000000 -0500
@@ -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.
@@ -907,8 +917,8 @@
/* 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);
diff -ur --exclude=README_FILES /var/tmp/postfix-3.0.15/src/smtpd/smtpd_check.h ./src/smtpd/smtpd_check.h
--- /var/tmp/postfix-3.0.15/src/smtpd/smtpd_check.h 2017-01-01 11:21:44.000000000 -0500
+++ ./src/smtpd/smtpd_check.h 2024-01-22 16:16:48.000000000 -0500
@@ -25,6 +25,7 @@
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