]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Remove conversion from locale to utf8 from public API
authorPetr Menšík <pemensik@redhat.com>
Tue, 15 Aug 2017 12:36:59 +0000 (14:36 +0200)
committerOndřej Surý <ondrej@sury.org>
Sat, 17 Mar 2018 13:13:47 +0000 (13:13 +0000)
Emit fatal failures on locale to ACE encoding

Separate idnout support, disable it for libidn2 < 2.0

Add custom path to libidn. Leave default path for multilib support.

Allow turning off IDN input processing by dig option

Improve documentation, fix support in host

Fix configure changes to adjust help text

Use strlcpy with size guard

Improve IDN variants choosing. Fix idn2 function name.

Remove immediate idn_locale_to_ace and idn_ace_to_locale.

Signed-off-by: Petr Menšík <pemensik@redhat.com>
bin/dig/dig.c
bin/dig/dig.docbook
bin/dig/dighost.c
bin/dig/host.c
bin/dig/include/dig/dig.h
config.h.in
configure.in

index 0181db614af398bb8ed530c2c767094887da9b3a..482809ccf03cf73c53a1d186e8fdd5c3588783b2 100644 (file)
@@ -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,12 +1046,28 @@ plus_option(const char *option, isc_boolean_t is_batchfile,
                                lookup->identify = state;
                                break;
                        case 'n':
-                               FULLCHECK("idnout");
+                               switch (cmd[3]) {
+                               case 'i':
+                                       FULLCHECK("idnin");
 #ifndef WITH_IDN_SUPPORT
-                               fprintf(stderr, ";; IDN support not enabled\n");
+                                       fprintf(stderr, ";; IDN input support"
+                                               " not enabled\n");
+#else
+                                       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;
+                                       lookup->idnout = state;
 #endif
+                                       break;
+                               default:
+                                       goto invalid_option;
+                               }
                                break;
                        default:
                                goto invalid_option;
index 219cfd5dee0a1f003ca518498fefb6f34a390c79..80318bb32fa11ee214c13dacb566e155492acc9b 100644 (file)
          </listitem>
        </varlistentry>
 
+       <varlistentry>
+         <term><option>+[no]idnin</option></term>
+         <listitem>
+           <para>
+             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.
+           </para>
+         </listitem>
+       </varlistentry>
+
        <varlistentry>
          <term><option>+[no]idnout</option></term>
          <listitem>
@@ -1288,10 +1299,9 @@ dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr
       <command>dig</command> 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 <envar>IDN_DISABLE</envar> environment variable.
-      The IDN support is disabled if the variable is set when
-      <command>dig</command> runs.
+      If you'd like to turn off the IDN support for some reason, use 
+      parameters <parameter>+noidnin</parameter> and
+      <parameter>+noidnout</parameter>.
     </para>
   </refsection>
 
index d752d156a474c6566b757324e3073f814b29200e..efa8b49e365c3b7736c74c9b2599fcf84458ba41 100644 (file)
@@ -148,59 +148,31 @@ static char servercookie[256];
 
 #ifdef WITH_IDN_SUPPORT
 static void idn_initialize(void);
-static isc_result_t idn_locale_to_utf8(const char *from,
-               char *to,
-               size_t tolen);
-static isc_result_t idn_utf8_to_ace(const char *from,
+static isc_result_t idn_locale_to_ace(const char *from,
                char *to,
                size_t tolen);
+
+#ifdef WITH_IDNKIT
+static isc_result_t idnkit_initialize(void);
+#endif
+#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);
-static isc_result_t append_textname(char *name,
-               const char *origin,
-               size_t namesize);
-
 #define MAXDLEN 256
 
 #ifdef WITH_IDNKIT
-static isc_result_t idnkit_initialize(void);
-static isc_result_t idnkit_locale_to_utf8(const char *from,
-               char *to,
-               size_t tolen);
-static isc_result_t idnkit_utf8_to_ace(const char *from,
-               char *to,
-               size_t tolen);
-static isc_result_t idnkit_ace_to_locale(const char *from,
-               char *to,
-               size_t tolen);
-
-#elif WITH_LIBIDN
-static isc_result_t libidn_locale_to_utf8(const char *from,
-               char *to,
-               size_t tolen);
-static isc_result_t libidn_utf8_to_ace(const char *from,
-               char *to,
-               size_t tolen);
-static isc_result_t libidn_ace_to_locale(const char *from,
-               char *to,
-               size_t tolen);
-
-#elif WITH_LIBIDN2
-static isc_result_t libidn2_locale_to_utf8(const char *from,
-               char *to,
-               size_t tolen);
-static isc_result_t libidn2_utf8_to_ace(const char *from,
-               char *to,
-               size_t tolen);
-static isc_result_t libidn2_ace_to_locale(const char *from,
+int idnoptions = 0;
+#endif
+static isc_result_t idn_ace_to_locale(const char *from,
                char *to,
                size_t tolen);
-#endif
-#endif /* WITH_IDN_SUPPORT */
+#endif /* WITH_IDN_OUT_SUPPORT */
 
 isc_socket_t *keep = NULL;
 isc_sockaddr_t keepaddr;
@@ -701,7 +673,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;
@@ -846,6 +823,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;
@@ -1353,6 +1331,12 @@ setup_system(isc_boolean_t ipv4only, isc_boolean_t ipv6only) {
        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)
@@ -2081,11 +2065,13 @@ setup_lookup(dig_lookup_t *lookup) {
        char store[MXNAME];
        char ecsbuf[20];
        char cookiebuf[256];
+       char *origin = NULL;
+       char *textname = NULL;
 #ifdef WITH_IDN_SUPPORT
-       char utf8_textname[MXNAME], utf8_origin[MXNAME], idn_textname[MXNAME];
+       char idn_origin[MXNAME], idn_textname[MXNAME];
 #endif
 
-#ifdef WITH_IDN_SUPPORT
+#ifdef WITH_IDN_OUT_SUPPORT
        result = dns_name_settotextfilter(lookup->idnout ?
                                          output_filter : NULL);
        check_result(result, "dns_name_settotextfilter");
@@ -2123,10 +2109,15 @@ setup_lookup(dig_lookup_t *lookup) {
         * `textname' doesn't contain TLD, but local mapping needs
         * TLD.
         */
+       textname = lookup->textname;
 #ifdef WITH_IDN_SUPPORT
-       result = idn_locale_to_utf8(lookup->textname, utf8_textname,
-                                   sizeof(utf8_textname));
-       check_result(result, "convert textname to UTF-8");
+       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
 
        /*
@@ -2137,11 +2128,7 @@ 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_SUPPORT
-               if ((count_dots(utf8_textname) >= ndots) || !usesearch)
-#else
-               if ((count_dots(lookup->textname) >= ndots) || !usesearch)
-#endif
+               if ((count_dots(textname) >= ndots) || !usesearch)
                {
                        lookup->origin = NULL; /* Force abs lookup */
                        lookup->done_as_is = ISC_TRUE;
@@ -2152,26 +2139,6 @@ setup_lookup(dig_lookup_t *lookup) {
                }
        }
 
-#ifdef WITH_IDN_SUPPORT
-       if (lookup->origin != NULL) {
-               debug("trying origin %s", lookup->origin->origin);
-               result = idn_locale_to_utf8(lookup->origin->origin,
-                                           utf8_origin, sizeof(utf8_origin));
-               check_result(result, "convert origin to UTF-8");
-               result = append_textname(utf8_textname,
-                                        utf8_origin, sizeof(utf8_textname));
-               check_result(result, "append origin to textname");
-       }
-       result = idn_utf8_to_ace(utf8_textname,
-                                idn_textname, sizeof(idn_textname));
-       if (lookup->origin != NULL && result == ISC_R_NOSPACE) {
-               dns_message_puttempname(lookup->sendmsg,
-                                       &lookup->name);
-               return ISC_FALSE;
-       }
-       check_result(result, "convert UTF-8 textname to IDN encoding");
-
-#else /* WITH_IDN_SUPPORT */
        if (lookup->origin != NULL) {
                debug("trying origin %s", lookup->origin->origin);
                result = dns_message_gettempname(lookup->sendmsg,
@@ -2179,8 +2146,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);
@@ -2190,7 +2167,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) {
@@ -2201,8 +2178,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 &&
@@ -2227,20 +2204,13 @@ 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_SUPPORT
-                       len = (unsigned int) strlen(idn_textname);
-                       isc_buffer_init(&b, idn_textname, len);
-#else
-                       len = (unsigned int) strlen(lookup->textname);
-                       isc_buffer_init(&b, lookup->textname, len);
-#endif
+                       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,
@@ -4286,57 +4256,23 @@ destroy_libs(void) {
 #ifdef WITH_IDN_SUPPORT
 static void
 idn_initialize(void) {
+#ifdef WITH_IDNKIT
        isc_result_t result;
+#endif
 
 #ifdef HAVE_SETLOCALE
        /* Set locale */
        (void)setlocale(LC_ALL, "");
 #endif
 
-#ifdef HAVE_IDNKIT
+#ifdef WITH_IDNKIT
        /* Create configuration context. */
        result = idnkit_initialize();
        check_result(result, "idnkit initializationt");
 #endif
-
-       /* Set domain name -> text post-conversion filter. */
-       result = dns_name_settotextfilter(output_filter);
-       check_result(result, "dns_name_settotextfilter");
-}
-
-static isc_result_t
-idn_locale_to_utf8(const char *from, char *to, size_t tolen) {
-#ifdef WITH_IDNKIT
-       return (idnkit_locale_to_utf8(from, to, tolen));
-#elif WITH_LIBIDN
-       return (libidn_locale_to_utf8(from, to, tolen));
-#else /* WITH_LIBIDN2 */
-       return (libidn2_locale_to_utf8(from, to, tolen));
-#endif
-}
-
-static isc_result_t
-idn_utf8_to_ace(const char *from, char *to, size_t tolen) {
-#ifdef WITH_IDNKIT
-       return (idnkit_utf8_to_ace(from, to, tolen));
-#elif WITH_LIBIDN
-       return (libidn_utf8_to_ace(from, to, tolen));
-#else /* WITH_LIBIDN2 */
-       return (libidn2_utf8_to_ace(from, to, tolen));
-#endif
-}
-
-static isc_result_t
-idn_ace_to_locale(const char *from, char *to, size_t tolen) {
-#ifdef WITH_IDNKIT
-       return (idnkit_ace_to_locale(from, to, tolen));
-#elif WITH_LIBIDN
-       return (libidn_ace_to_locale(from, to, tolen));
-#else /* WITH_LIBIDN2 */
-       return (libidn2_ace_to_locale(from, to, tolen));
-#endif
 }
 
+#ifdef WITH_IDN_OUT_SUPPORT
 static isc_result_t
 output_filter(isc_buffer_t *buffer, unsigned int used_org,
              isc_boolean_t absolute)
@@ -4369,8 +4305,9 @@ output_filter(isc_buffer_t *buffer, unsigned int used_org,
         * Convert contents of 'tmp1' to local encoding.
         */
        result = idn_ace_to_locale(tmp1, tmp2, sizeof(tmp2));
-       if (result != ISC_R_SUCCESS)
+       if (result != ISC_R_SUCCESS) {
                return (ISC_R_SUCCESS);
+       }
        strlcpy(tmp1, tmp2, MAXDLEN);
 
        /*
@@ -4390,146 +4327,97 @@ output_filter(isc_buffer_t *buffer, unsigned int used_org,
 
        return (ISC_R_SUCCESS);
 }
+#endif
 
-static isc_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 (ISC_R_SUCCESS);
-
-       /* Append dot and origin */
-       if (namelen + 1 + originlen >= namesize) {
-               debug("append_textname failure: name + origin is too long");
-               return (ISC_R_NOSPACE);
+#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));
        }
-
-       if (*origin != '.')
-               name[namelen++] = '.';
-       (void)strlcpy(name + namelen, origin, namesize - namelen);
-       return (ISC_R_SUCCESS);
 }
 
-#ifdef WITH_IDNKIT
 static isc_result_t
 idnkit_initialize(void) {
        idn_result_t result;
 
        result = idn_nameinit(1);
-
-       if (result == idn_success) {
-               return (ISC_R_SUCCESS);
-       } else {
-               debug("idnkit api initialization failed: %s",
-                     idn_result_tostring(result));
-               return (ISC_R_FAILURE);
-       }
-}
-
-static isc_result_t
-idnkit_locale_to_utf8(const char *from, char *to, size_t tolen) {
-       idn_result_t result;
-
-       result = idn_encodename(IDN_LOCALCONV | IDN_DELIMMAP, from, to, tolen);
-
-       if (result == idn_success) {
-               return (ISC_R_SUCCESS);
-       } else {
-               debug("idnkit idn_encodename failed: %s",
-                     idn_result_tostring(result));
-               if (result == idn_invalid_length)
-                       return (ISC_R_NOSPACE);
-               else
-                       return (ISC_R_FAILURE);
-       }
+       idnkit_check_result(result, "idnkit api initialization failed");
+       return (ISC_R_SUCCESS);
 }
 
 static isc_result_t
-idnkit_utf8_to_ace(const char *from, char *to, size_t tolen) {
+idn_locale_to_ace(const char *from, char *to, size_t tolen) {
+       char utf8_textname[MXNAME];
        idn_result_t result;
 
-       result = idn_encodename(IDN_LOCALMAP | IDN_NAMEPREP |
-                           IDN_IDNCONV | IDN_LENCHECK, from, to, tolen);
+       result = idn_encodename(IDN_LOCALCONV | IDN_DELIMMAP, from,
+                               utf8_textname, sizeof(utf8_textname));
+       idnkit_check_result(result, "idnkit idn_encodename to utf8 failed");
 
-       if (result == idn_success) {
-               return (ISC_R_SUCCESS);
-       } else {
-               debug("idnkit idn_encodename failed: %s",
-                     idn_result_tostring(result));
-               return (ISC_R_FAILURE);
-       }
+       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
-idnkit_ace_to_locale(const char *from, char *to, size_t tolen) {
+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) {
-               return (ISC_R_SUCCESS);
-       } else {
+       if (result != idn_success) {
                debug("idnkit idn_decodename failed: %s",
-                     idn_result_tostring(result) );
+                     idn_result_tostring(result));
                return (ISC_R_FAILURE);
        }
+       return (ISC_R_SUCCESS);
 }
 #endif /* WITH_IDNKIT */
 
 #ifdef WITH_LIBIDN
 static isc_result_t
-libidn_locale_to_utf8(const char *from, char *to, size_t tolen) {
+idn_locale_to_ace(const char *from, char *to, size_t tolen) {
        isc_result_t result = ISC_R_FAILURE;
+       int res;
        char *tmp_str = NULL;
+       char *ace_str = NULL;
 
        tmp_str = stringprep_locale_to_utf8(from);
 
        if (tmp_str != NULL) {
                if (strlen(tmp_str) >= tolen) {
                        debug("UTF-8 string is too long");
-                       result = ISC_R_FAILURE;
-                       goto cleanup;
+                       free(tmp_str);
+                       return ISC_R_NOSPACE;
                }
-
-               (void) strncpy(to, tmp_str, tolen);
-
-               result = ISC_R_SUCCESS;
        }
+       else
+               return ISC_R_FAILURE;
 
-cleanup:
-       free(tmp_str);
-       return (result);
-}
-
-static isc_result_t
-libidn_utf8_to_ace(const char *from, char *to, size_t tolen) {
-       int res;
-       char *tmp_str = NULL;
-
-       res = idna_to_ascii_8z(from, &tmp_str, 0);
-
+       res = idna_to_ascii_8z(tmp_str, &ace_str, 0);
        if (res == IDNA_SUCCESS) {
                /* check the length */
                if (strlen(tmp_str) >= tolen) {
                        debug("encoded ASC string is too long");
-                       return ISC_R_FAILURE;
+                       result = ISC_R_NOSPACE;
+               } else {
+                       (void) strncpy(to, ace_str, tolen);
+                       result = ISC_R_SUCCESS;
                }
-
-               (void) strncpy(to, tmp_str, tolen);
-               free(tmp_str);
-               return ISC_R_SUCCESS;
-       } else {
-               debug("libidn idna_to_ascii_8z failed: %s",
-                     idna_strerror(res));
        }
 
-       return ISC_R_FAILURE;
+       free(tmp_str);
+       free(ace_str);
+       if (res != IDNA_SUCCESS) {
+               fatal("idna_to_ascii_8z failed: %s", idna_strerror(res));
+       }
+       return (result);
 }
 
 static isc_result_t
-libidn_ace_to_locale(const char *from, char *to, size_t tolen) {
+idn_ace_to_locale(const char *from, char *to, size_t tolen) {
        int res;
        isc_result_t result;
        char *tmp_str = NULL;
@@ -4548,7 +4436,7 @@ libidn_ace_to_locale(const char *from, char *to, size_t tolen) {
 
                result = ISC_R_SUCCESS;
        } else {
-               debug("libidn idna_to_unicode_8z8l failed: %s",
+               debug("idna_to_unicode_8z8l failed: %s",
                      idna_strerror(res));
                result = ISC_R_FAILURE;
        }
@@ -4560,9 +4448,8 @@ cleanup:
 #endif /* WITH_LIBIDN */
 
 #ifdef WITH_LIBIDN2
-/* Converts name from locale directly into ACE format, skip UTF-8 step */
 static isc_result_t
-libidn2_locale_to_utf8(const char *from, char *to, size_t tolen) {
+idn_locale_to_ace(const char *from, char *to, size_t tolen) {
        int res;
        char *tmp_str = NULL;
 
@@ -4574,40 +4461,22 @@ libidn2_locale_to_utf8(const char *from, char *to, size_t tolen) {
                /* check the length */
                if (strlen(tmp_str) >= tolen) {
                        debug("ACE string is too long");
-                       free(tmp_str);
-                       return ISC_R_FAILURE;
+                       idn2_free(tmp_str);
+                       return ISC_R_NOSPACE;
                }
 
-               (void) strncpy(to, tmp_str, tolen);
-               free(tmp_str);
-
+               (void) strlcpy(to, tmp_str, tolen);
+               idn2_free(tmp_str);
                return ISC_R_SUCCESS;
        }
 
-       debug("libidn2 idn2_lookup_u8 failed: %s", idn2_strerror(res));
+       fatal("idn2_lookup_ul failed: %s", idn2_strerror(res));
        return ISC_R_FAILURE;
 }
 
+#ifdef WITH_IDN_OUT_SUPPORT
 static isc_result_t
-libidn2_utf8_to_ace(const char *from, char *to, size_t tolen) {
-       int res;
-
-       /* Just check the format again. */
-       res = idn2_to_unicode_8zlz(from, NULL,
-                              IDN2_NONTRANSITIONAL|IDN2_NFC_INPUT);
-       if (res == IDN2_OK) {
-               strncpy(to, from, tolen);
-               return ISC_R_SUCCESS;
-       }
-       debug("libidn2 idn2_to_unicode_8zlz failed: %s", idn2_strerror(res));
-       if (res == IDN2_TOO_BIG_DOMAIN)
-               return ISC_R_NOSPACE;
-       else
-               return ISC_R_FAILURE;
-}
-
-static isc_result_t
-libidn2_ace_to_locale(const char *from, char *to, size_t tolen) {
+idn_ace_to_locale(const char *from, char *to, size_t tolen) {
        int res;
        char *tmp_str = NULL;
 
@@ -4626,11 +4495,12 @@ libidn2_ace_to_locale(const char *from, char *to, size_t tolen) {
                free(tmp_str);
                return ISC_R_SUCCESS;
        } else {
-               debug("libidn idna_to_ascii_8z failed: %s",
+               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 */
index 5aa242e105dd0d8e716e203f482204583319f25e..cbb548d2fccba60027db78e7e7ef56d69384b4ae 100644 (file)
@@ -19,7 +19,7 @@
 #include <locale.h>
 #endif
 
-#ifdef WITH_IDN
+#ifdef WITH_IDNKIT
 #include <idn/result.h>
 #include <idn/log.h>
 #include <idn/resconf.h>
index 48fc8f14b532283df2873293150eba1c859e10f0..b08e99f94b95b194246dba1f420d437206023787 100644 (file)
@@ -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
 
index 79eba6384ec07aac41a00905febe88cddd8e060d..757a1730dbce5100122da322eb4241fef28dd175 100644 (file)
@@ -599,6 +599,9 @@ int sigwait(const unsigned int *set, int *sig);
 /* define if idnkit support is to be included. */
 #undef WITH_IDN
 
+#undef WITH_IDN_OUT_SUPPORT
+
+/* define if IDN input support is to be included. */
 /* 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
index 4c7b06b4b75fe211735de4670743d9eead744f33..79624651514578037fca658613d394888f60fa5b 100644 (file)
@@ -4701,8 +4701,8 @@ NOM_PATH_FILE(XSLT_DBLATEX_FASTBOOK, xsl/latex_book_fast.xsl, $dblatex_xsl_trees
 # IDN support using idnkit
 #
 AC_ARG_WITH(idnkit,
-           AS_HELP_STRING([--with-idn[=PATH]],
-                          [enable IDN support using idnkit idnkit yes|no|path]),
+           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)
@@ -4776,8 +4776,9 @@ AC_SUBST(IDNKIT_LIBS)
 #
 # IDN support using libidn
 #
+LIBIDN_LIBS=
 AC_ARG_WITH(libidn,
-       [  --with-libidn[=PATH]   enable IDN support using GNU libidn yes|no|path],
+       AS_HELP_STRING([--with-libidn[=PATH]], [enable IDN support using GNU libidn [yes|no|path]]),
        use_libidn="$withval", use_libidn="no")
 case "$use_libidn" in
 yes)
@@ -4786,19 +4787,19 @@ yes)
        else
                libidn_path=$prefix
        fi
+       LIBIDN_LIBS="-lidn"
        ;;
 no)
        ;;
 *)
+       LIBIDN_LIBS="-L$use_libidn/lib -lidn"
        libidn_path="$use_libidn"
        ;;
 esac
 
-LIBIDN_LIBS=
 if test "$use_libidn" != no; then
        AC_DEFINE(WITH_LIBIDN, 1, [define if libidn support is to be included.])
        STD_CINCLUDES="$STD_CINCLUDES -I$libidn_path/include"
-       LIBIDN_LIBS="-lidn"
 fi
 AC_SUBST(LIBIDN_LIBS)
 
@@ -4806,8 +4807,9 @@ AC_SUBST(LIBIDN_LIBS)
 # IDN support using libidn2
 #
 
+LIBIDN2_LIBS=
 AC_ARG_WITH(libidn2,
-       [  --with-libidn2[=PATH]  enable IDN support using GNU libidn2 yes|no|path],
+       AS_HELP_STRING([--with-libidn2[=PATH]], [enable IDN support using GNU libidn2 [yes|no|path]]),
        use_libidn2="$withval", use_libidn2="no")
 case "$use_libidn2" in
 yes)
@@ -4816,19 +4818,36 @@ yes)
        else
                libidn2_path=$prefix
        fi
+       LIBIDN2_LIBS="-lidn2"
        ;;
 no)
        ;;
 *)
        libidn2_path="$use_libidn2"
+       LIBIDN2_LIBS="-L$libidn2_path/lib -lidn2"
        ;;
 esac
 
-LIBIDN2_LIBS=
 if test "$use_libidn2" != no; then
        AC_DEFINE(WITH_LIBIDN2, 1, [define if libidn2 support is to be included.])
+       saved_cflags="$CFLAGS"
+       saved_libs="$LIBS"
+       LIBS="$LIBIDN2_LIBS"
+       CFLAGS="-I$libidn2_path/include"
+
+       AC_MSG_NOTICE(checking for idn2_to_unicode_8zlz)
+AC_TRY_LINK([
+#include <idn2.h>
+],[ idn2_to_unicode_8zlz(".", NULL, IDN2_NONTRANSITIONAL|IDN2_NFC_INPUT); ],
+       [AC_MSG_RESULT(yes)
+       use_libidn2_out=yes],
+       [AC_MSG_RESULT(no)
+       use_libidn2_out=no]
+)
+
        STD_CINCLUDES="$STD_CINCLUDES -I$libidn2_path/include"
-       LIBIDN_LIBS="-lidn2"
+       LIBS="$saved_libs"
+       CFLAGS="$saved_cflags"
 fi
 AC_SUBST(LIBIDN2_LIBS)
 
@@ -4849,7 +4868,10 @@ fi
 
 # the IDN support is on
 if test "$use_idnkit" != no || test "$use_libidn" != no || test "$use_libidn2" != no; then
-       AC_DEFINE(WITH_IDN_SUPPORT, 1, [define if IDN support is to be included.])
+       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
 
 #