summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2022-05-27 23:03:02 +0100
committerJeremy Harris <jgh146exb@wizmail.org>2022-06-02 12:58:39 +0100
commit2b68e140a846db4f24f4e29dfa16db73dc35c37f (patch)
tree4584e6301c10f489613bd4421a6beca262cfa89a
parentc2046b73572e3b2ea94b4bf7fea9810b73d606c4 (diff)
downloadexim4-2b68e140a846db4f24f4e29dfa16db73dc35c37f.tar.gz
Handle a v4mapped sender address given us by a proxy. Bug 2855
-rw-r--r--doc/doc-txt/ChangeLog3
-rw-r--r--src/exim_monitor/em_main.c48
-rw-r--r--src/src/host.c11
-rw-r--r--src/src/spool_out.c4
-rwxr-xr-xtest/runtest2
-rw-r--r--test/stdout/003528
-rw-r--r--test/stdout/341520
7 files changed, 75 insertions, 41 deletions
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 72cd3c667..3e6da9185 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -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
-----------------
diff --git a/src/exim_monitor/em_main.c b/src/exim_monitor/em_main.c
index 69de8dc4d..5714b999c 100644
--- a/src/exim_monitor/em_main.c
+++ b/src/exim_monitor/em_main.c
@@ -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;
}
diff --git a/src/src/host.c b/src/src/host.c
index f69e0341a..e43b507e5 100644
--- a/src/src/host.c
+++ b/src/src/host.c
@@ -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 4 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
diff --git a/src/src/spool_out.c b/src/src/spool_out.c
index 713584091..510eda6c1 100644
--- a/src/src/spool_out.c
+++ b/src/src/spool_out.c
@@ -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)
diff --git a/test/runtest b/test/runtest
index c88a8929e..4a304a8aa 100755
--- a/test/runtest
+++ b/test/runtest
@@ -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>/;
diff --git a/test/stdout/0035 b/test/stdout/0035
index 2a2bc285c..c2f2cf56f 100644
--- a/test/stdout/0035
+++ b/test/stdout/0035
@@ -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
diff --git a/test/stdout/3415 b/test/stdout/3415
index 0ce6f1909..11060a1b9 100644
--- a/test/stdout/3415
+++ b/test/stdout/3415
@@ -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