[exim-cvs] Move connect ACL before TLS-on-connect

Top Page
Delete this message
Reply to this message
Author: Exim Git Commits Mailing List
Date:  
To: exim-cvs
Subject: [exim-cvs] Move connect ACL before TLS-on-connect
Gitweb: https://git.exim.org/exim.git/commitdiff/4243a209fd9499f30bebd58ceaa2d0d9845407ae
Commit:     4243a209fd9499f30bebd58ceaa2d0d9845407ae
Parent:     f31b1cd64dfcc7e6a8860ee418543949effd517e
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Sat Dec 10 10:47:05 2022 +0000
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Sat Dec 10 15:53:02 2022 +0000


    Move connect ACL before TLS-on-connect
---
 doc/doc-docbook/spec.xfpt             | 15 ++++++----
 doc/doc-txt/ChangeLog                 |  9 ++++++
 src/src/EDITME                        |  2 +-
 src/src/smtp_in.c                     | 52 +++++++++++++++++++++++++----------
 test/confs/5711                       | 17 ++++++++++--
 test/confs/5721                       | 17 ++++++++++--
 test/log/5711                         | 30 ++++++++++++--------
 test/log/5721                         | 28 +++++++++++--------
 test/rejectlog/5711                   |  4 +++
 test/rejectlog/5721                   |  4 +++
 test/scripts/5710-GnuTLS-events/5711  | 12 +++++++-
 test/scripts/5720-OpenSSL-events/5721 | 12 +++++++-
 test/stdout/5711                      | 12 ++++++++
 test/stdout/5721                      | 12 ++++++++
 14 files changed, 177 insertions(+), 49 deletions(-)


diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index 9d3813e5a..1b3c2b454 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -16193,11 +16193,13 @@ case. That is why the default tries a DNS lookup first.
.cindex "host" "rejecting connections from"
If this option is set, incoming SMTP calls from the hosts listed are rejected
as soon as the connection is made.
-This option is mostly obsolete, retained for backward compatibility because
+This option is obsolete, and retained only for backward compatibility, because
nowadays the ACL specified by &%acl_smtp_connect%& can also reject incoming
-connections immediately
+connections immediately.
+
.new
-(except for tls-on-connect connections).
+If the connection is on a TLS-on-connect port then the TCP connection is
+just dropped. Otherwise, an SMTP error is sent first.
.wen

The ability to give an immediate rejection (either by this option or using an
@@ -30487,8 +30489,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.

-For tls-on-connect connections, the ACL is run after the TLS connection
-is accepted (however, &%host_reject_connection%& is tested before).
+.new
+For tls-on-connect connections, the ACL is run before the TLS connection
+is accepted; if the ACL does not accept then the TCP connection is dropped without
+any TLS startup attempt and without any SMTP response being transmitted.
+.wen


 .subsection "The EHLO/HELO ACL" SECID192
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 5ac91dc99..f8ab5da0c 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -66,6 +66,15 @@ JH/15 Fix argument parsing for ${run } expansion. Previously, when an argument
       included a close-brace character (eg. it itself used an expansion) an
       error occurred.


+JH/16 Move running the smtp connect ACL to before, for TLS-on-connect ports,
+      starting TLS.  Previously it was after, meaning that attackers on such
+      ports had to be screened using the host_reject_connection main config
+      option. The new sequence aligns better with the STARTTLS behaviour, and
+      permits defences against crypto-processing load attacks, even though it
+      is strictly an incompatible change.
+      Also, avoid sending any SMTP fail response for either the connect ACL
+      or host_reject_connection, for TLS-on-connect ports.
+


Exim version 4.96
-----------------
diff --git a/src/src/EDITME b/src/src/EDITME
index 625df18f5..4fcaeda5b 100644
--- a/src/src/EDITME
+++ b/src/src/EDITME
@@ -401,7 +401,7 @@ TRANSPORT_SMTP=yes
# For Redis you need to have hiredis installed on your system
# (https://github.com/redis/hiredis).
# Depending on where it is installed you may have to edit the CFLAGS
-# (often += -I/usr/local/include) and LDFLAGS (-lhiredis) lines.
+# (often += -I/usr/local/include) and LOOKUP_LIBS (-lhiredis) lines.

# If your system has pkg-config then the _INCLUDE/_LIBS setting can be
# handled for you automatically by also defining the _PC variable to reference
diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c
index 9b60702c1..b161f362d 100644
--- a/src/src/smtp_in.c
+++ b/src/src/smtp_in.c
@@ -2505,6 +2505,22 @@ else DEBUG(D_receive)
#endif


+static void
+log_connect_tls_drop(const uschar * what, const uschar * log_msg)
+{
+gstring * g = s_tlslog(NULL);
+uschar * tls = string_from_gstring(g);
+
+log_write(L_connection_reject,
+  log_reject_target, "%s%s%s dropped by %s%s%s",
+  LOGGING(dnssec) && sender_host_dnssec ? US" DS" : US"",
+  host_and_ident(TRUE),
+  tls ? tls : US"",
+  what,
+  log_msg ? US": " : US"", log_msg);
+}
+
+
 /*************************************************
 *          Start an SMTP session                 *
 *************************************************/
@@ -2857,7 +2873,10 @@ if (!f.sender_host_unknown)
     {
     log_write(L_connection_reject, LOG_MAIN|LOG_REJECT, "refused connection "
       "from %s (host_reject_connection)", host_and_ident(FALSE));
-    smtp_printf("554 SMTP service not available\r\n", FALSE);
+#ifndef DISABLE_TLS
+    if (!tls_in.on_connect)
+#endif
+      smtp_printf("554 SMTP service not available\r\n", FALSE);
     return FALSE;
     }


@@ -2983,18 +3002,6 @@ if (check_proxy_protocol_host())
setup_proxy_protocol_host();
#endif

-/* Start up TLS if tls_on_connect is set. This is for supporting the legacy
-smtps port for use with older style SSL MTAs. */
-
-#ifndef DISABLE_TLS
-if (tls_in.on_connect)
-  {
-  if (tls_server_start(&user_msg) != OK)
-    return smtp_log_tls_fail(user_msg);
-  cmd_list[CMD_LIST_TLS_AUTH].is_mail_cmd = TRUE;
-  }
-#endif
-
 /* Run the connect ACL if it exists */


 user_msg = NULL;
@@ -3004,11 +3011,28 @@ if (acl_smtp_connect)
   if ((rc = acl_check(ACL_WHERE_CONNECT, NULL, acl_smtp_connect, &user_msg,
               &log_msg)) != OK)
     {
-    (void) smtp_handle_acl_fail(ACL_WHERE_CONNECT, rc, user_msg, log_msg);
+#ifndef DISABLE_TLS
+    if (tls_in.on_connect)
+      log_connect_tls_drop(US"'connect' ACL", log_msg);
+    else
+#endif
+      (void) smtp_handle_acl_fail(ACL_WHERE_CONNECT, rc, user_msg, log_msg);
     return FALSE;
     }
   }


+/* Start up TLS if tls_on_connect is set. This is for supporting the legacy
+smtps port for use with older style SSL MTAs. */
+
+#ifndef DISABLE_TLS
+if (tls_in.on_connect)
+  {
+  if (tls_server_start(&user_msg) != OK)
+    return smtp_log_tls_fail(user_msg);
+  cmd_list[CMD_LIST_TLS_AUTH].is_mail_cmd = TRUE;
+  }
+#endif
+
 /* Output the initial message for a two-way SMTP connection. It may contain
 newlines, which then cause a multi-line response to be given. */


diff --git a/test/confs/5711 b/test/confs/5711
index d66935645..57a9fef08 100644
--- a/test/confs/5711
+++ b/test/confs/5711
@@ -6,7 +6,7 @@ primary_hostname = myhost.test.ex

# ----- Main settings -----

-acl_smtp_connect = accept logwrite = ACL conn
+acl_smtp_connect = check_conn
 acl_smtp_quit =    accept logwrite = ACL quit
 acl_smtp_notquit = accept logwrite = ACL notquit


@@ -16,13 +16,26 @@ tls_certificate = DIR/aux-fixed/cert1
host_reject_connection = ${acl {hrc}}
event_action = ${acl {tls_fail}}

+log_selector = +pid
+
# ------ ACL ------

begin acl

 hrc:
-  accept    logwrite = eval host_reject_connection
+  warn        logwrite = eval host_reject_connection
+  accept    condition = ${if eq {$received_port}{PORT_D}}
         # no mesage= hence host_reject_connection should be empty
+  deny        condition = ${if eq {$received_port}{PORT_D2}}
+        message = *
+                # PORT_D2 gets a host_reject_connection
+
+check_conn:
+  warn        logwrite =    ACL conn
+  deny        condition =    ${if eq {$received_port}{PORT_D3}}
+        log_message =    we dislike you
+        # PORT_D3 gets a conn ACL fail
+  accept


 tls_fail:
   warn        logwrite =  EV $event_name
diff --git a/test/confs/5721 b/test/confs/5721
index d156b1bf5..84c7785d9 100644
--- a/test/confs/5721
+++ b/test/confs/5721
@@ -6,7 +6,7 @@ primary_hostname = myhost.test.ex


# ----- Main settings -----

-acl_smtp_connect = accept logwrite = ACL conn
+acl_smtp_connect = check_conn
 acl_smtp_quit =    accept logwrite = ACL quit
 acl_smtp_notquit = accept logwrite = ACL notquit


@@ -16,13 +16,26 @@ tls_certificate = DIR/aux-fixed/cert1
host_reject_connection = ${acl {hrc}}
event_action = ${acl {tls_fail}}

+log_selector = +pid
+
# ------ ACL ------

begin acl

 hrc:
-  accept    logwrite = eval host_reject_connection
+  warn        logwrite = eval host_reject_connection
+  accept    condition = ${if eq {$received_port}{PORT_D}}
         # no mesage= hence host_reject_connection should be empty
+  deny        condition = ${if eq {$received_port}{PORT_D2}}
+        message = *
+                # PORT_D2 gets a host_reject_connection
+
+check_conn:
+  warn        logwrite =    ACL conn
+  deny        condition =    ${if eq {$received_port}{PORT_D3}}
+        log_message =    we dislike you
+        # PORT_D3 gets a conn ACL fail
+  accept


 tls_fail:
   warn        logwrite =  EV $event_name
diff --git a/test/log/5711 b/test/log/5711
index 32556a618..baf38b97d 100644
--- a/test/log/5711
+++ b/test/log/5711
@@ -1,14 +1,20 @@


******** SERVER ********
-1999-03-02 09:44:33 exim x.yz daemon started: pid=p1234, 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
+1999-03-02 09:44:33 [1237] exim x.yz daemon started: pid=p1236, no queue runs, listening for SMTPS on port PORT_D port PORT_D2 port PORT_D3
+1999-03-02 09:44:33 [1238] eval host_reject_connection
+1999-03-02 09:44:33 [1238] ACL conn
+1999-03-02 09:44:33 [1238] ACL quit
+1999-03-02 09:44:33 [1239] eval host_reject_connection
+1999-03-02 09:44:33 [1239] ACL conn
+1999-03-02 09:44:33 [1239] TLS error on connection from [127.0.0.1] (recv): The TLS connection was non-properly terminated.
+1999-03-02 09:44:33 [1239] ACL notquit
+1999-03-02 09:44:33 [1234] eval host_reject_connection
+1999-03-02 09:44:33 [1234] refused connection from [127.0.0.1] (host_reject_connection)
+1999-03-02 09:44:33 [1235] eval host_reject_connection
+1999-03-02 09:44:33 [1235] ACL conn
+1999-03-02 09:44:33 [1235] H=[127.0.0.1] dropped by 'connect' ACL: we dislike you
+1999-03-02 09:44:33 [1240] eval host_reject_connection
+1999-03-02 09:44:33 [1240] ACL conn
+1999-03-02 09:44:33 [1240] EV tls:fail:connect
+1999-03-02 09:44:33 [1240] EVDATA: (gnutls_handshake): The TLS connection was non-properly terminated.
+1999-03-02 09:44:33 [1240] 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
index a1c9f9e37..41583c55a 100644
--- a/test/log/5721
+++ b/test/log/5721
@@ -1,13 +1,19 @@

******** SERVER ********
-1999-03-02 09:44:33 exim x.yz daemon started: pid=p1234, 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
+1999-03-02 09:44:33 [1237] exim x.yz daemon started: pid=p1236, no queue runs, listening for SMTPS on port PORT_D port PORT_D2 port PORT_D3
+1999-03-02 09:44:33 [1238] eval host_reject_connection
+1999-03-02 09:44:33 [1238] ACL conn
+1999-03-02 09:44:33 [1238] ACL quit
+1999-03-02 09:44:33 [1239] eval host_reject_connection
+1999-03-02 09:44:33 [1239] ACL conn
+1999-03-02 09:44:33 [1239] ACL notquit
+1999-03-02 09:44:33 [1234] eval host_reject_connection
+1999-03-02 09:44:33 [1234] refused connection from [127.0.0.1] (host_reject_connection)
+1999-03-02 09:44:33 [1235] eval host_reject_connection
+1999-03-02 09:44:33 [1235] ACL conn
+1999-03-02 09:44:33 [1235] H=[127.0.0.1] dropped by 'connect' ACL: we dislike you
+1999-03-02 09:44:33 [1240] eval host_reject_connection
+1999-03-02 09:44:33 [1240] ACL conn
+1999-03-02 09:44:33 [1240] EV tls:fail:connect
+1999-03-02 09:44:33 [1240] EVDATA: SSL_accept: TCP connection closed by peer
+1999-03-02 09:44:33 [1240] TLS error on connection from [127.0.0.1] (tls lib accept fn): TCP connection closed by peer
diff --git a/test/rejectlog/5711 b/test/rejectlog/5711
new file mode 100644
index 000000000..e9945c13e
--- /dev/null
+++ b/test/rejectlog/5711
@@ -0,0 +1,4 @@
+
+******** SERVER ********
+1999-03-02 09:44:33 [1234] refused connection from [127.0.0.1] (host_reject_connection)
+1999-03-02 09:44:33 [1235] H=[127.0.0.1] dropped by 'connect' ACL: we dislike you
diff --git a/test/rejectlog/5721 b/test/rejectlog/5721
new file mode 100644
index 000000000..e9945c13e
--- /dev/null
+++ b/test/rejectlog/5721
@@ -0,0 +1,4 @@
+
+******** SERVER ********
+1999-03-02 09:44:33 [1234] refused connection from [127.0.0.1] (host_reject_connection)
+1999-03-02 09:44:33 [1235] H=[127.0.0.1] dropped by 'connect' ACL: we dislike you
diff --git a/test/scripts/5710-GnuTLS-events/5711 b/test/scripts/5710-GnuTLS-events/5711
index 7c276229d..725703f2a 100644
--- a/test/scripts/5710-GnuTLS-events/5711
+++ b/test/scripts/5710-GnuTLS-events/5711
@@ -1,6 +1,6 @@
# smtp-on-connect drop-before-tls-accept
#
-exim -DSERVER=server -tls-on-connect -bd -oX PORT_D
+exim -DSERVER=server -tls-on-connect -bd -oX PORT_D:PORT_D2:PORT_D3
****
#
# Normal, full connect and quit
@@ -15,6 +15,16 @@ client-anytls -tls-on-connect 127.0.0.1 PORT_D
??? 220
****
#
+# server rejects using host_reject_connection option
+client-anytls -tls-on-connect 127.0.0.1 PORT_D2
+???*
+****
+#
+# server rejects using conn ACL
+client-anytls -tls-on-connect 127.0.0.1 PORT_D3
+???*
+****
+#
# client disconnects before server TLS accept completes
client 127.0.0.1 PORT_D
+++ 1
diff --git a/test/scripts/5720-OpenSSL-events/5721 b/test/scripts/5720-OpenSSL-events/5721
index 0f72c17d2..19f977c7b 100644
--- a/test/scripts/5720-OpenSSL-events/5721
+++ b/test/scripts/5720-OpenSSL-events/5721
@@ -1,6 +1,6 @@
# smtp-on-connect drop-before-tls-accept
#
-exim -DSERVER=server -tls-on-connect -bd -oX PORT_D
+exim -DSERVER=server -tls-on-connect -bd -oX PORT_D:PORT_D2:PORT_D3
****
#
# Normal, full connect and quit
@@ -15,6 +15,16 @@ client-anytls -tls-on-connect 127.0.0.1 PORT_D
??? 220
****
#
+# server rejects using host_reject_connection option
+client-anytls -tls-on-connect 127.0.0.1 PORT_D2
+???*
+****
+#
+# server rejects using conn ACL
+client-anytls -tls-on-connect 127.0.0.1 PORT_D3
+???*
+****
+#
# client disconnects before server TLS accept completes
client 127.0.0.1 PORT_D
+++ 1
diff --git a/test/stdout/5711 b/test/stdout/5711
index d3bf62e95..f96f81b96 100644
--- a/test/stdout/5711
+++ b/test/stdout/5711
@@ -13,6 +13,18 @@ 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 1226 ... connected
+Attempting to start TLS
+Failed to start TLS
+???*
+Expected EOF read
+End of script
+Connecting to 127.0.0.1 port 1227 ... connected
+Attempting to start TLS
+Failed to start TLS
+???*
+Expected EOF read
+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
index d3bf62e95..f96f81b96 100644
--- a/test/stdout/5721
+++ b/test/stdout/5721
@@ -13,6 +13,18 @@ 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 1226 ... connected
+Attempting to start TLS
+Failed to start TLS
+???*
+Expected EOF read
+End of script
+Connecting to 127.0.0.1 port 1227 ... connected
+Attempting to start TLS
+Failed to start TLS
+???*
+Expected EOF read
+End of script
Connecting to 127.0.0.1 port 1225 ... connected
+++ 1
End of script