add an extra newline character before appending the new
setting, causing information to become garbled. Fix by
Michael Tokarev. File: postconf/postconf_edit.c.
+
+20250619
+
+ Bugfix (defect introduced: Postfix-3.10, date 20250117):
+ include the current TLS security level in the SMTP connection
+ cache lookup key for lookups by next-hop destination. The
+ idea is that to deliver a message without "TLS-Required:
+ no" header, the Postfix SMTP client must not reuse a
+ connection that was created during a burst of deliveries
+ of messages with "TLS-Required: no" to the same destination.
+
+ Including the TLS security level in the SMTP connection
+ cache lookup key will also prevent false connection reuse
+ when any future feature is added that overrides the TLS
+ security level based on message content or envelope metadata.
+ Files: smtp/smtp.h.
+
+ Likewise, include the current TLS security level in the TLS
+ client serverid field. File: smtp/smtp_proto.c.
+
+ Bugfix (defect introduced: Postfix-3.10, date 20250117): the
+ Postfix SMTP client attempted to look up TLSA records even
+ with "TLS-Required: no". This could result in unnecessary
+ failures. Fix by Viktor Dukhovni & Wietse. Files: smtp/smtp.h,
+ smtp/smtp_policy.c, smtp/smtp_connect.c.
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20250422"
-#define MAIL_VERSION_NUMBER "3.10.2"
+#define MAIL_RELEASE_DATE "20250710"
+#define MAIL_VERSION_NUMBER "3.10.3"
#ifdef SNAPSHOT
#define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE
VSTRING *host; /* hostname or empty */
VSTRING *addr; /* printable address or empty */
unsigned port; /* network byte order or null */
+#ifdef USE_TLS
+ int tlsreqno; /* "TLS-Required: no" */
+#endif
struct DNS_RR *rr; /* DNS resource record or null */
struct DNS_RR *mx; /* DNS resource record or null */
/* Private members. */
struct SMTP_STATE *parent; /* parent linkage */
} SMTP_ITERATOR;
+#ifdef USE_TLS
+#define IF_USE_TLS(...) (__VA_ARGS__)
+#else
+#define IF_USE_TLS(...)
+#endif
+
#define SMTP_ITER_INIT(iter, _dest, _host, _addr, _port, state) do { \
vstring_strcpy((iter)->dest, (_dest)); \
vstring_strcpy((iter)->host, (_host)); \
vstring_strcpy((iter)->addr, (_addr)); \
(iter)->port = (_port); \
+ IF_USE_TLS((iter)->tlsreqno = 0); \
(iter)->mx = (iter)->rr = 0; \
vstring_strcpy((iter)->saved_dest, ""); \
(iter)->parent = (state); \
*/
#define SMTP_KEY_MASK_SCACHE_DEST_LABEL \
(SMTP_KEY_FLAG_SERVICE | COND_SASL_SMTP_KEY_FLAG_SENDER \
- | SMTP_KEY_FLAG_REQ_NEXTHOP)
+ | SMTP_KEY_FLAG_REQ_NEXTHOP | SMTP_KEY_FLAG_TLS_LEVEL)
/*
* Connection-cache endpoint lookup key. The SENDER, CUR_NEXTHOP, HOSTNAME,
SMTP_ITERATOR *iter = state->iterator;
SMTP_TLS_POLICY *tls = state->tls;
+ /*
+ * If the message contains a "TLS-Required: no" header, update the
+ * iterator to limit the policy at TLS_LEV_MAY.
+ *
+ * We must do this early to avoid possible failure if TLSA record lookups
+ * fail, or if TLSA records are found, but can't be activated because the
+ * security level has been reset to "may".
+ *
+ * Note that the REQUIRETLS verb in ESMTP overrides the "TLS-Required: no"
+ * header.
+ */
+#ifdef USE_TLS
+ if (var_tls_required_enable
+ && (state->request->sendopts & SOPT_REQUIRETLS_HEADER)) {
+ iter->tlsreqno = 1;
+ }
+#endif
+
/*
* Determine the TLS level for this destination.
*/
}
#endif
- /*
- * Otherwise, if the TLS level is not TLS_LEV_NONE or some non-level, and
- * the message contains a "TLS-Required: no" header, limit the level to
- * TLS_LEV_MAY.
- */
- else if (var_tls_required_enable && tls->level > TLS_LEV_NONE
- && (state->request->sendopts & SOPT_REQUIRETLS_HEADER)) {
- tls->level = TLS_LEV_MAY;
- }
-
/*
* Success.
*/
* XXX: The TLS library will salt the serverid with further details of the
* protocol and cipher requirements including the server ehlo response.
* Deferring the helo to the digested suffix results in more predictable
- * SSL session lookup key lengths.
+ * SSL session lookup key lengths. Add the current TLS security level to
+ * account for TLS level overrides based on message content or envelope
+ * metadata.
*/
serverid = vstring_alloc(10);
smtp_key_prefix(serverid, "&", state->iterator, SMTP_KEY_FLAG_SERVICE
| SMTP_KEY_FLAG_CUR_NEXTHOP /* With port */
| SMTP_KEY_FLAG_HOSTNAME
- | SMTP_KEY_FLAG_ADDR);
+ | SMTP_KEY_FLAG_ADDR
+ | SMTP_KEY_FLAG_TLS_LEVEL);
if (state->tls->conn_reuse) {
TLS_CLIENT_PARAMS tls_params;
tls->level = global_tls_level();
site_level = TLS_LEV_NOTFOUND;
- if (tls_policy) {
+ if (iter->tlsreqno) {
+ if (msg_verbose)
+ msg_info("%s: no tls policy lookup", __func__);
+ if (tls->level > TLS_LEV_MAY)
+ tls->level = TLS_LEV_MAY;
+ } else if (tls_policy) {
tls_policy_lookup(tls, &site_level, dest, "next-hop destination");
} else if (tls_per_site) {
tls_site_lookup(tls, &site_level, dest, "next-hop destination");