summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPhilip Hazel <ph10@hermes.cam.ac.uk>2006-02-13 11:13:37 +0000
committerPhilip Hazel <ph10@hermes.cam.ac.uk>2006-02-13 11:13:37 +0000
commit1688f43b3071b3b4d7d3a88a6ccf28c1bc3272e0 (patch)
treea1ec1b451f03d8ad7645d29bd9253d795cef1064 /src
parent21c28500c0afea85a4acc9cd2e6c816522394431 (diff)
Better debug diagnosis of malformed IPv4 addresses.
Diffstat (limited to 'src')
-rw-r--r--src/src/string.c10
-rw-r--r--src/src/verify.c23
2 files changed, 28 insertions, 5 deletions
diff --git a/src/src/string.c b/src/src/string.c
index a093a3874..2fe57b303 100644
--- a/src/src/string.c
+++ b/src/src/string.c
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/string.c,v 1.8 2006/02/07 11:19:00 ph10 Exp $ */
+/* $Cambridge: exim/src/src/string.c,v 1.9 2006/02/13 11:13:37 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -28,6 +28,7 @@ Arguments:
s a string
maskptr NULL if no mask is permitted to follow
otherwise, points to an int where the offset of '/' is placed
+ if there is no / followed by trailing digits, *maskptr is set 0
Returns: 0 if the string is not a textual representation of an IP address
4 if it is an IPv4 address
@@ -127,7 +128,9 @@ if (Ustrchr(s, ':') != NULL)
sign, which introduces the interface specifier (scope id) of a link local
address. */
- if (!v4end) return (*s == 0 || *s == '%' || *s == '/')? yield : 0;
+ if (!v4end)
+ return (*s == 0 || *s == '%' ||
+ (*s == '/' && maskptr != NULL && *maskptr != 0))? yield : 0;
}
/* Test for IPv4 address, which may be the tail-end of an IPv6 address. */
@@ -139,7 +142,8 @@ for (i = 0; i < 4; i++)
if (isdigit(*s) && isdigit(*(++s))) s++;
}
-return (*s == 0 || *s == '/')? yield : 0;
+return (*s == 0 || (*s == '/' && maskptr != NULL && *maskptr != 0))?
+ yield : 0;
}
#endif /* COMPILE_UTILITY */
diff --git a/src/src/verify.c b/src/src/verify.c
index 117cf81f8..ef7ab8d22 100644
--- a/src/src/verify.c
+++ b/src/src/verify.c
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/verify.c,v 1.31 2006/02/07 11:19:00 ph10 Exp $ */
+/* $Cambridge: exim/src/src/verify.c,v 1.32 2006/02/13 11:13:37 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -1945,7 +1945,7 @@ int maskoffset;
BOOL iplookup = FALSE;
BOOL isquery = FALSE;
BOOL isiponly = cb->host_name != NULL && cb->host_name[0] == 0;
-uschar *t = ss;
+uschar *t;
uschar *semicolon;
uschar **aliases;
@@ -1986,6 +1986,24 @@ a (possibly masked) comparision with the current IP address. */
if (string_is_ip_address(ss, &maskoffset) != 0)
return (host_is_in_net(cb->host_address, ss, maskoffset)? OK : FAIL);
+/* The pattern is not an IP address. A common error that people make is to omit
+one component of an IPv4 address, either by accident, or believing that, for
+example, 1.2.3/24 is the same as 1.2.3.0/24, or 1.2.3 is the same as 1.2.3.0,
+which it isn't. (Those applications that do accept 1.2.3 as an IP address
+interpret it as 1.2.0.3 because the final component becomes 16-bit - this is an
+ancient specification.) To aid in debugging these cases, we give a specific
+error if the pattern contains only digits and dots or contains a slash preceded
+only by digits and dots (a slash at the start indicates a file name and of
+course slashes may be present in lookups, but not preceded only by digits and
+dots). */
+
+for (t = ss; isdigit(*t) || *t == '.'; t++);
+if (*t == 0 || (*t == '/' && t != ss))
+ {
+ *error = US"malformed IPv4 address or address mask";
+ return ERROR;
+ }
+
/* See if there is a semicolon in the pattern */
semicolon = Ustrchr(ss, ';');
@@ -2013,6 +2031,7 @@ if (Ustrncmp(ss, "net", 3) == 0 && semicolon != NULL)
if (mlen == 0 && t == ss+3) mlen = -1; /* No mask supplied */
iplookup = (*t++ == '-');
}
+else t = ss;
/* Do the IP address lookup if that is indeed what we have */