diff options
-rw-r--r-- | src/src/functions.h | 2 | ||||
-rw-r--r-- | src/src/tls-gnu.c | 5 | ||||
-rw-r--r-- | src/src/tls-openssl.c | 23 | ||||
-rw-r--r-- | src/src/transports/smtp.c | 14 | ||||
-rw-r--r-- | src/src/transports/smtp.h | 2 | ||||
-rw-r--r-- | src/src/verify.c | 3 |
6 files changed, 40 insertions, 9 deletions
diff --git a/src/src/functions.h b/src/src/functions.h index 9d933fea7..32bd0bc07 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -30,7 +30,7 @@ extern int tls_client_start(int, host_item *, address_item *, # ifdef EXPERIMENTAL_OCSP uschar *, # endif - int, int); + int, int, uschar *, uschar *); extern void tls_close(BOOL, BOOL); extern int tls_feof(void); extern int tls_ferror(void); diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index 4f1169aa4..280744ec0 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -1563,6 +1563,8 @@ Arguments: require_ciphers list of allowed ciphers or NULL dh_min_bits minimum number of bits acceptable in server's DH prime timeout startup timeout + verify_hosts mandatory client verification + try_verify_hosts optional client verification Returns: OK/DEFER/FAIL (because using common functions), but for a client, DEFER and FAIL have the same meaning @@ -1577,7 +1579,8 @@ tls_client_start(int fd, host_item *host, #ifdef EXPERIMENTAL_OCSP uschar *require_ocsp ARG_UNUSED, #endif - int dh_min_bits, int timeout) + int dh_min_bits, int timeout, + uschar *verify_hosts, uschar *try_verify_hosts) { int rc; const char *error; diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 2b8d798c9..a9adb6134 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -1504,6 +1504,8 @@ Argument: dh_min_bits minimum number of bits acceptable in server's DH prime (unused in OpenSSL) timeout startup timeout + verify_hosts mandatory client verification + try_verify_hosts optional client verification Returns: OK on success FAIL otherwise - note that tls_error() will not give DEFER @@ -1518,7 +1520,8 @@ tls_client_start(int fd, host_item *host, address_item *addr, #ifdef EXPERIMENTAL_OCSP uschar *hosts_require_ocsp, #endif - int dh_min_bits ARG_UNUSED, int timeout) + int dh_min_bits ARG_UNUSED, int timeout, + uschar *verify_hosts, uschar *try_verify_hosts) { static uschar txt[256]; uschar *expciphers; @@ -1556,8 +1559,22 @@ if (expciphers != NULL) return tls_error(US"SSL_CTX_set_cipher_list", host, NULL); } -rc = setup_certs(client_ctx, verify_certs, crl, host, FALSE, verify_callback_client); -if (rc != OK) return rc; +/* stick to the old behaviour for compatibility if tls_verify_certificates is + set but both tls_verify_hosts and tls_try_verify_hosts is not set. Check only + the specified host patterns if one of them is defined */ +if (((verify_hosts == NULL) && (try_verify_hosts == NULL)) || + (verify_check_host(&verify_hosts) == OK)) + { + rc = setup_certs(client_ctx, verify_certs, crl, host, FALSE, verify_callback_client); + if (rc != OK) return rc; + client_verify_optional = FALSE; + } +else if (verify_check_host(&try_verify_hosts) == OK) + { + rc = setup_certs(client_ctx, verify_certs, crl, host, TRUE, verify_callback_client); + if (rc != OK) return rc; + client_verify_optional = TRUE; + } if ((client_ssl = SSL_new(client_ctx)) == NULL) return tls_error(US"SSL_new", host, NULL); SSL_set_session_id_context(client_ssl, sid_ctx, Ustrlen(sid_ctx)); diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index a77e472d6..938844799 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -153,8 +153,12 @@ optionlist smtp_transport_options[] = { (void *)offsetof(smtp_transport_options_block, tls_sni) }, { "tls_tempfail_tryclear", opt_bool, (void *)offsetof(smtp_transport_options_block, tls_tempfail_tryclear) }, + { "tls_try_verify_hosts", opt_stringptr, + (void *)offsetof(smtp_transport_options_block, tls_try_verify_hosts) }, { "tls_verify_certificates", opt_stringptr, - (void *)offsetof(smtp_transport_options_block, tls_verify_certificates) } + (void *)offsetof(smtp_transport_options_block, tls_verify_certificates) }, + { "tls_verify_hosts", opt_stringptr, + (void *)offsetof(smtp_transport_options_block, tls_verify_hosts) } #endif #ifdef EXPERIMENTAL_TPDA ,{ "tpda_host_defer_action", opt_stringptr, @@ -227,7 +231,9 @@ smtp_transport_options_block smtp_transport_option_defaults = { NULL, /* tls_verify_certificates */ EXIM_CLIENT_DH_DEFAULT_MIN_BITS, /* tls_dh_min_bits */ - TRUE /* tls_tempfail_tryclear */ + TRUE, /* tls_tempfail_tryclear */ + NULL, /* tls_verify_hosts */ + NULL /* tls_try_verify_hosts */ #endif #ifndef DISABLE_DKIM ,NULL, /* dkim_canon */ @@ -1446,7 +1452,9 @@ if (tls_offered && !suppress_tls && ob->hosts_require_ocsp, #endif ob->tls_dh_min_bits, - ob->command_timeout); + ob->command_timeout, + ob->tls_verify_hosts, + ob->tls_try_verify_hosts); /* TLS negotiation failed; give an error. From outside, this function may be called again to try in clear on a new connection, if the options permit diff --git a/src/src/transports/smtp.h b/src/src/transports/smtp.h index 6c22e4b96..fc4e014c1 100644 --- a/src/src/transports/smtp.h +++ b/src/src/transports/smtp.h @@ -64,6 +64,8 @@ typedef struct { uschar *tls_verify_certificates; int tls_dh_min_bits; BOOL tls_tempfail_tryclear; + uschar *tls_verify_hosts; + uschar *tls_try_verify_hosts; #endif #ifndef DISABLE_DKIM uschar *dkim_domain; diff --git a/src/src/verify.c b/src/src/verify.c index 711b3af5a..c83748a12 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -641,7 +641,8 @@ else #ifdef EXPERIMENTAL_OCSP ob->hosts_require_ocsp, #endif - ob->tls_dh_min_bits, callout); + ob->tls_dh_min_bits, callout, + ob->tls_verify_hosts, ob->tls_try_verify_hosts); /* TLS negotiation failed; give an error. Try in clear on a new connection, if the options permit it for this host. */ |