From fd6e2d18420f43b0c956d943024cb462e1af6aa6 Mon Sep 17 00:00:00 2001
From: Jeremy Harris <jgh146exb@wizmail.org>
Date: Tue, 28 May 2019 00:26:48 +0100
Subject: [PATCH] PIPE_CONNECT: avoid using when the transport helo_data uses
 $sending_ip_address

---
 doc/doc-txt/experimental-spec.txt |  3 +++
 src/src/transports/smtp.c         | 30 +++++++++++++++++++++---------
 test/confs/4050                   |  3 +++
 test/log/4051                     | 10 ++++++++++
 test/scripts/4050-pipe-conn/4051  | 12 +++++++++++-
 5 files changed, 48 insertions(+), 10 deletions(-)

diff --git a/doc/doc-txt/experimental-spec.txt b/doc/doc-txt/experimental-spec.txt
index 301152f1a..328d0940a 100644
--- a/doc/doc-txt/experimental-spec.txt
+++ b/doc/doc-txt/experimental-spec.txt
@@ -941,6 +941,9 @@ change.
 
 NOTE: since the EHLO command must be constructed before the connection is
 made it cannot depend on the interface IP address that will be used.
+The string "$sending_ip_address" is checked for; if it appears in helo_data
+and "def:sending_ip_address" does not, the facility is disabled.
+
 Transport configurations should be checked for this.  An example avoidance:
 
  helo_data =	${if def:sending_ip_address \
diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
index 3ed2166ce..5c7b440c1 100644
--- a/src/src/transports/smtp.c
+++ b/src/src/transports/smtp.c
@@ -2106,17 +2106,29 @@ if (!continue_hostname)
   sx->avoid_option = sx->peer_offered = smtp_peer_options = 0;
 
 #ifdef EXPERIMENTAL_PIPE_CONNECT
-  if (verify_check_given_host(CUSS &ob->hosts_pipe_connect, sx->conn_args.host) == OK)
-    {
-    sx->early_pipe_ok = TRUE;
-    if (  read_ehlo_cache_entry(sx)
-       && sx->ehlo_resp.cleartext_features & OPTION_EARLY_PIPE)
+  if (  verify_check_given_host(CUSS &ob->hosts_pipe_connect,
+					    sx->conn_args.host) == OK)
+
+    /* We don't find out the local ip address until the connect, so if
+    the helo string might use it avoid doing early-pipelining. */
+
+    if (  !sx->helo_data
+       || !Ustrstr(sx->helo_data, "$sending_ip_address")
+       || Ustrstr(sx->helo_data, "def:sending_ip_address")
+       )
       {
-      DEBUG(D_transport) debug_printf("Using cached cleartext PIPE_CONNECT\n");
-      sx->early_pipe_active = TRUE;
-      sx->peer_offered = sx->ehlo_resp.cleartext_features;
+      sx->early_pipe_ok = TRUE;
+      if (  read_ehlo_cache_entry(sx)
+	 && sx->ehlo_resp.cleartext_features & OPTION_EARLY_PIPE)
+	{
+	DEBUG(D_transport)
+	  debug_printf("Using cached cleartext PIPE_CONNECT\n");
+	sx->early_pipe_active = TRUE;
+	sx->peer_offered = sx->ehlo_resp.cleartext_features;
+	}
       }
-    }
+    else DEBUG(D_transport)
+      debug_printf("helo needs $sending_ip_address\n");
 
   if (sx->early_pipe_active)
     sx->outblock.conn_args = &sx->conn_args;
diff --git a/test/confs/4050 b/test/confs/4050
index 7cddca9a2..c26b7a9c2 100644
--- a/test/confs/4050
+++ b/test/confs/4050
@@ -59,6 +59,9 @@ smtp:
   driver =		smtp
   hosts_try_fastopen =	:
   hosts_pipe_connect =	CONTROL
+.ifdef HELO_MSG
+  helo_data =		HELO_MSG
+.endif
   max_rcpt =		1
 
 #
diff --git a/test/log/4051 b/test/log/4051
index b1d814429..c332087d7 100644
--- a/test/log/4051
+++ b/test/log/4051
@@ -18,6 +18,11 @@
 1999-03-02 09:44:33 10HmbD-0005vi-00 => clientno@test.ex R=client T=smtp H=127.0.0.1 [127.0.0.1] L C="250 OK id=10HmbE-0005vi-00"
 1999-03-02 09:44:33 10HmbD-0005vi-00 Completed
 1999-03-02 09:44:33 End queue run: pid=pppp
+1999-03-02 09:44:33 10HmbF-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for helo_data@test.ex
+1999-03-02 09:44:33 Start queue run: pid=pppp
+1999-03-02 09:44:33 10HmbF-0005vi-00 => helo_data@test.ex R=client T=smtp H=127.0.0.1 [127.0.0.1] L C="250 OK id=10HmbG-0005vi-00"
+1999-03-02 09:44:33 10HmbF-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp
 
 ******** SERVER ********
 1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
@@ -42,3 +47,8 @@
 1999-03-02 09:44:33 10HmbE-0005vi-00 => :blackhole: <clientno@test.ex> R=server
 1999-03-02 09:44:33 10HmbE-0005vi-00 Completed
 1999-03-02 09:44:33 End queue run: pid=pppp
+1999-03-02 09:44:33 10HmbG-0005vi-00 <= CALLER@the.local.host.name H=(127.0.0.1) [127.0.0.1] P=esmtp L. S=sss id=E10HmbF-0005vi-00@the.local.host.name for helo_data@test.ex
+1999-03-02 09:44:33 Start queue run: pid=pppp
+1999-03-02 09:44:33 10HmbG-0005vi-00 => :blackhole: <helo_data@test.ex> R=server
+1999-03-02 09:44:33 10HmbG-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp
diff --git a/test/scripts/4050-pipe-conn/4051 b/test/scripts/4050-pipe-conn/4051
index 45e4b7410..dd5f4c7a8 100644
--- a/test/scripts/4050-pipe-conn/4051
+++ b/test/scripts/4050-pipe-conn/4051
@@ -54,6 +54,16 @@ exim -DNOTDAEMON -DSERVER=server -q
 ****
 #
 #
-killdaemon
+# Check that client doesn't try when transport uses $sending_ip_address in
+# helo_data
+exim helo_data@test.ex
+Subject test 5
+****
+exim -DCONTROL=127.0.0.1 -DHELO_MSG='$sending_ip_address' -q
+****
+exim -DNOTDAEMON -DSERVER=server -q
+****
+#
 #
+killdaemon
 no_msglog_check
-- 
2.30.2