UTF8: Avoid treating a punycoded dns lookup as an implicit redirection
authorJeremy Harris <jgh146exb@wizmail.org>
Sat, 18 Apr 2015 14:48:58 +0000 (15:48 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Sat, 18 Apr 2015 15:22:48 +0000 (16:22 +0100)
src/src/dns.c
test/dnszones-src/db.test.ex
test/stdout/0405

index 6f75386ed528c23236b2953584de4c4247e127b2..a9970d9fe571addfbd95d09e9ed096264be0b2e8 100644 (file)
@@ -581,6 +581,8 @@ if (previous != NULL)
   {
   uschar * alabel;
   uschar * errstr = NULL;
+  DEBUG(D_dns) if (string_is_utf8(name))
+    debug_printf("convert utf8 '%s' to alabel for for lookup\n", name);
   if ((alabel = string_domain_utf8_to_alabel(name, &errstr)), errstr)
     {
     DEBUG(D_dns)
@@ -738,7 +740,8 @@ won't return any.
 If fully_qualified_name is not NULL, set it to point to the full name
 returned by the resolver, if this is different to what it is given, unless
 the returned name starts with "*" as some nameservers seem to be returning
-wildcards in this form.
+wildcards in this form.  In international mode "different" means "alabel
+forms are different".
 
 Arguments:
   dnsa                  pointer to dns_answer structure
@@ -799,18 +802,19 @@ for (i = 0; i < 10; i++)
 
   if (i == 0 && fully_qualified_name != NULL)
     {
-    if (cname_rr.data != NULL)
-      {
-      if (Ustrcmp(cname_rr.name, *fully_qualified_name) != 0 &&
-          cname_rr.name[0] != '*')
-        *fully_qualified_name = string_copy_dnsdomain(cname_rr.name);
-      }
-    else if (type_rr.data != NULL)
-      {
-      if (Ustrcmp(type_rr.name, *fully_qualified_name) != 0 &&
-          type_rr.name[0] != '*')
-        *fully_qualified_name = string_copy_dnsdomain(type_rr.name);
-      }
+    uschar * rr_name = cname_rr.data ? cname_rr.name
+      : type_rr.data ? type_rr.name : NULL;
+    if (  rr_name
+       && Ustrcmp(rr_name, *fully_qualified_name) != 0
+       && rr_name[0] != '*'
+#ifdef EXPERIMENTAL_INTERNATIONAL
+       && (  !string_is_utf8(*fully_qualified_name)
+         || Ustrcmp(rr_name,
+              string_domain_utf8_to_alabel(*fully_qualified_name, NULL)) != 0
+         )
+#endif
+       )
+        *fully_qualified_name = string_copy_dnsdomain(rr_name);
     }
 
   /* If any data records of the correct type were found, we are done. */
index ebf9a4021b74475801b25b2bc3dc65330b9c13ad..ab1643452a7aa1a08df7fc31a3389e077dad107c 100644 (file)
@@ -38,9 +38,9 @@ dontqualify  A       V4NET.255.255.254
 
 UpperCase    A       127.0.0.1
 
-; A host with UTF-8 characters used for its lookup ( π.test.ex )
+; A host with punycoded UTF-8 characters used for its lookup ( mx.π.test.ex )
 
-mx.xn--1xa   A       V4NET.255.255.255
+mx.xn--1xa         A       V4NET.255.255.255
 
 ; A non-standard name for localhost
 
@@ -358,9 +358,13 @@ mxt97        MX  1  ten-1.test.ex.
 
 mxt1c        MX  1  dontqualify.
 
-; MX with UTF-8 characters used for its lookup ( π.test.ex )
+; MX with punycoded UTF-8 characters used for its lookup ( π.test.ex )
 
-xn--1xa      MX  0  mx.xn--1xa.test.ex.
+xn--1xa      MX  0  mx.π.test.ex.
+
+; MX with actual UTF-8 characters in its name, for allow_utf8_domains mode test
+
+π            MX  0  mx.xn--1xa.test.ex.
 
 ; -------- Testing SRV records --------
 
index f5b5dce4143601f4df8578faad5f27bfd6a0e2c0..8a0641056b5c2d8f88feef84058b70af292b1ed3 100644 (file)
@@ -1,5 +1,4 @@
 syntax error: domain missing or malformed
-bounce@xn--1xa.test.ex
-    <-- bounce@π.test.ex
+bounce@π.test.ex
   router = r1, transport = t1
   host mx.xn--1xa.test.ex [V4NET.255.255.255] MX=0