#if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
# define EXIM_HAVE_OPENSSL_TLSEXT
#endif
+#if OPENSSL_VERSION_NUMBER >= 0x010100000L
+# define EXIM_HAVE_OPENSSL_CHECKHOST
+#endif
+#if OPENSSL_VERSION_NUMBER >= 0x010000000L \
+ && (OPENSSL_VERSION_NUMBER & 0x0000ff000L) >= 0x000002000L
+# define EXIM_HAVE_OPENSSL_CHECKHOST
+#endif
#if !defined(EXIM_HAVE_OPENSSL_TLSEXT) && !defined(DISABLE_OCSP)
# warning "OpenSSL library version too old; define DISABLE_OCSP in Makefile"
#ifdef EXPERIMENTAL_CERTNAMES
uschar * verify_cert_hostnames;
#endif
-#ifdef EXPERIMENTAL_TPDA
+#ifdef EXPERIMENTAL_EVENT
uschar * event_action;
#endif
} tls_ext_ctx_cb;
static int
tls_error(uschar *prefix, host_item *host, uschar *msg)
{
-if (msg == NULL)
+if (!msg)
{
ERR_error_string(ERR_get_error(), ssl_errstring);
msg = (uschar *)ssl_errstring;
}
-if (host == NULL)
+if (host)
+ {
+ log_write(0, LOG_MAIN, "H=%s [%s] TLS error on connection (%s): %s",
+ host->name, host->address, prefix, msg);
+ return FAIL;
+ }
+else
{
uschar *conn_info = smtp_get_connection_info();
if (Ustrncmp(conn_info, US"SMTP ", 5) == 0)
conn_info += 5;
+ /* I'd like to get separated H= here, but too hard for now */
log_write(0, LOG_MAIN, "TLS error on %s (%s): %s",
conn_info, prefix, msg);
return DEFER;
}
-else
- {
- log_write(0, LOG_MAIN, "TLS error on connection to %s [%s] (%s): %s",
- host->name, host->address, prefix, msg);
- return FAIL;
- }
}
X509 * cert = X509_STORE_CTX_get_current_cert(x509ctx);
int depth = X509_STORE_CTX_get_error_depth(x509ctx);
static uschar txt[256];
+#ifdef EXPERIMENTAL_EVENT
+uschar * ev;
+uschar * yield;
+#endif
X509_NAME_oneline(X509_get_subject_name(cert), CS txt, sizeof(txt));
ERR_clear_error();
}
#endif
-#ifdef EXPERIMENTAL_TPDA
- if (tlsp == &tls_out && client_static_cbinfo->event_action)
+#ifdef EXPERIMENTAL_EVENT
+ ev = tlsp == &tls_out ? client_static_cbinfo->event_action : event_action;
+ if (ev)
{
tlsp->peercert = X509_dup(cert);
- if (tpda_raise_event(client_static_cbinfo->event_action,
- US"tls:cert", string_sprintf("%d", depth)) == DEFER)
+ if ((yield = event_raise(ev, US"tls:cert", string_sprintf("%d", depth))))
{
log_write(0, LOG_MAIN, "SSL verify denied by event-action: "
- "depth=%d cert=%s", depth, txt);
+ "depth=%d cert=%s: %s", depth, txt, yield);
tlsp->certificate_verified = FALSE;
*calledp = TRUE;
return 0; /* reject */
&& ((verify_cert_hostnames = client_static_cbinfo->verify_cert_hostnames)))
/* client, wanting hostname check */
-# if OPENSSL_VERSION_NUMBER >= 0x010100000L || OPENSSL_VERSION_NUMBER >= 0x010002000L
+# if EXIM_HAVE_OPENSSL_CHECKHOST
# ifndef X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS
# define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 0
# endif
# endif
#endif /*EXPERIMENTAL_CERTNAMES*/
-#ifdef EXPERIMENTAL_TPDA
- if (tlsp == &tls_out)
- {
- if (tpda_raise_event(client_static_cbinfo->event_action,
- US"tls:cert", US"0") == DEFER)
+#ifdef EXPERIMENTAL_EVENT
+ ev = tlsp == &tls_out ? client_static_cbinfo->event_action : event_action;
+ if (ev)
+ if ((yield = event_raise(ev, US"tls:cert", US"0")))
{
log_write(0, LOG_MAIN, "SSL verify denied by event-action: "
- "depth=0 cert=%s", txt);
+ "depth=0 cert=%s: %s", txt, yield);
tlsp->certificate_verified = FALSE;
*calledp = TRUE;
return 0; /* reject */
}
- }
#endif
DEBUG(D_tls) debug_printf("SSL%s verify ok: depth=0 SN=%s\n",
{
X509 * cert = X509_STORE_CTX_get_current_cert(x509ctx);
static uschar txt[256];
-#ifdef EXPERIMENTAL_TPDA
+#ifdef EXPERIMENTAL_EVENT
int depth = X509_STORE_CTX_get_error_depth(x509ctx);
+uschar * yield;
#endif
X509_NAME_oneline(X509_get_subject_name(cert), CS txt, sizeof(txt));
tls_out.peerdn = txt;
tls_out.peercert = X509_dup(cert);
-#ifdef EXPERIMENTAL_TPDA
+#ifdef EXPERIMENTAL_EVENT
if (client_static_cbinfo->event_action)
{
- if (tpda_raise_event(client_static_cbinfo->event_action,
- US"tls:cert", string_sprintf("%d", depth)) == DEFER)
+ if ((yield = event_raise(client_static_cbinfo->event_action,
+ US"tls:cert", string_sprintf("%d", depth))))
{
log_write(0, LOG_MAIN, "DANE verify denied by event-action: "
- "depth=%d cert=%s", depth, txt);
+ "depth=%d cert=%s: %s", depth, txt, yield);
tls_out.certificate_verified = FALSE;
return 0; /* reject */
}
cbinfo->dhparam = dhparam;
cbinfo->server_cipher_list = NULL;
cbinfo->host = host;
-#ifdef EXPERIMENTAL_TPDA
+#ifdef EXPERIMENTAL_EVENT
cbinfo->event_action = NULL;
#endif
return tls_error(US"SSL_CTX_load_verify_locations", host, NULL);
/* Load the list of CAs for which we will accept certs, for sending
- to the client. XXX only for file source, not dir? */
+ to the client. This is only for the one-file tls_verify_certificates
+ variant.
+ If a list isn't loaded into the server, but
+ some verify locations are set, the server end appears to make
+ a wildcard reqest for client certs.
+ Meanwhile, the client library as deafult behaviour *ignores* the list
+ we send over the wire - see man SSL_CTX_set_client_cert_cb.
+ Because of this, and that the dir variant is likely only used for
+ the public-CA bundle (not for a private CA), not worth fixing.
+ */
if (file != NULL)
{
STACK_OF(X509_NAME) * names = SSL_load_client_CA_file(CS file);
}
#endif
-#ifdef EXPERIMENTAL_TPDA
-client_static_cbinfo->event_action = tb->tpda_event_action;
+#ifdef EXPERIMENTAL_EVENT
+client_static_cbinfo->event_action = tb->event_action;
#endif
/* There doesn't seem to be a built-in timeout on connection. */