diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9c14d9960e..08a189ddc3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -88,7 +88,7 @@ stages: - test -w "${CCACHE_DIR}" && export PATH="/usr/lib/ccache:${PATH}" - ./autogen.sh script: - - ./configure --enable-developer --with-libtool --disable-static --with-atf=/usr/local + - ./configure --enable-developer --with-libtool --disable-static --with-atf=/usr/local --with-libidn2 - make -j${PARALLEL_JOBS_BUILD:-1} -k all V=1 artifacts: expire_in: '1 hour' diff --git a/CHANGES b/CHANGES index 2c2e503716..bcdf8f3849 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +4915. [func] Implement IDNA2008 support in dig by adding support + for libidn2. New dig option +idnin has been added, + which allows to process invalid domain names much + like dig without IDN support. libidn2 version 2.0 + or higher is needed for +idnout enabled by default. + 4914. [bug] A bug in zone database reference counting could lead to a crash when multiple versions of a slave zone were transferred from a master in close succession. diff --git a/bin/dig/Makefile.in b/bin/dig/Makefile.in index 46a4cf60f7..ceb272d0a2 100644 --- a/bin/dig/Makefile.in +++ b/bin/dig/Makefile.in @@ -19,7 +19,7 @@ READLINE_LIB = @READLINE_LIB@ CINCLUDES = -I${srcdir}/include ${DNS_INCLUDES} \ ${BIND9_INCLUDES} ${ISC_INCLUDES} \ - ${IRS_INCLUDES} ${ISCCFG_INCLUDES} @DST_OPENSSL_INC@ + ${IRS_INCLUDES} ${ISCCFG_INCLUDES} @LIBIDN2_CFLAGS@ @DST_OPENSSL_INC@ CDEFINES = -DVERSION=\"${VERSION}\" @CRYPTO@ CWARNINGS = @@ -41,10 +41,10 @@ DEPLIBS = ${DNSDEPLIBS} ${IRSDEPLIBS} ${BIND9DEPLIBS} \ ${ISCDEPLIBS} ${ISCCFGDEPLIBS} LIBS = ${DNSLIBS} ${IRSLIBS} ${BIND9LIBS} ${ISCCFGLIBS} \ - ${ISCLIBS} @IDNLIBS@ @LIBS@ + ${ISCLIBS} @IDNKIT_LIBS@ @LIBIDN2_LIBS@ @LIBS@ NOSYMLIBS = ${DNSLIBS} ${IRSLIBS} ${BIND9LIBS} ${ISCCFGLIBS} \ - ${ISCNOSYMLIBS} @IDNLIBS@ @LIBS@ + ${ISCNOSYMLIBS} @IDNKIT_LIBS@ @LIBIDN2_LIBS@ @LIBS@ SUBDIRS = diff --git a/bin/dig/dig.c b/bin/dig/dig.c index cfe05cd7b4..482809ccf0 100644 --- a/bin/dig/dig.c +++ b/bin/dig/dig.c @@ -190,7 +190,8 @@ help(void) { " +[no]fail (Don't try next server on SERVFAIL)\n" " +[no]header-only (Send query without a question section)\n" " +[no]identify (ID responders in short answers)\n" -" +[no]idnout (convert IDN response)\n" +" +[no]idnin (Parse IDN names)\n" +" +[no]idnout (Convert IDN response)\n" " +[no]ignore (Don't revert to TCP for TC responses.)\n" " +[no]keepalive (Request EDNS TCP keepalive)\n" " +[no]keepopen (Keep the TCP socket open between queries)\n" @@ -1045,13 +1046,29 @@ plus_option(const char *option, isc_boolean_t is_batchfile, lookup->identify = state; break; case 'n': - FULLCHECK("idnout"); -#ifndef WITH_IDN - fprintf(stderr, ";; IDN support not enabled\n"); + switch (cmd[3]) { + case 'i': + FULLCHECK("idnin"); +#ifndef WITH_IDN_SUPPORT + fprintf(stderr, ";; IDN input support" + " not enabled\n"); #else - lookup->idnout = state; + lookup->idnin = state; #endif break; + case 'o': + FULLCHECK("idnout"); +#ifndef WITH_IDN_OUT_SUPPORT + fprintf(stderr, ";; IDN output support" + " not enabled\n"); +#else + lookup->idnout = state; +#endif + break; + default: + goto invalid_option; + } + break; default: goto invalid_option; } diff --git a/bin/dig/dig.docbook b/bin/dig/dig.docbook index 219cfd5dee..80318bb32f 100644 --- a/bin/dig/dig.docbook +++ b/bin/dig/dig.docbook @@ -776,6 +776,17 @@ + + + + + Process [do not process] IDN domain names on input. + This requires IDN SUPPORT to have been enabled at + compile time. The default is to process IDN input. + + + + @@ -1288,10 +1299,9 @@ dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr dig appropriately converts character encoding of domain name before sending a request to DNS server or displaying a reply from the server. - If you'd like to turn off the IDN support for some reason, defines - the IDN_DISABLE environment variable. - The IDN support is disabled if the variable is set when - dig runs. + If you'd like to turn off the IDN support for some reason, use + parameters +noidnin and + +noidnout. diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 508c620e67..c5d027bd4f 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -24,18 +24,25 @@ #include #include #include +#include #ifdef HAVE_LOCALE_H #include #endif -#ifdef WITH_IDN +#ifdef WITH_IDN_SUPPORT +#ifdef WITH_IDNKIT #include #include #include #include #endif +#ifdef WITH_LIBIDN2 +#include +#endif +#endif /* WITH_IDN_SUPPORT */ + #include #include #include @@ -134,18 +141,26 @@ int lookup_counter = 0; static char servercookie[256]; -#ifdef WITH_IDN -static void initialize_idn(void); -static isc_result_t output_filter(isc_buffer_t *buffer, - unsigned int used_org, - isc_boolean_t absolute); -static idn_result_t append_textname(char *name, const char *origin, - size_t namesize); -static void idn_check_result(idn_result_t r, const char *msg); +#ifdef WITH_IDN_SUPPORT +static void idn_initialize(void); +static isc_result_t idn_locale_to_ace(const char *from, + char *to, + size_t tolen); +#endif /* WITH_IDN_SUPPORT */ -#define MAXDLEN 256 -int idnoptions = 0; +#ifdef WITH_IDN_OUT_SUPPORT +static isc_result_t idn_ace_to_locale(const char *from, + char *to, + size_t tolen); +static isc_result_t output_filter(isc_buffer_t *buffer, + unsigned int used_org, + isc_boolean_t absolute); +#define MAXDLEN 256 + +#ifdef WITH_IDNKIT +int idnoptions = 0; #endif +#endif /* WITH_IDN_OUT_SUPPORT */ isc_socket_t *keep = NULL; isc_sockaddr_t keepaddr; @@ -646,7 +661,12 @@ make_empty_lookup(void) { looknew->ttlunits = ISC_FALSE; looknew->ttlunits = ISC_FALSE; looknew->qr = ISC_FALSE; -#ifdef WITH_IDN +#ifdef WITH_IDN_SUPPORT + looknew->idnin = ISC_TRUE; +#else + looknew->idnin = ISC_FALSE; +#endif +#ifdef WITH_IDN_OUT_SUPPORT looknew->idnout = ISC_TRUE; #else looknew->idnout = ISC_FALSE; @@ -791,6 +811,7 @@ clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers) { looknew->nocrypto = lookold->nocrypto; looknew->ttlunits = lookold->ttlunits; looknew->qr = lookold->qr; + looknew->idnin = lookold->idnin; looknew->idnout = lookold->idnout; looknew->udpsize = lookold->udpsize; looknew->edns = lookold->edns; @@ -1294,8 +1315,19 @@ setup_system(isc_boolean_t ipv4only, isc_boolean_t ipv6only) { irs_resconf_destroy(&resconf); -#ifdef WITH_IDN - initialize_idn(); +#ifdef HAVE_SETLOCALE + /* Set locale */ + (void)setlocale(LC_ALL, ""); +#endif + +#ifdef WITH_IDN_SUPPORT + idn_initialize(); +#endif + +#ifdef WITH_IDN_OUT_SUPPORT + /* Set domain name -> text post-conversion filter. */ + result = dns_name_settotextfilter(output_filter); + check_result(result, "dns_name_settotextfilter"); #endif if (keyfile[0] != 0) @@ -2026,12 +2058,13 @@ setup_lookup(dig_lookup_t *lookup) { char store[MXNAME]; char ecsbuf[20]; char cookiebuf[256]; -#ifdef WITH_IDN - idn_result_t mr; - char utf8_textname[MXNAME], utf8_origin[MXNAME], idn_textname[MXNAME]; + char *origin = NULL; + char *textname = NULL; +#ifdef WITH_IDN_SUPPORT + char idn_origin[MXNAME], idn_textname[MXNAME]; #endif -#ifdef WITH_IDN +#ifdef WITH_IDN_OUT_SUPPORT result = dns_name_settotextfilter(lookup->idnout ? output_filter : NULL); check_result(result, "dns_name_settotextfilter"); @@ -2064,15 +2097,20 @@ setup_lookup(dig_lookup_t *lookup) { isc_buffer_init(&lookup->onamebuf, lookup->oname_space, sizeof(lookup->oname_space)); -#ifdef WITH_IDN /* * We cannot convert `textname' and `origin' separately. * `textname' doesn't contain TLD, but local mapping needs * TLD. */ - mr = idn_encodename(IDN_LOCALCONV | IDN_DELIMMAP, lookup->textname, - utf8_textname, sizeof(utf8_textname)); - idn_check_result(mr, "convert textname to UTF-8"); + textname = lookup->textname; +#ifdef WITH_IDN_SUPPORT + if (lookup->idnin) { + result = idn_locale_to_ace(lookup->textname, idn_textname, + sizeof(idn_textname)); + check_result(result, "convert textname to IDN encoding"); + debug("idn_textname: %s", idn_textname); + textname = idn_textname; + } #endif /* @@ -2083,8 +2121,8 @@ setup_lookup(dig_lookup_t *lookup) { * is TRUE or we got a domain line in the resolv.conf file. */ if (lookup->new_search) { -#ifdef WITH_IDN - if ((count_dots(utf8_textname) >= ndots) || !usesearch) { + if ((count_dots(textname) >= ndots) || !usesearch) + { lookup->origin = NULL; /* Force abs lookup */ lookup->done_as_is = ISC_TRUE; lookup->need_search = usesearch; @@ -2092,33 +2130,8 @@ setup_lookup(dig_lookup_t *lookup) { lookup->origin = ISC_LIST_HEAD(search_list); lookup->need_search = ISC_FALSE; } -#else - if ((count_dots(lookup->textname) >= ndots) || !usesearch) { - lookup->origin = NULL; /* Force abs lookup */ - lookup->done_as_is = ISC_TRUE; - lookup->need_search = usesearch; - } else if (lookup->origin == NULL && usesearch) { - lookup->origin = ISC_LIST_HEAD(search_list); - lookup->need_search = ISC_FALSE; - } -#endif } -#ifdef WITH_IDN - if (lookup->origin != NULL) { - mr = idn_encodename(IDN_LOCALCONV | IDN_DELIMMAP, - lookup->origin->origin, utf8_origin, - sizeof(utf8_origin)); - idn_check_result(mr, "convert origin to UTF-8"); - mr = append_textname(utf8_textname, utf8_origin, - sizeof(utf8_textname)); - idn_check_result(mr, "append origin to textname"); - } - mr = idn_encodename(idnoptions | IDN_LOCALMAP | IDN_NAMEPREP | - IDN_IDNCONV | IDN_LENCHECK, utf8_textname, - idn_textname, sizeof(idn_textname)); - idn_check_result(mr, "convert UTF-8 textname to IDN encoding"); -#else if (lookup->origin != NULL) { debug("trying origin %s", lookup->origin->origin); result = dns_message_gettempname(lookup->sendmsg, @@ -2126,8 +2139,18 @@ setup_lookup(dig_lookup_t *lookup) { check_result(result, "dns_message_gettempname"); dns_name_init(lookup->oname, NULL); /* XXX Helper funct to conv char* to name? */ - len = (unsigned int) strlen(lookup->origin->origin); - isc_buffer_init(&b, lookup->origin->origin, len); + origin = lookup->origin->origin; +#ifdef WITH_IDN_SUPPORT + if (lookup->idnin) { + result = idn_locale_to_ace(lookup->origin->origin, + idn_origin, sizeof(idn_origin)); + check_result(result, "convert origin to IDN encoding"); + debug("trying idn origin %s", idn_origin); + origin = idn_origin; + } +#endif + len = (unsigned int) strlen(origin); + isc_buffer_init(&b, origin, len); isc_buffer_add(&b, len); result = dns_name_fromtext(lookup->oname, &b, dns_rootname, 0, &lookup->onamebuf); @@ -2137,7 +2160,7 @@ setup_lookup(dig_lookup_t *lookup) { dns_message_puttempname(lookup->sendmsg, &lookup->oname); fatal("'%s' is not in legal name syntax (%s)", - lookup->origin->origin, + origin, isc_result_totext(result)); } if (lookup->trace && lookup->trace_root) { @@ -2148,8 +2171,8 @@ setup_lookup(dig_lookup_t *lookup) { dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); - len = (unsigned int) strlen(lookup->textname); - isc_buffer_init(&b, lookup->textname, len); + len = (unsigned int) strlen(textname); + isc_buffer_init(&b, textname, len); isc_buffer_add(&b, len); result = dns_name_fromtext(name, &b, NULL, 0, NULL); if (result == ISC_R_SUCCESS && @@ -2174,28 +2197,17 @@ setup_lookup(dig_lookup_t *lookup) { } } dns_message_puttempname(lookup->sendmsg, &lookup->oname); - } else -#endif - { + } else { debug("using root origin"); if (lookup->trace && lookup->trace_root) dns_name_clone(dns_rootname, lookup->name); else { -#ifdef WITH_IDN - len = (unsigned int) strlen(idn_textname); - isc_buffer_init(&b, idn_textname, len); + len = (unsigned int) strlen(textname); + isc_buffer_init(&b, textname, len); isc_buffer_add(&b, len); result = dns_name_fromtext(lookup->name, &b, dns_rootname, 0, &lookup->namebuf); -#else - len = (unsigned int) strlen(lookup->textname); - isc_buffer_init(&b, lookup->textname, len); - isc_buffer_add(&b, len); - result = dns_name_fromtext(lookup->name, &b, - dns_rootname, 0, - &lookup->namebuf); -#endif } if (result != ISC_R_SUCCESS) { dns_message_puttempname(lookup->sendmsg, @@ -4153,7 +4165,7 @@ cancel_all(void) { */ void destroy_libs(void) { -#ifdef WITH_IDN +#ifdef WITH_IDN_SUPPORT isc_result_t result; #endif @@ -4187,7 +4199,7 @@ destroy_libs(void) { clear_searchlist(); -#ifdef WITH_IDN +#ifdef WITH_IDN_SUPPORT result = dns_name_settotextfilter(NULL); check_result(result, "dns_name_settotextfilter"); #endif @@ -4234,27 +4246,7 @@ destroy_libs(void) { isc_mem_destroy(&mctx); } -#ifdef WITH_IDN -static void -initialize_idn(void) { - idn_result_t r; - isc_result_t result; - -#ifdef HAVE_SETLOCALE - /* Set locale */ - (void)setlocale(LC_ALL, ""); -#endif - /* Create configuration context. */ - r = idn_nameinit(1); - if (r != idn_success) - fatal("idn api initialization failed: %s", - idn_result_tostring(r)); - - /* Set domain name -> text post-conversion filter. */ - result = dns_name_settotextfilter(output_filter); - check_result(result, "dns_name_settotextfilter"); -} - +#ifdef WITH_IDN_OUT_SUPPORT static isc_result_t output_filter(isc_buffer_t *buffer, unsigned int used_org, isc_boolean_t absolute) @@ -4262,6 +4254,7 @@ output_filter(isc_buffer_t *buffer, unsigned int used_org, char tmp1[MAXDLEN], tmp2[MAXDLEN]; size_t fromlen, tolen; isc_boolean_t end_with_dot; + isc_result_t result; /* * Copy contents of 'buffer' to 'tmp1', supply trailing dot @@ -4270,6 +4263,7 @@ output_filter(isc_buffer_t *buffer, unsigned int used_org, fromlen = isc_buffer_usedlength(buffer) - used_org; if (fromlen >= MAXDLEN) return (ISC_R_SUCCESS); + memmove(tmp1, (char *)isc_buffer_base(buffer) + used_org, fromlen); end_with_dot = (tmp1[fromlen - 1] == '.') ? ISC_TRUE : ISC_FALSE; if (absolute && !end_with_dot) { @@ -4278,13 +4272,16 @@ output_filter(isc_buffer_t *buffer, unsigned int used_org, return (ISC_R_SUCCESS); tmp1[fromlen - 1] = '.'; } + tmp1[fromlen] = '\0'; /* * Convert contents of 'tmp1' to local encoding. */ - if (idn_decodename(IDN_DECODE_APP, tmp1, tmp2, MAXDLEN) != idn_success) + result = idn_ace_to_locale(tmp1, tmp2, sizeof(tmp2)); + if (result != ISC_R_SUCCESS) { return (ISC_R_SUCCESS); + } strlcpy(tmp1, tmp2, MAXDLEN); /* @@ -4304,32 +4301,115 @@ output_filter(isc_buffer_t *buffer, unsigned int used_org, return (ISC_R_SUCCESS); } +#endif -static idn_result_t -append_textname(char *name, const char *origin, size_t namesize) { - size_t namelen = strlen(name); - size_t originlen = strlen(origin); - - /* Already absolute? */ - if (namelen > 0 && name[namelen - 1] == '.') - return (idn_success); - - /* Append dot and origin */ - - if (namelen + 1 + originlen >= namesize) - return (idn_buffer_overflow); - - if (*origin != '.') - name[namelen++] = '.'; - (void)strlcpy(name + namelen, origin, namesize - namelen); - return (idn_success); +#ifdef WITH_IDN_SUPPORT +#ifdef WITH_IDNKIT +static void +idnkit_check_result(idn_result_t result, const char *msg) { + if (result != idn_success) { + fatal("%s: %s", msg, idn_result_tostring(result)); + } } static void -idn_check_result(idn_result_t r, const char *msg) { - if (r != idn_success) { - exitcode = 1; - fatal("%s: %s", msg, idn_result_tostring(r)); - } +idn_initialize(void) { + idn_result_t result; + + /* Create configuration context. */ + result = idn_nameinit(1); + idnkit_check_result(result, "idnkit api initialization failed"); + return (ISC_R_SUCCESS); } -#endif /* WITH_IDN */ + +static isc_result_t +idn_locale_to_ace(const char *from, char *to, size_t tolen) { + char utf8_textname[MXNAME]; + idn_result_t result; + + result = idn_encodename(IDN_LOCALCONV | IDN_DELIMMAP, from, + utf8_textname, sizeof(utf8_textname)); + idnkit_check_result(result, "idnkit idn_encodename to utf8 failed"); + + result = idn_encodename(idnoptions | IDN_LOCALMAP | IDN_NAMEPREP | + IDN_IDNCONV | IDN_LENCHECK, + utf8_textname, to, tolen); + idnkit_check_result(result, "idnkit idn_encodename to idn failed"); + return (ISC_R_SUCCESS); +} + +static isc_result_t +idn_ace_to_locale(const char *from, char *to, size_t tolen) { + idn_result_t result; + + result = idn_decodename(IDN_DECODE_APP, from, to, tolen); + if (result != idn_success) { + debug("idnkit idn_decodename failed: %s", + idn_result_tostring(result)); + return (ISC_R_FAILURE); + } + return (ISC_R_SUCCESS); +} +#endif /* WITH_IDNKIT */ + +#ifdef WITH_LIBIDN2 +static void +idn_initialize(void) { +} + +static isc_result_t +idn_locale_to_ace(const char *from, char *to, size_t tolen) { + int res; + char *tmp_str = NULL; + + res = idn2_lookup_ul(from, &tmp_str, IDN2_NONTRANSITIONAL); + if (res == IDN2_DISALLOWED) + res = idn2_lookup_ul(from, &tmp_str, IDN2_TRANSITIONAL); + + if (res == IDN2_OK) { + /* check the length */ + if (strlen(tmp_str) >= tolen) { + debug("ACE string is too long"); + idn2_free(tmp_str); + return ISC_R_NOSPACE; + } + + (void) strlcpy(to, tmp_str, tolen); + idn2_free(tmp_str); + return ISC_R_SUCCESS; + } + + fatal("idn2_lookup_ul failed: %s", idn2_strerror(res)); + return ISC_R_FAILURE; +} + +#ifdef WITH_IDN_OUT_SUPPORT +static isc_result_t +idn_ace_to_locale(const char *from, char *to, size_t tolen) { + int res; + char *tmp_str = NULL; + + res = idn2_to_unicode_8zlz(from, &tmp_str, + IDN2_NONTRANSITIONAL|IDN2_NFC_INPUT); + + if (res == IDN2_OK) { + /* check the length */ + if (strlen(tmp_str) >= tolen) { + debug("encoded ASC string is too long"); + idn2_free(tmp_str); + return ISC_R_FAILURE; + } + + (void) strncpy(to, tmp_str, tolen); + free(tmp_str); + return ISC_R_SUCCESS; + } else { + debug("idn2_to_unicode_8zlz failed: %s", + idn2_strerror(res)); + } + + return ISC_R_FAILURE; +} +#endif /* WITH_IDN_OUT_SUPPORT */ +#endif /* WITH_LIBIDN2 */ +#endif /* WITH_IDN_SUPPORT */ diff --git a/bin/dig/host.c b/bin/dig/host.c index f27b839c7b..cbb548d2fc 100644 --- a/bin/dig/host.c +++ b/bin/dig/host.c @@ -19,7 +19,7 @@ #include #endif -#ifdef WITH_IDN +#ifdef WITH_IDNKIT #include #include #include @@ -721,7 +721,7 @@ parse_args(isc_boolean_t is_batchfile, int argc, char **argv) { lookup->rdtype != dns_rdatatype_axfr) lookup->rdtype = rdtype; lookup->rdtypeset = ISC_TRUE; -#ifdef WITH_IDN +#ifdef WITH_IDNKIT idnoptions = 0; #endif if (rdtype == dns_rdatatype_axfr) { @@ -736,7 +736,7 @@ parse_args(isc_boolean_t is_batchfile, int argc, char **argv) { } else if (rdtype == dns_rdatatype_any) { if (!lookup->tcp_mode_set) lookup->tcp_mode = ISC_TRUE; -#ifdef WITH_IDN +#ifdef WITH_IDNKIT } else if (rdtype == dns_rdatatype_a || rdtype == dns_rdatatype_aaaa || rdtype == dns_rdatatype_mx) { @@ -771,7 +771,7 @@ parse_args(isc_boolean_t is_batchfile, int argc, char **argv) { if (!lookup->rdtypeset || lookup->rdtype != dns_rdatatype_axfr) lookup->rdtype = dns_rdatatype_any; -#ifdef WITH_IDN +#ifdef WITH_IDNKIT idnoptions = 0; #endif list_type = dns_rdatatype_any; @@ -885,7 +885,7 @@ main(int argc, char **argv) { ISC_LIST_INIT(search_list); fatalexit = 1; -#ifdef WITH_IDN +#ifdef WITH_IDNKIT idnoptions = IDN_ASCCHECK; #endif diff --git a/bin/dig/include/dig/dig.h b/bin/dig/include/dig/dig.h index 48fc8f14b5..b08e99f94b 100644 --- a/bin/dig/include/dig/dig.h +++ b/bin/dig/include/dig/dig.h @@ -129,6 +129,7 @@ struct dig_lookup { use_usec, nocrypto, ttlunits, + idnin, idnout, qr; char textname[MXNAME]; /*% Name we're going to be looking up */ @@ -268,7 +269,7 @@ extern char *progname; extern int tries; extern int fatalexit; extern isc_boolean_t verbose; -#ifdef WITH_IDN +#ifdef WITH_IDNKIT extern int idnoptions; #endif diff --git a/config.h.in b/config.h.in index 79eba6384e..52277996f9 100644 --- a/config.h.in +++ b/config.h.in @@ -597,7 +597,16 @@ int sigwait(const unsigned int *set, int *sig); #undef WANT_QUERYTRACE /* define if idnkit support is to be included. */ -#undef WITH_IDN +#undef WITH_IDNKIT + +/* define if IDN output support is to be included. */ +#undef WITH_IDN_OUT_SUPPORT + +/* define if IDN input support is to be included. */ +#undef WITH_IDN_SUPPORT + +/* define if libidn2 support is to be included. */ +#undef WITH_LIBIDN2 /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ diff --git a/configure b/configure index 4073acba3b..5a64ba72bf 100755 --- a/configure +++ b/configure @@ -681,7 +681,9 @@ UNITTESTS ATFLIBS ATFBIN ATFBUILD -IDNLIBS +LIBIDN2_LIBS +LIBIDN2_CFLAGS +IDNKIT_LIBS XSLT_DBLATEX_FASTBOOK XSLT_DBLATEX_STYLE XSLT_DOCBOOK_MAKETOC_XHTML @@ -942,7 +944,6 @@ infodir docdir oldincludedir includedir -runstatedir localstatedir sharedstatedir sysconfdir @@ -1041,10 +1042,11 @@ enable_dnstap with_protobuf_c with_libfstrm with_docbook_xsl -with_idn +with_idnkit with_libiconv with_iconv with_idnlib +with_libidn2 with_atf with_tuning enable_querytrace @@ -1107,7 +1109,6 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' -runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1360,15 +1361,6 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; - -runstatedir | --runstatedir | --runstatedi | --runstated \ - | --runstate | --runstat | --runsta | --runst | --runs \ - | --run | --ru | --r) - ac_prev=runstatedir ;; - -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ - | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ - | --run=* | --ru=* | --r=*) - runstatedir=$ac_optarg ;; - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1506,7 +1498,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir runstatedir + libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1659,7 +1651,6 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -1786,10 +1777,11 @@ Optional Packages: --with-protobuf-c=path Path where protobuf-c is installed, for dnstap --with-libfstrm=path Path where libfstrm is installed, for dnstap --with-docbook-xsl=PATH specify path for Docbook-XSL stylesheets - --with-idn=MPREFIX enable IDN support using idnkit [default PREFIX] + --with-idnkit=PATH enable IDN support using idnkit [yes|no|path] --with-libiconv=IPREFIX GNU libiconv are in IPREFIX [default PREFIX] --with-iconv=LIBSPEC specify iconv library [default -liconv] --with-idnlib=ARG specify libidnkit + --with-libidn2=PATH enable IDN support using GNU libidn2 [yes|no|path] --with-atf support Automated Test Framework --with-tuning=ARG Specify server tuning (large or default) --with-dlopen=ARG support dynamically loadable DLZ drivers @@ -22552,28 +22544,28 @@ fi # -# IDN support +# IDN support using idnkit # -# Check whether --with-idn was given. -if test "${with_idn+set}" = set; then : - withval=$with_idn; use_idn="$withval" +# Check whether --with-idnkit was given. +if test "${with_idnkit+set}" = set; then : + withval=$with_idnkit; use_idnkit="$withval" else - use_idn="no" + use_idnkit="no" fi -case "$use_idn" in +case "$use_idnkit" in yes) if test X$prefix = XNONE ; then - idn_path=/usr/local + idnkit_path=/usr/local else - idn_path=$prefix + idnkit_path=$prefix fi ;; no) ;; *) - idn_path="$use_idn" + idnkit_path="$use_idnkit" ;; esac @@ -22630,20 +22622,161 @@ if test "yes" = "$idnlib"; then as_fn_error $? "You must specify ARG for --with-idnlib." "$LINENO" 5 fi -IDNLIBS= -if test "no" != "$use_idn"; then +IDNKIT_LIBS= +if test "no" != "$use_idnkit"; then -$as_echo "#define WITH_IDN 1" >>confdefs.h +$as_echo "#define WITH_IDNKIT 1" >>confdefs.h - STD_CINCLUDES="$STD_CINCLUDES -I$idn_path/include" + STD_CINCLUDES="$STD_CINCLUDES -I$idnkit_path/include" if test "no" != "$idnlib"; then - IDNLIBS="$idnlib $iconvlib" + IDNKIT_LIBS="$idnlib $iconvlib" else - IDNLIBS="-L$idn_path/lib -lidnkit $iconvlib" + IDNKIT_LIBS="-L$idnkit_path/lib -lidnkit $iconvlib" fi fi +# +# IDN support using libidn2 +# + +LIBIDN2_CFLAGS= +LIBIDN2_LIBS= + +# Check whether --with-libidn2 was given. +if test "${with_libidn2+set}" = set; then : + withval=$with_libidn2; use_libidn2="$withval" +else + use_libidn2="no" +fi + +case $use_libidn2 in #( + no) : + : ;; #( + yes) : + + LIBIDN2_LIBS="-lidn2" + ;; #( + *) : + + LIBIDN2_CFLAGS="-I$use_libidn2/include" + LIBIDN2_LIBS="-L$use_libidn2/lib -lidn2" + ;; #( + *) : + ;; +esac + +if test "$use_libidn2" != "no"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing idn2_to_ascii_8z" >&5 +$as_echo_n "checking for library containing idn2_to_ascii_8z... " >&6; } +if ${ac_cv_search_idn2_to_ascii_8z+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char idn2_to_ascii_8z (); +int +main () +{ +return idn2_to_ascii_8z (); + ; + return 0; +} +_ACEOF +for ac_lib in '' idn2; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_idn2_to_ascii_8z=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_idn2_to_ascii_8z+:} false; then : + break +fi +done +if ${ac_cv_search_idn2_to_ascii_8z+:} false; then : + +else + ac_cv_search_idn2_to_ascii_8z=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_idn2_to_ascii_8z" >&5 +$as_echo "$ac_cv_search_idn2_to_ascii_8z" >&6; } +ac_res=$ac_cv_search_idn2_to_ascii_8z +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +$as_echo "#define WITH_LIBIDN2 1" >>confdefs.h + +else + as_fn_error $? "libidn2 requested, but not found" "$LINENO" 5 +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether libidn2 supports idn2_to_unicode_8zlz" >&5 +$as_echo_n "checking whether libidn2 supports idn2_to_unicode_8zlz... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +idn2_to_unicode_8zlz(".", NULL, IDN2_NONTRANSITIONAL|IDN2_NFC_INPUT); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define WITH_IDN_OUT_SUPPORT 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +fi + + + +# +# IDN support in general +# + +# check if idnkit and libidn2 are not used at the same time +if test "$use_idnkit" != no && test "$use_libidn2" != no; then + as_fn_error $? "idnkit and libidn2 cannot be used at the same time." "$LINENO" 5 +fi +# the IDN support is on +if test "$use_idnkit" != no || test "$use_libidn2" != no; then + +$as_echo "#define WITH_IDN_SUPPORT 1" >>confdefs.h + + if test "$use_libidn2" = no || test "$use_libidn2_out" != no; then + +$as_echo "#define WITH_IDN_OUT_SUPPORT 1" >>confdefs.h + + fi +fi + # # Check whether to build Automated Test Framework unit tests # diff --git a/configure.in b/configure.in index f2acb659fb..a4fa556243 100644 --- a/configure.in +++ b/configure.in @@ -4698,24 +4698,24 @@ NOM_PATH_FILE(XSLT_DBLATEX_STYLE, xsl/docbook.xsl, $dblatex_xsl_trees) NOM_PATH_FILE(XSLT_DBLATEX_FASTBOOK, xsl/latex_book_fast.xsl, $dblatex_xsl_trees) # -# IDN support +# IDN support using idnkit # -AC_ARG_WITH(idn, - AS_HELP_STRING([--with-idn[=MPREFIX]], - [enable IDN support using idnkit [default PREFIX]]), - use_idn="$withval", use_idn="no") -case "$use_idn" in +AC_ARG_WITH(idnkit, + AS_HELP_STRING([--with-idnkit[=PATH]], + [enable IDN support using idnkit [yes|no|path]]), + use_idnkit="$withval", use_idnkit="no") +case "$use_idnkit" in yes) if test X$prefix = XNONE ; then - idn_path=/usr/local + idnkit_path=/usr/local else - idn_path=$prefix + idnkit_path=$prefix fi ;; no) ;; *) - idn_path="$use_idn" + idnkit_path="$use_idnkit" ;; esac @@ -4761,17 +4761,66 @@ if test "yes" = "$idnlib"; then AC_MSG_ERROR([You must specify ARG for --with-idnlib.]) fi -IDNLIBS= -if test "no" != "$use_idn"; then - AC_DEFINE(WITH_IDN, 1, [define if idnkit support is to be included.]) - STD_CINCLUDES="$STD_CINCLUDES -I$idn_path/include" +IDNKIT_LIBS= +if test "no" != "$use_idnkit"; then + AC_DEFINE(WITH_IDNKIT, 1, [define if idnkit support is to be included.]) + STD_CINCLUDES="$STD_CINCLUDES -I$idnkit_path/include" if test "no" != "$idnlib"; then - IDNLIBS="$idnlib $iconvlib" + IDNKIT_LIBS="$idnlib $iconvlib" else - IDNLIBS="-L$idn_path/lib -lidnkit $iconvlib" + IDNKIT_LIBS="-L$idnkit_path/lib -lidnkit $iconvlib" + fi +fi +AC_SUBST(IDNKIT_LIBS) + +# +# IDN support using libidn2 +# + +LIBIDN2_CFLAGS= +LIBIDN2_LIBS= +AC_ARG_WITH(libidn2, + AS_HELP_STRING([--with-libidn2[=PATH]], [enable IDN support using GNU libidn2 [yes|no|path]]), + use_libidn2="$withval", use_libidn2="no") +AS_CASE([$use_libidn2], + [no],[:], + [yes],[ + LIBIDN2_LIBS="-lidn2" + ], + [*],[ + LIBIDN2_CFLAGS="-I$use_libidn2/include" + LIBIDN2_LIBS="-L$use_libidn2/lib -lidn2" + ]) + +AS_IF([test "$use_libidn2" != "no"], + [AC_SEARCH_LIBS([idn2_to_ascii_8z], [idn2], + [AC_DEFINE(WITH_LIBIDN2, 1, [define if libidn2 support is to be included.])], + [AC_MSG_ERROR([libidn2 requested, but not found])]) + AC_MSG_CHECKING(whether libidn2 supports idn2_to_unicode_8zlz) + AC_TRY_LINK([#include ], + [idn2_to_unicode_8zlz(".", NULL, IDN2_NONTRANSITIONAL|IDN2_NFC_INPUT);], + [AC_MSG_RESULT(yes) + AC_DEFINE(WITH_IDN_OUT_SUPPORT, 1, [define if IDN output support is to be included.])], + [AC_MSG_RESULT([no])]) + ]) +AC_SUBST([LIBIDN2_CFLAGS]) +AC_SUBST([LIBIDN2_LIBS]) + +# +# IDN support in general +# + +# check if idnkit and libidn2 are not used at the same time +if test "$use_idnkit" != no && test "$use_libidn2" != no; then + AC_MSG_ERROR([idnkit and libidn2 cannot be used at the same time.]) +fi +# the IDN support is on +if test "$use_idnkit" != no || test "$use_libidn2" != no; then + AC_DEFINE(WITH_IDN_SUPPORT, 1, [define if IDN input support is to be included.]) + if test "$use_libidn2" = no || test "$use_libidn2_out" != no; then + AC_DEFINE(WITH_IDN_OUT_SUPPORT, 1, [define if IDN output support is to be included.]) fi fi -AC_SUBST(IDNLIBS) # # Check whether to build Automated Test Framework unit tests diff --git a/doc/arm/notes.xml b/doc/arm/notes.xml index 599a29148b..453fa814fa 100644 --- a/doc/arm/notes.xml +++ b/doc/arm/notes.xml @@ -66,7 +66,9 @@ - None. + BIND now can be compiled against libidn2 library to add + IDNA2008 support. Previously BIND only supported IDNA2003 + using (now obsolete) idnkit-1 library. @@ -120,6 +122,13 @@ that have timed out, in addition to those that respond. [GL #64] + + + dig +noidnin can be used to disable IDN + processing on the input domain name, when BIND is compiled + with IDN support. + +