diff --git a/postfix/HISTORY b/postfix/HISTORY
index 21c269da6..14c278457 100644
--- a/postfix/HISTORY
+++ b/postfix/HISTORY
@@ -27393,3 +27393,32 @@ Apologies for any names omitted.
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.
diff --git a/postfix/html/postconf.5.html b/postfix/html/postconf.5.html
index fff711fd2..123d018fe 100644
--- a/postfix/html/postconf.5.html
+++ b/postfix/html/postconf.5.html
@@ -13770,11 +13770,13 @@ lookup key, and overrides the global smtp
and smtp_tls_enforce_peername settings.
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 NONE) 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".
+= yes".
MUST_NOPEERMATCH Require TLS encryption, but do not
require that the remote SMTP server hostname matches the information
@@ -14219,7 +14221,9 @@ destinations via smtp_tls_policy_
may
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)
diff --git a/postfix/html/smtp-source.1.html b/postfix/html/smtp-source.1.html
index db9a17bbb..2e4b71a0d 100644
--- a/postfix/html/smtp-source.1.html
+++ b/postfix/html/smtp-source.1.html
@@ -70,26 +70,37 @@ SMTP-SOURCE(1) SMTP-SOURCE(1)
in the default sender and recipient addresses, instead of the
machine hostname.
- -N 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.
+ -N Generate each recipient address by appending a number (a
+ per-process recipient counter) to the recipient address local-
+ part specified with the -t 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 "-t localpart+@domain" or "-t localpart+", where "+"
+ is the recipient address delimiter.
-o Old mode: don't send HELO, and don't send message headers.
-r recipient_count
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 -t 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 "-t localpart+@domain" or "-t localpart+", where "+"
+ is the recipient address delimiter.
-R interval
- 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 <= interval) between messages. Sus-
+ pending one thread does not affect other delivery threads.
-s session_count
- Run the specified number of SMTP sessions in parallel (default:
+ Run the specified number of SMTP sessions in parallel (default:
1).
-S subject
@@ -98,17 +109,17 @@ SMTP-SOURCE(1) SMTP-SOURCE(1)
-t to Use the specified recipient address (default: <foo@myhostname>).
-T windowsize
- 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.
-v Make the program more verbose, for debugging purposes.
-w interval
- 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.
[inet:]host[:port]
- Connect via TCP to host host, port port. The default port is
+ Connect via TCP to host host, port port. The default port is
smtp.
unix:pathname
diff --git a/postfix/man/man1/smtp-source.1 b/postfix/man/man1/smtp-source.1
index 014ee10a4..cd5bef089 100644
--- a/postfix/man/man1/smtp-source.1
+++ b/postfix/man/man1/smtp-source.1
@@ -65,19 +65,33 @@ Use the specified hostname or [address] in the HELO command
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).
diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5
index 6b31f52ba..496f2e3c0 100644
--- a/postfix/man/man5/postconf.5
+++ b/postfix/man/man5/postconf.5
@@ -9184,7 +9184,9 @@ and smtp_tls_enforce_peername settings.
.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
@@ -9613,7 +9615,9 @@ destinations via smtp_tls_policy_maps.
.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)
diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto
index b23c22dcb..6a0a52b93 100644
--- a/postfix/proto/postconf.proto
+++ b/postfix/proto/postconf.proto
@@ -10425,11 +10425,13 @@ lookup key, and overrides the global smtp_use_tls, smtp_enforce_tls,
and smtp_tls_enforce_peername settings.
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 NONE) 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".
+= yes".
MUST_NOPEERMATCH Require TLS encryption, but do not
require that the remote SMTP server hostname matches the information
@@ -11965,7 +11967,9 @@ destinations via smtp_tls_policy_maps.
may
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)
diff --git a/postfix/proto/stop.spell-history b/postfix/proto/stop.spell-history
index 32ba965cc..dcd003cfc 100644
--- a/postfix/proto/stop.spell-history
+++ b/postfix/proto/stop.spell-history
@@ -60,3 +60,5 @@ Fumiyasu
SATOH
INI
Serg
+Kinzler
+smtpstone
diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h
index 69605a600..49b73e3f2 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 "20230916"
+#define MAIL_RELEASE_DATE "20230923"
#define MAIL_VERSION_NUMBER "3.9"
#ifdef SNAPSHOT
diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c
index 3544e6a4e..8fb179053 100644
--- a/postfix/src/smtpd/smtpd.c
+++ b/postfix/src/smtpd/smtpd.c
@@ -5220,15 +5220,16 @@ static void smtpd_start_tls(SMTPD_STATE *state)
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" :
diff --git a/postfix/src/smtpstone/smtp-source.c b/postfix/src/smtpstone/smtp-source.c
index be388d614..ca8ec54ee 100644
--- a/postfix/src/smtpstone/smtp-source.c
+++ b/postfix/src/smtpstone/smtp-source.c
@@ -59,19 +59,33 @@
/* 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).
@@ -149,6 +163,7 @@
#include
#include
#include
+#include
/* Global library. */
@@ -201,8 +216,13 @@ static struct sockaddr_un sun;
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;
@@ -216,7 +236,8 @@ static int random_delay = 0;
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 *);
@@ -238,6 +259,20 @@ static void send_quit(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)
@@ -655,12 +690,15 @@ static void send_rcpt(int unused_event, void *context)
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++;
@@ -765,10 +803,19 @@ static void data_done(int unused, void *context)
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);
@@ -1021,15 +1068,22 @@ int main(int argc, char **argv)
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)
@@ -1045,7 +1099,7 @@ int main(int argc, char **argv)
subject = optarg;
break;
case 't':
- recipient = optarg;
+ recipient = make_recipient(optarg);
break;
case 'T':
if ((inet_windowsize = atoi(optarg)) <= 0)
@@ -1160,7 +1214,7 @@ int main(int argc, char **argv)
if (sender == 0)
sender = defaddr;
if (recipient == 0)
- recipient = defaddr;
+ recipient = make_recipient(defaddr);
}
/*