Logging: ensure that an error for a mistyped IPv6 address in a search
authorJeremy Harris <jgh146exb@wizmail.org>
Wed, 6 Dec 2023 19:54:40 +0000 (19:54 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Wed, 6 Dec 2023 19:54:40 +0000 (19:54 +0000)
list is available for logging.  Bug 3057

12 files changed:
doc/doc-docbook/spec.xfpt
doc/doc-txt/ChangeLog
src/src/match.c
src/src/string.c
src/src/verify.c
test/confs/0475
test/scripts/0000-Basic/0002
test/scripts/0000-Basic/0475
test/stderr/0002
test/stderr/0475
test/stdout/0002
test/stdout/0475

index 6022d7642ea0761ddf63ff89d83e2dce7e9d718c..dc8f5cc4d0347419fdfed60b57d6d235d24ee8a8 100644 (file)
@@ -39097,7 +39097,7 @@ selection marked by asterisks:
 .irow &`tls_peerdn`&                   &nbsp; "TLS peer DN on <= and => lines"
 .irow &`tls_resumption`&               &nbsp; "append * to cipher field"
 .irow &`tls_sni`&                      &nbsp; "TLS SNI on <= lines"
-.irow &`unknown_in_list`&              &nbsp; "DNS lookup failed in list match"
+.irow &`unknown_in_list`&              &nbsp; "lookup failed in list match"
 .irow &`all`&                          &nbsp; "&*all of the above*&"
 .endtable
 See also the &%slow_lookup_log%& main configuration option,
@@ -39516,7 +39516,8 @@ added to the log line, preceded by SNI=.
 .next
 .cindex "log" "DNS failure in list"
 &%unknown_in_list%&: This setting causes a log entry to be written when the
-result of a list match is failure because a DNS lookup failed.
+result of a list match is failure because a DNS lookup failed, or because
+a bad IP address was in the list.
 .endlist
 
 
index 369e951202603160a76d3e64467b4a847a6cb872..2d82df43d8010a67794413ad532eb6ead75cab74 100644 (file)
@@ -44,6 +44,11 @@ JH/08 Bug 3056: Tighten up parsing of DKIM DNS records.  Previously, whitespace
       Tighten parsing of DKIM header records.  Previously, all but lowercase
       alpha chars would be ignored in potential tag names.
 
+JH/09 Bug 3057: Add heuristic for spotting mistyped IPv6 addresses in lists
+      being searched.  Previously we only had one for IPv4 addresses. Per the
+      documentation, the error results by default in a no-match result for the
+      list.  It is logged if the unknown_in_list log_selector is used.
+
 
 
 Exim version 4.97
index df440108e01085c45d558e431d894418518b6846..8b1a3bef6cc88e44326818aa21b7d792993b0748 100644 (file)
@@ -886,14 +886,19 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0)))
          log_write(0, LOG_MAIN, "%s: accepted by +include_defer", error);
          goto OK_RETURN;
 
-        case ERROR:            /* host name lookup failed - this can only */
-         if (ignore_unknown)   /* be for an incoming host (not outgoing) */
+        /* The ERROR return occurs when checking hosts, when either a forward
+        or reverse lookup has failed. It can also occur in a match_ip list if a
+        non-IP address item is encountered. The error string gives details of
+        which it was. */
+
+        case ERROR:
+         if (ignore_unknown)
            {
            HDEBUG(D_lists) debug_printf_indent("%s: item ignored by +ignore_unknown\n",
              error);
            }
          else
-          {
+           {
            HDEBUG(D_lists) debug_printf_indent("%s %s (%s)\n", ot,
              include_unknown? "yes":"no", error);
            (void)fclose(f);
index dfe0f24519f20d7cacf84971285e8c9d06c09e29..3bf2f1df780eb04dfc6de691195816e4b4ee210e 100644 (file)
@@ -57,6 +57,7 @@ union { /* we do not need this, but inet_pton() needs a place for storage */
 we return failure, as we do if the mask isn't a pure numerical value,
 or if it is negative. The actual length is checked later, once we know
 the address family. */
+
 if (slash = Ustrchr(ip_addr, '/'))
   {
   uschar * rest;
@@ -74,10 +75,11 @@ if (slash = Ustrchr(ip_addr, '/'))
     return 0;
     }
 
-  *maskptr = slash - ip_addr;     /* offset of the slash */
+  *maskptr = slash - ip_addr;  /* offset of the slash */
   endp = slash;
   }
-else if (maskptr) *maskptr = 0; /* no slash found */
+else if (maskptr)
+  *maskptr = 0;                        /* no slash found */
 
 /* The interface-ID suffix (%<id>) is optional (for IPv6). If it
 exists, we check it syntactically. Later, if we know the address
@@ -160,7 +162,7 @@ switch (af)
 int
 string_is_ip_address(const uschar * ip_addr, int * maskptr)
 {
-return string_is_ip_addressX(ip_addr, maskptr, 0);
+return string_is_ip_addressX(ip_addr, maskptr, NULL);
 }
 
 #endif  /* COMPILE_UTILITY */
index d080ddd631bd8f2985b1c26f71bc2a92f51ad298..194e9a76a8896e27c1daeceb60fcdeed32fa0b1c 100644 (file)
@@ -2971,7 +2971,7 @@ if (*ss == '@')
 a (possibly masked) comparison 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);
+  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
@@ -2982,13 +2982,25 @@ 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). */
+dots).  Then the equivalent for IPv6 (roughly). */
 
-for (t = ss; isdigit(*t) || *t == '.'; ) t++;
-if (!*t  || (*t == '/' && t != ss))
+if (Ustrchr(ss, ':'))
   {
-  *error = string_sprintf("malformed IPv4 address or address mask: %.*s", (int)(t - ss), ss);
-  return ERROR;
+  for (t = ss; isxdigit(*t) || *t == ':' || *t == '.'; ) t++;
+  if (!*t  ||  (*t == '/' || *t == '%') && t != ss)
+    {
+    *error = string_sprintf("malformed IPv6 address or address mask: %.*s", (int)(t - ss), ss);
+    return ERROR;
+    }
+  }
+else
+  {
+  for (t = ss; isdigit(*t) || *t == '.'; ) t++;
+  if (!*t  || (*t == '/' && t != ss))
+    {
+    *error = string_sprintf("malformed IPv4 address or address mask: %.*s", (int)(t - ss), ss);
+    return ERROR;
+    }
   }
 
 /* See if there is a semicolon in the pattern, separating a searchtype
index dfca55c7857054186570e4939dbf5e1b0b3ce711..58eb420523ffb690f75fbba037f68509e750ca3c 100644 (file)
@@ -7,6 +7,7 @@
 
 acl_smtp_rcpt = $local_part
 
+log_selector = +unknown_in_list
 
 # ----- ACL -----
 
@@ -18,4 +19,10 @@ a1:
 a2:
   deny hosts = 1.2.3/24
 
+a3:
+  deny hosts = <; fe80::1
+
+a4:
+  deny hosts = <; fe80:1
+
 # End
index c1fa1bdb514a48ad185d3485edae79f03bb6a8a3..9b1e5120ed15d6125bd101f711874d2edec28a32 100644 (file)
@@ -418,7 +418,7 @@ mask:   ${if eq {1}{2}{${mask:invalid}}{NO}}
 5>3m:   ${if >{5 } {3m }{y}{n}}
 5>3z:   ${if >{5 } {3z }{y}{n}}
 5>a:    ${if >{ 5 } {a}{y}{n}}
-5>bad:  ${if >{5 } {${lookup{trick}lsearch{DIR/aux-fixed/0002.lsearch}}} {y}{n}}
+5>bad:  ${if >{5 } {${lookup{trick}lsearch{DIR/aux-fixed/TESTNUM.lsearch}}} {y}{n}}
 
 >0:     ${if > {}{0}{y}{n}}
 =:      ${if = {}{}{y}{n}}
@@ -472,6 +472,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
+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
@@ -527,10 +528,10 @@ match_ip:        08 ${if match_ip{V4NET.11.12.13}{+hlist}}
 match_ip:        09 ${if match_ip{V4NET.11.12.14}{+hlist}}
 match_ip:        10 ${if match_ip{192.168.3.4}{+hlist}}
 match_ip:        11 ${if match_ip{somename}{+hlist}}
-match_ip:        12 ${if match_ip{1.2.3.4}{lsearch;DIR/aux-fixed/0002.matchip}}
-match_ip:        13 ${if match_ip{1.2.3.4}{net-lsearch;DIR/aux-fixed/0002.matchip}}
-match_ip:        14 ${if match_ip{5.6.7.8}{net24-lsearch;DIR/aux-fixed/0002.matchip}}
-match_ip:        15 ${if match_ip{abcd::dcba}{net-iplsearch;DIR/aux-fixed/0002.matchip}}
+match_ip:        12 ${if match_ip{1.2.3.4}{lsearch;DIR/aux-fixed/TESTNUM.matchip}}
+match_ip:        13 ${if match_ip{1.2.3.4}{net-lsearch;DIR/aux-fixed/TESTNUM.matchip}}
+match_ip:        14 ${if match_ip{5.6.7.8}{net24-lsearch;DIR/aux-fixed/TESTNUM.matchip}}
+match_ip:        15 ${if match_ip{abcd::dcba}{net-iplsearch;DIR/aux-fixed/TESTNUM.matchip}}
 
 queue_running:  ${if queue_running{y}{n}}
 first_delivery: ${if first_delivery{y}{n}}
@@ -552,126 +553,126 @@ acl if: ${if acl {{a_defer}{argN}{arg2}} {Y:$value}{N:$value}}
 # Lookups: DIR is the testing directory. In this test we can only use the
 # lookups that are required in all cases.
 
-${lookup{postmaster}lsearch         {DIR/aux-fixed/0002.aliases}{$value}fail}
-${lookup{postmaster}lsearch,ret=full{DIR/aux-fixed/0002.aliases}{$value}fail}
-
-${lookup{x@y}lsearch*@{DIR/aux-fixed/0002.starat}{$value}fail}
-${lookup{x@z}lsearch* {DIR/aux-fixed/0002.starat}{$value}fail}
-${lookup{x@z}lsearch*@{DIR/aux-fixed/0002.starat}{$value}fail}
-${lookup{x@w}lsearch*@{DIR/aux-fixed/0002.starat}{$value}fail}
-
-${lookup{x@y}lsearch*@,ret=full {DIR/aux-fixed/0002.starat}{$value}fail}
-${lookup{x@z}lsearch*,ret=full  {DIR/aux-fixed/0002.starat}{$value}fail}
-${lookup{x@z}lsearch*@,ret=full {DIR/aux-fixed/0002.starat}{$value}fail}
-${lookup{x@w}lsearch*@,ret=full {DIR/aux-fixed/0002.starat}{$value}fail}
-
-${lookup{a.b.c.d}  partial-lsearch {DIR/aux-fixed/0002.domains}{$value}fail}
-${lookup{x.y.z}    partial-lsearch {DIR/aux-fixed/0002.domains}{$value}{failed x.y.z}}
-${lookup{p.q}      partial-lsearch {DIR/aux-fixed/0002.domains}{$value}fail}
-${lookup{o.p.q}    partial-lsearch {DIR/aux-fixed/0002.domains}{$value}fail}
-${lookup{m.n.o.p.q}partial-lsearch {DIR/aux-fixed/0002.domains}{$value}fail}
-${lookup{x.y.z}    partial1-lsearch{DIR/aux-fixed/0002.domains}{$value}fail}
-${lookup{x.y.z}    partial0-lsearch{DIR/aux-fixed/0002.domains}{$value}fail}
-
-${lookup{a.b.c.d}  partial-lsearch,ret=full {DIR/aux-fixed/0002.domains}{$value}fail}
-${lookup{x.y.z}    partial-lsearch,ret=full {DIR/aux-fixed/0002.domains}{$value}{failed x.y.z}}
-${lookup{p.q}      partial-lsearch,ret=full {DIR/aux-fixed/0002.domains}{$value}fail}
-${lookup{o.p.q}    partial-lsearch,ret=full {DIR/aux-fixed/0002.domains}{$value}fail}
-${lookup{m.n.o.p.q}partial-lsearch,ret=full {DIR/aux-fixed/0002.domains}{$value}fail}
-${lookup{x.y.z}    partial1-lsearch,ret=full{DIR/aux-fixed/0002.domains}{$value}fail}
-${lookup{x.y.z}    partial0-lsearch,ret=full{DIR/aux-fixed/0002.domains}{$value}fail}
-
-q1:  ${lookup{abc}        lsearch{DIR/aux-fixed/0002.quoted}}
-q2:  ${lookup{xyz}        lsearch{DIR/aux-fixed/0002.quoted}}
-q3:  ${lookup{pqr}        lsearch{DIR/aux-fixed/0002.quoted}}
-q4:  ${lookup{a:b}        lsearch{DIR/aux-fixed/0002.quoted}}
-q5:  ${lookup{"quoted"}   lsearch{DIR/aux-fixed/0002.quoted}}
-q6:  ${lookup{white space}lsearch{DIR/aux-fixed/0002.quoted}}
-q7:  ${lookup{b\\s}       lsearch{DIR/aux-fixed/0002.quoted}}
-
-q1f: ${lookup{abc}        lsearch,ret=full{DIR/aux-fixed/0002.quoted}}
-q2f: ${lookup{xyz}        lsearch,ret=full{DIR/aux-fixed/0002.quoted}}
-q3f: ${lookup{pqr}        lsearch,ret=full{DIR/aux-fixed/0002.quoted}}
-q4f: ${lookup{a:b}        lsearch,ret=full{DIR/aux-fixed/0002.quoted}}
-q5f: ${lookup{"quoted"}   lsearch,ret=full{DIR/aux-fixed/0002.quoted}}
-q6f: ${lookup{white space}lsearch,ret=full{DIR/aux-fixed/0002.quoted}}
-q7f: ${lookup{b\\s}       lsearch,ret=full{DIR/aux-fixed/0002.quoted}}
-
-abc:   ${lookup{abc}wildlsearch{DIR/aux-var/0002.wild}}
-a.b.c: ${lookup{a.b.c}wildlsearch{DIR/aux-var/0002.wild}}
-ab.c:  ${lookup{ab.c}wildlsearch{DIR/aux-var/0002.wild}}
-xyz:   ${lookup{xyz}wildlsearch{DIR/aux-var/0002.wild}}
-.Xyz:   ${lookup{Xyz}wildlsearch{DIR/aux-var/0002.wild}}
-.Zyz:   ${lookup{Zyz}wildlsearch{DIR/aux-var/0002.wild}}
-a b:   ${lookup{a b}wildlsearch{DIR/aux-var/0002.wild}}
-a  b:  ${lookup{a  b}wildlsearch{DIR/aux-var/0002.wild}}
-a:b:   ${lookup{a:b}wildlsearch{DIR/aux-var/0002.wild}}
-a.b:   ${lookup{a.b}wildlsearch{DIR/aux-var/0002.wild}}
-a..b:  ${lookup{a..b}wildlsearch{DIR/aux-var/0002.wild}}
-a9b:   ${lookup{a9b}wildlsearch{DIR/aux-var/0002.wild}}
-a99b:  ${lookup{a99b}wildlsearch{DIR/aux-var/0002.wild}}
+${lookup{postmaster}lsearch         {DIR/aux-fixed/TESTNUM.aliases}{$value}fail}
+${lookup{postmaster}lsearch,ret=full{DIR/aux-fixed/TESTNUM.aliases}{$value}fail}
+
+${lookup{x@y}lsearch*@{DIR/aux-fixed/TESTNUM.starat}{$value}fail}
+${lookup{x@z}lsearch* {DIR/aux-fixed/TESTNUM.starat}{$value}fail}
+${lookup{x@z}lsearch*@{DIR/aux-fixed/TESTNUM.starat}{$value}fail}
+${lookup{x@w}lsearch*@{DIR/aux-fixed/TESTNUM.starat}{$value}fail}
+
+${lookup{x@y}lsearch*@,ret=full {DIR/aux-fixed/TESTNUM.starat}{$value}fail}
+${lookup{x@z}lsearch*,ret=full  {DIR/aux-fixed/TESTNUM.starat}{$value}fail}
+${lookup{x@z}lsearch*@,ret=full {DIR/aux-fixed/TESTNUM.starat}{$value}fail}
+${lookup{x@w}lsearch*@,ret=full {DIR/aux-fixed/TESTNUM.starat}{$value}fail}
+
+${lookup{a.b.c.d}  partial-lsearch {DIR/aux-fixed/TESTNUM.domains}{$value}fail}
+${lookup{x.y.z}    partial-lsearch {DIR/aux-fixed/TESTNUM.domains}{$value}{failed x.y.z}}
+${lookup{p.q}      partial-lsearch {DIR/aux-fixed/TESTNUM.domains}{$value}fail}
+${lookup{o.p.q}    partial-lsearch {DIR/aux-fixed/TESTNUM.domains}{$value}fail}
+${lookup{m.n.o.p.q}partial-lsearch {DIR/aux-fixed/TESTNUM.domains}{$value}fail}
+${lookup{x.y.z}    partial1-lsearch{DIR/aux-fixed/TESTNUM.domains}{$value}fail}
+${lookup{x.y.z}    partial0-lsearch{DIR/aux-fixed/TESTNUM.domains}{$value}fail}
+
+${lookup{a.b.c.d}  partial-lsearch,ret=full {DIR/aux-fixed/TESTNUM.domains}{$value}fail}
+${lookup{x.y.z}    partial-lsearch,ret=full {DIR/aux-fixed/TESTNUM.domains}{$value}{failed x.y.z}}
+${lookup{p.q}      partial-lsearch,ret=full {DIR/aux-fixed/TESTNUM.domains}{$value}fail}
+${lookup{o.p.q}    partial-lsearch,ret=full {DIR/aux-fixed/TESTNUM.domains}{$value}fail}
+${lookup{m.n.o.p.q}partial-lsearch,ret=full {DIR/aux-fixed/TESTNUM.domains}{$value}fail}
+${lookup{x.y.z}    partial1-lsearch,ret=full{DIR/aux-fixed/TESTNUM.domains}{$value}fail}
+${lookup{x.y.z}    partial0-lsearch,ret=full{DIR/aux-fixed/TESTNUM.domains}{$value}fail}
+
+q1:  ${lookup{abc}        lsearch{DIR/aux-fixed/TESTNUM.quoted}}
+q2:  ${lookup{xyz}        lsearch{DIR/aux-fixed/TESTNUM.quoted}}
+q3:  ${lookup{pqr}        lsearch{DIR/aux-fixed/TESTNUM.quoted}}
+q4:  ${lookup{a:b}        lsearch{DIR/aux-fixed/TESTNUM.quoted}}
+q5:  ${lookup{"quoted"}   lsearch{DIR/aux-fixed/TESTNUM.quoted}}
+q6:  ${lookup{white space}lsearch{DIR/aux-fixed/TESTNUM.quoted}}
+q7:  ${lookup{b\\s}       lsearch{DIR/aux-fixed/TESTNUM.quoted}}
+
+q1f: ${lookup{abc}        lsearch,ret=full{DIR/aux-fixed/TESTNUM.quoted}}
+q2f: ${lookup{xyz}        lsearch,ret=full{DIR/aux-fixed/TESTNUM.quoted}}
+q3f: ${lookup{pqr}        lsearch,ret=full{DIR/aux-fixed/TESTNUM.quoted}}
+q4f: ${lookup{a:b}        lsearch,ret=full{DIR/aux-fixed/TESTNUM.quoted}}
+q5f: ${lookup{"quoted"}   lsearch,ret=full{DIR/aux-fixed/TESTNUM.quoted}}
+q6f: ${lookup{white space}lsearch,ret=full{DIR/aux-fixed/TESTNUM.quoted}}
+q7f: ${lookup{b\\s}       lsearch,ret=full{DIR/aux-fixed/TESTNUM.quoted}}
+
+abc:   ${lookup{abc}wildlsearch{DIR/aux-var/TESTNUM.wild}}
+a.b.c: ${lookup{a.b.c}wildlsearch{DIR/aux-var/TESTNUM.wild}}
+ab.c:  ${lookup{ab.c}wildlsearch{DIR/aux-var/TESTNUM.wild}}
+xyz:   ${lookup{xyz}wildlsearch{DIR/aux-var/TESTNUM.wild}}
+.Xyz:   ${lookup{Xyz}wildlsearch{DIR/aux-var/TESTNUM.wild}}
+.Zyz:   ${lookup{Zyz}wildlsearch{DIR/aux-var/TESTNUM.wild}}
+a b:   ${lookup{a b}wildlsearch{DIR/aux-var/TESTNUM.wild}}
+a  b:  ${lookup{a  b}wildlsearch{DIR/aux-var/TESTNUM.wild}}
+a:b:   ${lookup{a:b}wildlsearch{DIR/aux-var/TESTNUM.wild}}
+a.b:   ${lookup{a.b}wildlsearch{DIR/aux-var/TESTNUM.wild}}
+a..b:  ${lookup{a..b}wildlsearch{DIR/aux-var/TESTNUM.wild}}
+a9b:   ${lookup{a9b}wildlsearch{DIR/aux-var/TESTNUM.wild}}
+a99b:  ${lookup{a99b}wildlsearch{DIR/aux-var/TESTNUM.wild}}
 
 # Should give the same results as above because expansion does nothing
 
-abc:   ${lookup{abc}nwildlsearch{DIR/aux-var/0002.wild}}
-a.b.c: ${lookup{a.b.c}nwildlsearch{DIR/aux-var/0002.wild}}
-ab.c:  ${lookup{ab.c}nwildlsearch{DIR/aux-var/0002.wild}}
-xyz:   ${lookup{xyz}nwildlsearch{DIR/aux-var/0002.wild}}
-.Xyz:   ${lookup{Xyz}nwildlsearch{DIR/aux-var/0002.wild}}
-.Zyz:   ${lookup{Zyz}nwildlsearch{DIR/aux-var/0002.wild}}
-a b:   ${lookup{a b}nwildlsearch{DIR/aux-var/0002.wild}}
-a  b:  ${lookup{a  b}nwildlsearch{DIR/aux-var/0002.wild}}
-a:b:   ${lookup{a:b}nwildlsearch{DIR/aux-var/0002.wild}}
+abc:   ${lookup{abc}nwildlsearch{DIR/aux-var/TESTNUM.wild}}
+a.b.c: ${lookup{a.b.c}nwildlsearch{DIR/aux-var/TESTNUM.wild}}
+ab.c:  ${lookup{ab.c}nwildlsearch{DIR/aux-var/TESTNUM.wild}}
+xyz:   ${lookup{xyz}nwildlsearch{DIR/aux-var/TESTNUM.wild}}
+.Xyz:   ${lookup{Xyz}nwildlsearch{DIR/aux-var/TESTNUM.wild}}
+.Zyz:   ${lookup{Zyz}nwildlsearch{DIR/aux-var/TESTNUM.wild}}
+a b:   ${lookup{a b}nwildlsearch{DIR/aux-var/TESTNUM.wild}}
+a  b:  ${lookup{a  b}nwildlsearch{DIR/aux-var/TESTNUM.wild}}
+a:b:   ${lookup{a:b}nwildlsearch{DIR/aux-var/TESTNUM.wild}}
 
 # Should fail because of no expansion
 
-a.b:   ${lookup{a.b}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NO}}
-a..b:  ${lookup{a..b}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NO}}
-a9b:   ${lookup{a9b}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NO}}
-a99b:  ${lookup{a99b}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NO}}
+a.b:   ${lookup{a.b}nwildlsearch{DIR/aux-var/TESTNUM.wild}{$value}{NO}}
+a..b:  ${lookup{a..b}nwildlsearch{DIR/aux-var/TESTNUM.wild}{$value}{NO}}
+a9b:   ${lookup{a9b}nwildlsearch{DIR/aux-var/TESTNUM.wild}{$value}{NO}}
+a99b:  ${lookup{a99b}nwildlsearch{DIR/aux-var/TESTNUM.wild}{$value}{NO}}
 
 # But these should succeed
 
-a\\:b:  ${lookup{a\\:b}nwildlsearch{DIR/aux-var/0002.wild}}
-a\\:Xb: ${lookup{a\\:Xb}nwildlsearch{DIR/aux-var/0002.wild}}
+a\\:b:  ${lookup{a\\:b}nwildlsearch{DIR/aux-var/TESTNUM.wild}}
+a\\:Xb: ${lookup{a\\:Xb}nwildlsearch{DIR/aux-var/TESTNUM.wild}}
 
 # Some tests of case-(in)dependence
 
-.MiXeD-CD:  ${lookup{MiXeD-CD}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NOT FOUND}}
-.MixeD-CD:  ${lookup{MixeD-CD}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NOT FOUND}}
-.MiXeD-Ncd: ${lookup{MiXeD-Ncd}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NOT FOUND}}
-.MixeD-Ncd: ${lookup{MixeD-Ncd}nwildlsearch{DIR/aux-var/0002.wild}{$value}{NOT FOUND}}
+.MiXeD-CD:  ${lookup{MiXeD-CD}nwildlsearch{DIR/aux-var/TESTNUM.wild}{$value}{NOT FOUND}}
+.MixeD-CD:  ${lookup{MixeD-CD}nwildlsearch{DIR/aux-var/TESTNUM.wild}{$value}{NOT FOUND}}
+.MiXeD-Ncd: ${lookup{MiXeD-Ncd}nwildlsearch{DIR/aux-var/TESTNUM.wild}{$value}{NOT FOUND}}
+.MixeD-Ncd: ${lookup{MixeD-Ncd}nwildlsearch{DIR/aux-var/TESTNUM.wild}{$value}{NOT FOUND}}
 
 # IP address (CIDR) lookups
 
-1.2.3.4:      ${lookup{1.2.3.4}iplsearch{DIR/aux-fixed/0002.iplsearch}}
-1.2.3.5:      ${lookup{1.2.3.5}iplsearch{DIR/aux-fixed/0002.iplsearch}}
-1.2.3.5:      ${lookup{1.2.3.5}iplsearch*{DIR/aux-fixed/0002.iplsearch}}
-abcd::cdab:   ${lookup{abcd::cdab}iplsearch{DIR/aux-fixed/0002.iplsearch}}
-192.168.1.2:  ${lookup{192.168.1.2}iplsearch{DIR/aux-fixed/0002.iplsearch}}
-192.168.5.6:  ${lookup{192.168.5.6}iplsearch{DIR/aux-fixed/0002.iplsearch}}
-abcd:abcd::   ${lookup{abcd:abcd::}iplsearch{DIR/aux-fixed/0002.iplsearch}}
-abcd:abcd:1:: ${lookup{abcd:abcd:1::}iplsearch{DIR/aux-fixed/0002.iplsearch}}
-abcd:abcd::3  ${lookup{abcd:abcd::3}iplsearch{DIR/aux-fixed/0002.iplsearch}}
-rhubarb       ${lookup{rhubarb}iplsearch{DIR/aux-fixed/0002.iplsearch}}
+1.2.3.4:      ${lookup{1.2.3.4}iplsearch{DIR/aux-fixed/TESTNUM.iplsearch}}
+1.2.3.5:      ${lookup{1.2.3.5}iplsearch{DIR/aux-fixed/TESTNUM.iplsearch}}
+1.2.3.5:      ${lookup{1.2.3.5}iplsearch*{DIR/aux-fixed/TESTNUM.iplsearch}}
+abcd::cdab:   ${lookup{abcd::cdab}iplsearch{DIR/aux-fixed/TESTNUM.iplsearch}}
+192.168.1.2:  ${lookup{192.168.1.2}iplsearch{DIR/aux-fixed/TESTNUM.iplsearch}}
+192.168.5.6:  ${lookup{192.168.5.6}iplsearch{DIR/aux-fixed/TESTNUM.iplsearch}}
+abcd:abcd::   ${lookup{abcd:abcd::}iplsearch{DIR/aux-fixed/TESTNUM.iplsearch}}
+abcd:abcd:1:: ${lookup{abcd:abcd:1::}iplsearch{DIR/aux-fixed/TESTNUM.iplsearch}}
+abcd:abcd::3  ${lookup{abcd:abcd::3}iplsearch{DIR/aux-fixed/TESTNUM.iplsearch}}
+rhubarb       ${lookup{rhubarb}iplsearch{DIR/aux-fixed/TESTNUM.iplsearch}}
 
 
 # Nested Lookups - style 1
 
-${lookup{${lookup{key1}lsearch{DIR/aux-fixed/0002.rec}{$value}{key1f}}}lsearch{DIR/aux-fixed/0002.rec}{$value}fail}
-${lookup{${lookup{key3}lsearch{DIR/aux-fixed/0002.rec}{$value}{key1f}}}lsearch{DIR/aux-fixed/0002.rec}{$value}fail}
+${lookup{${lookup{key1}lsearch{DIR/aux-fixed/TESTNUM.rec}{$value}{key1f}}}lsearch{DIR/aux-fixed/TESTNUM.rec}{$value}fail}
+${lookup{${lookup{key3}lsearch{DIR/aux-fixed/TESTNUM.rec}{$value}{key1f}}}lsearch{DIR/aux-fixed/TESTNUM.rec}{$value}fail}
 
 # Nested Lookups - style 2
 
-${lookup{key1}lsearch{DIR/aux-fixed/0002.rec}{${lookup{$value}lsearch{DIR/aux-fixed/0002.rec}{$value}{failed for $value}}}{failed for key1}}
-${lookup{key3}lsearch{DIR/aux-fixed/0002.rec}{${lookup{$value}lsearch{DIR/aux-fixed/0002.rec}{$value}{failed for $value}}}{failed for key1}}
+${lookup{key1}lsearch{DIR/aux-fixed/TESTNUM.rec}{${lookup{$value}lsearch{DIR/aux-fixed/TESTNUM.rec}{$value}{failed for $value}}}{failed for key1}}
+${lookup{key3}lsearch{DIR/aux-fixed/TESTNUM.rec}{${lookup{$value}lsearch{DIR/aux-fixed/TESTNUM.rec}{$value}{failed for $value}}}{failed for key1}}
 
 # Other nesting tests
 
-${lookup{one}lsearch{DIR/aux-fixed/0002.alias1}{$value${lookup{one}lsearch{DIR/aux-fixed/0002.alias2}{,$value}}}{${lookup{one}lsearch{DIR/aux-fixed/0002.alias2}{$value}fail}}}
-${lookup{two}lsearch{DIR/aux-fixed/0002.alias1}{$value${lookup{two}lsearch{DIR/aux-fixed/0002.alias2}{,$value}}}{${lookup{two}lsearch{DIR/aux-fixed/0002.alias2}{$value}fail}}}
-${lookup{both}lsearch{DIR/aux-fixed/0002.alias1}{$value${lookup{both}lsearch{DIR/aux-fixed/0002.alias2}{,$value}}}{${lookup{both}lsearch{DIR/aux-fixed/0002.alias2}{$value}fail}}}
-${lookup{neither}lsearch{DIR/aux-fixed/0002.alias1}{$value${lookup{neither}lsearch{DIR/aux-fixed/0002.alias2}{,$value}}}{${lookup{neither}lsearch{DIR/aux-fixed/0002.alias2}{$value}fail}}}
+${lookup{one}lsearch{DIR/aux-fixed/TESTNUM.alias1}{$value${lookup{one}lsearch{DIR/aux-fixed/TESTNUM.alias2}{,$value}}}{${lookup{one}lsearch{DIR/aux-fixed/TESTNUM.alias2}{$value}fail}}}
+${lookup{two}lsearch{DIR/aux-fixed/TESTNUM.alias1}{$value${lookup{two}lsearch{DIR/aux-fixed/TESTNUM.alias2}{,$value}}}{${lookup{two}lsearch{DIR/aux-fixed/TESTNUM.alias2}{$value}fail}}}
+${lookup{both}lsearch{DIR/aux-fixed/TESTNUM.alias1}{$value${lookup{both}lsearch{DIR/aux-fixed/TESTNUM.alias2}{,$value}}}{${lookup{both}lsearch{DIR/aux-fixed/TESTNUM.alias2}{$value}fail}}}
+${lookup{neither}lsearch{DIR/aux-fixed/TESTNUM.alias1}{$value${lookup{neither}lsearch{DIR/aux-fixed/TESTNUM.alias2}{,$value}}}{${lookup{neither}lsearch{DIR/aux-fixed/TESTNUM.alias2}{$value}fail}}}
 
 # Lookup quotes for standardly expected lookups
 
@@ -798,26 +799,26 @@ toobig    ${from_utf8:aĀd}
 # File insertion
 
 ${readfile}
-${readfile{DIR/aux-fixed/0002.readfile}}
-${readfile{DIR/aux-fixed/0002.readfile}{}}
-${readfile{DIR/aux-fixed/0002.readfile}{:}}
-${readfile{DIR/aux-fixed/0002.readfile}{ - }}
+${readfile{DIR/aux-fixed/TESTNUM.readfile}}
+${readfile{DIR/aux-fixed/TESTNUM.readfile}{}}
+${readfile{DIR/aux-fixed/TESTNUM.readfile}{:}}
+${readfile{DIR/aux-fixed/TESTNUM.readfile}{ - }}
 ${readfile{/non/exist/file}}
 ${if exists{/non/exist/file}{${readfile{/non/exist/file}}}{non-exist}}
->${readfile{DIR/aux-fixed/0002.readfile}{!}}\
+>${readfile{DIR/aux-fixed/TESTNUM.readfile}{!}}\
     <
 
 # Calling a command
 
-${run{DIR/aux-fixed/0002.runfile 0}}
+${run{DIR/aux-fixed/TESTNUM.runfile 0}}
 rc=$runrc
-${run{DIR/aux-fixed/0002.runfile 0}{1}{2}}
+${run{DIR/aux-fixed/TESTNUM.runfile 0}{1}{2}}
 rc=$runrc
-${run{DIR/aux-fixed/0002.runfile 0}{$value}{2}}
+${run{DIR/aux-fixed/TESTNUM.runfile 0}{$value}{2}}
 rc=$runrc
-${run{DIR/aux-fixed/0002.runfile 1}{$value}{2}}
+${run{DIR/aux-fixed/TESTNUM.runfile 1}{$value}{2}}
 rc=$runrc
-${run{DIR/aux-fixed/0002.runfile 1}{$value}{$value}}
+${run{DIR/aux-fixed/TESTNUM.runfile 1}{$value}{$value}}
 rc=$runrc
 ${run{DIR/test-nonexist}{Y}{N}}
 rc=$runrc
@@ -825,9 +826,9 @@ rc=$runrc
 rc=$runrc
 ${if eq{1}{2}{${run{/non/exist}}}{1!=2}}
 rc=$runrc
-${run,preexpand {DIR/aux-fixed/0002.runfile 0}}
+${run,preexpand {DIR/aux-fixed/TESTNUM.runfile 0}}
 rc=$runrc
-${run{DIR/aux-fixed/0002.runfile ${quote:1}}{$value}{2}}
+${run{DIR/aux-fixed/TESTNUM.runfile ${quote:1}}{$value}{2}}
 rc=$runrc
 
 # PRVS
@@ -1138,10 +1139,11 @@ Subject: =?iso-8859-8?Q?_here_we_go=3A_a_string_that_is_going_to_be_encoded=3A_i
 .
 quit
 ****
-# Certain kind of error
+# Bad IP addresses
 exim -d -be
 match_ip:        15 ${if match_ip{1.2.3.4}{1.2.3}}
 match_ip:        16 ${if match_ip{1.2.3.4}{1.2.3.4/abc}}
+match_ip:        17 ${if match_ip{::1}{<; aaaa:bbbb}}
 ****
 # Operation of inlist and negated inlist
 exim -be
index 5008c8768b0017950451f022524d51c1aed50d0a..05f3a70e40c1617f470b730c3e52c96ec080782d 100644 (file)
@@ -4,5 +4,7 @@ helo test
 mail from:<>
 rcpt to:<a1@b>
 rcpt to:<a2@b>
+rcpt to:<a3@b>
+rcpt to:<a4@b>
 quit
 ****
index a74e98c11f4f7478f8ae719f45157466dc192f00..087b58f60615bc3aa1829a39e8ed9046152bbf7f 100644 (file)
@@ -746,5 +746,8 @@ sender address = CALLER@myhost.test.ex
   1.2.3.4 in "1.2.3.4/abc"?
    list element: 1.2.3.4/abc
    1.2.3.4 in "1.2.3.4/abc"? no (malformed IPv4 address or address mask: 1.2.3.4)
-  search_tidyup called
+   ::1 in "<; aaaa:bbbb"?
+   ╎list element: aaaa:bbbb
+   ╎::1 in "<; aaaa:bbbb"? no (malformed IPv6 address or address mask: aaaa:bbbb)
+   search_tidyup called
 >>>>>>>>>>>>>>>> Exim pid=p1240 (fresh-exec) terminating with rc=0 >>>>>>>>>>>>>>>>
index 4626506f53a9d395f47b00dc8765b4190febc663..f080bfc0ee72b3240b31043b56c091458a785715 100644 (file)
@@ -11,7 +11,7 @@
 >>>  list element: @[]
 >>> test in helo_lookup_domains? no (end of list)
 >>> using ACL "a1"
->>> processing "deny" (TESTSUITE/test-config 16)
+>>> processing "deny" (TESTSUITE/test-config 17)
 >>> check hosts = 1.2.3.4 : <; 1.2.3.4::5.6.7.8
 >>> host in "1.2.3.4 : <; 1.2.3.4::5.6.7.8"?
 >>>  list element: 1.2.3.4
@@ -21,11 +21,31 @@ LOG: unknown lookup type "<" in host list item "<; 1.2.3.4:5.6.7.8"
 >>> deny: condition test deferred in ACL "a1"
 LOG: H=(test) [V4NET.0.0.0] F=<> temporarily rejected RCPT <a1@b>: unknown lookup type "<"
 >>> using ACL "a2"
->>> processing "deny" (TESTSUITE/test-config 19)
+>>> processing "deny" (TESTSUITE/test-config 20)
 >>> check hosts = 1.2.3/24
 >>> host in "1.2.3/24"?
 >>>  list element: 1.2.3/24
 >>>  host in "1.2.3/24"? no (malformed IPv4 address or address mask: 1.2.3)
+LOG: list matching forced to fail: malformed IPv4 address or address mask: 1.2.3
 >>>  deny: condition test failed in ACL "a2"
 >>>  end of ACL "a2": implicit DENY
 LOG: H=(test) [V4NET.0.0.0] F=<> rejected RCPT <a2@b>
+>>>  using ACL "a3"
+>>>  processing "deny" (TESTSUITE/test-config 23)
+>>>  check hosts = <; fe80::1
+>>>  host in "<; fe80::1"?
+>>>   list element: fe80::1
+>>>  host in "<; fe80::1"? no (end of list)
+>>>  deny: condition test failed in ACL "a3"
+>>>  end of ACL "a3": implicit DENY
+LOG: H=(test) [V4NET.0.0.0] F=<> rejected RCPT <a3@b>
+>>>  using ACL "a4"
+>>>  processing "deny" (TESTSUITE/test-config 26)
+>>>  check hosts = <; fe80:1
+>>>  host in "<; fe80:1"?
+>>>   list element: fe80:1
+>>>   host in "<; fe80:1"? no (malformed IPv6 address or address mask: fe80:1)
+LOG: list matching forced to fail: malformed IPv6 address or address mask: fe80:1
+>>>   deny: condition test failed in ACL "a4"
+>>>   end of ACL "a4": implicit DENY
+LOG: H=(test) [V4NET.0.0.0] F=<> rejected RCPT <a4@b>
index d5bb0605c5fac58628816137f1b82047fb21a368..a79a5c733e66e4d8aef79316da65d54ab10b5985 100644 (file)
@@ -466,6 +466,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
+> isip6:  n   fe80:a00:20ff:fe86:a061
 > isip:   y  fe80::1.2.3.4
 > isip:   n  rhubarb
 > isip4:  n  rhubarb
@@ -1091,6 +1092,7 @@ xyz
 221 myhost.test.ex closing connection\r
 > match_ip:        15 
 > match_ip:        16 
+> match_ip:        17 
 > 
 > in list
 > in list
index 819cea3bcc8e57ee1301d9daca823c099cd539e1..d1f718997a22e171863ed4d7d5d64b51b78aaf0d 100644 (file)
@@ -8,4 +8,6 @@
 250 OK\r
 451 Temporary local problem - please try later\r
 550 Administrative prohibition\r
+550 Administrative prohibition\r
+550 Administrative prohibition\r
 221 the.local.host.name closing connection\r