diff --git a/CHANGES b/CHANGES index f528315d10..05171d4be7 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +4989. [cleanup] IDN support in dig has been reworked. IDNA2003 + fallbacks were removed in the process. [GL #384] + 4988. [bug] Don't synthesize NXDOMAIN from NSEC for records under a DNAME. diff --git a/bin/dig/Makefile.in b/bin/dig/Makefile.in index 69d540ffe8..62cd72361e 100644 --- a/bin/dig/Makefile.in +++ b/bin/dig/Makefile.in @@ -64,6 +64,8 @@ MANOBJS = ${MANPAGES} ${HTMLPAGES} @BIND9_MAKE_RULES@ +LDFLAGS = @LIBIDN2_LDFLAGS@ + dig@EXEEXT@: dig.@O@ dighost.@O@ ${UOBJS} ${DEPLIBS} export BASEOBJS="dig.@O@ dighost.@O@ ${UOBJS}"; \ export LIBS0="${DNSLIBS} ${IRSLIBS}"; \ diff --git a/bin/dig/dig.c b/bin/dig/dig.c index 320d2490d1..5b4e8a78c2 100644 --- a/bin/dig/dig.c +++ b/bin/dig/dig.c @@ -1051,7 +1051,7 @@ plus_option(char *option, isc_boolean_t is_batchfile, switch (cmd[3]) { case 'i': FULLCHECK("idnin"); -#ifndef WITH_IDN_SUPPORT +#ifndef HAVE_LIBIDN2 fprintf(stderr, ";; IDN input support" " not enabled\n"); #else @@ -1060,7 +1060,7 @@ plus_option(char *option, isc_boolean_t is_batchfile, break; case 'o': FULLCHECK("idnout"); -#ifndef WITH_IDN_OUT_SUPPORT +#ifndef HAVE_LIBIDN2 fprintf(stderr, ";; IDN output support" " not enabled\n"); #else diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 5928392a67..f5b29002ce 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -30,12 +30,9 @@ #include #endif -#ifdef WITH_IDN_SUPPORT - -#ifdef WITH_LIBIDN2 +#ifdef HAVE_LIBIDN2 #include -#endif -#endif /* WITH_IDN_SUPPORT */ +#endif /* HAVE_LIBIDN2 */ #include #include @@ -135,23 +132,12 @@ int lookup_counter = 0; static char servercookie[256]; -#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 */ - -#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 - -#endif /* WITH_IDN_OUT_SUPPORT */ +#ifdef HAVE_LIBIDN2 +static void idn_locale_to_ace(const char *src, char *dst, size_t dstlen); +static void idn_ace_to_locale(const char *src, char **dst); +static isc_result_t idn_output_filter(isc_buffer_t *buffer, + unsigned int used_org); +#endif /* HAVE_LIBIDN2 */ isc_socket_t *keep = NULL; isc_sockaddr_t keepaddr; @@ -638,16 +624,13 @@ make_empty_lookup(void) { looknew->ttlunits = ISC_FALSE; looknew->ttlunits = ISC_FALSE; looknew->qr = ISC_FALSE; -#ifdef WITH_IDN_SUPPORT +#ifdef HAVE_LIBIDN2 looknew->idnin = ISC_TRUE; -#else - looknew->idnin = ISC_FALSE; -#endif -#ifdef WITH_IDN_OUT_SUPPORT looknew->idnout = ISC_TRUE; #else + looknew->idnin = ISC_FALSE; looknew->idnout = ISC_FALSE; -#endif +#endif /* HAVE_LIBIDN2 */ looknew->udpsize = 0; looknew->edns = -1; looknew->recurse = ISC_TRUE; @@ -1301,16 +1284,6 @@ setup_system(isc_boolean_t ipv4only, isc_boolean_t ipv6only) { (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) setup_file_key(); else if (keysecret[0] != 0) @@ -2033,15 +2006,13 @@ setup_lookup(dig_lookup_t *lookup) { char cookiebuf[256]; char *origin = NULL; char *textname = NULL; -#ifdef WITH_IDN_SUPPORT +#ifdef HAVE_LIBIDN2 char idn_origin[MXNAME], idn_textname[MXNAME]; -#endif -#ifdef WITH_IDN_OUT_SUPPORT result = dns_name_settotextfilter(lookup->idnout ? - output_filter : NULL); + idn_output_filter : NULL); check_result(result, "dns_name_settotextfilter"); -#endif +#endif /* HAVE_LIBIDN2 */ REQUIRE(lookup != NULL); INSIST(!free_now); @@ -2076,14 +2047,13 @@ setup_lookup(dig_lookup_t *lookup) { * TLD. */ textname = lookup->textname; -#ifdef WITH_IDN_SUPPORT +#ifdef HAVE_LIBIDN2 if (lookup->idnin) { - result = idn_locale_to_ace(textname, idn_textname, sizeof(idn_textname)); - check_result(result, "convert textname to IDN encoding"); + idn_locale_to_ace(textname, idn_textname, sizeof(idn_textname)); debug("idn_textname: %s", idn_textname); textname = idn_textname; } -#endif +#endif /* HAVE_LIBIDN2 */ /* * If the name has too many dots, force the origin to be NULL @@ -2112,14 +2082,14 @@ setup_lookup(dig_lookup_t *lookup) { dns_name_init(lookup->oname, NULL); /* XXX Helper funct to conv char* to name? */ origin = lookup->origin->origin; -#ifdef WITH_IDN_SUPPORT +#ifdef HAVE_LIBIDN2 if (lookup->idnin) { - result = idn_locale_to_ace(origin, idn_origin, sizeof(idn_origin)); - check_result(result, "convert origin to IDN encoding"); + idn_locale_to_ace(origin, idn_origin, + sizeof(idn_origin)); debug("trying idn origin %s", idn_origin); origin = idn_origin; } -#endif +#endif /* HAVE_LIBIDN2 */ len = (unsigned int) strlen(origin); isc_buffer_init(&b, origin, len); isc_buffer_add(&b, len); @@ -4144,9 +4114,9 @@ cancel_all(void) { */ void destroy_libs(void) { -#ifdef WITH_IDN_SUPPORT +#ifdef HAVE_LIBIDN2 isc_result_t result; -#endif +#endif /* HAVE_LIBIDN2 */ if (keep != NULL) isc_socket_detach(&keep); @@ -4178,10 +4148,10 @@ destroy_libs(void) { clear_searchlist(); -#ifdef WITH_IDN_SUPPORT +#ifdef HAVE_LIBIDN2 result = dns_name_settotextfilter(NULL); check_result(result, "dns_name_settotextfilter"); -#endif +#endif /* HAVE_LIBIDN2 */ dns_name_destroy(); if (commctx != NULL) { @@ -4221,135 +4191,151 @@ destroy_libs(void) { isc_mem_destroy(&mctx); } -#ifdef WITH_IDN_OUT_SUPPORT +#ifdef HAVE_LIBIDN2 static isc_result_t -output_filter(isc_buffer_t *buffer, unsigned int used_org, - isc_boolean_t absolute) -{ - char tmp1[MAXDLEN], tmp2[MAXDLEN]; - size_t fromlen, tolen; - isc_boolean_t end_with_dot; - isc_result_t result; +idn_output_filter(isc_buffer_t *buffer, unsigned int used_org) { + char src[MXNAME], *dst; + size_t srclen, dstlen; /* - * Copy contents of 'buffer' to 'tmp1', supply trailing dot - * if 'absolute' is true, and terminate with NUL. + * Copy name from 'buffer' to 'src' and terminate it with NULL. */ - 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) { - fromlen++; - if (fromlen >= MAXDLEN) - return (ISC_R_SUCCESS); - tmp1[fromlen - 1] = '.'; - } - - tmp1[fromlen] = '\0'; - - /* - * Convert contents of 'tmp1' to local encoding. - */ - result = idn_ace_to_locale(tmp1, tmp2, sizeof(tmp2)); - if (result != ISC_R_SUCCESS) { + srclen = isc_buffer_usedlength(buffer) - used_org; + if (srclen > sizeof(src)) { + warn("Input name too long to perform IDN conversion"); return (ISC_R_SUCCESS); } - /* - * Copy the converted contents in 'tmp1' back to 'buffer'. - * If we have appended trailing dot, remove it. - */ - tolen = strlen(tmp2); - if (absolute && !end_with_dot && tmp2[tolen - 1] == '.') - tolen--; + memmove(src, (char *)isc_buffer_base(buffer) + used_org, srclen); + src[srclen] = '\0'; - if (isc_buffer_length(buffer) < used_org + tolen) + /* + * Convert 'src' to the current locale's character encoding. + */ + idn_ace_to_locale(src, &dst); + + /* + * Check whether the converted name will fit back into 'buffer'. + */ + dstlen = strlen(dst); + if (isc_buffer_length(buffer) < used_org + dstlen) { + idn2_free(dst); return (ISC_R_NOSPACE); + } - isc_buffer_subtract(buffer, isc_buffer_usedlength(buffer) - used_org); - memmove(isc_buffer_used(buffer), tmp2, tolen); - isc_buffer_add(buffer, (unsigned int)tolen); + /* + * Put the converted name back into 'buffer'. + */ + isc_buffer_subtract(buffer, srclen); + memmove(isc_buffer_used(buffer), dst, dstlen); + isc_buffer_add(buffer, dstlen); + + /* + * Clean up. + */ + idn2_free(dst); return (ISC_R_SUCCESS); } -#endif -#ifdef WITH_IDN_SUPPORT -#ifdef WITH_LIBIDN2 +/*% + * Convert 'src', which is a string using the current locale's character + * encoding, into an ACE string suitable for use in the DNS, storing the + * conversion result in 'dst', which is 'dstlen' bytes large. + * + * 'dst' MUST be large enough to hold any valid domain name. + */ static void -idn_initialize(void) { -} - -static isc_result_t -idn_locale_to_ace(const char *from, char *to, size_t tolen) { +idn_locale_to_ace(const char *src, char *dst, size_t dstlen) { + const char *final_src; + char *ascii_src; int res; - char *tmp_str = NULL; - res = idn2_to_ascii_lz(from, &tmp_str, IDN2_NONTRANSITIONAL|IDN2_NFC_INPUT); - if (res == IDN2_DISALLOWED) { - res = idn2_to_ascii_lz(from, &tmp_str, IDN2_TRANSITIONAL|IDN2_NFC_INPUT); + /* + * We trust libidn2 to return an error if 'src' is too large to be a + * valid domain name. + */ + res = idn2_to_ascii_lz(src, &ascii_src, IDN2_NONTRANSITIONAL); + if (res != IDN2_OK) { + fatal("'%s' is not a legal IDNA2008 name (%s), use +noidnin", + src, idn2_strerror(res)); } - if (res == IDN2_OK) { - /* - * idn2_to_ascii_lz() normalizes all strings to lowerl case, - * but we generally don't want to lowercase all input strings; - * make sure to return the original case if the two strings - * differ only in case - */ - if (!strcasecmp(from, tmp_str)) { - if (strlen(from) >= tolen) { - debug("from string is too long"); - idn2_free(tmp_str); - return ISC_R_NOSPACE; - } - idn2_free(tmp_str); - (void) strlcpy(to, from, tolen); - return ISC_R_SUCCESS; - } - /* check the length */ - if (strlen(tmp_str) >= tolen) { - debug("ACE string is too long"); - idn2_free(tmp_str); - return ISC_R_NOSPACE; - } + /* + * idn2_to_ascii_lz() normalizes all strings to lower case, but we + * generally don't want to lowercase all input strings; make sure to + * return the original case if the two strings differ only in case. + */ + final_src = (strcasecmp(src, ascii_src) == 0 ? src : ascii_src); - (void) strlcpy(to, tmp_str, tolen); - idn2_free(tmp_str); - return ISC_R_SUCCESS; - } + (void)strlcpy(dst, final_src, dstlen); - fatal("'%s' is not a legal IDN name (%s), use +noidnin", from, idn2_strerror(res)); - return ISC_R_FAILURE; + idn2_free(ascii_src); } -#ifdef WITH_IDN_OUT_SUPPORT -static isc_result_t -idn_ace_to_locale(const char *from, char *to, size_t tolen) { +/*% + * Convert 'src', which is an ACE string suitable for use in the DNS, into a + * string using the current locale's character encoding, storing the conversion + * result in 'dst'. + * + * The caller MUST subsequently release 'dst' using idn2_free(). + */ +static void +idn_ace_to_locale(const char *src, char **dst) { + char *local_src, *utf8_src; 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) strlcpy(to, tmp_str, tolen); - idn2_free(tmp_str); - return ISC_R_SUCCESS; + /* + * We need to: + * + * 1) check whether 'src' is a valid IDNA2008 name, + * 2) if it is, output it in the current locale's character encoding. + * + * Unlike idn2_to_ascii_*(), idn2_to_unicode_*() functions are unable + * to perform IDNA2008 validity checks. Thus, we need to decode any + * Punycode in 'src', check if the resulting name is a valid IDNA2008 + * name, and only once we ensure it is, output that name in the current + * locale's character encoding. + * + * We could just use idn2_to_unicode_8zlz() + idn2_to_ascii_lz(), but + * then we would not be able to universally tell invalid names and + * character encoding errors apart (if the current locale uses ASCII + * for character encoding, the former function would fail even for a + * valid IDNA2008 name, as long as it contained any non-ASCII + * character). Thus, we need to take a longer route. + * + * First, convert 'src' to UTF-8, ignoring the current locale. + */ + res = idn2_to_unicode_8z8z(src, &utf8_src, 0); + if (res != IDN2_OK) { + fatal("Bad ACE string '%s' (%s), use +noidnout", + src, idn2_strerror(res)); } - fatal("'%s' is not a legal IDN name (%s), use +noidnout", from, idn2_strerror(res)); - return ISC_R_FAILURE; + /* + * Then, check whether decoded 'src' is a valid IDNA2008 name. + */ + res = idn2_to_ascii_8z(utf8_src, NULL, IDN2_NONTRANSITIONAL); + if (res != IDN2_OK) { + fatal("'%s' is not a legal IDNA2008 name (%s), use +noidnout", + src, idn2_strerror(res)); + } + + /* + * Finally, try converting the decoded 'src' into the current locale's + * character encoding. + */ + res = idn2_to_unicode_8zlz(utf8_src, &local_src, 0); + if (res != IDN2_OK) { + fatal("Cannot represent '%s' in the current locale (%s), " + "use +noidnout or a different locale", + src, idn2_strerror(res)); + } + + /* + * Free the interim conversion result. + */ + idn2_free(utf8_src); + + *dst = local_src; } -#endif /* WITH_IDN_OUT_SUPPORT */ -#endif /* WITH_LIBIDN2 */ -#endif /* WITH_IDN_SUPPORT */ +#endif /* HAVE_LIBIDN2 */ diff --git a/bin/tests/system/feature-test.c b/bin/tests/system/feature-test.c index 0c20930cc4..f95ce4742a 100644 --- a/bin/tests/system/feature-test.c +++ b/bin/tests/system/feature-test.c @@ -153,7 +153,7 @@ main(int argc, char **argv) { } if (strcmp(argv[1], "--with-idn") == 0) { -#ifdef WITH_LIBIDN2 +#ifdef HAVE_LIBIDN2 return (0); #else return (1); diff --git a/bin/tests/system/idna/tests.sh b/bin/tests/system/idna/tests.sh index 3a9b91b442..644aa3eccb 100644 --- a/bin/tests/system/idna/tests.sh +++ b/bin/tests/system/idna/tests.sh @@ -136,46 +136,6 @@ idna_fail() { status=`expr $status + $ret` } -# Check if current version of libidn2 is >= a given version -# -# This requires that: -# a) "pkg-config" exists on the system -# b) The libidn2 installed has an associated ".pc" file -# c) The system sort command supports "-V" -# -# $1 - Minimum version required -# -# Returns: -# 0 - Version check is OK, libidn2 at required version or greater. -# 1 - Version check was made, but libidn2 not at required version. -# 2 - Could not carry out version check - -libidn_version_check() { - ret=2 - if [ -n "`command -v pkg-config`" ]; then - version=`pkg-config --modversion --silence-errors libidn2` - if [ -n "$version" ]; then - # Does the sort command have a "-V" flag on this system? - sort -V 2>&1 > /dev/null << . -. - if [ $? -eq 0 ]; then - # Sort -V exists. Sort the IDN version and the minimum version - # required. If the IDN version is greater than or equal to that - # version, it will appear last in the list. - last_version=`printf "%s\n" $version $1 | sort -V | tail -1` - if [ "$version" = "$last_version" ]; then - ret=0 - else - ret=1 - fi - fi - fi - fi - - return $ret -} - - # Function to check that case is preserved for an all-ASCII label. # # Without IDNA support, case-preservation is the expected behavior. @@ -310,16 +270,7 @@ idna_enabled_test() { text="Checking fake A-label" idna_fail "$text" "" "xn--ahahah" idna_test "$text" "+noidnin +noidnout" "xn--ahahah" "xn--ahahah." - - # Owing to issues with libdns, the next test will fail for versions of - # libidn earlier than 2.0.5. For this reason, get the version (if - # available) and compare with 2.0.5. - libidn_version_check 2.0.5 - if [ $? -ne 0 ]; then - echo_i "Skipping fake A-label +noidnin +idnout test (libidn2 version issues)" - else - idna_test "$text" "+noidnin +idnout" "xn--ahahah" "xn--ahahah." - fi + idna_fail "$text" "+noidnin +idnout" "xn--ahahah" idna_fail "$text" "+idnin +noidnout" "xn--ahahah" idna_fail "$text" "+idnin +idnout" "xn--ahahah" @@ -327,7 +278,7 @@ idna_enabled_test() { # BIND rejects such labels: with +idnin label="xn--xflod18hstflod18hstflod18hstflod18hstflod18hstflod18-1iejjjj" - text="Checking punycode label shorter than minimum valid length" + text="Checking punycode label longer than maximum valid length" idna_fail "$text" "" "$label" idna_fail "$text" "+noidnin +noidnout" "$label" idna_fail "$text" "+noidnin +idnout" "$label" @@ -337,9 +288,11 @@ idna_enabled_test() { - # Tests of a valid unicode string but an invalid U-label + # Tests of a valid unicode string but an invalid U-label (input) # - # Symbols are not valid IDNA names. + # Symbols are not valid IDNA2008 names. Check whether dig rejects them + # when they are supplied on the command line to ensure no IDNA2003 + # fallbacks are in place. # # +noidnin: "dig" should send unicode octets to the server and display the # returned qname in the same form. @@ -347,12 +300,34 @@ idna_enabled_test() { # # The +[no]idnout options should not have any effect on the test. - text="Checking invalid U-label" - idna_fail "$text" "" "🧦.com" - idna_test "$text" "+noidnin +noidnout" "🧦.com" "\240\159\167\166.com." - idna_test "$text" "+noidnin +idnout" "🧦.com" "\240\159\167\166.com." - idna_fail "$text" "+idnin +noidnout" "🧦.com" - idna_fail "$text" "+idnin +idnout" "🧦.com" + text="Checking invalid input U-label" + idna_fail "$text" "" "√.com" + idna_test "$text" "+noidnin +noidnout" "√.com" "\226\136\154.com." + idna_test "$text" "+noidnin +idnout" "√.com" "\226\136\154.com." + idna_fail "$text" "+idnin +noidnout" "√.com" + idna_fail "$text" "+idnin +idnout" "√.com" + + # Tests of a valid unicode string but an invalid U-label (output) + # + # Symbols are not valid IDNA2008 names. Check whether dig rejects them + # when they are received in DNS responses to ensure no IDNA2003 fallbacks + # are in place. + # + # Note that an invalid U-label is accepted even when +idnin is in effect + # because "xn--19g" is valid Punycode. + # + # +noidnout: "dig" should send the ACE string to the server and display the + # returned qname. + # +idnout: "dig" should generate an error. + # + # The +[no]idnin options should not have any effect on the test. + + text="Checking invalid output U-label" + idna_fail "$text" "" "xn--19g" + idna_test "$text" "+noidnin +noidnout" "xn--19g" "xn--19g." + idna_fail "$text" "+noidnin +idnout" "xn--19g" + idna_test "$text" "+idnin +noidnout" "xn--19g" "xn--19g." + idna_fail "$text" "+idnin +idnout" "xn--19g" } diff --git a/config.h.in b/config.h.in index 94f5aab4d0..deee256e1b 100644 --- a/config.h.in +++ b/config.h.in @@ -293,6 +293,9 @@ int sigwait(const unsigned int *set, int *sig); /* Define to 1 if you have the header file. */ #undef HAVE_GSSAPI_KRB5_H +/* Define to 1 if you have the header file. */ +#undef HAVE_IDN2_H + /* Define to 1 if you have the if_nametoindex function. */ #undef HAVE_IF_NAMETOINDEX @@ -323,6 +326,9 @@ int sigwait(const unsigned int *set, int *sig); /* Define to 1 if you have the `c_r' library (-lc_r). */ #undef HAVE_LIBC_R +/* Define if libidn2 was found */ +#undef HAVE_LIBIDN2 + /* Define to 1 if you have the `nsl' library (-lnsl). */ #undef HAVE_LIBNSL @@ -620,15 +626,6 @@ int sigwait(const unsigned int *set, int *sig); /* Define to enable very verbose query trace logging. */ #undef WANT_QUERYTRACE -/* 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). */ #if defined AC_APPLE_UNIVERSAL_BUILD diff --git a/configure b/configure index 4c48cb51c8..258b61b62f 100755 --- a/configure +++ b/configure @@ -676,6 +676,7 @@ ATFBUILD LD_WRAP_TESTS CMOCKA_LIBS CMOCKA_CFLAGS +LIBIDN2_LDFLAGS LIBIDN2_LIBS LIBIDN2_CFLAGS XSLT_DBLATEX_FASTBOOK @@ -1059,6 +1060,8 @@ CPP PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR +LIBIDN2_CFLAGS +LIBIDN2_LIBS CMOCKA_CFLAGS CMOCKA_LIBS' @@ -1762,7 +1765,8 @@ 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-libidn2=PATH enable IDN support using GNU libidn2 [yes|no|path] + --with-libidn2=PATH enable IDN support using GNU libidn2 + [yes|no(default)|path] --with-cmocka=no enable cmocka based tests (default is no) --with-atf support Automated Test Framework --with-tuning=ARG Specify server tuning (large or default) @@ -1801,6 +1805,10 @@ Some influential environment variables: directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path + LIBIDN2_CFLAGS + C compiler flags for LIBIDN2, overriding pkg-config + LIBIDN2_LIBS + linker flags for LIBIDN2, overriding pkg-config CMOCKA_CFLAGS C compiler flags for CMOCKA, overriding pkg-config CMOCKA_LIBS linker flags for CMOCKA, overriding pkg-config @@ -22416,34 +22424,135 @@ LIBIDN2_LIBS= # Check whether --with-libidn2 was given. if test "${with_libidn2+set}" = set; then : - withval=$with_libidn2; use_libidn2="$withval" + withval=$with_libidn2; with_libidn2="$withval" else - use_libidn2="no" + with_libidn2="no" fi -case $use_libidn2 in #( - no) : - : ;; #( +case $with_libidn2 in #( yes) : - : ;; #( - *) : - LIBIDN2_CFLAGS="-I$use_libidn2/include" - LIBIDN2_LDFLAGS="-L$use_libidn2/lib" - ;; #( - *) : - ;; -esac +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libidn2" >&5 +$as_echo_n "checking for libidn2... " >&6; } -if test "$use_libidn2" != "no"; then : - save_CFLAGS="$CFLAGS" - save_LIBS="$LIBS" - save_LDFLAGS="$LDFLAGS" - CFLAGS="$LIBIDN2_CFLAGS $CFLAGS" - LDFLAGS="$LIBIDN2_LDFLAGS $LDFLAGS" - { $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 : +if test -n "$LIBIDN2_CFLAGS"; then + pkg_cv_LIBIDN2_CFLAGS="$LIBIDN2_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libidn2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libidn2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBIDN2_CFLAGS=`$PKG_CONFIG --cflags "libidn2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBIDN2_LIBS"; then + pkg_cv_LIBIDN2_LIBS="$LIBIDN2_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libidn2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libidn2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBIDN2_LIBS=`$PKG_CONFIG --libs "libidn2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBIDN2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libidn2" 2>&1` + else + LIBIDN2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libidn2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBIDN2_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (libidn2) were not met: + +$LIBIDN2_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LIBIDN2_CFLAGS +and LIBIDN2_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LIBIDN2_CFLAGS +and LIBIDN2_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see . +See \`config.log' for more details" "$LINENO" 5; } +else + LIBIDN2_CFLAGS=$pkg_cv_LIBIDN2_CFLAGS + LIBIDN2_LIBS=$pkg_cv_LIBIDN2_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_LIBIDN2 1" >>confdefs.h + +fi ;; #( + no) : + ;; #( + *) : + save_CFLAGS="$CFLAGS" + save_CPPFLAGS="$CPPFLAGS" + save_LDFLAGS="$LDFLAGS" + save_LIBS="$LIBS" + LIBIDN2_CFLAGS="-I$with_libidn2/include" + LIBIDN2_LDFLAGS="-L$with_libidn2/lib" + CFLAGS="$LIBIDN2_CFLAGS $CFLAGS" + CPPFLAGS="$LIBIDN2_CFLAGS $CPPFLAGS" + LDFLAGS="$LIBIDN2_LDFLAGS $LDFLAGS" + for ac_header in idn2.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "idn2.h" "ac_cv_header_idn2_h" "$ac_includes_default" +if test "x$ac_cv_header_idn2_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_IDN2_H 1 +_ACEOF + +else + as_fn_error $? "idn2.h not found" "$LINENO" 5 +fi + +done + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing idn2_to_ascii_lz" >&5 +$as_echo_n "checking for library containing idn2_to_ascii_lz... " >&6; } +if ${ac_cv_search_idn2_to_ascii_lz+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS @@ -22456,11 +22565,11 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char idn2_to_ascii_8z (); +char idn2_to_ascii_lz (); int main () { -return idn2_to_ascii_8z (); +return idn2_to_ascii_lz (); ; return 0; } @@ -22473,66 +22582,42 @@ for ac_lib in '' idn2; do 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 + ac_cv_search_idn2_to_ascii_lz=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext - if ${ac_cv_search_idn2_to_ascii_8z+:} false; then : + if ${ac_cv_search_idn2_to_ascii_lz+:} false; then : break fi done -if ${ac_cv_search_idn2_to_ascii_8z+:} false; then : +if ${ac_cv_search_idn2_to_ascii_lz+:} false; then : else - ac_cv_search_idn2_to_ascii_8z=no + ac_cv_search_idn2_to_ascii_lz=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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_idn2_to_ascii_lz" >&5 +$as_echo "$ac_cv_search_idn2_to_ascii_lz" >&6; } +ac_res=$ac_cv_search_idn2_to_ascii_lz if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + LIBIDN2_LIBS="$ac_cv_search_idn2_to_ascii_lz" -$as_echo "#define WITH_IDN_SUPPORT 1" >>confdefs.h +$as_echo "#define HAVE_LIBIDN2 1" >>confdefs.h - -$as_echo "#define WITH_LIBIDN2 1" >>confdefs.h - - LIBIDN2_LIBS="$LIBIDN2_LDFLAGS -lidn2" else as_fn_error $? "libidn2 requested, but not found" "$LINENO" 5 fi - 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 - CFLAGS="$save_CFLAGS" - LIBS="$save_LIBS" - LDFLAGS="$save_LDFLAGS" - -fi + CFLAGS="$save_CFLAGS" + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" ;; #( + *) : + ;; +esac @@ -26684,7 +26769,7 @@ report() { test "X$JSONSTATS" = "X" || echo " JSON statistics (--with-libjson)" test "X$ZLIB" = "X" || echo " HTTP zlib compression (--with-zlib)" test "X$NZD_TOOLS" = "X" || echo " LMDB database to store configuration for 'addzone' zones (--with-lmdb)" - test "no" = "$use_libidn2" || echo " IDN support (--with-libidn2)" + test "no" = "$with_libidn2" || echo " IDN support (--with-libidn2)" fi if test "no" != "$use_pkcs11"; then @@ -26781,7 +26866,7 @@ report() { test "X$JSONSTATS" = "X" && echo " JSON statistics (--with-libjson)" test "X$ZLIB" = "X" && echo " HTTP zlib compression (--with-zlib)" test "X$NZD_TOOLS" = "X" && echo " LMDB database to store configuration for 'addzone' zones (--with-lmdb)" - test "no" = "$use_libidn2" && echo " IDN support (--with-libidn2)" + test "no" = "$with_libidn2" && echo " IDN support (--with-libidn2)" echo "-------------------------------------------------------------------------------" echo "Configured paths:" diff --git a/configure.in b/configure.in index 7824531d2b..17506d2e9a 100644 --- a/configure.in +++ b/configure.in @@ -4521,38 +4521,35 @@ NOM_PATH_FILE(XSLT_DBLATEX_FASTBOOK, xsl/latex_book_fast.xsl, $dblatex_xsl_trees LIBIDN2_CFLAGS= LIBIDN2_LDFLAGS= 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_CFLAGS="-I$use_libidn2/include" - LIBIDN2_LDFLAGS="-L$use_libidn2/lib" - ]) - -AS_IF([test "$use_libidn2" != "no"], - [save_CFLAGS="$CFLAGS" - save_LIBS="$LIBS" - save_LDFLAGS="$LDFLAGS" - CFLAGS="$LIBIDN2_CFLAGS $CFLAGS" - LDFLAGS="$LIBIDN2_LDFLAGS $LDFLAGS" - AC_SEARCH_LIBS([idn2_to_ascii_8z], [idn2], - [AC_DEFINE(WITH_IDN_SUPPORT, 1, [define if IDN input support is to be included.]) - AC_DEFINE(WITH_LIBIDN2, 1, [define if libidn2 support is to be included.]) - LIBIDN2_LIBS="$LIBIDN2_LDFLAGS -lidn2"], - [AC_MSG_ERROR([libidn2 requested, but not found])]) - 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])]) - CFLAGS="$save_CFLAGS" - LIBS="$save_LIBS" - LDFLAGS="$save_LDFLAGS" - ]) +AC_ARG_WITH([libidn2], + [AS_HELP_STRING([--with-libidn2[=PATH]], [enable IDN support using GNU libidn2 [yes|no(default)|path]])], + [with_libidn2="$withval"], [with_libidn2="no"]) +AS_CASE([$with_libidn2], + [yes], [PKG_CHECK_MODULES([LIBIDN2], [libidn2], + [AC_DEFINE([HAVE_LIBIDN2], [1], [Define if libidn2 was found])])], + [no], [], + [*], [save_CFLAGS="$CFLAGS" + save_CPPFLAGS="$CPPFLAGS" + save_LDFLAGS="$LDFLAGS" + save_LIBS="$LIBS" + LIBIDN2_CFLAGS="-I$with_libidn2/include" + LIBIDN2_LDFLAGS="-L$with_libidn2/lib" + CFLAGS="$LIBIDN2_CFLAGS $CFLAGS" + CPPFLAGS="$LIBIDN2_CFLAGS $CPPFLAGS" + LDFLAGS="$LIBIDN2_LDFLAGS $LDFLAGS" + AC_CHECK_HEADERS([idn2.h], + [], + [AC_MSG_ERROR([idn2.h not found])]) + AC_SEARCH_LIBS([idn2_to_ascii_lz], [idn2], + [LIBIDN2_LIBS="$ac_cv_search_idn2_to_ascii_lz" + AC_DEFINE([HAVE_LIBIDN2], [1], [Define if libidn2 was found])], + [AC_MSG_ERROR([libidn2 requested, but not found])]) + CFLAGS="$save_CFLAGS" + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS"]) AC_SUBST([LIBIDN2_CFLAGS]) +AC_SUBST([LIBIDN2_LDFLAGS]) AC_SUBST([LIBIDN2_LIBS]) # @@ -5313,7 +5310,7 @@ report() { test "X$JSONSTATS" = "X" || echo " JSON statistics (--with-libjson)" test "X$ZLIB" = "X" || echo " HTTP zlib compression (--with-zlib)" test "X$NZD_TOOLS" = "X" || echo " LMDB database to store configuration for 'addzone' zones (--with-lmdb)" - test "no" = "$use_libidn2" || echo " IDN support (--with-libidn2)" + test "no" = "$with_libidn2" || echo " IDN support (--with-libidn2)" fi if test "no" != "$use_pkcs11"; then @@ -5410,7 +5407,7 @@ report() { test "X$JSONSTATS" = "X" && echo " JSON statistics (--with-libjson)" test "X$ZLIB" = "X" && echo " HTTP zlib compression (--with-zlib)" test "X$NZD_TOOLS" = "X" && echo " LMDB database to store configuration for 'addzone' zones (--with-lmdb)" - test "no" = "$use_libidn2" && echo " IDN support (--with-libidn2)" + test "no" = "$with_libidn2" && echo " IDN support (--with-libidn2)" echo "-------------------------------------------------------------------------------" echo "Configured paths:" diff --git a/lib/dns/include/dns/name.h b/lib/dns/include/dns/name.h index ea6d772361..74d114e1ef 100644 --- a/lib/dns/include/dns/name.h +++ b/lib/dns/include/dns/name.h @@ -192,8 +192,7 @@ LIBDNS_EXTERNAL_DATA extern const dns_name_t *dns_wildcardname; * is from 'buffer'->base + 'used_org' to the end of the used region. */ typedef isc_result_t (*dns_name_totextfilter_t)(isc_buffer_t *target, - unsigned int used_org, - isc_boolean_t absolute); + unsigned int used_org); /*** *** Initialization diff --git a/lib/dns/name.c b/lib/dns/name.c index 5dc3e35e6f..75225f3ee3 100644 --- a/lib/dns/name.c +++ b/lib/dns/name.c @@ -1517,7 +1517,7 @@ dns_name_totext2(const dns_name_t *name, unsigned int options, totext_filter_proc = *mem; #endif if (totext_filter_proc != NULL) - return ((*totext_filter_proc)(target, oused, saw_root)); + return ((*totext_filter_proc)(target, oused)); return (ISC_R_SUCCESS); }