From ef2e5890df09193717f9d345ffaaa406e2d8aae7 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Mon, 3 Jan 2022 16:08:37 +0000 Subject: [PATCH] TLS: event for daemon accept fail --- doc/doc-docbook/spec.xfpt | 9 +++++++ doc/doc-txt/NewStuff | 4 +++- src/src/smtp_in.c | 4 ++-- src/src/tls-gnu.c | 5 ++++ src/src/tls-openssl.c | 6 ++++- test/confs/5711 | 34 +++++++++++++++++++++++++++ test/confs/5721 | 34 +++++++++++++++++++++++++++ test/log/5711 | 14 +++++++++++ test/log/5721 | 13 ++++++++++ test/scripts/5710-GnuTLS-events/5711 | 24 +++++++++++++++++++ test/scripts/5720-OpenSSL-events/5721 | 23 ++++++++++++++++++ test/stdout/5711 | 18 ++++++++++++++ test/stdout/5721 | 18 ++++++++++++++ 13 files changed, 202 insertions(+), 4 deletions(-) create mode 100644 test/confs/5711 create mode 100644 test/confs/5721 create mode 100644 test/log/5711 create mode 100644 test/log/5721 create mode 100644 test/scripts/5710-GnuTLS-events/5711 create mode 100644 test/scripts/5720-OpenSSL-events/5721 create mode 100644 test/stdout/5711 create mode 100644 test/stdout/5721 diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index 00f0dac02..ed5b06a2d 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -30469,6 +30469,11 @@ accepted by an &%accept%& verb that has a &%message%& modifier, the contents of the message override the banner message that is otherwise specified by the &%smtp_banner%& option. +.new +For tls-on-connect connections, the ACL is run after the TLS connection +is accepted (however, &%host_reject_connection%& is tested before). +.wen + .section "The EHLO/HELO ACL" "SECID192" .cindex "EHLO" "ACL for" @@ -42604,6 +42609,7 @@ Events have names which correspond to the point in process at which they fire. The name is placed in the variable &$event_name$& and the event action expansion must check this, as it will be called for every possible event type. +.new The current list of events is: .display &`dane:fail after transport `& per connection @@ -42618,9 +42624,11 @@ The current list of events is: &`tcp:connect before transport `& per connection &`tcp:close after transport `& per connection &`tls:cert before both `& per certificate in verification chain +&`tls:fail:connect after main `& per connection &`smtp:connect after transport `& per connection &`smtp:ehlo after transport `& per connection .endd +.wen New event types may be added in future. The event name is a colon-separated list, defining the type of @@ -42646,6 +42654,7 @@ with the event type: &`msg:rcpt:host:defer `& error string &`msg:rcpt:defer `& error string &`tls:cert `& verification chain depth +&`tls:fail:connect `& error string &`smtp:connect `& smtp banner &`smtp:ehlo `& smtp ehlo response .endd diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index 27e80e025..77009ec33 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -13,7 +13,9 @@ Version 4.96 2. A variant of the "mask" expansion operator to give normalised IPv6. - 3. UTC output option for exim_dumpdb, exim_fixdb + 3. UTC output option for exim_dumpdb, exim_fixdb. + + 4. An event for failing TLS connects to the daemon. Version 4.95 diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 5de861216..a48fac605 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -2442,9 +2442,9 @@ return done - 2; /* Convert yield values */ #ifndef DISABLE_TLS static BOOL -smtp_log_tls_fail(uschar * errstr) +smtp_log_tls_fail(const uschar * errstr) { -uschar * conn_info = smtp_get_connection_info(); +const 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 */ diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index c5a9ad096..4f1039903 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -3043,6 +3043,9 @@ ALARM_CLR(0); if (rc != GNUTLS_E_SUCCESS) { + DEBUG(D_tls) debug_printf(" error %d from gnutls_handshake: %s\n", + rc, gnutls_strerror(rc)); + /* It seems that, except in the case of a timeout, we have to close the connection right here; otherwise if the other end is running OpenSSL it hangs until the server times out. */ @@ -3050,11 +3053,13 @@ if (rc != GNUTLS_E_SUCCESS) if (sigalrm_seen) { tls_error(US"gnutls_handshake", US"timed out", NULL, errstr); + (void) event_raise(event_action, US"tls:fail:connect", *errstr); gnutls_db_remove_session(state->session); } else { tls_error_gnu(state, US"gnutls_handshake", rc, errstr); + (void) event_raise(event_action, US"tls:fail:connect", *errstr); (void) gnutls_alert_send_appropriate(state->session, rc); gnutls_deinit(state->session); gnutls_certificate_free_credentials(state->lib_state.x509_cred); diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 627be433c..0c7772921 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -3311,6 +3311,7 @@ if (rc <= 0) case SSL_ERROR_ZERO_RETURN: DEBUG(D_tls) debug_printf("Got SSL_ERROR_ZERO_RETURN\n"); (void) tls_error(US"SSL_accept", NULL, sigalrm_seen ? US"timed out" : NULL, errstr); + (void) event_raise(event_action, US"tls:fail:connect", *errstr); if (SSL_get_shutdown(ssl) == SSL_RECEIVED_SHUTDOWN) SSL_shutdown(ssl); @@ -3328,8 +3329,9 @@ if (rc <= 0) || r == SSL_R_VERSION_TOO_LOW #endif || r == SSL_R_UNKNOWN_PROTOCOL || r == SSL_R_UNSUPPORTED_PROTOCOL) - s = string_sprintf("%s (%s)", s, SSL_get_version(ssl)); + s = string_sprintf("(%s)", SSL_get_version(ssl)); (void) tls_error(US"SSL_accept", NULL, sigalrm_seen ? US"timed out" : s, errstr); + (void) event_raise(event_action, US"tls:fail:connect", *errstr); return FAIL; } @@ -3340,6 +3342,7 @@ if (rc <= 0) if (!errno) { *errstr = US"SSL_accept: TCP connection closed by peer"; + (void) event_raise(event_action, US"tls:fail:connect", *errstr); return FAIL; } DEBUG(D_tls) debug_printf(" - syscall %s\n", strerror(errno)); @@ -3348,6 +3351,7 @@ if (rc <= 0) sigalrm_seen ? US"timed out" : ERR_peek_error() ? NULL : string_sprintf("ret %d", error), errstr); + (void) event_raise(event_action, US"tls:fail:connect", *errstr); return FAIL; } } diff --git a/test/confs/5711 b/test/confs/5711 new file mode 100644 index 000000000..d66935645 --- /dev/null +++ b/test/confs/5711 @@ -0,0 +1,34 @@ +# Exim test configuration 5711 + +.include DIR/aux-var/tls_conf_prefix + +primary_hostname = myhost.test.ex + +# ----- Main settings ----- + +acl_smtp_connect = accept logwrite = ACL conn +acl_smtp_quit = accept logwrite = ACL quit +acl_smtp_notquit = accept logwrite = ACL notquit + +tls_advertise_hosts = * +tls_certificate = DIR/aux-fixed/cert1 + +host_reject_connection = ${acl {hrc}} +event_action = ${acl {tls_fail}} + +# ------ ACL ------ + +begin acl + +hrc: + accept logwrite = eval host_reject_connection + # no mesage= hence host_reject_connection should be empty + +tls_fail: + warn logwrite = EV $event_name + accept condition = ${if eq {tls:fail:connect}{$event_name}} + logwrite = EVDATA: $event_data + accept + + +# End diff --git a/test/confs/5721 b/test/confs/5721 new file mode 100644 index 000000000..d156b1bf5 --- /dev/null +++ b/test/confs/5721 @@ -0,0 +1,34 @@ +# Exim test configuration 5721 + +.include DIR/aux-var/tls_conf_prefix + +primary_hostname = myhost.test.ex + +# ----- Main settings ----- + +acl_smtp_connect = accept logwrite = ACL conn +acl_smtp_quit = accept logwrite = ACL quit +acl_smtp_notquit = accept logwrite = ACL notquit + +tls_advertise_hosts = * +tls_certificate = DIR/aux-fixed/cert1 + +host_reject_connection = ${acl {hrc}} +event_action = ${acl {tls_fail}} + +# ------ ACL ------ + +begin acl + +hrc: + accept logwrite = eval host_reject_connection + # no mesage= hence host_reject_connection should be empty + +tls_fail: + warn logwrite = EV $event_name + accept condition = ${if eq {tls:fail:connect}{$event_name}} + logwrite = EVDATA: $event_data + accept + + +# End diff --git a/test/log/5711 b/test/log/5711 new file mode 100644 index 000000000..0616b56b2 --- /dev/null +++ b/test/log/5711 @@ -0,0 +1,14 @@ + +******** SERVER ******** +1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTPS on port PORT_D +1999-03-02 09:44:33 eval host_reject_connection +1999-03-02 09:44:33 ACL conn +1999-03-02 09:44:33 ACL quit +1999-03-02 09:44:33 eval host_reject_connection +1999-03-02 09:44:33 ACL conn +1999-03-02 09:44:33 TLS error on connection from [127.0.0.1] (recv): The TLS connection was non-properly terminated. +1999-03-02 09:44:33 ACL notquit +1999-03-02 09:44:33 eval host_reject_connection +1999-03-02 09:44:33 EV tls:fail:connect +1999-03-02 09:44:33 EVDATA: (gnutls_handshake): The TLS connection was non-properly terminated. +1999-03-02 09:44:33 TLS error on connection from [127.0.0.1] (tls lib accept fn): TCP connection closed by peer diff --git a/test/log/5721 b/test/log/5721 new file mode 100644 index 000000000..bf826cef4 --- /dev/null +++ b/test/log/5721 @@ -0,0 +1,13 @@ + +******** SERVER ******** +1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTPS on port PORT_D +1999-03-02 09:44:33 eval host_reject_connection +1999-03-02 09:44:33 ACL conn +1999-03-02 09:44:33 ACL quit +1999-03-02 09:44:33 eval host_reject_connection +1999-03-02 09:44:33 ACL conn +1999-03-02 09:44:33 ACL notquit +1999-03-02 09:44:33 eval host_reject_connection +1999-03-02 09:44:33 EV tls:fail:connect +1999-03-02 09:44:33 EVDATA: SSL_accept: TCP connection closed by peer +1999-03-02 09:44:33 TLS error on connection from [127.0.0.1] (tls lib accept fn): TCP connection closed by peer diff --git a/test/scripts/5710-GnuTLS-events/5711 b/test/scripts/5710-GnuTLS-events/5711 new file mode 100644 index 000000000..7c276229d --- /dev/null +++ b/test/scripts/5710-GnuTLS-events/5711 @@ -0,0 +1,24 @@ +# smtp-on-connect drop-before-tls-accept +# +exim -DSERVER=server -tls-on-connect -bd -oX PORT_D +**** +# +# Normal, full connect and quit +client-anytls -tls-on-connect 127.0.0.1 PORT_D +??? 220 +quit +??? 221 +**** +# +# full connect but no quit +client-anytls -tls-on-connect 127.0.0.1 PORT_D +??? 220 +**** +# +# client disconnects before server TLS accept completes +client 127.0.0.1 PORT_D ++++ 1 +**** +# +sleep 1 +killdaemon diff --git a/test/scripts/5720-OpenSSL-events/5721 b/test/scripts/5720-OpenSSL-events/5721 new file mode 100644 index 000000000..0f72c17d2 --- /dev/null +++ b/test/scripts/5720-OpenSSL-events/5721 @@ -0,0 +1,23 @@ +# smtp-on-connect drop-before-tls-accept +# +exim -DSERVER=server -tls-on-connect -bd -oX PORT_D +**** +# +# Normal, full connect and quit +client-anytls -tls-on-connect 127.0.0.1 PORT_D +??? 220 +quit +??? 221 +**** +# +# full connect but no quit +client-anytls -tls-on-connect 127.0.0.1 PORT_D +??? 220 +**** +# +# client disconnects before server TLS accept completes +client 127.0.0.1 PORT_D ++++ 1 +**** +# +killdaemon diff --git a/test/stdout/5711 b/test/stdout/5711 new file mode 100644 index 000000000..d3bf62e95 --- /dev/null +++ b/test/stdout/5711 @@ -0,0 +1,18 @@ +Connecting to 127.0.0.1 port 1225 ... connected +Attempting to start TLS +Succeeded in starting TLS +??? 220 +<<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +>>> quit +??? 221 +<<< 221 myhost.test.ex closing connection +End of script +Connecting to 127.0.0.1 port 1225 ... connected +Attempting to start TLS +Succeeded in starting TLS +??? 220 +<<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +End of script +Connecting to 127.0.0.1 port 1225 ... connected ++++ 1 +End of script diff --git a/test/stdout/5721 b/test/stdout/5721 new file mode 100644 index 000000000..d3bf62e95 --- /dev/null +++ b/test/stdout/5721 @@ -0,0 +1,18 @@ +Connecting to 127.0.0.1 port 1225 ... connected +Attempting to start TLS +Succeeded in starting TLS +??? 220 +<<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +>>> quit +??? 221 +<<< 221 myhost.test.ex closing connection +End of script +Connecting to 127.0.0.1 port 1225 ... connected +Attempting to start TLS +Succeeded in starting TLS +??? 220 +<<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +End of script +Connecting to 127.0.0.1 port 1225 ... connected ++++ 1 +End of script -- 2.30.2