2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-30 21:55:20 +00:00

postfix-3.4-20181118

This commit is contained in:
Wietse Venema
2018-11-18 00:00:00 -05:00
committed by Viktor Dukhovni
parent 5690047582
commit 2cda534f4b
19 changed files with 271 additions and 234 deletions

2
postfix/.indent.pro vendored
View File

@@ -336,7 +336,6 @@
-TSTATE
-TSTRING_LIST
-TSTRING_TABLE
-TSUMMARY_CLASS
-TSYS_EXITS_DETAIL
-TTLSMGR_SCACHE
-TTLSP_STATE
@@ -356,6 +355,7 @@
-TTLS_SESS_STATE
-TTLS_TICKET_KEY
-TTLS_TLSA
-TTLS_USAGE
-TTLS_VINFO
-TTLScontext_t
-TTOK822

View File

@@ -23770,9 +23770,7 @@ Apologies for any names omitted.
postmap/postmap.c.
Cleanup: don't use ssize_t for boolean result. File:
global/smtp_stream.c. Memory leak: the Berkeley DB client
leaked a small amount of memory asfter failing to open a
table. File: util/dict_db.c.
global/smtp_stream.c.
Cleanup: memory leak caused by missing dbenv->close() call
after failing to open a Berkeley DB table. File: util/dict_db.c.
@@ -23794,3 +23792,26 @@ Apologies for any names omitted.
tls/tls_proxy_context_print.c, tls/tls_proxy_context_scan.c,
tls/tls_client.c, tls/tls_server.c, smtpd/smtpd.c,
posttls-finger/posttls-finger.c.
Cleanup: vstream_memopen() flags handling. File:
util/vstream.c.
Cleanup: the SMTP client now uses 'attr_print_plain'
serialization and 'attr_scan_plain' deserialization for
connection cache lookup keys, which now contain a serialized
version of the TLS context. File: smtp/smtp_session.c.
20181117
The Postfix SMTP client now logs whether an SMTP-over-TLS
connection is newly established ("TLS connection established")
or whether the connection is reused ("TLS connection reused").
Files: smtp/smtp.h, smtp/smtp_proto.c, smtp/smtp_session.c.
20181118
Cleanup, no behavior change: updated comments concerning
connection reuse, and updated some identifiers to reflect
current reality. Files: smtp_reuse.c, smtp_key.c, smtp_proto.c,
smtp_tls_policy.c, smtp.h, smtp_connect.c.

View File

@@ -12,7 +12,6 @@ GGeenneerraall ccoonnffiigguurraattiioonn
* TLS_README: TLS Encryption and authentication
* FORWARD_SECRECY_README: TLS Forward Secrecy
* IPV6_README: IP Version 6 Support
* IPV6_README: IP Version 6 Support
* SMTPUTF8_README: SMTPUTF8 Support
* COMPATIBILITY_README: Backwards-Compatibility Safety Net
* INSTALL: Installation from source code

View File

@@ -323,7 +323,7 @@ verification status.
(No client certificate requested)
TLS 1.3 examples. Some of the new attributes may not appear when not
applicable or not available in an older versions of the OpenSSL library.
applicable or not available in older versions of the OpenSSL library.
Received: from localhost (localhost [127.0.0.1])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256

View File

@@ -434,7 +434,7 @@ Received: from host.example.com (host.example.com [192.168.0.2])
</blockquote>
<p> TLS 1.3 examples. Some of the new attributes may not appear when not
applicable or not available in an older versions of the OpenSSL library. </p>
applicable or not available in older versions of the OpenSSL library. </p>
<blockquote>
<pre>

View File

@@ -46,8 +46,6 @@ configuration examples </a>
<li> <a href="IPV6_README.html"> IP Version 6 Support </a>
<li> <a href="IPV6_README.html"> IP Version 6 Support </a>
<li> <a href="SMTPUTF8_README.html"> SMTPUTF8 Support </a>
<li> <a href="COMPATIBILITY_README.html"> Backwards-Compatibility Safety Net</a>

View File

@@ -434,7 +434,7 @@ Received: from host.example.com (host.example.com [192.168.0.2])
</blockquote>
<p> TLS 1.3 examples. Some of the new attributes may not appear when not
applicable or not available in an older versions of the OpenSSL library. </p>
applicable or not available in older versions of the OpenSSL library. </p>
<blockquote>
<pre>

View File

@@ -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 "20181117"
#define MAIL_RELEASE_DATE "20181118"
#define MAIL_VERSION_NUMBER "3.4"
#ifdef SNAPSHOT

View File

@@ -192,17 +192,25 @@ typedef struct SMTP_STATE {
} SMTP_STATE;
/*
* TODO: use the new SMTP_ITER name space.
* Primitives to enable/disable/test connection caching and reuse based on
* the delivery request next-hop destination (i.e. not smtp_fallback_relay).
*
* Connection cache lookup by the request next-hop destination allows a reuse
* request to skip over bad hosts, and may result in a connection to a
* fall-back relay. Once we have found a 'good' host for a request next-hop,
* clear the request next-hop destination, to avoid caching less-preferred
* connections under that same request next-hop.
*/
#define SET_NEXTHOP_STATE(state, nexthop) { \
#define SET_SCACHE_REQUEST_NEXTHOP(state, nexthop) do { \
vstring_strcpy((state)->iterator->request_nexthop, nexthop); \
}
} while (0)
#define FREE_NEXTHOP_STATE(state) { \
#define CLEAR_SCACHE_REQUEST_NEXTHOP(state) do { \
STR((state)->iterator->request_nexthop)[0] = 0; \
}
} while (0)
#define HAVE_NEXTHOP_STATE(state) (STR((state)->iterator->request_nexthop)[0] != 0)
#define HAVE_SCACHE_REQUEST_NEXTHOP(state) \
(STR((state)->iterator->request_nexthop)[0] != 0)
/*
@@ -229,6 +237,7 @@ typedef struct SMTP_STATE {
#define SMTP_FEATURE_EARLY_TLS_MAIL_REPLY (1<<19) /* CVE-2009-3555 */
#define SMTP_FEATURE_XFORWARD_IDENT (1<<20)
#define SMTP_FEATURE_SMTPUTF8 (1<<21) /* RFC 6531 */
#define SMTP_FEATURE_FROM_PROXY (1<<22) /* proxied connection */
/*
* Features that passivate under the endpoint.
@@ -617,7 +626,7 @@ char *smtp_key_prefix(VSTRING *, const char *, SMTP_ITERATOR *, int);
#define SMTP_KEY_FLAG_SERVICE (1<<0) /* service name */
#define SMTP_KEY_FLAG_SENDER (1<<1) /* sender address */
#define SMTP_KEY_FLAG_REQ_NEXTHOP (1<<2) /* request nexthop */
#define SMTP_KEY_FLAG_NEXTHOP (1<<3) /* current nexthop */
#define SMTP_KEY_FLAG_CUR_NEXTHOP (1<<3) /* current nexthop */
#define SMTP_KEY_FLAG_HOSTNAME (1<<4) /* remote host name */
#define SMTP_KEY_FLAG_ADDR (1<<5) /* remote address */
#define SMTP_KEY_FLAG_PORT (1<<6) /* remote port */
@@ -626,7 +635,7 @@ char *smtp_key_prefix(VSTRING *, const char *, SMTP_ITERATOR *, int);
#define SMTP_KEY_MASK_ALL \
(SMTP_KEY_FLAG_SERVICE | SMTP_KEY_FLAG_SENDER | \
SMTP_KEY_FLAG_REQ_NEXTHOP | \
SMTP_KEY_FLAG_NEXTHOP | SMTP_KEY_FLAG_HOSTNAME | \
SMTP_KEY_FLAG_CUR_NEXTHOP | SMTP_KEY_FLAG_HOSTNAME | \
SMTP_KEY_FLAG_ADDR | SMTP_KEY_FLAG_PORT | SMTP_KEY_FLAG_TLS_LEVEL)
/*
@@ -640,14 +649,14 @@ char *smtp_key_prefix(VSTRING *, const char *, SMTP_ITERATOR *, int);
((var_smtp_sender_auth && *var_smtp_sasl_passwd) ? \
SMTP_KEY_FLAG_SENDER : 0)
#define COND_SASL_SMTP_KEY_FLAG_NEXTHOP \
(*var_smtp_sasl_passwd ? SMTP_KEY_FLAG_NEXTHOP : 0)
#define COND_SASL_SMTP_KEY_FLAG_CUR_NEXTHOP \
(*var_smtp_sasl_passwd ? SMTP_KEY_FLAG_CUR_NEXTHOP : 0)
#ifdef USE_TLS
#define COND_TLS_SMTP_KEY_FLAG_NEXTHOP \
(TLS_MUST_MATCH(state->tls->level) ? SMTP_KEY_FLAG_NEXTHOP : 0)
#define COND_TLS_SMTP_KEY_FLAG_CUR_NEXTHOP \
(TLS_MUST_MATCH(state->tls->level) ? SMTP_KEY_FLAG_CUR_NEXTHOP : 0)
#else
#define COND_TLS_SMTP_KEY_FLAG_NEXTHOP \
#define COND_TLS_SMTP_KEY_FLAG_CUR_NEXTHOP \
(0)
#endif
@@ -655,10 +664,13 @@ char *smtp_key_prefix(VSTRING *, const char *, SMTP_ITERATOR *, int);
(*var_smtp_sasl_passwd ? SMTP_KEY_FLAG_HOSTNAME : 0)
/*
* Connection-cache destination lookup key. The SENDER attribute is a proxy
* for sender-dependent SASL credentials (or absence thereof), and prevents
* false connection sharing when different SASL credentials may be required
* for different deliveries to the same domain and port. The SERVICE
* Connection-cache destination lookup key, based on the delivery request
* nexthop. The SENDER attribute is a proxy for sender-dependent SASL
* credentials (or absence thereof), and prevents false connection sharing
* when different SASL credentials may be required for different deliveries
* to the same domain and port. Likewise, the delivery request nexthop
* (REQ_NEXTHOP) prevents false sharing of TLS identities (the destination
* key links only to appropriate endpoint lookup keys). The SERVICE
* attribute is a proxy for all request-independent configuration details.
*/
#define SMTP_KEY_MASK_SCACHE_DEST_LABEL \
@@ -666,15 +678,18 @@ char *smtp_key_prefix(VSTRING *, const char *, SMTP_ITERATOR *, int);
| SMTP_KEY_FLAG_REQ_NEXTHOP)
/*
* Connection-cache endpoint lookup key. The SENDER, NEXTHOP, and HOSTNAME
* attributes are proxies for SASL credentials (or absence thereof), and
* prevent false connection sharing when different SASL credentials may be
* required for different deliveries to the same IP address and port.
* Connection-cache endpoint lookup key. The SENDER, CUR_NEXTHOP, HOSTNAME,
* PORT and TLS_LEVEL attributes are proxies for SASL credentials and TLS
* authentication (or absence thereof), and prevent false connection sharing
* when different SASL credentials or TLS identities may be required for
* different deliveries to the same IP address and port. The SERVICE
* attribute is a proxy for all request-independent configuration details.
*/
#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 \
| COND_TLS_SMTP_KEY_FLAG_NEXTHOP | SMTP_KEY_FLAG_ADDR | \
| COND_SASL_SMTP_KEY_FLAG_CUR_NEXTHOP \
| COND_SASL_SMTP_KEY_FLAG_HOSTNAME \
| COND_TLS_SMTP_KEY_FLAG_CUR_NEXTHOP | SMTP_KEY_FLAG_ADDR | \
SMTP_KEY_FLAG_PORT | SMTP_KEY_FLAG_TLS_LEVEL)
/*
@@ -703,11 +718,6 @@ extern int smtp_mode;
/* 111 8th Avenue
/* New York, NY 10011, USA
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*
/* TLS support originally by:
/* Lutz Jaenicke
/* BTU Cottbus

View File

@@ -417,13 +417,13 @@ static void smtp_cleanup_session(SMTP_STATE *state)
state->session = 0;
/*
* If this session was good, reset the logical next-hop state, so that we
* won't cache connections to alternate servers under the logical
* next-hop destination. Otherwise we could end up skipping over the
* available and more preferred servers.
* If this session was good, reset the logical next-hop destination, so
* that we won't cache connections to less-preferred servers under the
* logical next-hop destination. Otherwise we could end up skipping over
* the available and more-preferred servers.
*/
if (HAVE_NEXTHOP_STATE(state) && !throttled)
FREE_NEXTHOP_STATE(state);
if (HAVE_SCACHE_REQUEST_NEXTHOP(state) && !throttled)
CLEAR_SCACHE_REQUEST_NEXTHOP(state);
/*
* Clean up the lists with todo and dropped recipients.
@@ -678,7 +678,7 @@ static int smtp_reuse_session(SMTP_STATE *state, DNS_RR **addr_list,
#endif
SMTP_ITER_SAVE_DEST(state->iterator);
if (*addr_list && SMTP_RCPT_LEFT(state) > 0
&& HAVE_NEXTHOP_STATE(state)
&& HAVE_SCACHE_REQUEST_NEXTHOP(state)
&& (session = smtp_reuse_nexthop(state, SMTP_KEY_MASK_SCACHE_DEST_LABEL)) != 0) {
session_count = 1;
smtp_update_addr_list(addr_list, STR(iter->addr), session_count);
@@ -899,7 +899,7 @@ static void smtp_connect_inet(SMTP_STATE *state, const char *nexthop,
if (addr_list && (state->misc_flags & SMTP_MISC_FLAG_FIRST_NEXTHOP)) {
smtp_cache_policy(state, domain);
if (state->misc_flags & SMTP_MISC_FLAG_CONN_CACHE_MASK)
SET_NEXTHOP_STATE(state, dest);
SET_SCACHE_REQUEST_NEXTHOP(state, dest);
}
/*
@@ -1124,8 +1124,8 @@ static void smtp_connect_inet(SMTP_STATE *state, const char *nexthop,
/*
* Cleanup.
*/
if (HAVE_NEXTHOP_STATE(state))
FREE_NEXTHOP_STATE(state);
if (HAVE_SCACHE_REQUEST_NEXTHOP(state))
CLEAR_SCACHE_REQUEST_NEXTHOP(state);
argv_free(sites);
}

View File

@@ -53,7 +53,7 @@
/* .IP SMTP_KEY_FLAG_REQ_NEXTHOP
/* The request nexthop destination. This is a proxy for
/* destination-dependent, but host-independent context.
/* .IP SMTP_KEY_FLAG_NEXTHOP
/* .IP SMTP_KEY_FLAG_CUR_NEXTHOP
/* The current iterator's nexthop destination (request nexthop
/* or fallback nexthop, including optional [] and :port). This
/* is the form that users specify in a SASL or TLS lookup
@@ -183,7 +183,7 @@ char *smtp_key_prefix(VSTRING *buffer, const char *delim_na,
*/
if (flags & SMTP_KEY_FLAG_REQ_NEXTHOP)
smtp_key_append_str(buffer, STR(iter->request_nexthop), delim_na);
if (flags & SMTP_KEY_FLAG_NEXTHOP)
if (flags & SMTP_KEY_FLAG_CUR_NEXTHOP)
smtp_key_append_str(buffer, STR(iter->dest), delim_na);
/*

View File

@@ -899,7 +899,7 @@ static int smtp_start_tls(SMTP_STATE *state)
*/
serverid = vstring_alloc(10);
smtp_key_prefix(serverid, "&", state->iterator, SMTP_KEY_FLAG_SERVICE
| SMTP_KEY_FLAG_NEXTHOP /* With port */
| SMTP_KEY_FLAG_CUR_NEXTHOP /* With port */
| SMTP_KEY_FLAG_HOSTNAME
| SMTP_KEY_FLAG_ADDR);
@@ -1018,6 +1018,11 @@ static int smtp_start_tls(SMTP_STATE *state)
* context attributes.
*/
session->tls_context = tls_proxy_context_receive(session->stream);
if (session->tls_context) {
session->features |= SMTP_FEATURE_FROM_PROXY;
tls_log_summary(TLS_ROLE_CLIENT, TLS_USAGE_NEW,
session->tls_context);
}
}
} else { /* state->tls->conn_reuse */

View File

@@ -23,27 +23,26 @@
/* This module implements the SMTP client specific interface to
/* the generic session cache infrastructure.
/*
/* A cached connection is closed when the TLS policy requires
/* that TLS is enabled.
/* The caller needs to include additional state in _key_flags
/* to avoid false sharing of SASL-authenticated or TLS-authenticated
/* sessions.
/*
/* smtp_save_session() stores the current session under the
/* next-hop logical destination (if available) and under the
/* remote server address. The SMTP_SESSION object is destroyed.
/* delivery request next-hop logical destination (if applicable)
/* and under the remote server address. The SMTP_SESSION object
/* is destroyed.
/*
/* smtp_reuse_nexthop() looks up a cached session by its logical
/* destination, and verifies that the session is still alive.
/* The restored session information includes the "best MX" bit
/* and overrides the iterator dest, host and addr fields.
/* The result is null in case of failure.
/* smtp_reuse_nexthop() looks up a cached session by its
/* delivery request next-hop destination, and verifies that
/* the session is still alive. The restored session information
/* includes the "best MX" bit and overrides the iterator dest,
/* host and addr fields. The result is null in case of failure.
/*
/* smtp_reuse_addr() looks up a cached session by its server
/* address, and verifies that the session is still alive.
/* The restored session information does not include the "best
/* MX" bit, and does not override the iterator dest, host and
/* addr fields.
/* This function is a NOOP for TLS levels stronger than "encrypt",
/* because stronger levels require certificate checks,
/* The result is null in case of failure.
/* addr fields. The result is null in case of failure.
/*
/* Arguments:
/* .IP state
@@ -116,10 +115,16 @@ void smtp_save_session(SMTP_STATE *state, int name_key_flags,
int fd;
/*
* Encode the next-hop logical destination, if available. Reuse storage
* that is also used for cache lookup queries.
* Encode the delivery request next-hop destination, if applicable. Reuse
* storage that is also used for cache lookup queries.
*
* HAVE_SCACHE_REQUEST_NEXTHOP() controls whether or not to reuse or cache a
* connection by its delivery request next-hop destination. The idea is
* 1) to allow a reuse request to skip over bad hosts, and 2) to avoid
* caching a less-preferred connection when a more-preferred connection
* was possible.
*/
if (HAVE_NEXTHOP_STATE(state))
if (HAVE_SCACHE_REQUEST_NEXTHOP(state))
smtp_key_prefix(state->dest_label, SMTP_REUSE_KEY_DELIM_NA,
state->iterator, name_key_flags);
@@ -138,16 +143,18 @@ void smtp_save_session(SMTP_STATE *state, int name_key_flags,
state->session = 0;
/*
* Save the session under the next-hop name, if available.
* Save the session under the delivery request next-hop name, if
* applicable.
*
* XXX The logical to physical binding can be kept for as long as the DNS
* allows us to (but that could result in the caching of lots of unused
* bindings). The session should be idle for no more than 30 seconds or
* so.
*/
if (HAVE_NEXTHOP_STATE(state))
scache_save_dest(smtp_scache, var_smtp_cache_conn, STR(state->dest_label),
STR(state->dest_prop), STR(state->endp_label));
if (HAVE_SCACHE_REQUEST_NEXTHOP(state))
scache_save_dest(smtp_scache, var_smtp_cache_conn,
STR(state->dest_label), STR(state->dest_prop),
STR(state->endp_label));
/*
* Save every good session under its physical endpoint address.
@@ -165,15 +172,6 @@ static SMTP_SESSION *smtp_reuse_common(SMTP_STATE *state, int fd,
SMTP_ITERATOR *iter = state->iterator;
SMTP_SESSION *session;
/*
* Obsolete.
*/
#ifdef notdef
if (state->tls->level > TLS_LEV_NONE)
msg_panic("%s: unexpected plain-text cached session to %s",
myname, label);
#endif
/*
* Re-activate the SMTP_SESSION object.
*/
@@ -216,15 +214,6 @@ SMTP_SESSION *smtp_reuse_nexthop(SMTP_STATE *state, int name_key_flags)
SMTP_SESSION *session;
int fd;
/*
* Obsolete: the TLS level and nexthop are part of the connection cache
* key. TODO(tlsproxy) is the port included in the nexthop?
*/
#ifdef notdef
if (state->tls->level > TLS_LEV_NONE)
return (0);
#endif
/*
* Look up the session by its logical name.
*/
@@ -250,18 +239,13 @@ SMTP_SESSION *smtp_reuse_addr(SMTP_STATE *state, int endp_key_flags)
int fd;
/*
* Allow address-based reuse only for security levels that don't require
* certificate checks. Not to be confused with a similar constraint in
* the destination label smtp_key pattern, which conditionally includes
* the nexthop to prevent the reuse of an authenticated connection to the
* same MX hostname and the same IP address, but for a different nexthop
* destination (just in case we start to send SNI with the nexthop, and
* forget to update connection cache lookup key patterns).
* Address-based reuse is safe for security levels that require TLS
* certificate checks, as long as the current nexhop is included in the
* cache lookup key (COND_TLS_SMTP_KEY_FLAG_CUR_NEXTHOP). This is
* sufficient to prevent the reuse of a TLS-authenticated connection to
* the same MX hostname, IP address, and port, but for a different
* current nexthop destination with a different TLS policy.
*/
#ifdef USE_TLS
if (TLS_MUST_MATCH(state->tls->level))
return (0);
#endif
/*
* Look up the session by its IP address. This means that we have no

View File

@@ -113,11 +113,28 @@
#include <debug_peer.h>
#include <mail_params.h>
/* TLS Library. */
#include <tls_proxy.h>
/* Application-specific. */
#include "smtp.h"
#include "smtp_sasl.h"
/*
* Local, because these are meaningful only for code in this file.
*/
#define SESS_ATTR_DEST "destination"
#define SESS_ATTR_HOST "host_name"
#define SESS_ATTR_ADDR "host_addr"
#define SESS_ATTR_DEST_FEATURES "destination_features"
#define SESS_ATTR_TLS_LEVEL "tls_level"
#define SESS_ATTR_REUSE_COUNT "reuse_count"
#define SESS_ATTR_ENDP_FEATURES "endpoint_features"
#define SESS_ATTR_EXPIRE_TIME "expire_time"
/* smtp_session_alloc - allocate and initialize SMTP_SESSION structure */
SMTP_SESSION *smtp_session_alloc(VSTREAM *stream, SMTP_ITERATOR *iter,
@@ -183,7 +200,8 @@ void smtp_session_free(SMTP_SESSION *session)
vstream_fflush(session->stream);
}
if (session->tls_context) {
if (session->state->tls->conn_reuse)
if (session->features &
(SMTP_FEATURE_FROM_CACHE | SMTP_FEATURE_FROM_PROXY))
tls_proxy_context_free(session->tls_context);
else
tls_client_stop(smtp_tls_ctx, session->stream,
@@ -220,6 +238,7 @@ int smtp_session_passivate(SMTP_SESSION *session, VSTRING *dest_prop,
VSTRING *endp_prop)
{
SMTP_ITERATOR *iter = session->iterator;
VSTREAM *mp;
int fd;
/*
@@ -228,55 +247,61 @@ int smtp_session_passivate(SMTP_SESSION *session, VSTRING *dest_prop,
* destination (this information is needed for loop handling in
* smtp_proto()).
*
* XXX It would be nice to have a VSTRING to VSTREAM adapter so that we can
* 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: save SASL username and password information so that we can
* correctly save a reused authenticated connection.
*
* Note: the TLS level field is always present.
* These memory writes should never fail.
*/
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);
if ((mp = vstream_memopen(dest_prop, O_WRONLY)) == 0
|| attr_print_plain(mp, ATTR_FLAG_NONE,
SEND_ATTR_STR(SESS_ATTR_DEST, STR(iter->dest)),
SEND_ATTR_STR(SESS_ATTR_HOST, STR(iter->host)),
SEND_ATTR_STR(SESS_ATTR_ADDR, STR(iter->addr)),
SEND_ATTR_INT(SESS_ATTR_DEST_FEATURES,
session->features & SMTP_FEATURE_DESTINATION_MASK),
ATTR_TYPE_END) != 0
|| vstream_fclose(mp) != 0)
msg_fatal("smtp_session_passivate: can't save dest properties: %m");
/*
* Encode the physical endpoint properties: all the session properties
* except for "session from cache", "best MX", or "RSET failure".
* Plus the TLS level, reuse count, and connection expiration time.
*
* XXX It would be nice to have a VSTRING to VSTREAM adapter so that we can
* serialize the properties with attr_print() instead of using obscure
* hard-coded format strings.
* XXX Should also record how many non-delivering mail transactions there
* were during this session, and perhaps other statistics, so that we
* don't reuse a session too much.
*
* XXX Should also record an absolute time when a session must be closed,
* how many non-delivering mail transactions there were during this
* session, and perhaps other statistics, so that we don't reuse a
* session too much.
* TODO: passivate SASL username and password information so that we can
* correctly save a reused authenticated connection.
*
* XXX Be sure to use unsigned types in the format string. Sign characters
* would be rejected by the alldig() test on the reading end.
* These memory writes should never fail.
*/
vstring_sprintf(endp_prop, "%u\n%u\n%lu",
session->reuse_count,
session->features & SMTP_FEATURE_ENDPOINT_MASK,
(long) session->expire_time);
if ((mp = vstream_memopen(endp_prop, O_WRONLY)) == 0
|| attr_print_plain(mp, ATTR_FLAG_NONE,
SEND_ATTR_INT(SESS_ATTR_TLS_LEVEL,
session->state->tls->level),
SEND_ATTR_INT(SESS_ATTR_REUSE_COUNT,
session->reuse_count),
SEND_ATTR_INT(SESS_ATTR_ENDP_FEATURES,
session->features & SMTP_FEATURE_ENDPOINT_MASK),
SEND_ATTR_LONG(SESS_ATTR_EXPIRE_TIME,
(long) session->expire_time),
ATTR_TYPE_END) != 0
/*
* Append the passivated SASL attributes.
* Append the passivated TLS context. These memory writes should never
* fail.
*/
#ifdef notdef
if (smtp_sasl_enable)
smtp_sasl_passivate(endp_prop, session);
#ifdef USE_TLS
|| (session->tls_context
&& attr_print_plain(mp, ATTR_FLAG_NONE,
SEND_ATTR_FUNC(tls_proxy_context_print,
(void *) session->tls_context),
ATTR_TYPE_END) != 0)
#endif
|| vstream_fclose(mp) != 0)
msg_fatal("smtp_session_passivate: cannot save TLS context: %m");
/*
* Salvage the underlying file descriptor, and destroy the session
@@ -297,50 +322,52 @@ SMTP_SESSION *smtp_session_activate(int fd, SMTP_ITERATOR *iter,
VSTRING *endp_prop)
{
const char *myname = "smtp_session_activate";
VSTREAM *mp;
SMTP_SESSION *session;
char *dest_props;
char *endp_props;
const char *prop;
const char *dest;
const char *host;
const char *addr;
unsigned features; /* server features */
time_t expire_time; /* session re-use expiration time */
unsigned reuse_count; /* # times reused */
int endp_features; /* server features */
int dest_features; /* server features */
long expire_time; /* session re-use expiration time */
int reuse_count; /* # times reused */
TLS_SESS_STATE *tls_context = 0;
#ifdef USE_TLS
SMTP_TLS_POLICY *tls = iter->parent->tls;
#endif
#define SMTP_SESSION_ACTIVATE_ERR_RETURN() do { \
if (tls_context) \
tls_proxy_context_free(tls_context); \
return (0); \
} while (0)
/*
* 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
* ad-hoc, non-reusable code.
*
* XXX As a preliminary solution we use mystrtok(), but that function is not
* suitable for zero-length fields.
* Sanity check: if TLS is required, the cached properties must contain a
* TLS context.
*/
endp_props = STR(endp_prop);
if ((prop = mystrtok(&endp_props, "\n")) == 0 || !alldig(prop)) {
msg_warn("%s: bad cached session reuse count property", myname);
return (0);
}
reuse_count = atoi(prop);
if ((prop = mystrtok(&endp_props, "\n")) == 0 || !alldig(prop)) {
msg_warn("%s: bad cached session features property", myname);
return (0);
}
features = atoi(prop);
if ((prop = mystrtok(&endp_props, "\n")) == 0 || !alldig(prop)) {
msg_warn("%s: bad cached session expiration time property", myname);
return (0);
}
#ifdef MISSING_STRTOUL
expire_time = strtol(prop, 0, 10);
#else
expire_time = strtoul(prop, 0, 10);
if ((mp = vstream_memopen(endp_prop, O_RDONLY)) == 0
|| attr_scan_plain(mp, ATTR_FLAG_NONE,
RECV_ATTR_INT(SESS_ATTR_TLS_LEVEL,
&tls->level),
RECV_ATTR_INT(SESS_ATTR_REUSE_COUNT,
&reuse_count),
RECV_ATTR_INT(SESS_ATTR_ENDP_FEATURES,
&endp_features),
RECV_ATTR_LONG(SESS_ATTR_EXPIRE_TIME,
&expire_time),
ATTR_TYPE_END) != 4
#ifdef USE_TLS
|| ((tls->level > TLS_LEV_MAY
|| (tls->level == TLS_LEV_MAY && vstream_peek(mp) > 0))
&& attr_scan_plain(mp, ATTR_FLAG_NONE,
RECV_ATTR_FUNC(tls_proxy_context_scan,
(void *) &tls_context),
ATTR_TYPE_END) != 1)
#endif
|| vstream_fclose(mp) != 0) {
msg_warn("smtp_session_activate: bad cached endp properties");
SMTP_SESSION_ACTIVATE_ERR_RETURN();
}
/*
* Clobber the iterator's current nexthop, host and address fields with
@@ -355,36 +382,25 @@ SMTP_SESSION *smtp_session_activate(int fd, SMTP_ITERATOR *iter,
* correctly save a reused authenticated connection.
*/
if (dest_prop && VSTRING_LEN(dest_prop)) {
dest_props = STR(dest_prop);
if ((dest = mystrtok(&dest_props, "\n")) == 0) {
msg_warn("%s: missing cached session destination property", myname);
return (0);
if ((mp = vstream_memopen(dest_prop, O_RDONLY)) == 0
|| attr_scan_plain(mp, ATTR_FLAG_NONE,
RECV_ATTR_STR(SESS_ATTR_DEST, iter->dest),
RECV_ATTR_STR(SESS_ATTR_HOST, iter->host),
RECV_ATTR_STR(SESS_ATTR_ADDR, iter->addr),
RECV_ATTR_INT(SESS_ATTR_DEST_FEATURES,
&dest_features),
ATTR_TYPE_END) != 4
|| vstream_fclose(mp) != 0) {
msg_warn("smtp_session_passivate: bad cached dest properties");
SMTP_SESSION_ACTIVATE_ERR_RETURN();
}
if ((host = mystrtok(&dest_props, "\n")) == 0) {
msg_warn("%s: missing cached session hostname property", myname);
return (0);
}
if ((addr = mystrtok(&dest_props, "\n")) == 0) {
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);
} else {
dest_features = 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);
}
features |= atoi(prop);
SMTP_ITER_CLOBBER(iter, dest, host, addr);
}
/*
* Allright, bundle up what we have sofar.
@@ -393,7 +409,9 @@ SMTP_SESSION *smtp_session_activate(int fd, SMTP_ITERATOR *iter,
session = smtp_session_alloc(vstream_fdopen(fd, O_RDWR), iter,
(time_t) 0, NO_FLAGS);
session->features = (features | SMTP_FEATURE_FROM_CACHE);
session->features =
(endp_features | dest_features | SMTP_FEATURE_FROM_CACHE);
session->tls_context = tls_context;
CACHE_THIS_SESSION_UNTIL(expire_time);
session->reuse_count = ++reuse_count;
@@ -401,20 +419,15 @@ SMTP_SESSION *smtp_session_activate(int fd, SMTP_ITERATOR *iter,
msg_info("%s: dest=%s host=%s addr=%s port=%u features=0x%x, "
"ttl=%ld, reuse=%d",
myname, STR(iter->dest), STR(iter->host),
STR(iter->addr), ntohs(iter->port), features,
STR(iter->addr), ntohs(iter->port),
endp_features | dest_features,
(long) (expire_time - time((time_t *) 0)),
reuse_count);
/*
* Re-activate the SASL attributes.
*/
#ifdef notdef
if (smtp_sasl_enable && smtp_sasl_activate(session, endp_props) < 0) {
vstream_fdclose(session->stream);
session->stream = 0;
smtp_session_free(session);
return (0);
}
#if USE_TLS
if (tls_context)
tls_log_summary(TLS_ROLE_CLIENT, TLS_USAGE_USED,
session->tls_context);
#endif
return (session);

View File

@@ -668,7 +668,7 @@ int smtp_tls_policy_cache_query(DSN_BUF *why, SMTP_TLS_POLICY *tls,
* values that also appear in other cache and table search keys.
*/
key = vstring_alloc(100);
smtp_key_prefix(key, ":", iter, SMTP_KEY_FLAG_NEXTHOP
smtp_key_prefix(key, ":", iter, SMTP_KEY_FLAG_CUR_NEXTHOP
| SMTP_KEY_FLAG_HOSTNAME
| SMTP_KEY_FLAG_PORT);
ctable_newcontext(policy_cache, (void *) iter);

View File

@@ -115,12 +115,12 @@ extern const char *str_tls_level(int);
#endif
/*-
* Backwards compatibility with OpenSSL < 1.1.1a (or some later version).
* Backwards compatibility with OpenSSL < 1.1.1a.
*
* The client-only interface SSL_get_server_tmp_key() is slated to be made to
* work on both client and server, and renamed to SSL_get_peer_tmp_key(), with
* the original name left behind as an alias. We use the new name when
* available.
* In OpenSSL 1.1.1a the client-only interface SSL_get_server_tmp_key() was
* updated to work on both the client and the server, and was renamed to
* SSL_get_peer_tmp_key(), with the original name left behind as an alias. We
* use the new name when available.
*/
#if OPENSSL_VERSION_NUMBER < 0x1010101fUL
#undef SSL_get_signature_nid
@@ -159,9 +159,13 @@ extern const char *str_tls_level(int);
/*
* TLS role, presently for logging.
*/
typedef enum { TLS_ROLE_CLIENT, TLS_ROLE_SERVER, } TLS_ROLE;
typedef enum {
TLS_ROLE_CLIENT, TLS_ROLE_SERVER,
} TLS_ROLE;
typedef enum { TLS_USAGE_NEW, TLS_USAGE_USED, } TLS_USAGE;
typedef enum {
TLS_USAGE_NEW, TLS_USAGE_USED,
} TLS_USAGE;
/*
* Names of valid tlsmgr(8) session caches.

View File

@@ -1191,6 +1191,9 @@ TLS_SESS_STATE *tls_client_post_connect(TLS_SESS_STATE *TLScontext,
&& !TLS_NEVER_SECURED(props->tls_level))
TLScontext->peer_status |= TLS_CERT_FLAG_SECURED;
/*
* With the handshake done, extract TLS 1.3 signature metadata.
*/
tls_get_signature_params(TLScontext);
if (TLScontext->log_mask & TLS_LOG_SUMMARY)

View File

@@ -14,6 +14,12 @@
/* TLS_USAGE usage;
/* TLS_SESS_STATE *TLScontext;
/*
/* const char *tls_compile_version(void)
/*
/* const char *tls_run_version(void)
/*
/* const char **tls_pkey_algorithms(void)
/*
/* .SH Internal functions
/* .nf
/* .na
@@ -103,12 +109,6 @@
/*
/* int tls_validate_digest(dgst)
/* const char *dgst;
/*
/* const char *tls_compile_version(void)
/*
/* const char *tls_run_version(void)
/*
/* const char **tls_pkey_algorithms(void)
/* DESCRIPTION
/* This module implements public and internal routines that
/* support the TLS client and server.
@@ -118,6 +118,16 @@
/* connections, or TLS_ROLE_SERVER for incoming server connections,
/* and the "usage" must be TLS_USAGE_NEW or TLS_USAGE_USED.
/*
/* tls_compile_version() returns a text string description of
/* the compile-time TLS library.
/*
/* tls_run_version() is just tls_compile_version() but with the runtime
/* version instead of the compile-time version.
/*
/* tls_pkey_algorithms() returns a pointer to null-terminated
/* array of string constants with the names of the supported
/* public-key algorithms.
/*
/* tls_alloc_app_context() creates an application context that
/* holds the SSL context for the application and related cached state.
/*
@@ -190,16 +200,6 @@
/*
/* tls_validate_digest() returns non-zero if the named digest
/* is usable and zero otherwise.
/*
/* tls_compile_version() returns a text string description of
/* the compile-time TLS library.
/*
/* tls_run_version() is just tls_compile_version() but with the runtime
/* version instead of the compile-time version.
/*
/* tls_pkey_algorithms() returns a pointer to null-terminated
/* array of string constants with the names of the supported
/* public-key algorithms.
/* LICENSE
/* .ad
/* .fi

View File

@@ -1714,7 +1714,7 @@ VSTREAM *vstream_memreopen(VSTREAM *stream, VSTRING *string, int flags)
stream->write_fn = 0;
stream->vstring = string;
memcpy(&stream->buf, &stream->vstring->vbuf, sizeof(stream->buf));
stream->buf.flags |= (flags | VSTREAM_FLAG_MEMORY);
stream->buf.flags |= VSTREAM_FLAG_MEMORY;
switch (VSTREAM_ACC_MASK(flags)) {
case O_RDONLY:
stream->buf.flags |= VSTREAM_FLAG_READ;