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); } /*