From 61a01f48604ff6f5f84b64a5aaee722ebae8fadc Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Mon, 31 Oct 2016 23:01:38 -0700 Subject: [PATCH] [v9_9] 4496. [func] dig: add +idnout to control whether labels are display in punycode or not. Requires idn support to be enabled at compile time. [RT #43398] (cherry picked from commit 42470b0b87da24b18e0ff6ce78f3143e89df6d31) (cherry picked from commit 6552f33198438390724c5823b8dbcf477ec9638c) (cherry picked from commit 7aec46a5ef4074c3957d525643188257c7575841) --- CHANGES | 4 + bin/dig/dig.c | 19 ++- bin/dig/dig.docbook | 11 ++ bin/dig/dighost.c | 9 +- bin/dig/include/dig/dig.h | 3 +- bin/tests/system/Makefile.in | 25 +++- bin/tests/system/conf.sh.in | 3 +- bin/tests/system/digdelv/ns2/example.db | 2 + bin/tests/system/digdelv/tests.sh | 17 +++ bin/tests/system/feature-test.c | 149 ++++++++++++++++++++++++ lib/dns/name.c | 3 +- 11 files changed, 238 insertions(+), 7 deletions(-) create mode 100644 bin/tests/system/feature-test.c diff --git a/CHANGES b/CHANGES index 4d204e62d0..74172d44a8 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +4496. [func] dig: add +idnout to control whether labels are + display in punycode or not. Requires idn support + to be enabled at compile time. [RT #43398] + 4494. [bug] Look for . [RT #43429] 4492. [bug] irs_resconf_load failed to initialise sortlistnxt diff --git a/bin/dig/dig.c b/bin/dig/dig.c index 4c4b6aee6a..48ddb9e30d 100644 --- a/bin/dig/dig.c +++ b/bin/dig/dig.c @@ -200,6 +200,7 @@ help(void) { " +[no]edns[=###] (Set EDNS version) [0]\n" " +[no]fail (Don't try next server on SERVFAIL)\n" " +[no]identify (ID responders in short answers)\n" +" +[no]idnout (convert IDN response)\n" " +[no]ignore (Don't revert to TCP for TC responses.)" "\n" " +[no]keepopen (Keep the TCP socket open between queries)\n" @@ -917,8 +918,22 @@ plus_option(const char *option, isc_boolean_t is_batchfile, case 'i': switch (cmd[1]) { case 'd': /* identify */ - FULLCHECK("identify"); - lookup->identify = state; + switch (cmd[2]) { + case 'e': + FULLCHECK("identify"); + lookup->identify = state; + break; + case 'n': + FULLCHECK("idnout"); +#ifndef WITH_IDN + fprintf(stderr, ";; IDN support not enabled\n"); +#else + lookup->idnout = state; +#endif + break; + default: + goto invalid_option; + } break; case 'g': /* ignore */ default: /* diff --git a/bin/dig/dig.docbook b/bin/dig/dig.docbook index 8b7e3829b4..25bb52467b 100644 --- a/bin/dig/dig.docbook +++ b/bin/dig/dig.docbook @@ -660,6 +660,17 @@ + + + + + Convert [do not convert] puny code on output. + This requires IDN SUPPORT to have been enabled at + compile time. The default is to convert output. + + + + diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index bfd9ee82ba..6b120bb9af 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -774,6 +774,11 @@ make_empty_lookup(void) { looknew->besteffort = ISC_TRUE; looknew->dnssec = ISC_FALSE; looknew->nsid = ISC_FALSE; +#ifdef WITH_IDN + looknew->idnout = ISC_TRUE; +#else + looknew->idnout = ISC_FALSE; +#endif #ifdef DIG_SIGCHASE looknew->sigchase = ISC_FALSE; #if DIG_SIGCHASE_TD @@ -857,6 +862,7 @@ clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers) { looknew->besteffort = lookold->besteffort; looknew->dnssec = lookold->dnssec; looknew->nsid = lookold->nsid; + looknew->idnout = lookold->idnout; #ifdef DIG_SIGCHASE looknew->sigchase = lookold->sigchase; #if DIG_SIGCHASE_TD @@ -2040,7 +2046,8 @@ setup_lookup(dig_lookup_t *lookup) { #endif #ifdef WITH_IDN - result = dns_name_settotextfilter(output_filter); + result = dns_name_settotextfilter(lookup->idnout ? + output_filter : NULL); check_result(result, "dns_name_settotextfilter"); #endif diff --git a/bin/dig/include/dig/dig.h b/bin/dig/include/dig/dig.h index 9e6a9b0110..e6535e7328 100644 --- a/bin/dig/include/dig/dig.h +++ b/bin/dig/include/dig/dig.h @@ -129,7 +129,8 @@ struct dig_lookup { done_as_is, besteffort, dnssec, - nsid; /*% Name Server ID (RFC 5001) */ + nsid, /*% Name Server ID (RFC 5001) */ + idnout; #ifdef DIG_SIGCHASE isc_boolean_t sigchase; #if DIG_SIGCHASE_TD diff --git a/bin/tests/system/Makefile.in b/bin/tests/system/Makefile.in index 80971670d4..fbe9ec4a65 100644 --- a/bin/tests/system/Makefile.in +++ b/bin/tests/system/Makefile.in @@ -21,10 +21,31 @@ top_srcdir = @top_srcdir@ SUBDIRS = builtin dlzexternal fetchlimit filter-aaaa lwresd \ statistics rpz rrl rsabigexponent tkey tsiggss -TARGETS = +CINCLUDES = ${ISC_INCLUDES} ${DNS_INCLUDES} + +CDEFINES = @USE_GSSAPI@ +CWARNINGS = + +DNSLIBS = +ISCLIBS = ../../../lib/isc/libisc.@A@ + +DNSDEPLIBS = +ISCDEPLIBS = + +DEPLIBS = + +LIBS = @LIBS@ + +OBJS = feature-test.@O@ +SRCS = feature-test.c + +TARGETS = feature-test@EXEEXT@ @BIND9_MAKE_RULES@ +feature-test@EXEEXT@: feature-test.@O@ + ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ feature-test.@O@ ${ISCLIBS} ${LIBS} + # Running the scripts below is bypassed when a separate # build directory is used. @@ -37,6 +58,8 @@ testclean clean distclean:: if test -f ./cleanall.sh; then sh ./cleanall.sh; fi rm -f systests.output rm -f random.data + rm -f ${TARGETS} + rm -f ${OBJS} distclean:: rm -f conf.sh diff --git a/bin/tests/system/conf.sh.in b/bin/tests/system/conf.sh.in index bc3b0eab76..5e42c977c4 100644 --- a/bin/tests/system/conf.sh.in +++ b/bin/tests/system/conf.sh.in @@ -56,6 +56,7 @@ ARPANAME=$TOP/bin/tools/arpaname SAMPLE=$TOP/lib/export/samples/sample GENRANDOM=$TOP/bin/tools/genrandom NSLOOKUP=$TOP/bin/dig/nslookup +FEATURETEST=$TOP/bin/tests/system/feature-test RANDFILE=$TOP/bin/tests/system/random.data @@ -107,4 +108,4 @@ fi export NAMED LWRESD DIG NSUPDATE KEYGEN KEYFRLAB SIGNER KEYSIGNER KEYSETTOOL \ PERL SUBDIRS RNDC CHECKZONE PK11GEN PK11LIST PK11DEL TESTSOCK6 \ - JOURNALPRINT ARPANAME SAMPLE NSLOOKUP DESCRIPTION + JOURNALPRINT ARPANAME SAMPLE NSLOOKUP DESCRIPTION FEATURETEST diff --git a/bin/tests/system/digdelv/ns2/example.db b/bin/tests/system/digdelv/ns2/example.db index 0a1aa5d615..1c19010d3b 100644 --- a/bin/tests/system/digdelv/ns2/example.db +++ b/bin/tests/system/digdelv/ns2/example.db @@ -34,6 +34,8 @@ b AAAA fd92:7065:b8e:ffff::2 c A 10.0.0.3 c AAAA fd92:7065:b8e:ffff::3 +xn--caf-dma A 10.1.2.3 + foo TXT "testing" foo A 10.0.1.0 foo SSHFP 2 1 123456789abcdef67890123456789abcdef67890 diff --git a/bin/tests/system/digdelv/tests.sh b/bin/tests/system/digdelv/tests.sh index c1d96f508c..9e6d016948 100644 --- a/bin/tests/system/digdelv/tests.sh +++ b/bin/tests/system/digdelv/tests.sh @@ -205,6 +205,23 @@ if [ -x ${DIG} ] ; then if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` + n=`expr $n + 1` + if $FEATURETEST --with-idn + then + echo "I:checking dig +idnout ($n)" + ret=0 + $DIG $DIGOPTS @10.53.0.3 +noidnout xn--caf-dma.example. > dig.out.1.test$n 2>&1 || ret=1 + $DIG $DIGOPTS @10.53.0.3 +idnout xn--caf-dma.example. > dig.out.2.test$n 2>&1 || ret=1 + grep "^xn--caf-dma.example" dig.out.1.test$n > /dev/null || ret=1 + grep "^xn--caf-dma.example" dig.out.2.test$n > /dev/null && ret=1 + grep 10.1.2.3 dig.out.1.test$n > /dev/null || ret=1 + grep 10.1.2.3 dig.out.2.test$n > /dev/null || ret=1 + if [ $ret != 0 ]; then echo "I:failed"; fi + status=`expr $status + $ret` + else + echo "I:skipping 'dig +idnout' as IDN support is not enabled ($n)" + fi + else echo "$DIG is needed, so skipping these dig tests" fi diff --git a/bin/tests/system/feature-test.c b/bin/tests/system/feature-test.c new file mode 100644 index 0000000000..ea03518a99 --- /dev/null +++ b/bin/tests/system/feature-test.c @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC") + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include + +#include +#include +#include +#include + +#include +#include + +#ifdef WIN32 +#include +#endif + +#ifndef MAXHOSTNAMELEN +#ifdef HOST_NAME_MAX +#define MAXHOSTNAMELEN HOST_NAME_MAX +#else +#define MAXHOSTNAMELEN 256 +#endif +#endif + +static void +usage() { + fprintf(stderr, "usage: feature-test \n"); + fprintf(stderr, "args:\n"); + fprintf(stderr, " --enable-filter-aaaa\n"); + fprintf(stderr, " --gethostname\n"); + fprintf(stderr, " --gssapi\n"); + fprintf(stderr, " --have-dlopen\n"); + fprintf(stderr, " --have-geoip\n"); + fprintf(stderr, " --have-libxml2\n"); + fprintf(stderr, " --rpz-nsip\n"); + fprintf(stderr, " --rpz-nsdname\n"); + fprintf(stderr, " --with-idn\n"); +} + +int +main(int argc, char **argv) { + if (argc != 2) { + usage(); + return (1); + } + + if (strcmp(argv[1], "--enable-filter-aaaa") == 0) { +#ifdef ALLOW_FILTER_AAAA + return (0); +#else + return (1); +#endif + } + + if (strcmp(argv[1], "--gethostname") == 0) { + char hostname[MAXHOSTNAMELEN]; + int n; +#ifdef WIN32 + /* From lwres InitSocket() */ + WORD wVersionRequested; + WSADATA wsaData; + int err; + + wVersionRequested = MAKEWORD(2, 0); + err = WSAStartup( wVersionRequested, &wsaData ); + if (err != 0) { + fprintf(stderr, "WSAStartup() failed: %d\n", err); + exit(1); + } +#endif + + n = gethostname(hostname, sizeof(hostname)); + if (n == -1) { + perror("gethostname"); + return(1); + } + fprintf(stdout, "%s\n", hostname); +#ifdef WIN32 + WSACleanup(); +#endif + return (0); + } + + if (strcmp(argv[1], "--gssapi") == 0) { +#if defined(GSSAPI) + return (0); +#else + return (1); +#endif + } + + if (strcmp(argv[1], "--have-dlopen") == 0) { +#if defined(HAVE_DLOPEN) && defined(ISC_DLZ_DLOPEN) + return (0); +#else + return (1); +#endif + } + + if (strcmp(argv[1], "--have-geoip") == 0) { +#ifdef HAVE_GEOIP + return (0); +#else + return (1); +#endif + } + + if (strcmp(argv[1], "--have-libxml2") == 0) { +#ifdef HAVE_LIBXML2 + return (0); +#else + return (1); +#endif + } + + if (strcmp(argv[1], "--rpz-nsip") == 0) { +#ifdef ENABLE_RPZ_NSIP + return (0); +#else + return (1); +#endif + } + + if (strcmp(argv[1], "--rpz-nsdname") == 0) { +#ifdef ENABLE_RPZ_NSDNAME + return (0); +#else + return (1); +#endif + } + + if (strcmp(argv[1], "--with-idn") == 0) { +#ifdef WITH_IDN + return (0); +#else + return (1); +#endif + } + + fprintf(stderr, "unknown arg: %s\n", argv[1]); + usage(); + return (1); +} diff --git a/lib/dns/name.c b/lib/dns/name.c index b60e567be6..30d42653a5 100644 --- a/lib/dns/name.c +++ b/lib/dns/name.c @@ -2339,7 +2339,8 @@ dns_name_settotextfilter(dns_name_totextfilter_t proc) { return (ISC_R_SUCCESS); } if (proc == NULL) { - isc_mem_put(thread_key_mctx, mem, sizeof(*mem)); + if (mem != NULL) + isc_mem_put(thread_key_mctx, mem, sizeof(*mem)); res = isc_thread_key_setspecific(totext_filter_proc_key, NULL); if (res != 0) result = ISC_R_UNEXPECTED;