On Thu, Jun 19, 2025 at 09:53:38PM +1000, Viktor Dukhovni via Postfix-users
wrote:
> However, there's a problematic interaction with DANE TLSA records.
> Patch below.
I should not have trimmed the patch context so radically, better patch
below, in case your sources are slightly older or newer. The patch
merge base is 3.11-20250606.
--
Viktor.
--- a/src/smtp/smtp.h
+++ b/src/smtp/smtp.h
@@ -57,10 +57,11 @@ typedef struct SMTP_ITERATOR {
VSTRING *request_nexthop; /* delivery request nexhop or empty */
VSTRING *dest; /* current nexthop */
VSTRING *host; /* hostname or empty */
VSTRING *addr; /* printable address or empty */
unsigned port; /* network byte order or null */
+ int tlsreqno; /* "TLS-Required: no" */
struct DNS_RR *rr; /* DNS resource record or null */
struct DNS_RR *mx; /* DNS resource record or null */
/* Private members. */
VSTRING *saved_dest; /* saved current nexthop */
struct SMTP_STATE *parent; /* parent linkage */
@@ -69,10 +70,11 @@ typedef struct SMTP_ITERATOR {
#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); \
+ (iter)->tlsreqno = 0; \
(iter)->mx = (iter)->rr = 0; \
vstring_strcpy((iter)->saved_dest, ""); \
(iter)->parent = (state); \
} while (0)
--- a/src/smtp/smtp_connect.c
+++ b/src/smtp/smtp_connect.c
@@ -505,10 +505,23 @@ static void smtp_cache_policy(SMTP_STATE *state, const
char *dest)
static int smtp_get_effective_tls_level(DSN_BUF *why, SMTP_STATE *state)
{
SMTP_ITERATOR *iter = state->iterator;
SMTP_TLS_POLICY *tls = state->tls;
+ /*
+ * If the message contains a "TLS-Required: no" header, update the iterator
+ * to cap the policy at TLS_LEV_MAY.
+ *
+ * We must do this early to avoid possible failure if TLSA record lookups
+ * fail, of if TLSA records are found, but can't be activated because the
+ * security level has been reset to "may".
+ */
+ if (var_tls_required_enable
+ && (state->request->sendopts & SOPT_REQUIRETLS_HEADER)) {
+ iter->tlsreqno = 1;
+ }
+
/*
* Determine the TLS level for this destination.
*/
if (!smtp_tls_policy_cache_query(why, tls, iter)) {
return (0);
@@ -527,20 +540,10 @@ static int smtp_get_effective_tls_level(DSN_BUF *why,
SMTP_STATE *state)
return (0);
}
}
#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.
*/
return (1);
}
--- a/src/smtp/smtp_tls_policy.c
+++ b/src/smtp/smtp_tls_policy.c
@@ -649,11 +649,14 @@ static void *policy_create(const char *unused_key, void
*context)
* and next-hop policies.
*/
tls->level = global_tls_level();
site_level = TLS_LEV_NOTFOUND;
- if (tls_policy) {
+ if (iter->tlsreqno) {
+ 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");
if (site_level != TLS_LEV_INVALID
&& strcasecmp_utf8(dest, host) != 0)
_______________________________________________
Postfix-users mailing list -- [email protected]
To unsubscribe send an email to [email protected]