Handle a v4mapped sender address given us by a proxy. Bug 2855
authorJeremy Harris <jgh146exb@wizmail.org>
Fri, 27 May 2022 22:03:02 +0000 (23:03 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Thu, 2 Jun 2022 11:58:39 +0000 (12:58 +0100)
doc/doc-txt/ChangeLog
src/exim_monitor/em_main.c
src/src/host.c
src/src/spool_out.c
test/runtest
test/stdout/0035
test/stdout/3415

index 72cd3c667414ea99a7dc2171b2ed7c3da3f838d8..3e6da91852f69ecda5814c414a7e6e9a50f46894 100644 (file)
@@ -148,6 +148,9 @@ JH/32 Fix CHUNKING for a second message on a connection when the first was
 JH/33 Fis ${srs_encode ...} to handle an empty sender address, now returning
       an empty address.  Previously the expansion returned an error.
 
+HS/01 Bug 2855: Handle a v4mapped sender address given us by a frontending
+      proxy.  Previously these were misparsed, leading to paniclog entries.
+
 
 Exim version 4.95
 -----------------
index 69de8dc4d37055ea9d82890243a16dc839e4fc5b..5714b999caad38dd4b8b071b4a5f6dd8cab20d15 100644 (file)
@@ -197,19 +197,47 @@ Returns:     0 if there is no port, else the port number.
 */
 
 int
-host_address_extract_port(uschar *address)
+host_address_extract_port(uschar * address)
 {
-int skip = -3;                     /* Skip 3 dots in IPv4 addresses */
-address--;
-while (*(++address) != 0)
+int port = 0;
+uschar *endptr;
+
+/* Handle the "bracketed with colon on the end" format */
+
+if (*address == '[')
+  {
+  uschar *rb = address + 1;
+  while (*rb != 0 && *rb != ']') rb++;
+  if (*rb++ == 0) return 0;            /* Missing ]; leave invalid address */
+  if (*rb == ':')
+    {
+    port = Ustrtol(rb + 1, &endptr, 10);
+    if (*endptr != 0) return 0;                /* Invalid port; leave invalid address */
+    }
+  else if (*rb != 0) return 0;         /* Bad syntax; leave invalid address */
+  memmove(address, address + 1, rb - address - 2);
+  rb[-2] = 0;
+  }
+
+/* Handle the "dot on the end" format */
+
+else
   {
-  int ch = *address;
-  if (ch == ':') skip = 0;         /* Skip 0 dots in IPv6 addresses */
-    else if (ch == '.' && skip++ >= 0) break;
+  int skip = -3;                       /* Skip 3 dots in IPv4 addresses */
+  address--;
+  while (*(++address) != 0)
+    {
+    int ch = *address;
+    if (ch == ':') skip = 0;           /* Skip 0 dots in IPv6 addresses */
+      else if (ch == '.' && skip++ >= 0) break;
+    }
+  if (*address == 0) return 0;
+  port = Ustrtol(address + 1, &endptr, 10);
+  if (*endptr != 0) return 0;          /* Invalid port; leave invalid address */
+  *address = 0;
   }
-if (*address == 0) return 0;
-*address++ = 0;
-return Uatoi(address);
+
+return port;
 }
 
 
index f69e0341a03ff446bafbaa922a22acb3afd1b055..e43b507e5e29b68df784a1dcace0ce16006ea42a 100644 (file)
@@ -370,15 +370,18 @@ while ((name = string_nextinlist(&list, &sep, NULL, 0)))
 *        Extract port from address string        *
 *************************************************/
 
-/* In the spool file, and in the -oMa and -oMi options, a host plus port is
-given as an IP address followed by a dot and a port number. This function
-decodes this.
+/* In the -oMa and -oMi options, a host plus port is given as an IP address
+followed by a dot and a port number. This function decodes this.
 
 An alternative format for the -oMa and -oMi options is [ip address]:port which
-is what Exim uses for output, because it seems to becoming commonly used,
+is what Exim uses for output, because it seems to becoming commonly used,
 whereas the dot form confuses some programs/people. So we recognize that form
 too.
 
+The spool file used to use the first form, but this breaks with a v4mapped ipv6
+hybrid, because the parsing here is not clever.  So for spool we now use the
+second form.
+
 Argument:
   address    points to the string; if there is a port, the '.' in the string
              is overwritten with zero to terminate the address; if the string
index 7135840913a9d6192d1b02fc9843fa70e4a89b42..510eda6c1e9ab6ea976bf60c9d107fe28a7790bb 100644 (file)
@@ -191,7 +191,7 @@ if (sender_helo_name) spool_var_write(fp, US"helo_name", sender_helo_name);
 if (sender_host_address)
   {
   if (is_tainted(sender_host_address)) putc('-', fp);
-  fprintf(fp, "-host_address %s.%d\n", sender_host_address, sender_host_port);
+  fprintf(fp, "-host_address [%s]:%d\n", sender_host_address, sender_host_port);
   if (sender_host_name)
     spool_var_write(fp, US"host_name", sender_host_name);
   }
@@ -205,7 +205,7 @@ if (sender_host_auth_pubname)
 if (interface_address)
   {
   if (is_tainted(interface_address)) putc('-', fp);
-  fprintf(fp, "-interface_address %s.%d\n", interface_address, interface_port);
+  fprintf(fp, "-interface_address [%s]:%d\n", interface_address, interface_port);
   }
 
 if (smtp_active_hostname != primary_hostname)
index c88a8929ecbd4254c5877dcec7304c3bf42f06a0..4a304a8aa5d8eb0d54831722a49bc8f5f07e378c 100755 (executable)
@@ -792,7 +792,7 @@ RESET_AFTER_EXTRA_LINE_READ:
     }
 
   # Port in host address in spool file output from -Mvh
-  s/^(--?host_address) (.*)\.\d+/$1 $2.9999/;
+  s/^(--?host_address) (.*[:.])\d+$/$1 ${2}9999/;
 
   if ($dynamic_socket and $dynamic_socket->opened and my $port = $dynamic_socket->sockport) {
     s/^Connecting to 127\.0\.0\.1 port \K$port/<dynamic port>/;
index 2a2bc285c3bceb13b587f61db57da3b5b5ba55cc..c2f2cf56fcae0478c743983d484abc82b8315c68 100644 (file)
@@ -147,8 +147,8 @@ ddddddddd 0
 -received_time_usec .uuuuuu
 -received_time_complete tttt.uuuuuu
 --helo_name rhu.barb
--host_address 127.0.0.1.9999
--interface_address 127.0.0.1.1225
+-host_address [127.0.0.1]:9999
+-interface_address [127.0.0.1]:1112
 -received_protocol esmtp
 -body_linecount 0
 -max_received_linelength 0
@@ -170,8 +170,8 @@ ddddddddd 0
 -received_time_usec .uuuuuu
 -received_time_complete tttt.uuuuuu
 --helo_name rhu.barb
--host_address 127.0.0.1.9999
--interface_address 127.0.0.1.1225
+-host_address [127.0.0.1]:9999
+-interface_address [127.0.0.1]:1112
 -received_protocol esmtp
 -body_linecount 0
 -max_received_linelength 0
@@ -196,8 +196,8 @@ ddddddddd 0
 -received_time_usec .uuuuuu
 -received_time_complete tttt.uuuuuu
 --helo_name rhu.barb
--host_address 127.0.0.1.9999
--interface_address 127.0.0.1.1225
+-host_address [127.0.0.1]:9999
+-interface_address [127.0.0.1]:1112
 -received_protocol esmtp
 -body_linecount 0
 -max_received_linelength 0
@@ -220,8 +220,8 @@ ddddddddd 0
 -received_time_usec .uuuuuu
 -received_time_complete tttt.uuuuuu
 --helo_name rhu.barb
--host_address 127.0.0.1.9999
--interface_address 127.0.0.1.1225
+-host_address [127.0.0.1]:9999
+-interface_address [127.0.0.1]:1112
 -received_protocol esmtp
 -body_linecount 0
 -max_received_linelength 25
@@ -244,8 +244,8 @@ ddddddddd 0
 -received_time_usec .uuuuuu
 -received_time_complete tttt.uuuuuu
 --helo_name rhu.barb
--host_address 127.0.0.1.9999
--interface_address 127.0.0.1.1225
+-host_address [127.0.0.1]:9999
+-interface_address [127.0.0.1]:1112
 -received_protocol esmtp
 -body_linecount 0
 -max_received_linelength 25
@@ -271,8 +271,8 @@ ddddddddd 0
 -received_time_usec .uuuuuu
 -received_time_complete tttt.uuuuuu
 --helo_name rhu.barb
--host_address 127.0.0.1.9999
--interface_address 127.0.0.1.1225
+-host_address [127.0.0.1]:9999
+-interface_address [127.0.0.1]:1112
 -received_protocol esmtp
 -body_linecount 0
 -max_received_linelength 25
@@ -298,8 +298,8 @@ ddddddddd 0
 -received_time_usec .uuuuuu
 -received_time_complete tttt.uuuuuu
 --helo_name rhu.barb
--host_address 127.0.0.1.9999
--interface_address 127.0.0.1.1225
+-host_address [127.0.0.1]:9999
+-interface_address [127.0.0.1]:1112
 -received_protocol esmtp
 -body_linecount 0
 -max_received_linelength 25
index 0ce6f19096c466cedbf618784a7ba5532e5ad74a..11060a1b9e831e037a5c6f3dec2129716b779309 100644 (file)
@@ -158,10 +158,10 @@ ddddddddd 0
 -received_time_usec .uuuuuu
 -received_time_complete tttt.uuuuuu
 --helo_name rhu.barb
--host_address 127.0.0.1.9999
+-host_address [127.0.0.1]:9999
 -host_auth au1
 -host_auth_pubname PLAIN
--interface_address 127.0.0.1.1225
+-interface_address [127.0.0.1]:1112
 -received_protocol esmtpa
 -body_linecount 0
 -max_received_linelength 0
@@ -188,10 +188,10 @@ ddddddddd 0
 -received_time_usec .uuuuuu
 -received_time_complete tttt.uuuuuu
 --helo_name rhu.barb
--host_address 127.0.0.1.9999
+-host_address [127.0.0.1]:9999
 -host_auth au1
 -host_auth_pubname PLAIN
--interface_address 127.0.0.1.1225
+-interface_address [127.0.0.1]:1112
 -received_protocol esmtpa
 -body_linecount 0
 -max_received_linelength 0
@@ -216,10 +216,10 @@ ddddddddd 0
 -received_time_usec .uuuuuu
 -received_time_complete tttt.uuuuuu
 --helo_name rhu.barb
--host_address 127.0.0.1.9999
+-host_address [127.0.0.1]:9999
 -host_auth au1
 -host_auth_pubname PLAIN
--interface_address 127.0.0.1.1225
+-interface_address [127.0.0.1]:1112
 -received_protocol esmtpa
 -body_linecount 0
 -max_received_linelength 0
@@ -244,10 +244,10 @@ ddddddddd 0
 -received_time_usec .uuuuuu
 -received_time_complete tttt.uuuuuu
 --helo_name rhu.barb
--host_address 127.0.0.1.9999
+-host_address [127.0.0.1]:9999
 -host_auth au1
 -host_auth_pubname PLAIN
--interface_address 127.0.0.1.1225
+-interface_address [127.0.0.1]:1112
 -received_protocol esmtpa
 -body_linecount 0
 -max_received_linelength 0
@@ -272,10 +272,10 @@ ddddddddd 0
 -received_time_usec .uuuuuu
 -received_time_complete tttt.uuuuuu
 --helo_name rhu.barb
--host_address 127.0.0.1.9999
+-host_address [127.0.0.1]:9999
 -host_auth au1
 -host_auth_pubname PLAIN
--interface_address 127.0.0.1.1225
+-interface_address [127.0.0.1]:1112
 -received_protocol esmtpa
 -body_linecount 0
 -max_received_linelength 15