From 8d909960c69378a54d9493586d74ba361948bf49 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sat, 18 Mar 2017 14:41:50 +0000 Subject: [PATCH] Expansions: check numeric values of IPv4 address components --- doc/doc-docbook/spec.xfpt | 11 ++++++++--- doc/doc-txt/ChangeLog | 3 +++ src/src/string.c | 15 +++++++++------ test/scripts/0000-Basic/0002 | 3 +++ test/stdout/0002 | 3 +++ 5 files changed, 26 insertions(+), 9 deletions(-) diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index 91dacb7bb..128ee8004 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -11042,9 +11042,14 @@ colon-separated components are permitted, each containing from one to four hexadecimal digits. There may be fewer than eight components if an empty component (adjacent colons) is present. Only one empty component is permitted. -&*Note*&: The checks are just on the form of the address; actual numerical -values are not considered. Thus, for example, 999.999.999.999 passes the IPv4 -check. The main use of these tests is to distinguish between IP addresses and +.new +&*Note*&: The checks used to be just on the form of the address; actual numerical +values were not considered. Thus, for example, 999.999.999.999 passed the IPv4 +check. +This is no longer the case. +.wen + +The main use of these tests is to distinguish between IP addresses and host names, or between IPv4 and IPv6 addresses. For example, you could use .code ${if isip4{$sender_host_address}... diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index f43475ba3..ac35c75f1 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -35,6 +35,9 @@ PP/02 Bug 2070: uClibc defines __GLIBC__ without providing glibc headers; add noisy ifdef guards to special-case this sillyness. Patch from Bernd Kuhls. +JH/05 Tighten up the checking in isip4 (et al): dotted-quad components larger + than 255 are no longer allowed. + Exim version 4.89 ----------------- diff --git a/src/src/string.c b/src/src/string.c index cec59506d..4850fd958 100644 --- a/src/src/string.c +++ b/src/src/string.c @@ -42,7 +42,7 @@ int yield = 4; /* If an optional mask is permitted, check for it. If found, pass back the offset. */ -if (maskptr != NULL) +if (maskptr) { const uschar *ss = s + Ustrlen(s); *maskptr = 0; @@ -79,7 +79,7 @@ if (Ustrchr(s, ':') != NULL) if we hit the / that introduces a mask or the % that introduces the interface specifier (scope id) of a link-local address. */ - if (*s == 0 || *s == '%' || *s == '/') return had_double_colon? yield : 0; + if (*s == 0 || *s == '%' || *s == '/') return had_double_colon ? yield : 0; /* If a component starts with an additional colon, we have hit a double colon. This is permitted to appear once only, and counts as at least @@ -135,13 +135,16 @@ if (Ustrchr(s, ':') != NULL) for (i = 0; i < 4; i++) { + long n; + uschar * end; + if (i != 0 && *s++ != '.') return 0; - if (!isdigit(*s++)) return 0; - if (isdigit(*s) && isdigit(*(++s))) s++; + n = strtol(CCS s, CSS &end, 10); + if (n > 255 || n < 0 || end <= s || end > s+3) return 0; + s = end; } -return (*s == 0 || (*s == '/' && maskptr != NULL && *maskptr != 0))? - yield : 0; +return !*s || (*s == '/' && maskptr && *maskptr != 0) ? yield : 0; } #endif /* COMPILE_UTILITY */ diff --git a/test/scripts/0000-Basic/0002 b/test/scripts/0000-Basic/0002 index cf8dc36e0..cb0bb188f 100644 --- a/test/scripts/0000-Basic/0002 +++ b/test/scripts/0000-Basic/0002 @@ -417,6 +417,8 @@ gei: ${if gei{ABC}{abc}{y}{n}} isip: ${if isip {1.2.3.4}{y}{n}} 1.2.3.4 isip4: ${if isip4{1.2.3.4}{y}{n}} 1.2.3.4 isip6: ${if isip6{1.2.3.4}{y}{n}} 1.2.3.4 +isip: ${if isip {::1.2.3.256}{y}{n}} ::1.2.3.256 +isip4: ${if isip4{1.2.3.256}{y}{n}} 1.2.3.256 isip: ${if isip {1:2:3:4}{y}{n}} 1:2:3:4 isip4: ${if isip4{1:2:3:4}{y}{n}} 1:2:3:4 isip6: ${if isip6{1:2:3:4}{y}{n}} 1:2:3:4 @@ -426,6 +428,7 @@ isip6: ${if isip6{::1}{y}{n}} ::1 isip: ${if isip {fe80::a00:20ff:fe86:a061}{y}{n}} fe80::a00:20ff:fe86:a061 isip4: ${if isip4{fe80::a00:20ff:fe86:a061}{y}{n}} fe80::a00:20ff:fe86:a061 isip6: ${if isip6{fe80::a00:20ff:fe86:a061}{y}{n}} fe80::a00:20ff:fe86:a061 +isip: ${if isip {fe80::1.2.3.4}{y}{n}} fe80::1.2.3.4 isip: ${if isip {rhubarb}{y}{n}} rhubarb isip4: ${if isip4{rhubarb}{y}{n}} rhubarb isip6: ${if isip6{rhubarb}{y}{n}} rhubarb diff --git a/test/stdout/0002 b/test/stdout/0002 index fa445b01c..5593f06cc 100644 --- a/test/stdout/0002 +++ b/test/stdout/0002 @@ -393,6 +393,8 @@ newline tab\134backslash ~tilde\177DEL\200\201. > isip: y 1.2.3.4 > isip4: y 1.2.3.4 > isip6: n 1.2.3.4 +> isip: n ::1.2.3.256 +> isip4: n 1.2.3.256 > isip: n 1:2:3:4 > isip4: n 1:2:3:4 > isip6: n 1:2:3:4 @@ -402,6 +404,7 @@ newline tab\134backslash ~tilde\177DEL\200\201. > isip: y fe80::a00:20ff:fe86:a061 > isip4: n fe80::a00:20ff:fe86:a061 > isip6: y fe80::a00:20ff:fe86:a061 +> isip: y fe80::1.2.3.4 > isip: n rhubarb > isip4: n rhubarb > isip6: n rhubarb -- 2.25.1