From 766e7a65f0fcb236afb7d8ad79db5f340b5d3b83 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sat, 18 Apr 2015 15:48:58 +0100 Subject: [PATCH] UTF8: Avoid treating a punycoded dns lookup as an implicit redirection --- src/src/dns.c | 30 +++++++++++++++++------------- test/dnszones-src/db.test.ex | 12 ++++++++---- test/stdout/0405 | 3 +-- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/src/dns.c b/src/src/dns.c index 6f75386ed..a9970d9fe 100644 --- a/src/src/dns.c +++ b/src/src/dns.c @@ -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. */ diff --git a/test/dnszones-src/db.test.ex b/test/dnszones-src/db.test.ex index ebf9a4021..ab1643452 100644 --- a/test/dnszones-src/db.test.ex +++ b/test/dnszones-src/db.test.ex @@ -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 -------- diff --git a/test/stdout/0405 b/test/stdout/0405 index f5b5dce41..8a0641056 100644 --- a/test/stdout/0405 +++ b/test/stdout/0405 @@ -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 -- 2.30.2