Cleanup: missing #ifdef USE_TLS. Files: smtp/smtp_session.c,
posttls-finger/posttls-finger.c.
+
+20190217
+
+ Cleanup: when the master daemon runs with PID=1 (init mode),
+ reap orhpan processes from non-Postfix code running in the
+ same container, instead of terminating with a panic. File:
+ master/master_spawn.c.
+
+20190218
+
+ Bugfix: tlsproxy did not enable DANE-style PKI because
+ libtls seems to have to accreted multiple init functions
+ instead of reusing the tls_client_init() and tls_client_start()
+ API. And some functions that do initialization don't even
+ have init in their name! Problem report by Andreas Schulze.
+ Viktor Dukhovni. Files: tls/tls_misc.c, tlsproxy/tlsproxy.c.
+
+ Workaround: Postfix libtls makes DANE-specific changes to
+ the shared SSL_CTX. To avoid false sharing, tlsproxy needs
+ to label the SSL_CTX cache with DANE bits until we can
+ remove the code that modifies SSL_CTX. File: tlsproxy/tlsproxy.c.
+
+ Cleanup: Postfix libtls changed the shared SSL_CTX to
+ override ciphers. instead of changing the SSL handle. To
+ avoid false sharing in tlsproxy, the changes are now made
+ to the SSL handle. Viktor Dukhovni. Files: tls/tls.h,
+ tls/tls_client.c, tls/tls_misc.c, tls/tls_server.c.
+
+20190219
+
+ Bugfix: in the Postfix SMTP client, TLS wrappermode was not
+ tested in tlsproxy mode. It needed some setup for buffering
+ and timeouts. Problem report by Andreas Schulze. File:
+ smtp/smtp_proto.c.
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20190212"
-#define MAIL_VERSION_NUMBER "3.4.0-RC2"
+#define MAIL_RELEASE_DATE "20190221"
+#define MAIL_VERSION_NUMBER "3.4.0-RC3"
#ifdef SNAPSHOT
#define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE
if (msg_verbose)
msg_info("master_reap_child: pid %d", pid);
if ((proc = (MASTER_PROC *) binhash_find(master_child_table,
- (void *) &pid, sizeof(pid))) == 0)
+ (void *) &pid, sizeof(pid))) == 0) {
+ if (init_mode)
+ continue; /* non-Postfix process */
msg_panic("master_reap: unknown pid: %d", pid);
+ }
serv = proc->serv;
#define MASTER_KILL_SIGNAL SIGTERM
&& (state->misc_flags & SMTP_MISC_FLAG_IN_STARTTLS) == 0) {
/* XXX Mix-up of per-session and per-request flags. */
state->misc_flags |= SMTP_MISC_FLAG_IN_STARTTLS;
+ smtp_stream_setup(state->session->stream, var_smtp_starttls_tmout,
+ var_smtp_rec_deadline);
tls_helo_status = smtp_start_tls(state);
state->misc_flags &= ~SMTP_MISC_FLAG_IN_STARTTLS;
return (tls_helo_status);
SSL_CTX *sni_ctx;
int log_mask;
char *cache_type;
- char *cipher_exclusions; /* Last cipher selection state */
- char *cipher_list; /* Last cipher selection state */
- int cipher_grade; /* Last cipher selection state */
- VSTRING *why;
};
/*
/*
* Cipher lists with exclusions.
*/
-extern const char *tls_set_ciphers(TLS_APPL_STATE *, const char *,
- const char *, const char *);
+extern const char *tls_set_ciphers(TLS_SESS_STATE *, const char *,
+ const char *);
/*
* Populate TLS context with TLS 1.3-related signature parameters.
if (TLS_DANE_BASED(props->tls_level))
protomask |= TLS_PROTOCOL_SSLv2;
+ /*
+ * Allocate a new TLScontext for the new connection and get an SSL
+ * structure. Add the location of TLScontext to the SSL to later retrieve
+ * the information inside the tls_verify_certificate_callback().
+ *
+ * If session caching was enabled when TLS was initialized, the cache type
+ * is stored in the client SSL context.
+ */
+ TLScontext = tls_alloc_sess_context(log_mask, props->namaddr);
+ TLScontext->cache_type = app_ctx->cache_type;
+
+ if ((TLScontext->con = SSL_new(app_ctx->ssl_ctx)) == NULL) {
+ msg_warn("Could not allocate 'TLScontext->con' with SSL_new()");
+ tls_print_errors();
+ tls_free_context(TLScontext);
+ return (0);
+ }
+
/*
* Per session cipher selection for sessions with mandatory encryption
*
* to stay the same between connections, so we make use of a 1-element
* cache to return the same result for identical inputs.
*/
- cipher_list = tls_set_ciphers(app_ctx, "TLS", props->cipher_grade,
+ cipher_list = tls_set_ciphers(TLScontext, props->cipher_grade,
props->cipher_exclusions);
if (cipher_list == 0) {
- msg_warn("%s: %s: aborting TLS session",
- props->namaddr, vstring_str(app_ctx->why));
+ /* already warned */
+ tls_free_context(TLScontext);
return (0);
}
if (log_mask & TLS_LOG_VERBOSE)
*/
myserverid = tls_serverid_digest(props, protomask, cipher_list);
- /*
- * Allocate a new TLScontext for the new connection and get an SSL
- * structure. Add the location of TLScontext to the SSL to later retrieve
- * the information inside the tls_verify_certificate_callback().
- *
- * If session caching was enabled when TLS was initialized, the cache type
- * is stored in the client SSL context.
- */
- TLScontext = tls_alloc_sess_context(log_mask, props->namaddr);
- TLScontext->cache_type = app_ctx->cache_type;
-
TLScontext->serverid = myserverid;
TLScontext->stream = props->stream;
TLScontext->mdalg = props->mdalg;
/* Alias DANE digest info from props */
TLScontext->dane = props->dane;
- if ((TLScontext->con = SSL_new(app_ctx->ssl_ctx)) == NULL) {
- msg_warn("Could not allocate 'TLScontext->con' with SSL_new()");
- tls_print_errors();
- tls_free_context(TLScontext);
- return (0);
- }
if (!SSL_set_ex_data(TLScontext->con, TLScontext_index, TLScontext)) {
msg_warn("Could not set application data for 'TLScontext->con'");
tls_print_errors();
/* const char *str_tls_cipher_grade(grade)
/* int grade;
/*
-/* const char *tls_set_ciphers(app_ctx, context, grade, exclusions)
-/* TLS_APPL_STATE *app_ctx;
-/* const char *context;
+/* const char *tls_set_ciphers(TLScontext, grade, exclusions)
+/* TLS_SESS_STATE *TLScontext;
/* int grade;
/* const char *exclusions;
/*
/* When the input specifies an undefined grade, str_tls_cipher_grade()
/* logs no warning, returns a null pointer.
/*
-/* tls_set_ciphers() generates a cipher list from the specified
-/* grade, minus any ciphers specified via a list of exclusions.
-/* The cipherlist is applied to the supplied SSL context if it
-/* is different from the most recently applied value. The return
-/* value is the cipherlist used and is overwritten upon each call.
-/* When the input is invalid, tls_set_ciphers() logs a warning with
-/* the specified context, and returns a null pointer result.
+/* tls_set_ciphers() applies the requested cipher grade and exclusions
+/* to the provided TLS session context, returning the resulting cipher
+/* list string. The return value is the cipherlist used and is
+/* overwritten upon each call. When the input is invalid,
+/* tls_set_ciphers() logs a warning, and returns a null result.
/*
/* tls_get_signature_params() updates the "TLScontext" with handshake
/* signature parameters pertaining to TLS 1.3, where the ciphersuite
int status;
} TLS_VINFO;
- /*
- * OpenSSL adopted the cipher selection patch, so we don't expect any more
- * broken ciphers other than AES and CAMELLIA.
- */
-typedef struct {
- const char *ssl_name;
- const int alg_bits;
- const char *evp_name;
-} cipher_probe_t;
-
-static const cipher_probe_t cipher_probes[] = {
- "AES", 256, "AES-256-CBC",
- "CAMELLIA", 256, "CAMELLIA-256-CBC",
- 0, 0, 0,
-};
-
/* tls_log_mask - Convert user TLS loglevel to internal log feature mask */
int tls_log_mask(const char *log_param, const char *log_level)
app_ctx->log_mask = log_mask;
}
-/* tls_exclude_missing - Append exclusions for missing ciphers */
-
-static const char *tls_exclude_missing(SSL_CTX *ctx, VSTRING *buf)
-{
- const char *myname = "tls_exclude_missing";
- static ARGV *exclude; /* Cached */
- SSL *s = 0;
- ssl_cipher_stack_t *ciphers;
- const SSL_CIPHER *c;
- const cipher_probe_t *probe;
- int alg_bits;
- int num;
- int i;
-
- /*
- * Process a list of probes which specify:
- *
- * An SSL cipher-suite name for a family of ciphers that use the same
- * symmetric algorithm at two or more key sizes, typically 128/256 bits.
- *
- * The key size (typically 256) that OpenSSL fails to check, and assumes
- * available when another key size (typically 128) is usable.
- *
- * The OpenSSL name of the symmetric algorithm associated with the SSL
- * cipher-suite. Typically, this is MUMBLE-256-CBC, where "MUMBLE" is the
- * name of the SSL cipher-suite that use the MUMBLE symmetric algorithm.
- * On systems that support the required encryption algorithm, the name is
- * listed in the output of "openssl list-cipher-algorithms".
- *
- * When an encryption algorithm is not available at the given key size but
- * the corresponding OpenSSL cipher-suite contains ciphers that have have
- * this key size, the problem ciphers are explicitly disabled in Postfix.
- * The list is cached in the static "exclude" array.
- */
- if (exclude == 0) {
- exclude = argv_alloc(1);
-
- /*
- * Iterate over the probe list
- */
- for (probe = cipher_probes; probe->ssl_name; ++probe) {
- /* No exclusions if evp_name is a valid algorithm */
- if (EVP_get_cipherbyname(probe->evp_name))
- continue;
-
- /*
- * Sadly there is no SSL_CTX_get_ciphers() interface, so we are
- * forced to allocate and free an SSL object. Fatal error if we
- * can't allocate the SSL object.
- */
- ERR_clear_error();
- if (s == 0 && (s = SSL_new(ctx)) == 0) {
- tls_print_errors();
- msg_fatal("%s: error allocating SSL object", myname);
- }
-
- /*
- * Cipher is not supported by libcrypto, nothing to do if also
- * not supported by libssl. Flush the OpenSSL error stack.
- *
- * XXX: There may be additional places in pre-existing code where
- * SSL errors are generated and ignored, that require a similar
- * "flush". Better yet, is to always flush before calls that run
- * tls_print_errors() on failure.
- *
- * Contrary to documentation, on SunOS 5.10 SSL_set_cipher_list()
- * returns success with no ciphers selected, when this happens
- * SSL_get_ciphers() produces a stack with 0 elements!
- */
- if (SSL_set_cipher_list(s, probe->ssl_name) == 0
- || (ciphers = SSL_get_ciphers(s)) == 0
- || (num = sk_SSL_CIPHER_num(ciphers)) == 0) {
- ERR_clear_error(); /* flush any generated errors */
- continue;
- }
- for (i = 0; i < num; ++i) {
- c = sk_SSL_CIPHER_value(ciphers, i);
- (void) SSL_CIPHER_get_bits(c, &alg_bits);
- if (alg_bits == probe->alg_bits)
- argv_add(exclude, SSL_CIPHER_get_name(c), ARGV_END);
- }
- }
- if (s != 0)
- SSL_free(s);
- }
- for (i = 0; i < exclude->argc; ++i)
- vstring_sprintf_append(buf, ":!%s", exclude->argv[i]);
- return (vstring_str(buf));
-}
-
-/* tls_apply_cipher_list - update SSL_CTX cipher list */
-
-static const char *tls_apply_cipher_list(TLS_APPL_STATE *app_ctx,
- const char *context, VSTRING *spec)
-{
- const char *new = tls_exclude_missing(app_ctx->ssl_ctx, spec);
-
- ERR_clear_error();
- if (SSL_CTX_set_cipher_list(app_ctx->ssl_ctx, new) == 0) {
- tls_print_errors();
- vstring_sprintf(app_ctx->why, "invalid %s cipher list: \"%s\"",
- context, new);
- return (0);
- }
- return (new);
-}
-
/* tls_protocol_mask - Bitmask of protocols to exclude */
int tls_protocol_mask(const char *plist)
VAR_OPENSSL_PATH, DEF_OPENSSL_PATH, &var_openssl_path, 1, 0,
0,
};
+
/* If this changes, update TLS_CLIENT_PARAMS in tls_proxy.h. */
static const CONFIG_INT_TABLE int_table[] = {
VAR_TLS_DAEMON_RAND_BYTES, DEF_TLS_DAEMON_RAND_BYTES, &var_tls_daemon_rand_bytes, 1, 0,
0,
};
+
/* If this changes, update TLS_CLIENT_PARAMS in tls_proxy.h. */
static const CONFIG_BOOL_TABLE bool_table[] = {
VAR_TLS_APPEND_DEF_CA, DEF_TLS_APPEND_DEF_CA, &var_tls_append_def_CA,
};
int flags;
+ tls_param_init();
+
/* Nothing for clients at this time */
if (role != TLS_ROLE_SERVER)
return;
TLScontext->namaddr, sni);
return SSL_TLSEXT_ERR_NOACK;
}
-
do {
/* Don't silently skip maps opened with the wrong flags. */
pem = maps_file_find(tls_server_sni_maps, cp, 0);
}
msg_info("TLS SNI %s from %s not matched, using default chain",
sni, TLScontext->namaddr);
+
/*
* XXX: We could lie and pretend to accept the name, but since we've
- * previously not impemented the callback (with OpenSSL then declining
- * the extension), and nothing bad happened, declining it explicitly
- * should be safe.
+ * previously not implemented the callback (with OpenSSL then
+ * declining the extension), and nothing bad happened, declining it
+ * explicitly should be safe.
*/
return SSL_TLSEXT_ERR_NOACK;
}
/* tls_set_ciphers - Set SSL context cipher list */
-const char *tls_set_ciphers(TLS_APPL_STATE *app_ctx, const char *context,
- const char *grade, const char *exclusions)
+const char *tls_set_ciphers(TLS_SESS_STATE *TLScontext, const char *grade,
+ const char *exclusions)
{
const char *myname = "tls_set_ciphers";
static VSTRING *buf;
- int new_grade;
char *save;
char *cp;
char *tok;
- const char *new_list;
- new_grade = tls_cipher_grade(grade);
- if (new_grade == TLS_CIPHER_NONE) {
- vstring_sprintf(app_ctx->why, "invalid %s cipher grade: \"%s\"",
- context, grade);
- return (0);
- }
if (buf == 0)
buf = vstring_alloc(10);
VSTRING_RESET(buf);
- /*
- * Given cached state and identical input, we return the same result.
- */
- if (app_ctx->cipher_list) {
- if (new_grade == app_ctx->cipher_grade
- && strcmp(app_ctx->cipher_exclusions, exclusions) == 0)
- return (app_ctx->cipher_list);
-
- /* Change required, flush cached state */
- app_ctx->cipher_grade = TLS_CIPHER_NONE;
-
- myfree(app_ctx->cipher_exclusions);
- app_ctx->cipher_exclusions = 0;
-
- myfree(app_ctx->cipher_list);
- app_ctx->cipher_list = 0;
- }
- switch (new_grade) {
+ switch (tls_cipher_grade(grade)) {
+ case TLS_CIPHER_NONE:
+ msg_warn("%s: invalid cipher grade: \"%s\"",
+ TLScontext->namaddr, grade);
+ return (0);
case TLS_CIPHER_HIGH:
vstring_strcpy(buf, var_tls_high_clist);
break;
vstring_strcpy(buf, var_tls_null_clist);
break;
default:
-
- /*
- * The caller MUST provide a valid cipher grade
- */
- msg_panic("invalid %s cipher grade: %d", context, new_grade);
+ /* Internal error, valid grade, but missing case label. */
+ msg_panic("%s: unexpected cipher grade: %s", myname, grade);
}
/*
* Can't exclude ciphers that start with modifiers.
*/
if (strchr("!+-@", *tok)) {
- vstring_sprintf(app_ctx->why,
- "invalid unary '!+-@' in %s cipher "
- "exclusion: \"%s\"", context, tok);
+ msg_warn("%s: invalid unary '!+-@' in cipher exclusion: %s",
+ TLScontext->namaddr, tok);
return (0);
}
vstring_sprintf_append(buf, ":!%s", tok);
}
myfree(save);
}
- if ((new_list = tls_apply_cipher_list(app_ctx, context, buf)) == 0)
+ ERR_clear_error();
+ if (SSL_set_cipher_list(TLScontext->con, vstring_str(buf)) == 0) {
+ msg_warn("%s: error setting cipher grade: \"%s\"",
+ TLScontext->namaddr, grade);
+ tls_print_errors();
return (0);
-
- /* Cache new state */
- app_ctx->cipher_grade = new_grade;
- app_ctx->cipher_exclusions = mystrdup(exclusions);
-
- return (app_ctx->cipher_list = mystrdup(new_list));
+ }
+ return (vstring_str(buf));
}
/* tls_get_signature_params - TLS 1.3 signature details */
const char *sni = (role == TLS_ROLE_CLIENT) ? 0 : ctx->peer_sni;
/*
- * When SNI was sent and accepted, the server-side log message now includes
- * a "to <sni-name>" detail after the "from <namaddr>" detail identifying
- * the remote client. We don't presently log (purportedly) accepted SNI on
- * the client side.
+ * When SNI was sent and accepted, the server-side log message now
+ * includes a "to <sni-name>" detail after the "from <namaddr>" detail
+ * identifying the remote client. We don't presently log (purportedly)
+ * accepted SNI on the client side.
*/
vstring_sprintf(msg, "%s TLS connection %s %s %s%s%s: %s"
" with cipher %s (%d/%d bits)",
TLS_CERT_IS_SECURED(ctx) ? "Verified" :
TLS_CERT_IS_TRUSTED(ctx) ? "Trusted" : "Untrusted",
usage == TLS_USAGE_NEW ? "established" : "reused",
- direction, ctx->namaddr, sni ? " to " : "", sni ? sni : "",
+ direction, ctx->namaddr, sni ? " to " : "", sni ? sni : "",
ctx->protocol, ctx->cipher_name, ctx->cipher_usebits,
ctx->cipher_algbits);
app_ctx->log_mask = log_mask;
/* See also: cache purging code in tls_set_ciphers(). */
- app_ctx->cipher_grade = TLS_CIPHER_NONE;
- app_ctx->cipher_exclusions = 0;
- app_ctx->cipher_list = 0;
app_ctx->cache_type = 0;
- app_ctx->why = vstring_alloc(1);
if (tls_server_sni_maps) {
SSL_CTX_set_tlsext_servername_callback(ssl_ctx, server_sni_callback);
SSL_CTX_free(app_ctx->sni_ctx);
if (app_ctx->cache_type)
myfree(app_ctx->cache_type);
- /* See also: cache purging code in tls_set_ciphers(). */
- if (app_ctx->cipher_exclusions)
- myfree(app_ctx->cipher_exclusions);
- if (app_ctx->cipher_list)
- myfree(app_ctx->cipher_list);
- if (app_ctx->why)
- vstring_free(app_ctx->why);
myfree((void *) app_ctx);
}
if (log_mask & TLS_LOG_VERBOSE)
msg_info("setting up TLS connection from %s", props->namaddr);
- cipher_list = tls_set_ciphers(app_ctx, "TLS", props->cipher_grade,
- props->cipher_exclusions);
- if (cipher_list == 0) {
- msg_warn("%s: %s: aborting TLS session", props->namaddr,
- vstring_str(app_ctx->why));
- return (0);
- }
- if (log_mask & TLS_LOG_VERBOSE)
- msg_info("%s: TLS cipher list \"%s\"", props->namaddr, cipher_list);
-
/*
* Allocate a new TLScontext for the new connection and get an SSL
* structure. Add the location of TLScontext to the SSL to later retrieve
TLScontext = tls_alloc_sess_context(log_mask, props->namaddr);
TLScontext->cache_type = app_ctx->cache_type;
- TLScontext->serverid = mystrdup(props->serverid);
- TLScontext->am_server = 1;
- TLScontext->stream = props->stream;
- TLScontext->mdalg = props->mdalg;
-
ERR_clear_error();
if ((TLScontext->con = (SSL *) SSL_new(app_ctx->ssl_ctx)) == 0) {
msg_warn("Could not allocate 'TLScontext->con' with SSL_new()");
tls_free_context(TLScontext);
return (0);
}
+ cipher_list = tls_set_ciphers(TLScontext, props->cipher_grade,
+ props->cipher_exclusions);
+ if (cipher_list == 0) {
+ /* already warned */
+ tls_free_context(TLScontext);
+ return (0);
+ }
+ if (log_mask & TLS_LOG_VERBOSE)
+ msg_info("%s: TLS cipher list \"%s\"", props->namaddr, cipher_list);
+
+ TLScontext->serverid = mystrdup(props->serverid);
+ TLScontext->am_server = 1;
+ TLScontext->stream = props->stream;
+ TLScontext->mdalg = props->mdalg;
+
if (!SSL_set_ex_data(TLScontext->con, TLScontext_index, TLScontext)) {
msg_warn("Could not set application data for 'TLScontext->con'");
tls_print_errors();
* TLS per-process status.
*/
static TLS_APPL_STATE *tlsp_server_ctx;
-static TLS_APPL_STATE *tlsp_client_ctx;
static bool tlsp_pre_jail_done;
static int ask_client_cert;
static char *tlsp_pre_jail_client_param_key; /* pre-jail global params */
{
state->client_start_props->ctx = state->appl_state;
state->client_start_props->fd = state->ciphertext_fd;
- state->tls_context = tls_client_start(state->client_start_props);
+ /* These predicates and warning belong inside tls_client_start(). */
+ if (!TLS_DANE_BASED(state->client_start_props->tls_level)
+ || tls_dane_avail())
+ state->tls_context = tls_client_start(state->client_start_props);
+ else
+ msg_warn("%s: DANE requested, but not available",
+ state->client_start_props->namaddr);
if (state->tls_context != 0)
return (TLSP_STAT_OK);
myfree(saved_server);
}
- /*
- * Macro for readability.
- */
-#define TLSP_CLIENT_INIT(params, props, a1, a2, a3, a4, a5, a6, a7, a8, a9, \
- a10, a11, a12, a13, a14) \
- tlsp_client_init((params), TLS_CLIENT_INIT_ARGS((props), a1, a2, a3, a4, \
- a5, a6, a7, a8, a9, a10, a11, a12, a13, a14))
-
/* tlsp_client_init - initialize a TLS client engine */
static TLS_APPL_STATE *tlsp_client_init(TLS_CLIENT_PARAMS *tls_params,
- TLS_CLIENT_INIT_PROPS *init_props)
+ TLS_CLIENT_INIT_PROPS *init_props,
+ int dane_based)
{
TLS_APPL_STATE *appl_state;
VSTRING *param_buf;
char *param_key;
VSTRING *init_buf;
char *init_key;
+ VSTRING *init_buf_for_hashing;
+ char *init_key_for_hashing;
int log_hints = 0;
/*
* First, compute the TLS_APPL_STATE cache lookup key. Save a copy of the
* pre-jail request TLS_CLIENT_PARAMS and TLSPROXY_CLIENT_INIT_PROPS
* settings, so that we can detect post-jail requests that do not match.
+ *
+ * Workaround: salt the hash-table key with DANE on/off info. This avoids
+ * cross-talk between DANE and non-DANE sessions. Postfix DANE support
+ * modifies SSL_CTX to override certificate verification because there is
+ * no other way to do this before OpenSSL 1.1.0.
*/
param_buf = vstring_alloc(100);
param_key = tls_proxy_client_param_with_names_to_string(
init_buf = vstring_alloc(100);
init_key = tls_proxy_client_init_with_names_to_string(
init_buf, init_props);
+ init_buf_for_hashing = vstring_alloc(100);
+ init_key_for_hashing = STR(vstring_sprintf(init_buf_for_hashing, "%s%d\n",
+ init_key, dane_based));
if (tlsp_pre_jail_done == 0) {
- if (tlsp_pre_jail_client_param_key != 0
- || tlsp_pre_jail_client_init_key != 0)
- msg_panic("tlsp_client_init: multiple pre-jail calls");
- tlsp_pre_jail_client_param_key = mystrdup(param_key);
- tlsp_pre_jail_client_init_key = mystrdup(init_key);
+ if (tlsp_pre_jail_client_param_key == 0
+ || tlsp_pre_jail_client_init_key == 0) {
+ tlsp_pre_jail_client_param_key = mystrdup(param_key);
+ tlsp_pre_jail_client_init_key = mystrdup(init_key);
+ } else if (strcmp(tlsp_pre_jail_client_param_key, param_key) != 0
+ || strcmp(tlsp_pre_jail_client_init_key, init_key) != 0) {
+ msg_panic("tlsp_client_init: too many pre-jail calls");
+ }
}
/*
* Look up the cached TLS_APPL_STATE for this tls_client_init request.
*/
if ((appl_state = (TLS_APPL_STATE *)
- htable_find(tlsp_client_app_cache, init_key)) == 0) {
+ htable_find(tlsp_client_app_cache, init_key_for_hashing)) == 0) {
/*
* Before creating a TLS_APPL_STATE instance, log a warning if a
*/
if (appl_state == 0
&& (appl_state = tls_client_init(init_props)) != 0) {
- (void) htable_enter(tlsp_client_app_cache, init_key,
+ (void) htable_enter(tlsp_client_app_cache, init_key_for_hashing,
(void *) appl_state);
/*
SSL_MODE_ENABLE_PARTIAL_WRITE
| SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
}
+ vstring_free(init_buf_for_hashing);
vstring_free(init_buf);
vstring_free(param_buf);
return (appl_state);
return;
}
state->appl_state = tlsp_client_init(state->tls_params,
- state->client_init_props);
+ state->client_init_props,
+ TLS_DANE_BASED(state->client_start_props->tls_level));
ready = state->appl_state != 0;
break;
case TLS_PROXY_FLAG_ROLE_SERVER:
if (clnt_use_tls || var_tlsp_clnt_per_site[0] || var_tlsp_clnt_policy[0]) {
TLS_CLIENT_PARAMS tls_params;
TLS_CLIENT_INIT_PROPS init_props;
+ int dane_based_mode;
tls_pre_jail_init(TLS_ROLE_CLIENT);
* Large parameter lists are error-prone, so we emulate a language
* feature that C does not have natively: named parameter lists.
*/
- tlsp_client_ctx =
- TLSP_CLIENT_INIT(tls_proxy_client_param_from_config(&tls_params),
- &init_props,
- log_param = var_tlsp_clnt_logparam,
- log_level = var_tlsp_clnt_loglevel,
- verifydepth = var_tlsp_clnt_scert_vd,
- cache_type = TLS_MGR_SCACHE_SMTP,
- chain_files = var_tlsp_clnt_chain_files,
- cert_file = var_tlsp_clnt_cert_file,
- key_file = var_tlsp_clnt_key_file,
- dcert_file = var_tlsp_clnt_dcert_file,
- dkey_file = var_tlsp_clnt_dkey_file,
- eccert_file = var_tlsp_clnt_eccert_file,
- eckey_file = var_tlsp_clnt_eckey_file,
- CAfile = var_tlsp_clnt_CAfile,
- CApath = var_tlsp_clnt_CApath,
- mdalg = var_tlsp_clnt_fpt_dgst);
- if (tlsp_client_ctx == 0)
- msg_warn("TLS client initialization failed");
+ (void) tls_proxy_client_param_from_config(&tls_params);
+ (void) TLS_CLIENT_INIT_ARGS(&init_props,
+ log_param = var_tlsp_clnt_logparam,
+ log_level = var_tlsp_clnt_loglevel,
+ verifydepth = var_tlsp_clnt_scert_vd,
+ cache_type = TLS_MGR_SCACHE_SMTP,
+ chain_files = var_tlsp_clnt_chain_files,
+ cert_file = var_tlsp_clnt_cert_file,
+ key_file = var_tlsp_clnt_key_file,
+ dcert_file = var_tlsp_clnt_dcert_file,
+ dkey_file = var_tlsp_clnt_dkey_file,
+ eccert_file = var_tlsp_clnt_eccert_file,
+ eckey_file = var_tlsp_clnt_eckey_file,
+ CAfile = var_tlsp_clnt_CAfile,
+ CApath = var_tlsp_clnt_CApath,
+ mdalg = var_tlsp_clnt_fpt_dgst);
+ for (dane_based_mode = 0; dane_based_mode < 2; dane_based_mode++) {
+ if (tlsp_client_init(&tls_params, &init_props,
+ dane_based_mode) == 0)
+ msg_warn("TLS client initialization failed");
+ }
}
/*