connection to an MX host, before that connection is stored
under a nexthop- or host-based storage key. Files:
smtp/smtp_connect.c, smtp/smtp.h.
+
+20180620
+
+ TLS connection reuse: save and restore the TLS level for a
+ reused connection, so that the reused connection will be
+ saved under a key that matches the connection's original
+ TLS level. This was not a problem for destinations that
+ require certificate verification, because we currently reuse
+ connections that require certificate checks only if they
+ are looked up by their nexthop destination. File:
+ smtp/smtp_session.c.
+
+ TLS connection reuse: with TLS level > encrypt, prohibit
+ sharing of the same connection endpoint under different
+ nexthops, by making the nexthop part of the endpoint-based
+ connection cache lookup key. File: smtp/smtp.h.
+
Wish list:
- When a connection is looked up by nexthop, we get a connection
- that was stored under some MX destination address and TLS
- level, but we don't get to find out the TLS level that was
- in effect when the connection was stored. This means that
- when a reused connection is saved, it will be saved under
- a key for a TLS level that may not match the connection's
- initial TLS level. This is not a problem for destinations
- that require certificate verification, because we currently
- don't reuse connections that require certificate checks.
- But we should eventually store a reused connection under a
- key with the right level.
-
- Store the TLS level that is in effect with the connection
- that is stored under the destination address, so that it
- can later be saved under that level.
-
Add 'retire after max_use * max_idle' support to the
event-server, so that tlsproxy processes will terminate
even on a busy server. This can build on the retirement
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20180619"
+#define MAIL_RELEASE_DATE "20180620"
#define MAIL_VERSION_NUMBER "3.4"
#ifdef SNAPSHOT
#define COND_SASL_SMTP_KEY_FLAG_NEXTHOP \
(*var_smtp_sasl_passwd ? SMTP_KEY_FLAG_NEXTHOP : 0)
+#ifdef USE_TLS
+#define COND_TLS_SMTP_KEY_FLAG_NEXTHOP \
+ (state->tls->level > TLS_LEV_ENCRYPT ? SMTP_KEY_FLAG_NEXTHOP : 0)
+#else
+#define COND_TLS_SMTP_KEY_FLAG_NEXTHOP \
+ (0)
+#endif
+
#define COND_SASL_SMTP_KEY_FLAG_HOSTNAME \
(*var_smtp_sasl_passwd ? SMTP_KEY_FLAG_HOSTNAME : 0)
#define SMTP_KEY_MASK_SCACHE_ENDP_LABEL \
(SMTP_KEY_FLAG_SERVICE | COND_SASL_SMTP_KEY_FLAG_SENDER \
| COND_SASL_SMTP_KEY_FLAG_NEXTHOP | COND_SASL_SMTP_KEY_FLAG_HOSTNAME \
- | SMTP_KEY_FLAG_ADDR | SMTP_KEY_FLAG_PORT | SMTP_KEY_FLAG_TLS_LEVEL)
+ | COND_TLS_SMTP_KEY_FLAG_NEXTHOP | SMTP_KEY_FLAG_ADDR | \
+ SMTP_KEY_FLAG_PORT | SMTP_KEY_FLAG_TLS_LEVEL)
/*
* Silly little macros.
* serialize the properties with attr_print() instead of using ad-hoc,
* non-reusable, code and hard-coded format strings.
*
- * TODO(tlsproxy): save TLS_SESS_STATE information so that we can
- * restore TLS session properties.
+ * TODO(tlsproxy): save TLS_SESS_STATE information so that we can restore
+ * TLS session properties.
*
* TODO: save SASL username and password information so that we can
* correctly save a reused authenticated connection.
+ *
+ * Note: the TLS level field is always present.
*/
- vstring_sprintf(dest_prop, "%s\n%s\n%s\n%u",
+ vstring_sprintf(dest_prop, "%s\n%s\n%s\n%u\n%u",
STR(iter->dest), STR(iter->host), STR(iter->addr),
+#ifdef USE_TLS
+ iter->parent->tls->level,
+#else
+ 0,
+#endif
session->features & SMTP_FEATURE_DESTINATION_MASK);
/*
time_t expire_time; /* session re-use expiration time */
unsigned reuse_count; /* # times reused */
+#ifdef USE_TLS
+ SMTP_TLS_POLICY *tls = iter->parent->tls;
+
+#endif
+
/*
* XXX it would be nice to have a VSTRING to VSTREAM adapter so that we
* can de-serialize the properties with attr_scan(), instead of using
msg_warn("%s: missing cached session address property", myname);
return (0);
}
+ /* Note: the TLS level field is always present. */
+ if ((prop = mystrtok(&dest_props, "\n")) == 0 || !alldig(prop)) {
+ msg_warn("%s: bad cached destination TLS level property", myname);
+ return (0);
+ }
+#ifdef USE_TLS
+ tls->level = atoi(prop);
+ if (msg_verbose)
+ msg_info("%s: tls_level=%d", myname, tls->level);
+#endif
if ((prop = mystrtok(&dest_props, "\n")) == 0 || !alldig(prop)) {
msg_warn("%s: bad cached destination features property", myname);
return (0);