Move connect ACL before TLS-on-connect
authorJeremy Harris <jgh146exb@wizmail.org>
Sat, 10 Dec 2022 10:47:05 +0000 (10:47 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Sat, 10 Dec 2022 15:53:02 +0000 (15:53 +0000)
14 files changed:
doc/doc-docbook/spec.xfpt
doc/doc-txt/ChangeLog
src/src/EDITME
src/src/smtp_in.c
test/confs/5711
test/confs/5721
test/log/5711
test/log/5721
test/rejectlog/5711 [new file with mode: 0644]
test/rejectlog/5721 [new file with mode: 0644]
test/scripts/5710-GnuTLS-events/5711
test/scripts/5720-OpenSSL-events/5721
test/stdout/5711
test/stdout/5721

index 9d3813e5a17a4130f3a083868441825c09892f03..1b3c2b45405d8e326e608b93b2d7cfbd12c65b8c 100644 (file)
@@ -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.
 .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
 nowadays the ACL specified by &%acl_smtp_connect%& can also reject incoming
-connections immediately
+connections immediately.
+
 .new
 .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
 .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.
 
 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
 
 
 .subsection "The EHLO/HELO ACL" SECID192
index 5ac91dc998334622ccb8a03cd652a2ab28601fc5..f8ab5da0c33b71ece8ac47c0fe846d257cc2d1a2 100644 (file)
@@ -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.
 
       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
 -----------------
 
 Exim version 4.96
 -----------------
index 625df18f5519b085fdba28bb4f2e22c4fc1e5b66..4fcaeda5b368aa8a2c69d51a8730e0ef6846a39e 100644 (file)
@@ -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
 # 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
 
 # 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
index 9b60702c15accc42b9068d3f0a9039799f11369c..b161f362d0e972a82d48e53fba9c2eac633ad661 100644 (file)
@@ -2505,6 +2505,22 @@ else DEBUG(D_receive)
 #endif
 
 
 #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                 *
 *************************************************/
 /*************************************************
 *          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));
     {
     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;
     }
 
     return FALSE;
     }
 
@@ -2983,18 +3002,6 @@ if (check_proxy_protocol_host())
   setup_proxy_protocol_host();
 #endif
 
   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;
 /* 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)
     {
   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;
     }
   }
 
     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. */
 
 /* Output the initial message for a two-way SMTP connection. It may contain
 newlines, which then cause a multi-line response to be given. */
 
index d669356458dd4eb0835d8ea49a6d869ee03b2a72..57a9fef08d8169bb2a9ee396a00b1eeed38cda7a 100644 (file)
@@ -6,7 +6,7 @@ primary_hostname = myhost.test.ex
 
 # ----- Main settings -----
 
 
 # ----- 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
 
 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}}
 
 host_reject_connection = ${acl {hrc}}
 event_action = ${acl {tls_fail}}
 
+log_selector = +pid
+
 # ------ ACL ------
 
 begin acl
 
 hrc:
 # ------ 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
                # 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
 
 tls_fail:
   warn         logwrite =  EV $event_name
index d156b1bf528d7de5373389ad4c6feea7b8d5b64a..84c7785d942ad59e9ddd000cae0fefe7b93f49f0 100644 (file)
@@ -6,7 +6,7 @@ primary_hostname = myhost.test.ex
 
 # ----- Main settings -----
 
 
 # ----- 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
 
 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}}
 
 host_reject_connection = ${acl {hrc}}
 event_action = ${acl {tls_fail}}
 
+log_selector = +pid
+
 # ------ ACL ------
 
 begin acl
 
 hrc:
 # ------ 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
                # 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
 
 tls_fail:
   warn         logwrite =  EV $event_name
index 32556a61830ee9be9ce49a6e40e7c14b4cf7e37d..baf38b97d514c8e7d9a674be04b881de443eae1a 100644 (file)
@@ -1,14 +1,20 @@
 
 ******** SERVER ********
 
 ******** 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
index a1c9f9e370eae21065726dc71fc34030d781795d..41583c55a659c20b472c1841ffaeec2d06917d01 100644 (file)
@@ -1,13 +1,19 @@
 
 ******** SERVER ********
 
 ******** 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 (file)
index 0000000..e9945c1
--- /dev/null
@@ -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 (file)
index 0000000..e9945c1
--- /dev/null
@@ -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
index 7c276229dff1d1da87335e687277fe2a1f8c7a7d..725703f2a00ff9152902d3143ad1b2791f0d1e30 100644 (file)
@@ -1,6 +1,6 @@
 # smtp-on-connect drop-before-tls-accept
 #
 # 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
 ****
 #
 # Normal, full connect and quit
@@ -15,6 +15,16 @@ client-anytls -tls-on-connect 127.0.0.1 PORT_D
 ??? 220
 ****
 #
 ??? 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
 # client disconnects before server TLS accept completes
 client 127.0.0.1 PORT_D
 +++ 1
index 0f72c17d2cf22055b73e923914bb84265a042830..19f977c7b6b5266408475d29acdb3abc379bcdc3 100644 (file)
@@ -1,6 +1,6 @@
 # smtp-on-connect drop-before-tls-accept
 #
 # 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
 ****
 #
 # Normal, full connect and quit
@@ -15,6 +15,16 @@ client-anytls -tls-on-connect 127.0.0.1 PORT_D
 ??? 220
 ****
 #
 ??? 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
 # client disconnects before server TLS accept completes
 client 127.0.0.1 PORT_D
 +++ 1
index d3bf62e9571574bf9f051ac900d4af4173a29028..f96f81b965ddcdd2e2689d3b214eb561fea34aac 100644 (file)
@@ -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
 ??? 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
 Connecting to 127.0.0.1 port 1225 ... connected
 +++ 1
 End of script
index d3bf62e9571574bf9f051ac900d4af4173a29028..f96f81b965ddcdd2e2689d3b214eb561fea34aac 100644 (file)
@@ -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
 ??? 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
 Connecting to 127.0.0.1 port 1225 ... connected
 +++ 1
 End of script