diff options
author | Jeremy Harris <jgh146exb@wizmail.org> | 2022-05-27 23:03:02 +0100 |
---|---|---|
committer | Jeremy Harris <jgh146exb@wizmail.org> | 2022-06-02 12:58:39 +0100 |
commit | 2b68e140a846db4f24f4e29dfa16db73dc35c37f (patch) | |
tree | 4584e6301c10f489613bd4421a6beca262cfa89a /src | |
parent | c2046b73572e3b2ea94b4bf7fea9810b73d606c4 (diff) |
Handle a v4mapped sender address given us by a proxy. Bug 2855
Diffstat (limited to 'src')
-rw-r--r-- | src/exim_monitor/em_main.c | 48 | ||||
-rw-r--r-- | src/src/host.c | 11 | ||||
-rw-r--r-- | src/src/spool_out.c | 4 |
3 files changed, 47 insertions, 16 deletions
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) |