From 52f93eed9f96e1630b181857289d5f2423f55cd7 Mon Sep 17 00:00:00 2001 From: Wolfgang Breyha Date: Tue, 18 Mar 2014 16:03:43 +0000 Subject: [PATCH] Add tls_verify_hosts and tls_try_verify_hosts to smtp transport, GnuTLS. --- src/src/tls-gnu.c | 23 ++++++++---- test/confs/2012 | 67 ++++++++++++++++++++++++++++++++--- test/confs/2112 | 2 +- test/log/2012 | 24 +++++++++++-- test/scripts/2000-GnuTLS/2012 | 9 +++++ 5 files changed, 110 insertions(+), 15 deletions(-) diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index 280744ec0..5600d6bb8 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -1604,18 +1604,27 @@ DEBUG(D_tls) debug_printf("Setting D-H prime minimum acceptable bits to %d\n", dh_min_bits); gnutls_dh_set_prime_bits(state->session, dh_min_bits); -if (state->exp_tls_verify_certificates == NULL) +/* 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 (((state->exp_tls_verify_certificates != NULL) && (verify_hosts == NULL) && (try_verify_hosts == NULL)) || + (verify_check_host(&verify_hosts) == OK)) { - DEBUG(D_tls) debug_printf("TLS: server certificate verification not required\n"); - state->verify_requirement = VERIFY_NONE; - /* we still ask for it, to log it, etc */ + 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(&try_verify_hosts) == OK) + { + DEBUG(D_tls) debug_printf("TLS: server certificate verification optional.\n"); + state->verify_requirement = VERIFY_OPTIONAL; gnutls_certificate_server_set_request(state->session, GNUTLS_CERT_REQUEST); } else { - 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); + DEBUG(D_tls) debug_printf("TLS: server certificate verification not required.\n"); + state->verify_requirement = VERIFY_NONE; + gnutls_certificate_server_set_request(state->session, GNUTLS_CERT_IGNORE); } gnutls_transport_set_ptr(state->session, (gnutls_transport_ptr)fd); diff --git a/test/confs/2012 b/test/confs/2012 index 75fa54a1c..263034435 100644 --- a/test/confs/2012 +++ b/test/confs/2012 @@ -1,4 +1,5 @@ # Exim test configuration 2012 +# TLS client: verify certificate from server - fails SERVER= @@ -35,18 +36,53 @@ tls_verify_certificates = ${if eq {SERVER}{server}{DIR/aux-fixed/cert2}fail} begin routers -client: +server_dump: + driver = redirect + condition = ${if eq {SERVER}{server}{yes}{no}} + data = :blackhole: + +client_x: + driver = accept + local_parts = userx + retry_use_local_part + transport = send_to_server_failcert + errors_to = "" + +client_y: + driver = accept + local_parts = usery + retry_use_local_part + transport = send_to_server_retry + +client_z: driver = accept - condition = ${if eq {SERVER}{server}{no}{yes}} + local_parts = userz retry_use_local_part - transport = send_to_server + transport = send_to_server_crypt + +client_q: + driver = accept + local_parts = userq + retry_use_local_part + transport = send_to_server_req_fail # ----- Transports ----- begin transports -send_to_server: +# this will fail to verify the cert at HOSTIPV4 so fail the crypt requirement +send_to_server_failcert: + driver = smtp + allow_localhost + hosts = HOSTIPV4 + hosts_require_tls = HOSTIPV4 + port = PORT_D + tls_certificate = DIR/aux-fixed/cert2 + tls_verify_certificates = DIR/aux-fixed/cert2 + +# this will fail to verify the cert at HOSTIPV4 so fail the crypt, then retry on 127.1; ok +send_to_server_retry: driver = smtp allow_localhost hosts = HOSTIPV4 : 127.0.0.1 @@ -54,6 +90,27 @@ send_to_server: port = PORT_D tls_certificate = DIR/aux-fixed/cert2 tls_verify_certificates = \ - ${if eq{$host_address}{127.0.0.1}{DIR/aux-fixed/cert1}{DIR/aux-fixed/cert2}} + ${if eq{$host_address}{127.0.0.1}{DIR/aux-fixed/cert1}{DIR/aux-fixed/cert2}} + +# this will fail to verify the cert at HOSTIPV4 but continue unverified though crypted +send_to_server_crypt: + driver = smtp + allow_localhost + hosts = HOSTIPV4 + hosts_require_tls = HOSTIPV4 + port = PORT_D + tls_certificate = DIR/aux-fixed/cert2 + tls_verify_certificates = DIR/aux-fixed/cert2 + tls_try_verify_hosts = * + +# this will fail to verify the cert at HOSTIPV4 and fallback to unencrypted +send_to_server_req_fail: + driver = smtp + allow_localhost + hosts = HOSTIPV4 + port = PORT_D + tls_certificate = DIR/aux-fixed/cert2 + tls_verify_certificates = DIR/aux-fixed/cert2 + tls_verify_hosts = * # End diff --git a/test/confs/2112 b/test/confs/2112 index 242d2d67c..deb02944d 100644 --- a/test/confs/2112 +++ b/test/confs/2112 @@ -92,7 +92,7 @@ send_to_server_retry: tls_verify_certificates = \ ${if eq{$host_address}{127.0.0.1}{DIR/aux-fixed/cert1}{DIR/aux-fixed/cert2}} -# this will fail to verify the cert but continue unverified though cypted +# this will fail to verify the cert but continue unverified though crypted send_to_server_crypt: driver = smtp allow_localhost diff --git a/test/log/2012 b/test/log/2012 index b4bceb688..1474a0bb2 100644 --- a/test/log/2012 +++ b/test/log/2012 @@ -1,12 +1,32 @@ 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 TLS error on connection to ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] (certificate verification failed): invalid -1999-03-02 09:44:33 10HmaX-0005vi-00 => userx@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=yes DN="C=UK,O=The Exim Maintainers,OU=Test Suite,CN=Phil Pennock" C="250 OK id=10HmaY-0005vi-00" +1999-03-02 09:44:33 10HmaX-0005vi-00 == userx@test.ex R=client_x T=send_to_server_failcert defer (-37): failure while setting up TLS session +1999-03-02 09:44:33 10HmaX-0005vi-00 ** userx@test.ex: retry timeout exceeded +1999-03-02 09:44:33 10HmaX-0005vi-00 userx@test.ex: error ignored 1999-03-02 09:44:33 10HmaX-0005vi-00 Completed +1999-03-02 09:44:33 10HmaY-0005vi-00 TLS error on connection to ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] (certificate verification failed): invalid +1999-03-02 09:44:33 10HmaY-0005vi-00 => usery@test.ex R=client_y T=send_to_server_retry H=127.0.0.1 [127.0.0.1] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=yes DN="C=UK,O=The Exim Maintainers,OU=Test Suite,CN=Phil Pennock" 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 => userz@test.ex R=client_z T=send_to_server_crypt H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no DN="C=UK,O=The Exim Maintainers,OU=Test Suite,CN=Phil Pennock" C="250 OK id=10HmbC-0005vi-00" +1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed +1999-03-02 09:44:33 10HmbA-0005vi-00 TLS error on connection to ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] (certificate verification failed): invalid +1999-03-02 09:44:33 10HmbA-0005vi-00 TLS session failure: delivering unencrypted to ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] (not in hosts_require_tls) +1999-03-02 09:44:33 10HmbA-0005vi-00 => userq@test.ex R=client_q T=send_to_server_req_fail H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] C="250 OK id=10HmbD-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 [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 10HmaY-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] 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=E10HmaX-0005vi-00@myhost.test.ex +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 10HmbB-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] 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 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 10HmbD-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtp S=sss id=E10HmbA-0005vi-00@myhost.test.ex diff --git a/test/scripts/2000-GnuTLS/2012 b/test/scripts/2000-GnuTLS/2012 index e86bf1707..3b25ba206 100644 --- a/test/scripts/2000-GnuTLS/2012 +++ b/test/scripts/2000-GnuTLS/2012 @@ -5,6 +5,15 @@ exim -DSERVER=server -bd -oX PORT_D exim userx@test.ex Testing **** +exim usery@test.ex +Testing +**** +exim userz@test.ex +Testing +**** +exim userq@test.ex +Testing +**** exim -qf **** killdaemon -- 2.30.2