The equivalent check on the server for client certificates is not
implemented. At least one major email provider is using a client
certificate which fails this check. They do not retry either without
-hte client certificate or in clear.
+the client certificate or in clear.
It is possible to duplicate the effect of this checking by
creative use of Events.
/* Values for verify_requirement */
enum peer_verify_requirement
- { VERIFY_NONE, VERIFY_OPTIONAL, VERIFY_REQUIRED
-#ifdef EXPERIMENTAL_CERTNAMES
- ,VERIFY_WITHHOST
-#endif
- };
+ { VERIFY_NONE, VERIFY_OPTIONAL, VERIFY_REQUIRED };
/* This holds most state for server or client; with this, we can set up an
outbound TLS-enabled connection in an ACL callout, while not stomping all
else
{
#ifdef EXPERIMENTAL_CERTNAMES
- if (state->verify_requirement == VERIFY_WITHHOST)
+ if (state->exp_tls_verify_cert_hostnames)
{
int sep = 0;
uschar * list = state->exp_tls_verify_cert_hostnames;
{
DEBUG(D_tls)
debug_printf("TLS certificate verification failed: cert name mismatch\n");
- gnutls_alert_send(state->session,
- GNUTLS_AL_FATAL, GNUTLS_A_BAD_CERTIFICATE);
- return FALSE;
+ if (state->verify_requirement >= VERIFY_REQUIRED)
+ {
+ gnutls_alert_send(state->session,
+ GNUTLS_AL_FATAL, GNUTLS_A_BAD_CERTIFICATE);
+ return FALSE;
+ }
+ return TRUE;
}
}
#endif
+#ifdef EXPERIMENTAL_CERTNAMES
+static void
+tls_client_setup_hostname_checks(host_item * host, exim_gnutls_state_st * state,
+ smtp_transport_options_block * ob)
+{
+if (verify_check_this_host(&ob->tls_verify_cert_hostnames, NULL,
+ host->name, host->address, NULL) == OK)
+ {
+ state->exp_tls_verify_cert_hostnames = host->name;
+ DEBUG(D_tls)
+ debug_printf("TLS: server cert verification includes hostname: \"%s\".\n",
+ state->exp_tls_verify_cert_hostnames);
+ }
+}
+#endif
+
+
/*************************************************
* Start a TLS session in a client *
*************************************************/
set but both tls_verify_hosts and tls_try_verify_hosts are unset. Check only
the specified host patterns if one of them is defined */
-if (( state->exp_tls_verify_certificates
- && !ob->tls_verify_hosts
- && !ob->tls_try_verify_hosts
- )
- ||
- verify_check_host(&ob->tls_verify_hosts) == OK
+if ( ( state->exp_tls_verify_certificates
+ && !ob->tls_verify_hosts
+ && !ob->tls_try_verify_hosts
+ )
+ || verify_check_this_host(&ob->tls_verify_hosts, NULL,
+ host->name, host->address, NULL) == OK
)
{
#ifdef EXPERIMENTAL_CERTNAMES
- if (verify_check_host(&ob->tls_verify_cert_hostnames) == OK)
- {
- DEBUG(D_tls)
- debug_printf("TLS: server cert incl. hostname verification required.\n");
- state->verify_requirement = VERIFY_WITHHOST;
- state->exp_tls_verify_cert_hostnames = host->name;
- DEBUG(D_tls) debug_printf("Cert hostname to check: \"%s\"\n",
- state->exp_tls_verify_cert_hostnames);
- }
- else
+ tls_client_setup_hostname_checks(host, state, ob);
#endif
- {
- DEBUG(D_tls)
- debug_printf("TLS: server certificate verification required.\n");
- state->verify_requirement = VERIFY_REQUIRED;
- }
+ DEBUG(D_tls)
+ debug_printf("TLS: server certificate verification required.\n");
+ state->verify_requirement = VERIFY_REQUIRED;
gnutls_certificate_server_set_request(state->session, GNUTLS_CERT_REQUIRE);
}
-else if (verify_check_host(&ob->tls_try_verify_hosts) == OK)
+else if (verify_check_this_host(&ob->tls_try_verify_hosts, NULL,
+ host->name, host->address, NULL) == OK)
{
+#ifdef EXPERIMENTAL_CERTNAMES
+ tls_client_setup_hostname_checks(host, state, ob);
+#endif
DEBUG(D_tls)
debug_printf("TLS: server certificate verification optional.\n");
state->verify_requirement = VERIFY_OPTIONAL;
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 ((!ob->tls_verify_hosts && !ob->tls_try_verify_hosts) ||
- (verify_check_host(&ob->tls_verify_hosts) == OK))
- {
- if ((rc = setup_certs(ctx, ob->tls_verify_certificates,
- ob->tls_crl, host, FALSE, verify_callback_client)) != OK)
- return rc;
+if ( (!ob->tls_verify_hosts && !ob->tls_try_verify_hosts)
+ || (verify_check_this_host(&ob->tls_verify_hosts, NULL,
+ host->name, host->address, NULL) == OK)
+ )
client_verify_optional = FALSE;
+else if (verify_check_this_host(&ob->tls_try_verify_hosts, NULL,
+ host->name, host->address, NULL) == OK)
+ client_verify_optional = TRUE;
+else
+ return OK;
+
+if ((rc = setup_certs(ctx, ob->tls_verify_certificates,
+ ob->tls_crl, host, client_verify_optional, verify_callback_client)) != OK)
+ return rc;
#ifdef EXPERIMENTAL_CERTNAMES
- if (verify_check_host(&ob->tls_verify_cert_hostnames) == OK)
- {
- cbinfo->verify_cert_hostnames = host->name;
- DEBUG(D_tls) debug_printf("Cert hostname to check: \"%s\"\n",
- cbinfo->verify_cert_hostnames);
- }
-#endif
- }
-else if (verify_check_host(&ob->tls_try_verify_hosts) == OK)
+if (verify_check_this_host(&ob->tls_verify_cert_hostnames, NULL,
+ host->name, host->address, NULL) == OK)
{
- if ((rc = setup_certs(ctx, ob->tls_verify_certificates,
- ob->tls_crl, host, TRUE, verify_callback_client)) != OK)
- return rc;
- client_verify_optional = TRUE;
+ cbinfo->verify_cert_hostnames = host->name;
+ DEBUG(D_tls) debug_printf("Cert hostname to check: \"%s\"\n",
+ cbinfo->verify_cert_hostnames);
}
-
+#endif
return OK;
}
retry_use_local_part
transport = send_to_server_req_passname
+client_t:
+ driver = accept
+ local_parts = usert
+ retry_use_local_part
+ transport = send_to_server_req_failcarryon
# ----- Transports -----
tls_verify_cert_hostnames = *
tls_verify_hosts = *
+# this will fail to verify the cert name but carry on (try-verify mode)
+# fail because the cert is "server1.example.com" and the test system is something else
+send_to_server_req_failcarryon:
+ driver = smtp
+ allow_localhost
+ hosts = HOSTNAME
+ port = PORT_D
+ tls_certificate = CERT2
+ tls_privatekey = CERT2
+
+ tls_verify_certificates = CA1
+ tls_verify_cert_hostnames = *
+ tls_try_verify_hosts = *
+
# End
retry_use_local_part
transport = send_to_server_req_passname
+client_t:
+ driver = accept
+ local_parts = usert
+ retry_use_local_part
+ transport = send_to_server_req_failcarryon
+
# ----- Transports -----
tls_verify_cert_hostnames = *
tls_verify_hosts = *
+send_to_server_req_failcarryon:
+ driver = smtp
+ allow_localhost
+ hosts = HOSTNAME
+ port = PORT_D
+ tls_certificate = CERT2
+ tls_privatekey = CERT2
+
+ tls_verify_certificates = CA1
+ tls_verify_cert_hostnames = *
+ tls_try_verify_hosts = *
+
# End
1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
1999-03-02 09:44:33 Start queue run: pid=pppp -qf
1999-03-02 09:44:33 10HmaX-0005vi-00 H=the.local.host.name [ip4.ip4.ip4.ip4] TLS error on connection (certificate verification failed)
1999-03-02 09:44:33 10HmaX-0005vi-00 TLS session failure: delivering unencrypted to the.local.host.name [ip4.ip4.ip4.ip4] (not in hosts_require_tls)
-1999-03-02 09:44:33 10HmaX-0005vi-00 => userr@test.ex R=client_r T=send_to_server_req_failname H=the.local.host.name [ip4.ip4.ip4.ip4] C="250 OK id=10HmaZ-0005vi-00"
+1999-03-02 09:44:33 10HmaX-0005vi-00 => userr@test.ex R=client_r T=send_to_server_req_failname H=the.local.host.name [ip4.ip4.ip4.ip4] C="250 OK id=10HmbA-0005vi-00"
1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaY-0005vi-00 => users@test.ex R=client_s T=send_to_server_req_passname H=server1.example.com [ip4.ip4.ip4.ip4] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=yes DN="CN=server1.example.com" C="250 OK id=10HmbA-0005vi-00"
+1999-03-02 09:44:33 10HmaY-0005vi-00 => users@test.ex R=client_s T=send_to_server_req_passname H=server1.example.com [ip4.ip4.ip4.ip4] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=yes DN="CN=server1.example.com" C="250 OK id=10HmbB-0005vi-00"
1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
+1999-03-02 09:44:33 10HmaZ-0005vi-00 => usert@test.ex R=client_t T=send_to_server_req_failcarryon H=the.local.host.name [ip4.ip4.ip4.ip4] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no DN="CN=server1.example.com" C="250 OK id=10HmbC-0005vi-00"
+1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
1999-03-02 09:44:33 End queue run: pid=pppp -qf
******** SERVER ********
1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
1999-03-02 09:44:33 TLS error on connection from the.local.host.name [ip4.ip4.ip4.ip4] (recv): A TLS fatal alert has been received.: Certificate is bad
1999-03-02 09:44:33 TLS error on connection from the.local.host.name [ip4.ip4.ip4.ip4] (send): The specified session has been invalidated for some reason.
-1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtp S=sss id=E10HmaX-0005vi-00@myhost.test.ex
-1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=yes DN="C=UK,O=The Exim Maintainers,OU=Test Suite,CN=Phil Pennock" S=sss id=E10HmaY-0005vi-00@myhost.test.ex
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtp S=sss id=E10HmaX-0005vi-00@myhost.test.ex
+1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=yes DN="C=UK,O=The Exim Maintainers,OU=Test Suite,CN=Phil Pennock" S=sss id=E10HmaY-0005vi-00@myhost.test.ex
+1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=yes DN="C=UK,O=The Exim Maintainers,OU=Test Suite,CN=Phil Pennock" S=sss id=E10HmaZ-0005vi-00@myhost.test.ex
1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
1999-03-02 09:44:33 Start queue run: pid=pppp -qf
1999-03-02 09:44:33 10HmaX-0005vi-00 SSL verify error: depth=0 error=unable to get local issuer certificate cert=/CN=server1.example.com
1999-03-02 09:44:33 10HmaX-0005vi-00 H=the.local.host.name [ip4.ip4.ip4.ip4] TLS error on connection (SSL_connect): error: <<detail omitted>>
1999-03-02 09:44:33 10HmaX-0005vi-00 TLS session failure: delivering unencrypted to the.local.host.name [ip4.ip4.ip4.ip4] (not in hosts_require_tls)
-1999-03-02 09:44:33 10HmaX-0005vi-00 => userq@test.ex R=client_q T=send_to_server_req_fail H=the.local.host.name [ip4.ip4.ip4.ip4] C="250 OK id=10HmbA-0005vi-00"
+1999-03-02 09:44:33 10HmaX-0005vi-00 => userq@test.ex R=client_q T=send_to_server_req_fail H=the.local.host.name [ip4.ip4.ip4.ip4] C="250 OK id=10HmbB-0005vi-00"
1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
1999-03-02 09:44:33 10HmaY-0005vi-00 SSL verify error: certificate name mismatch: "/CN=server1.example.com"
1999-03-02 09:44:33 10HmaY-0005vi-00 H=the.local.host.name [ip4.ip4.ip4.ip4] TLS error on connection (SSL_connect): error: <<detail omitted>>
1999-03-02 09:44:33 10HmaY-0005vi-00 TLS session failure: delivering unencrypted to the.local.host.name [ip4.ip4.ip4.ip4] (not in hosts_require_tls)
-1999-03-02 09:44:33 10HmaY-0005vi-00 => userr@test.ex R=client_r T=send_to_server_req_failname H=the.local.host.name [ip4.ip4.ip4.ip4] C="250 OK id=10HmbB-0005vi-00"
+1999-03-02 09:44:33 10HmaY-0005vi-00 => userr@test.ex R=client_r T=send_to_server_req_failname H=the.local.host.name [ip4.ip4.ip4.ip4] C="250 OK id=10HmbC-0005vi-00"
1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaZ-0005vi-00 => users@test.ex R=client_s T=send_to_server_req_passname H=server1.example.com [ip4.ip4.ip4.ip4] X=TLSv1:AES256-SHA:256 CV=yes DN="/CN=server1.example.com" C="250 OK id=10HmbC-0005vi-00"
+1999-03-02 09:44:33 10HmaZ-0005vi-00 => users@test.ex R=client_s T=send_to_server_req_passname H=server1.example.com [ip4.ip4.ip4.ip4] X=TLSv1:AES256-SHA:256 CV=yes DN="/CN=server1.example.com" C="250 OK id=10HmbD-0005vi-00"
1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbA-0005vi-00 SSL verify error: certificate name mismatch: "/CN=server1.example.com"
+
+1999-03-02 09:44:33 10HmbA-0005vi-00 => usert@test.ex R=client_t T=send_to_server_req_failcarryon H=the.local.host.name [ip4.ip4.ip4.ip4] X=TLSv1:AES256-SHA:256 CV=no DN="/CN=server1.example.com" C="250 OK id=10HmbE-0005vi-00"
+1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
1999-03-02 09:44:33 End queue run: pid=pppp -qf
******** SERVER ********
1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
1999-03-02 09:44:33 TLS error on connection from the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] (SSL_accept): error: <<detail omitted>>
1999-03-02 09:44:33 TLS client disconnected cleanly (rejected our certificate?)
-1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtp S=sss id=E10HmaX-0005vi-00@myhost.test.ex
+1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtp S=sss id=E10HmaX-0005vi-00@myhost.test.ex
1999-03-02 09:44:33 TLS error on connection from the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] (SSL_accept): error: <<detail omitted>>
1999-03-02 09:44:33 TLS client disconnected cleanly (rejected our certificate?)
-1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtp S=sss id=E10HmaY-0005vi-00@myhost.test.ex
-1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLSv1:AES256-SHA:256 CV=yes DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" S=sss id=E10HmaZ-0005vi-00@myhost.test.ex
+1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtp S=sss id=E10HmaY-0005vi-00@myhost.test.ex
+1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLSv1:AES256-SHA:256 CV=yes DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" S=sss id=E10HmaZ-0005vi-00@myhost.test.ex
+1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLSv1:AES256-SHA:256 CV=yes DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" S=sss id=E10HmbA-0005vi-00@myhost.test.ex
exim users@test.ex
Testing
****
+# this will fail to verify the cert name but carry on (try-verify mode)
+exim usert@test.ex
+Testing
+****
exim -qf
****
killdaemon
exim users@test.ex
Testing
****
+# this will fail to verify the cert name but carry on (try-verify mode)
+exim usert@test.ex
+Testing
+****
exim -qf
****
killdaemon
127.0.0.1 in hosts_verify_avoid_tls? no (end of list)
SMTP>> STARTTLS
SMTP<< 220 TLS go ahead
- in tls_verify_hosts? no (option unset)
- in tls_try_verify_hosts? no (option unset)
+127.0.0.1 in tls_verify_hosts? no (option unset)
+127.0.0.1 in tls_try_verify_hosts? no (option unset)
SMTP>> EHLO myhost.test.ex
SMTP<< 250-myhost.test.ex Hello the.local.host.name [ip4.ip4.ip4.ip4]
250-SIZE 52428800