mantools/check-see-postconf-d-output, proto/postconf.proto,
global/maillog_client.c, master/master.c, smtp/smtp.c,
smtpd/smtpd.c.
+
+20230917
+
+ Documentation: added a note to smtp_tls_security_level and
+ smtp_tls_policy_maps, that the level "MAY" will fall back
+ to plaintext after TLS failure, when a message has spent
+ minimal_backoff_time in the mail queue. File: proto/postconf.proto.
+
+20230929
+
+ Bugfix (bug introduced Postfix 2.5, 20080104): the Postfix
+ SMTP server was waiting for a client command instead of
+ replying immediately, after a client certificate verification
+ error in TLS wrappermode. Reported by Andreas Kinzler. File:
+ smtpd/smtpd.c.
+
+20230923
+
+ This changes the smtp-source test program, to avoid the
+ need to configure a large number of "valid" recipient
+ addresses in Postfix, by using a recipient address extension
+ in the form of a sequence number. The change is to append
+ the optional recipient address sequence number to the
+ recipient address localpart, instead of prepending it. To
+ use that sequence number as a recipient address extension,
+ specify an explicit address delimiter in the address
+ localpart, as in "-t localpart+@domain" or "-t localpart+"
+ where "+" is the Postfix recipient address delimiter. File:
+ smtpstone/smtp-source.c.
and <a href="postconf.5.html#smtp_tls_enforce_peername">smtp_tls_enforce_peername</a> settings. </dd>
<dt> MAY </dt> <dd> Try to use TLS if the server announces support,
-otherwise use an unencrypted connection. This has less precedence
+otherwise use an unencrypted connection; after a failed TLS handshake
+or TLS session, fall back to plaintext if the message has spent
+<a href="postconf.5.html#minimal_backoff_time">minimal_backoff_time</a> in the mail queue. This level has less precedence
than a more specific result (including <b>NONE</b>) from the alternate
host or next-hop lookup key, and has less precedence than the more
specific global "<a href="postconf.5.html#smtp_enforce_tls">smtp_enforce_tls</a> = yes" or "<a href="postconf.5.html#smtp_tls_enforce_peername">smtp_tls_enforce_peername</a>
-= yes". </dd>
+= yes". </dd>
<dt> MUST_NOPEERMATCH </dt> <dd> Require TLS encryption, but do not
require that the remote SMTP server hostname matches the information
<dt><b><a href="TLS_README.html#client_tls_may">may</a></b></dt>
<dd> Opportunistic TLS. Use TLS if this is supported by the remote
-SMTP server, otherwise use plaintext. Since
+SMTP server, otherwise use plaintext; after a failed TLS handshake
+or TLS session, fall back to plaintext if the message has spent
+<a href="postconf.5.html#minimal_backoff_time">minimal_backoff_time</a> in the mail queue. Since
sending in the clear is acceptable, demanding stronger than default TLS
security merely reduces interoperability.
The "<a href="postconf.5.html#smtp_tls_ciphers">smtp_tls_ciphers</a>" and "<a href="postconf.5.html#smtp_tls_protocols">smtp_tls_protocols</a>" (Postfix ≥ 2.6)
in the default sender and recipient addresses, instead of the
machine hostname.
- <b>-N</b> Prepend a non-repeating sequence number to each recipient
- address. This avoids the artificial 100% hit rate in the resolve
- and rewrite client caches and exercises the trivial-rewrite dae-
- mon, better approximating Postfix performance under real-life
- work-loads.
+ <b>-N</b> Generate each recipient address by appending a number (a
+ per-process recipient counter) to the recipient address local-
+ part specified with the <b>-t</b> option. This avoids an artificial
+ 100% hit rate in the trivial-rewrite daemon's resolve and re-
+ write client caches, better approximating Postfix performance
+ under real-life work-loads.
+
+ Note: to use the number as an address extension, specify an
+ explicit address delimiter at the end of the recipient local-
+ part, as in "<b>-t localpart+@domain</b>" or "<b>-t localpart+</b>", where "<b>+</b>"
+ is the recipient address delimiter.
<b>-o</b> Old mode: don't send HELO, and don't send message headers.
<b>-r</b> <i>recipient</i><b>_</b><i>count</i>
Send the specified number of recipients per transaction
- (default: 1). Recipient names are generated by prepending a
- number to the recipient address.
+ (default: 1). Generate each recipient address by appending a
+ number (a per-connection recipient counter) to the recipient
+ address localpart specified with the <b>-t</b> option.
+
+ Note: to use the number as an address extension, specify an
+ explicit address delimiter at the end of the recipient local-
+ part, as in "<b>-t localpart+@domain</b>" or "<b>-t localpart+</b>", where "<b>+</b>"
+ is the recipient address delimiter.
<b>-R</b> <i>interval</i>
- Wait for a random period of time 0 <= n <= interval between mes-
- sages. Suspending one thread does not affect other delivery
- threads.
+ Wait a random time (0 <= n <= <i>interval</i>) between messages. Sus-
+ pending one thread does not affect other delivery threads.
<b>-s</b> <i>session</i><b>_</b><i>count</i>
- Run the specified number of SMTP sessions in parallel (default:
+ Run the specified number of SMTP sessions in parallel (default:
1).
<b>-S</b> <i>subject</i>
<b>-t</b> <i>to</i> Use the specified recipient address (default: <foo@<a href="postconf.5.html#myhostname">myhostname</a>>).
<b>-T</b> <i>windowsize</i>
- Override the default TCP window size. To work around broken TCP
+ Override the default TCP window size. To work around broken TCP
window scaling implementations, specify a value > 0 and < 65536.
<b>-v</b> Make the program more verbose, for debugging purposes.
<b>-w</b> <i>interval</i>
- Wait a fixed time between messages. Suspending one thread does
+ Wait a fixed time between messages. Suspending one thread does
not affect other delivery threads.
[<b>inet:</b>]<i>host</i>[:<i>port</i>]
- Connect via TCP to host <i>host</i>, port <i>port</i>. The default port is
+ Connect via TCP to host <i>host</i>, port <i>port</i>. The default port is
<b>smtp</b>.
<b>unix:</b><i>pathname</i>
and in the default sender and recipient addresses, instead
of the machine hostname.
.IP "\fB\-N\fR"
-Prepend a non\-repeating sequence number to each recipient
-address. This avoids the artificial 100% hit rate in the
-resolve and rewrite client caches and exercises the
-trivial\-rewrite daemon, better approximating Postfix
-performance under real\-life work\-loads.
+Generate each recipient address by appending a number (a
+per\-process recipient counter) to the recipient address
+localpart specified with the \fB\-t\fR option. This avoids
+an artificial 100% hit rate in the trivial\-rewrite daemon's
+resolve and rewrite client caches, better approximating
+Postfix performance under real\-life work\-loads.
+
+Note: to use the number as an address extension, specify
+an explicit address delimiter at the end of the recipient
+localpart, as in "\fB\-t localpart+@domain\fR" or "\fB\-t
+localpart+\fR", where "\fB+\fR" is the recipient address
+delimiter.
.IP \fB\-o\fR
Old mode: don't send HELO, and don't send message headers.
.IP "\fB\-r \fIrecipient_count\fR"
Send the specified number of recipients per transaction (default: 1).
-Recipient names are generated by prepending a number to the
-recipient address.
+Generate each recipient address by appending a number (a
+per\-connection recipient counter) to the recipient address
+localpart specified with the \fB\-t\fR option.
+
+Note: to use the number as an address extension, specify
+an explicit address delimiter at the end of the recipient
+localpart, as in "\fB\-t localpart+@domain\fR" or "\fB\-t
+localpart+\fR", where "\fB+\fR" is the recipient address
+delimiter.
.IP "\fB\-R \fIinterval\fR"
-Wait for a random period of time 0 <= n <= interval between messages.
+Wait a random time (0 <= n <= \fIinterval\fR) between messages.
Suspending one thread does not affect other delivery threads.
.IP "\fB\-s \fIsession_count\fR"
Run the specified number of SMTP sessions in parallel (default: 1).
.br
.IP "MAY"
Try to use TLS if the server announces support,
-otherwise use an unencrypted connection. This has less precedence
+otherwise use an unencrypted connection; after a failed TLS handshake
+or TLS session, fall back to plaintext if the message has spent
+minimal_backoff_time in the mail queue. This level has less precedence
than a more specific result (including \fBNONE\fR) from the alternate
host or next\-hop lookup key, and has less precedence than the more
specific global "smtp_enforce_tls = yes" or "smtp_tls_enforce_peername
.br
.IP "\fBmay\fR"
Opportunistic TLS. Use TLS if this is supported by the remote
-SMTP server, otherwise use plaintext. Since
+SMTP server, otherwise use plaintext; after a failed TLS handshake
+or TLS session, fall back to plaintext if the message has spent
+minimal_backoff_time in the mail queue. Since
sending in the clear is acceptable, demanding stronger than default TLS
security merely reduces interoperability.
The "smtp_tls_ciphers" and "smtp_tls_protocols" (Postfix >= 2.6)
and smtp_tls_enforce_peername settings. </dd>
<dt> MAY </dt> <dd> Try to use TLS if the server announces support,
-otherwise use an unencrypted connection. This has less precedence
+otherwise use an unencrypted connection; after a failed TLS handshake
+or TLS session, fall back to plaintext if the message has spent
+minimal_backoff_time in the mail queue. This level has less precedence
than a more specific result (including <b>NONE</b>) from the alternate
host or next-hop lookup key, and has less precedence than the more
specific global "smtp_enforce_tls = yes" or "smtp_tls_enforce_peername
-= yes". </dd>
+= yes". </dd>
<dt> MUST_NOPEERMATCH </dt> <dd> Require TLS encryption, but do not
require that the remote SMTP server hostname matches the information
<dt><b><a href="TLS_README.html#client_tls_may">may</a></b></dt>
<dd> Opportunistic TLS. Use TLS if this is supported by the remote
-SMTP server, otherwise use plaintext. Since
+SMTP server, otherwise use plaintext; after a failed TLS handshake
+or TLS session, fall back to plaintext if the message has spent
+minimal_backoff_time in the mail queue. Since
sending in the clear is acceptable, demanding stronger than default TLS
security merely reduces interoperability.
The "smtp_tls_ciphers" and "smtp_tls_protocols" (Postfix ≥ 2.6)
SATOH
INI
Serg
+Kinzler
+smtpstone
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20230916"
+#define MAIL_RELEASE_DATE "20230923"
#define MAIL_VERSION_NUMBER "3.9"
#ifdef SNAPSHOT
if (requirecert && TLS_CERT_IS_TRUSTED(state->tls_context) == 0) {
/*
- * Fetch and reject the next command (should be EHLO), then
- * disconnect (side-effect of returning "421 ...".
+ * In non-wrappermode, fetch the next command (should be EHLO). Reply
+ * with 421, then disconnect (as a side-effect of replying with 421).
*/
cert_present = TLS_CERT_IS_PRESENT(state->tls_context);
msg_info("NOQUEUE: abort: TLS from %s: %s",
state->namaddr, cert_present ?
"Client certificate not trusted" :
"No client certificate presented");
- smtpd_chat_query(state);
+ if (var_smtpd_tls_wrappermode == 0)
+ smtpd_chat_query(state);
smtpd_chat_reply(state, "421 4.7.1 %s Error: %s",
var_myhostname, cert_present ?
"Client certificate not trusted" :
/* and in the default sender and recipient addresses, instead
/* of the machine hostname.
/* .IP "\fB-N\fR"
-/* Prepend a non-repeating sequence number to each recipient
-/* address. This avoids the artificial 100% hit rate in the
-/* resolve and rewrite client caches and exercises the
-/* trivial-rewrite daemon, better approximating Postfix
-/* performance under real-life work-loads.
+/* Generate each recipient address by appending a number (a
+/* per-process recipient counter) to the recipient address
+/* localpart specified with the \fB-t\fR option. This avoids
+/* an artificial 100% hit rate in the trivial-rewrite daemon's
+/* resolve and rewrite client caches, better approximating
+/* Postfix performance under real-life work-loads.
+/*
+/* Note: to use the number as an address extension, specify
+/* an explicit address delimiter at the end of the recipient
+/* localpart, as in "\fB-t localpart+@domain\fR" or "\fB-t
+/* localpart+\fR", where "\fB+\fR" is the recipient address
+/* delimiter.
/* .IP \fB-o\fR
/* Old mode: don't send HELO, and don't send message headers.
/* .IP "\fB-r \fIrecipient_count\fR"
/* Send the specified number of recipients per transaction (default: 1).
-/* Recipient names are generated by prepending a number to the
-/* recipient address.
+/* Generate each recipient address by appending a number (a
+/* per-connection recipient counter) to the recipient address
+/* localpart specified with the \fB-t\fR option.
+/*
+/* Note: to use the number as an address extension, specify
+/* an explicit address delimiter at the end of the recipient
+/* localpart, as in "\fB-t localpart+@domain\fR" or "\fB-t
+/* localpart+\fR", where "\fB+\fR" is the recipient address
+/* delimiter.
/* .IP "\fB-R \fIinterval\fR"
-/* Wait for a random period of time 0 <= n <= interval between messages.
+/* Wait a random time (0 <= n <= \fIinterval\fR) between messages.
/* Suspending one thread does not affect other delivery threads.
/* .IP "\fB-s \fIsession_count\fR"
/* Run the specified number of SMTP sessions in parallel (default: 1).
#include <valid_hostname.h>
#include <valid_mailhost_addr.h>
#include <compat_va_copy.h>
+#include <mymalloc.h>
/* Global library. */
static struct sockaddr *sa;
static int sa_length;
static int recipients = 1;
+static int session_rcpt_suffix = 0;
static char *defaddr;
-static char *recipient;
+typedef struct {
+ char *local;
+ char *at_domain;
+} RECIPIENT;
+static RECIPIENT *recipient;
static char *sender;
static char *message_data;
static int message_length;
static int fixed_delay = 0;
static int talk_lmtp = 0;
static char *subject = 0;
-static int number_rcpts = 0;
+static int global_rcpt_suffix = 0;
+static int global_rcpt_done = 0;
static int allow_reject = 0;
static void enqueue_connect(SESSION *);
static void quit_done(int, void *);
static void close_session(SESSION *);
+/* make_recipient - parse recipient into localpart and at_domain */
+
+static RECIPIENT *make_recipient(const char *address)
+{
+ RECIPIENT *rp = (RECIPIENT *) mymalloc(sizeof(*rp));
+ const char *at;
+
+ if ((at = strrchr(address, '@')) == 0)
+ at = address + strlen(address);
+ rp->local = mystrndup(address, at - address);
+ rp->at_domain = mystrdup(at);
+ return (rp);
+}
+
/* random_interval - generate a random value in 0 .. (small) interval */
static int random_interval(int interval)
if ((except = vstream_setjmp(session->stream)) != 0)
msg_fatal("%s while sending recipient", exception_text(except));
- if (session->rcpt_count > 1 || number_rcpts > 0)
- command(session->stream, "RCPT TO:<%d%s>",
- number_rcpts ? number_rcpts++ : session->rcpt_count,
- recipient);
+ if (session_rcpt_suffix)
+ command(session->stream, "RCPT TO:<%s%d%s>",
+ recipient->local, session->rcpt_done, recipient->at_domain);
+ else if (global_rcpt_suffix)
+ command(session->stream, "RCPT TO:<%s%d%s>",
+ recipient->local, global_rcpt_done++, recipient->at_domain);
else
- command(session->stream, "RCPT TO:<%s>", recipient);
+ command(session->stream, "RCPT TO:<%s%s>",
+ recipient->local, recipient->at_domain);
session->rcpt_count--;
session->rcpt_done++;
mypid = getpid();
}
smtp_printf(session->stream, "From: <%s>", sender);
- smtp_printf(session->stream, "To: <%s>", recipient);
+ if (global_rcpt_suffix)
+ smtp_printf(session->stream, "To: <%s%d%s>", recipient->local,
+ global_rcpt_done - 1, recipient->at_domain);
+ else if (session_rcpt_suffix)
+ smtp_printf(session->stream, "To: <%s%d%s>", recipient->local,
+ session->rcpt_done - 1, recipient->at_domain);
+ else
+ smtp_printf(session->stream, "To: <%s%s>",
+ recipient->local, recipient->at_domain);
smtp_printf(session->stream, "Date: %s", mydate);
smtp_printf(session->stream, "Message-Id: <%04x.%04x.%04x@%s>",
- mypid, vstream_fileno(session->stream), message_count, var_myhostname);
+ mypid, vstream_fileno(session->stream), message_count,
+ var_myhostname);
if (subject)
smtp_printf(session->stream, "Subject: %s", subject);
smtp_fputs("", 0, session->stream);
var_myhostname = optarg;
break;
case 'N':
- number_rcpts = 1;
+ if (session_rcpt_suffix)
+ msg_fatal("do not use -N and -r options at the same time");
+ global_rcpt_suffix = 1;
break;
case 'o':
send_helo_first = 0;
send_headers = 0;
break;
case 'r':
+ if (global_rcpt_suffix)
+ msg_fatal("do not use -N and -r options at the same time");
+ if (session_rcpt_suffix)
+ msg_fatal("do not use -r option multiple times");
if ((recipients = atoi(optarg)) <= 0)
msg_fatal("bad recipient count: %s", optarg);
+ session_rcpt_suffix = 1;
break;
case 'R':
if (fixed_delay > 0)
subject = optarg;
break;
case 't':
- recipient = optarg;
+ recipient = make_recipient(optarg);
break;
case 'T':
if ((inet_windowsize = atoi(optarg)) <= 0)
if (sender == 0)
sender = defaddr;
if (recipient == 0)
- recipient = defaddr;
+ recipient = make_recipient(defaddr);
}
/*