cleanup/cleanup_milter.c, cleanup/Makefile.in,
cleanup/test-queue-file18, cleanup/cleanup_milter.in18[a-d],
cleanup/cleanup_milter.ref18[a-d][12].
+
+20231219
+
+ Protocol enforcement: with "smtpd_forbid_bare_newline =
+ yes" (the default for Postfix 3.9), reply with "Error: bare
+ <LF> received" and disconnect when an SMTP client sends a
+ line ending in <LF>, violating the RFC 5321 requirement
+ that lines must end in <CR><LF>. Files: mantools/postlink,
+ proto/postconf.proto, global/mail_params.h, global/smtp_stream.c,
+ global/smtp_stream.h, smtpd/smtpd.c.
</p>
+</DD>
+
+<DT><b><a name="smtpd_forbid_bare_newline">smtpd_forbid_bare_newline</a>
+(default: Postfix ≥ 3.9: yes)</b></DT><DD>
+
+<p> Reply with "Error: bare <LF> received" and disconnect
+when a remote SMTP client sends a line ending in <LF>, violating
+the <a href="https://tools.ietf.org/html/rfc5321">RFC 5321</a> requirement that lines must end in <CR><LF>.
+This feature is enabled by default with Postfix ≥ 3.9 but may
+not work with non-standard clients such as netcat. Specify
+"<a href="postconf.5.html#smtpd_forbid_bare_newline">smtpd_forbid_bare_newline</a> = no" to disable (not recommended for
+an Internet-connected MTA). </p>
+
+<p> This feature is available in Postfix ≥ 3.9, 3.8.4, 3.7.9,
+3.6.13, and 3.5.23. </p>
+
+
</DD>
<DT><b><a name="smtpd_forbid_unauth_pipelining">smtpd_forbid_unauth_pipelining</a>
Disconnect remote SMTP clients that violate <a href="https://tools.ietf.org/html/rfc2920">RFC 2920</a> (or 5321)
command pipelining constraints.
+ Available in Postfix 3.9, 3.8.3, 3.7.9, 3.6.13, 3.5.23 and later:
+
+ <b><a href="postconf.5.html#smtpd_forbid_bare_newline">smtpd_forbid_bare_newline</a> (Postfix</b> ><b>= 3.9: yes)</b>
+ Reply with "Error: bare <LF> received" and disconnect when a
+ remote SMTP client sends a line ending in <LF>, violating the
+ <a href="https://tools.ietf.org/html/rfc5321">RFC 5321</a> requirement that lines must end in <CR><LF>.
+
<b>TARPIT CONTROLS</b>
When a remote SMTP client makes errors, the Postfix SMTP server can
insert delays before responding. This can help to slow down run-away
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 <LF> received" and disconnect
+when a remote SMTP client sends a line ending in <LF>, violating
+the RFC 5321 requirement that lines must end in <CR><LF>.
+This feature is enabled by default with Postfix >= 3.9 but may
+not work with non\-standard clients such as netcat. Specify
+"smtpd_forbid_bare_newline = no" to disable (not recommended for
+an Internet\-connected MTA).
+.PP
+This feature is available in Postfix >= 3.9, 3.8.4, 3.7.9,
+3.6.13, and 3.5.23.
.SH smtpd_forbid_unauth_pipelining (default: Postfix >= 3.9: yes)
Disconnect remote SMTP clients that violate RFC 2920 (or 5321)
command pipelining constraints. The server replies with "554 5.5.0
.IP "\fBsmtpd_forbid_unauth_pipelining (Postfix >= 3.9: yes)\fR"
Disconnect remote SMTP clients that violate RFC 2920 (or 5321)
command pipelining constraints.
+.PP
+Available in Postfix 3.9, 3.8.3, 3.7.9, 3.6.13, 3.5.23 and later:
+.IP "\fBsmtpd_forbid_bare_newline (Postfix >= 3.9: yes)\fR"
+Reply with "Error: bare <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>.
.SH "TARPIT CONTROLS"
.na
.nf
s;\bsmtpd_etrn_restrictions\b;<a href="postconf.5.html#smtpd_etrn_restrictions">$&</a>;g;
s;\bsmtpd_expansion_filter\b;<a href="postconf.5.html#smtpd_expansion_filter">$&</a>;g;
s;\bsmtpd_for[-</bB>]*\n*[ <bB>]*bidden_commands\b;<a href="postconf.5.html#smtpd_forbidden_commands">$&</a>;g;
+ s;\bsmtpd_for[-</bB>]*\n*[ <bB>]*bid_bare_newline\b;<a href="postconf.5.html#smtpd_forbid_bare_newline">$&</a>;g;
s;\bsmtpd_for[-</bB>]*\n*[ <bB>]*bid_unauth_pipelining\b;<a href="postconf.5.html#smtpd_forbid_unauth_pipelining">$&</a>;g;
s;\bsmtpd_hard_error_limit\b;<a href="postconf.5.html#smtpd_hard_error_limit">$&</a>;g;
s;\bsmtpd_helo_required\b;<a href="postconf.5.html#smtpd_helo_required">$&</a>;g;
<p> This feature is available in Postfix ≥ 3.9, 3.8.1, 3.7.6,
3.6.10, and 3.5.20. </p>
+%PARAM smtpd_forbid_bare_newline Postfix ≥ 3.9: yes
+
+<p> Reply with "Error: bare <LF> received" and disconnect
+when a remote SMTP client sends a line ending in <LF>, violating
+the RFC 5321 requirement that lines must end in <CR><LF>.
+This feature is enabled by default with Postfix ≥ 3.9 but may
+not work with non-standard clients such as netcat. Specify
+"smtpd_forbid_bare_newline = no" to disable (not recommended for
+an Internet-connected MTA). </p>
+
+<p> This feature is available in Postfix ≥ 3.9, 3.8.4, 3.7.9,
+3.6.13, and 3.5.23. </p>
+
%PARAM smtpd_forbid_unauth_pipelining Postfix ≥ 3.9: yes
<p> Disconnect remote SMTP clients that violate RFC 2920 (or 5321)
Amawalk
resychronization
ENVID
+netcat
client process name File proxymap proxymap c
available Files local command c local local c
ID if available File pipe pipe c
+ global smtp_stream h smtpd smtpd c
#define DEF_SMTPD_DNS_RE_FILTER ""
extern char *var_smtpd_dns_re_filter;
+ /*
+ * Backwards compatibility.
+ */
+#define VAR_SMTPD_FORBID_BARE_LF "smtpd_forbid_bare_newline"
+#define DEF_SMTPD_FORBID_BARE_LF 1
+
/*
* Share TLS sessions through tlsproxy(8).
*/
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20231213"
+#define MAIL_RELEASE_DATE "20231219"
#define MAIL_VERSION_NUMBER "3.9"
#ifdef SNAPSHOT
/* VSTREAM *stream;
/* char *format;
/* va_list ap;
+/*
+/* int smtp_forbid_bare_lf;
/* AUXILIARY API
/* int smtp_get_noexcept(vp, stream, maxlen, flags)
/* VSTRING *vp;
/* smtp_vprintf() is the machine underneath smtp_printf().
/*
/* smtp_get_noexcept() implements the subset of smtp_get()
-/* without timeouts and without making long jumps. Instead,
+/* without long jumps for timeout or EOF errors. Instead,
/* query the stream status with vstream_feof() etc.
+/* This function will make a VSTREAM long jump (error code
+/* SMTP_ERR_LF) when rejecting input with a bare newline byte.
/*
/* smtp_timeout_setup() is a backwards-compatibility interface
/* for programs that don't require deadline or data-rate support.
+/*
+/* smtp_forbid_bare_lf controls whether smtp_get_noexcept()
+/* will reject input with a bare newline byte.
/* DIAGNOSTICS
/* .fi
/* .ad
* the buffer. Such system calls would really hurt when receiving or sending
* body content one line at a time.
*/
+int smtp_forbid_bare_lf;
/* smtp_timeout_reset - reset per-stream error flags */
*/
case '\n':
vstring_truncate(vp, VSTRING_LEN(vp) - 1);
+ if (smtp_forbid_bare_lf
+ && (VSTRING_LEN(vp) == 0 || vstring_end(vp)[-1] != '\r'))
+ vstream_longjmp(stream, SMTP_ERR_LF);
while (VSTRING_LEN(vp) > 0 && vstring_end(vp)[-1] == '\r')
vstring_truncate(vp, VSTRING_LEN(vp) - 1);
VSTRING_TERMINATE(vp);
#define SMTP_ERR_QUIET 3 /* silent cleanup (application) */
#define SMTP_ERR_NONE 4 /* non-error case */
#define SMTP_ERR_DATA 5 /* application data error */
+#define SMTP_ERR_LF 6 /* bare <LF> protocol error */
extern void smtp_stream_setup(VSTREAM *, int, int, int);
extern void PRINTFLIKE(2, 3) smtp_printf(VSTREAM *, const char *,...);
extern void smtp_fwrite(const char *, ssize_t len, VSTREAM *);
extern void smtp_fread_buf(VSTRING *, ssize_t len, VSTREAM *);
extern void smtp_fputc(int, VSTREAM *);
+extern int smtp_forbid_bare_lf;
extern void smtp_vprintf(VSTREAM *, const char *, va_list);
/* .IP "\fBsmtpd_forbid_unauth_pipelining (Postfix >= 3.9: yes)\fR"
/* Disconnect remote SMTP clients that violate RFC 2920 (or 5321)
/* command pipelining constraints.
+/* .PP
+/* Available in Postfix 3.9, 3.8.3, 3.7.9, 3.6.13, 3.5.23 and later:
+/* .IP "\fBsmtpd_forbid_bare_newline (Postfix >= 3.9: yes)\fR"
+/* Reply with "Error: bare <LF> received" and disconnect
+/* when a remote SMTP client sends a line ending in <LF>, violating
+/* the RFC 5321 requirement that lines must end in <CR><LF>.
/* TARPIT CONTROLS
/* .ad
/* .fi
#define REASON_TIMEOUT "timeout"
#define REASON_LOST_CONNECTION "lost connection"
#define REASON_ERROR_LIMIT "too many errors"
+#define REASON_BARE_LF "bare <LF> received"
#ifdef USE_TLS
*/
done = 0;
do {
+ int payload_err;
/*
* Do not skip the smtp_fread_buf() call if read_len == 0. We still
smtp_fread_buf(state->buffer, read_len, state->client);
state->bdat_get_stream = vstream_memreopen(
state->bdat_get_stream, state->buffer, O_RDONLY);
+ vstream_control(state->bdat_get_stream, CA_VSTREAM_CTL_EXCEPT,
+ CA_VSTREAM_CTL_END);
+ if ((payload_err = vstream_setjmp(state->bdat_get_stream))
+ != SMTP_ERR_NONE)
+ vstream_longjmp(state->client, payload_err);
/*
* Read lines from the fragment. The last line may continue in the
var_myhostname);
break;
+ case SMTP_ERR_LF:
+ state->reason = REASON_BARE_LF;
+ if (vstream_setjmp(state->client) == 0)
+ smtpd_chat_reply(state, "521 5.5.2 %s Error: bare <LF> received",
+ var_myhostname);
+ break;
+
case 0:
/*
VAR_SMTPD_DELAY_OPEN, DEF_SMTPD_DELAY_OPEN, &var_smtpd_delay_open,
VAR_SMTPD_CLIENT_PORT_LOG, DEF_SMTPD_CLIENT_PORT_LOG, &var_smtpd_client_port_log,
VAR_SMTPD_FORBID_UNAUTH_PIPE, DEF_SMTPD_FORBID_UNAUTH_PIPE, &var_smtpd_forbid_unauth_pipe,
+ VAR_SMTPD_FORBID_BARE_LF, DEF_SMTPD_FORBID_BARE_LF, &smtp_forbid_bare_lf,
0,
};
static const CONFIG_NBOOL_TABLE nbool_table[] = {