TLS: event for daemon accept fail
authorJeremy Harris <jgh146exb@wizmail.org>
Mon, 3 Jan 2022 16:08:37 +0000 (16:08 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Mon, 3 Jan 2022 16:38:11 +0000 (16:38 +0000)
13 files changed:
doc/doc-docbook/spec.xfpt
doc/doc-txt/NewStuff
src/src/smtp_in.c
src/src/tls-gnu.c
src/src/tls-openssl.c
test/confs/5711 [new file with mode: 0644]
test/confs/5721 [new file with mode: 0644]
test/log/5711 [new file with mode: 0644]
test/log/5721 [new file with mode: 0644]
test/scripts/5710-GnuTLS-events/5711 [new file with mode: 0644]
test/scripts/5720-OpenSSL-events/5721 [new file with mode: 0644]
test/stdout/5711 [new file with mode: 0644]
test/stdout/5721 [new file with mode: 0644]

index 00f0dac02252784586e8a2e5d1aa20c50fab9c0e..ed5b06a2dc2bd3a28c9fe2b2b3aa18fe75f76733 100644 (file)
@@ -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
index 27e80e0254b325cc4af69b5d550d7f482b26f88d..77009ec33993e639705f42a32984fed7effcf74e 100644 (file)
@@ -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
index 5de8612169f85481f25cc5b5a85a39556a0edbbc..a48fac605c3f7b3d6eba45c608ea4d5e58df066d 100644 (file)
@@ -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 */
index c5a9ad0966f09dccf31f9ba2ad5f606c16059bda..4f10399030c193c2b547ddd8c69fb9dbf2d49573 100644 (file)
@@ -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);
index 627be433c613073148f8c5610b3e1b191e28cd51..0c77729218714481855f43e639f5cf2e747f92a6 100644 (file)
@@ -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 (file)
index 0000000..d669356
--- /dev/null
@@ -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 (file)
index 0000000..d156b1b
--- /dev/null
@@ -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 (file)
index 0000000..0616b56
--- /dev/null
@@ -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 (file)
index 0000000..bf826ce
--- /dev/null
@@ -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 (file)
index 0000000..7c27622
--- /dev/null
@@ -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 (file)
index 0000000..0f72c17
--- /dev/null
@@ -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 (file)
index 0000000..d3bf62e
--- /dev/null
@@ -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 (file)
index 0000000..d3bf62e
--- /dev/null
@@ -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