libidn2 support. Thanks Paul Wouters

This commit is contained in:
Willem Toorop 2018-01-08 12:54:48 +01:00
parent 2ff1bf6152
commit 546b75a9b1
4 changed files with 117 additions and 60 deletions

View File

@ -1,3 +1,6 @@
* 2018-0?-??: Version 1.?.?
* libidn2 support. Thanks Paul Wouters
* 2017-12-21: Version 1.3.0
* Bugfix #300: Detect dnsmasq and skip unit test that fails with it.
Thanks Tim Rühsen and Konomi Kitten

View File

@ -70,13 +70,13 @@ If you are installing from packages, you have to install the library and also th
External dependencies are linked outside the getdns API build tree (we rely on configure to find them). We would like to keep the dependency tree short. Please refer to section for building on Windows for separate dependency and build instructions for that platform.
* [libunbound from NLnet Labs](https://unbound.net/) version 1.4.16 or later.
* [libidn from the FSF](https://www.gnu.org/software/libidn/) version 1. (Note that the libidn version means the conversions between A-labels and U-labels may permit conversion of formally invalid labels under IDNA2008.)
* [libidn from the FSF](https://www.gnu.org/software/libidn/) version 1 or 2. (Note that the libidn version means the conversions between A-labels and U-labels may permit conversion of formally invalid labels under IDNA2008.)
* [libssl and libcrypto from the OpenSSL Project](https://www.openssl.org/) version 0.9.7 or later. (Note: version 1.0.1 or later is required for TLS support, version 1.0.2 or later is required for TLS hostname authentication)
* Doxygen is used to generate documentation; while this is not technically necessary for the build it makes things a lot more pleasant.
For example, to build on a recent version of Ubuntu, you would need the following packages:
# apt install build-essential libunbound-dev libidn11-dev libssl-dev libtool m4 autoconf
# apt install build-essential libunbound-dev libidn2-dev libssl-dev libtool m4 autoconf
If you are building from git, you need to do the following before building:
@ -98,8 +98,8 @@ Note: If you only want to build stubby, then use the `--with-stubby` option when
## Minimizing dependencies
* getdns can be configured for stub resolution mode only with the `--enable-stub-only` option to configure. This removes the dependency on `libunbound`.
* Currently getdns only offers two helper functions to deal with IDN: `getdns_convert_ulabel_to_alabel` and `getdns_convert_alabel_to_ulabel`. If you do not need these functions, getdns can be configured to compile without them with the `--without-libidn` option to configure.
* When both `--enable-stub-only` and `--without-libidn` options are used, getdns has only one dependency left, which is OpenSSL.
* Currently getdns only offers two helper functions to deal with IDN: `getdns_convert_ulabel_to_alabel` and `getdns_convert_alabel_to_ulabel`. If you do not need these functions, getdns can be configured to compile without them with the `--without-libidn` and `--without-libidn2` options to configure.
* When `--enable-stub-only`, `--without-libidn` and `--without-libidn2` options are used, getdns has only one dependency left, which is OpenSSL.
## Extensions and Event loop dependencies

View File

@ -763,6 +763,39 @@ else
fi
fi
my_with_libidn2=1
AC_ARG_WITH(libidn2, AS_HELP_STRING([--with-libidn2=pathname],
[path to libidn2 (default: search /usr/local ..)]),
[], [withval="yes"])
if test x_$withval = x_yes; then
for dir in /usr/local /opt/local /usr/pkg /usr/sfw; do
if test -f "$dir/include/idn2.h"; then
CFLAGS="$CFLAGS -I$dir/include"
LDFLAGS="$LDFLAGS -L$dir/lib"
AC_MSG_NOTICE([Found libidn2 in $dir])
break
fi
if test -f "$dir/include/idn2/idn2.h"; then
CFLAGS="$CFLAGS -I$dir/include/idn2"
LDFLAGS="$LDFLAGS -L$dir/lib"
AC_MSG_NOTICE([Found libidn2 in $dir])
break
fi
done
if test -f "/usr/include/idn2/idn2.h"; then
CFLAGS="$CFLAGS -I/usr/include/idn2"
#LDFLAGS="$LDFLAGS -L/usr/lib"
AC_MSG_NOTICE([Found libidn2 in /usr])
fi
else
if test x_$withval != x_no; then
CFLAGS="$CFLAGS -I$withval/include"
LDFLAGS="$LDFLAGS -L$withval/lib"
else
my_with_libidn2=0
fi
fi
if test $my_with_libunbound = 1
then
# find libunbound
@ -793,15 +826,37 @@ fi
found_all_libs=1
MISSING_DEPS=""
MISSING_SEP=""
if test $my_with_libidn = 1
working_libidn2=0
if test $my_with_libidn2 = 1
then
AC_MSG_NOTICE([Checking for dependency libidn])
AC_CHECK_LIB([idn], [idna_to_ascii_8z], [], [
MISSING_DEPS="${MISSING_DEPS}${MISSING_SEP}libidn"
AC_MSG_NOTICE([Checking for dependency libidn2])
AC_CHECK_LIB([idn2], [idn2_to_unicode_8z8z], [
working_libidn2=1
LIBS="-lidn2 $LIBS"
AC_DEFINE_UNQUOTED([HAVE_LIBIDN2], [1], [Define to 1 if you have the `idn2' library (-lidn).]) dnl `
], [
MISSING_DEPS="${MISSING_DEPS}${MISSING_SEP}libidn2"
MISSING_SEP=", "
found_all_libs=0
])
fi
if test $working_libidn2 = 0
then
if test $my_with_libidn = 1
then
AC_MSG_NOTICE([Checking for dependency libidn])
AC_CHECK_LIB([idn], [idna_to_ascii_8z], [], [
MISSING_DEPS="${MISSING_DEPS}${MISSING_SEP}libidn"
MISSING_SEP=", "
found_all_libs=0
])
else
if test $my_with_libidn2 = 1
then
found_all_libs=0
fi
fi
fi
AC_ARG_ENABLE(unbound-event-api, AC_HELP_STRING([--disable-unbound-event-api], [Disable usage of libunbounds event API]))
case "$enable_unbound_event_api" in

View File

@ -39,7 +39,9 @@
#ifndef USE_WINSOCK
#include <arpa/inet.h>
#endif
#ifdef HAVE_LIBIDN
#if defined(HAVE_LIBIDN2)
#include <idn2.h>
#elif defined(HAVE_LIBIDN)
#include <stringprep.h>
#include <idna.h>
#endif
@ -113,48 +115,44 @@ getdns_convert_fqdn_to_dns_name(
char *
getdns_convert_ulabel_to_alabel(const char *ulabel)
{
#ifdef HAVE_LIBIDN
int ret;
char *buf;
char *prepped;
char *prepped2;
#if defined(HAVE_LIBIDN2)
char *alabel;
if (ulabel == NULL)
return 0;
prepped2 = malloc(BUFSIZ);
if(!prepped2)
return 0;
setlocale(LC_ALL, "");
if ((prepped = stringprep_locale_to_utf8(ulabel)) == 0) {
/* convert to utf8 fails, which it can, but continue anyway */
if(strlen(ulabel)+1 > BUFSIZ) {
free(prepped2);
return 0;
}
memcpy(prepped2, ulabel, strlen(ulabel)+1);
} else {
if(strlen(prepped)+1 > BUFSIZ) {
free(prepped);
free(prepped2);
return 0;
}
memcpy(prepped2, prepped, strlen(prepped)+1);
free(prepped);
}
if ((ret = stringprep(prepped2, BUFSIZ, 0, stringprep_nameprep)) != STRINGPREP_OK) {
free(prepped2);
return 0;
}
if ((ret = idna_to_ascii_8z(prepped2, &buf, 0)) != IDNA_SUCCESS) {
free(prepped2);
return 0;
}
free(prepped2);
return buf;
if (!ulabel) return NULL;
if (idn2_lookup_ul(ulabel, &alabel, IDN2_NONTRANSITIONAL) == IDN2_OK
|| idn2_lookup_ul(ulabel, &alabel, IDN2_TRANSITIONAL) == IDN2_OK)
return alabel;
#elif defined(HAVE_LIBIDN)
char *alabel;
char *prepped;
char prepped2[BUFSIZ];
if (!ulabel) return NULL;
setlocale(LC_ALL, "");
if ((prepped = stringprep_locale_to_utf8(ulabel))) {
if(strlen(prepped)+1 > BUFSIZ) {
free(prepped);
return NULL;
}
memcpy(prepped2, prepped, strlen(prepped)+1);
free(prepped);
/* convert to utf8 fails, which it can, but continue anyway */
} else if (strlen(ulabel)+1 > BUFSIZ)
return NULL;
else
memcpy(prepped2, ulabel, strlen(ulabel)+1);
if (stringprep(prepped2, BUFSIZ, 0, stringprep_nameprep) == STRINGPREP_OK
&& idna_to_ascii_8z(prepped2, &alabel, 0) == IDNA_SUCCESS)
return alabel;
#else
(void)ulabel;
return NULL;
(void)ulabel;
#endif
return NULL;
}
/*---------------------------------------- getdns_convert_alabel_to_ulabel */
@ -171,20 +169,21 @@ getdns_convert_ulabel_to_alabel(const char *ulabel)
char *
getdns_convert_alabel_to_ulabel(const char *alabel)
{
#ifdef HAVE_LIBIDN
int ret; /* just in case we might want to use it someday */
char *buf;
#if defined(HAVE_LIBIDN2) || defined(HAVE_LIBIDN)
char *ulabel;
if (alabel == NULL)
return 0;
if ((ret = idna_to_unicode_8z8z(alabel, &buf, 0)) != IDNA_SUCCESS) {
return NULL;
}
return buf;
if (!alabel) return NULL;
# if defined(HAVE_LIBIDN2)
if (idn2_to_unicode_8z8z(alabel, &ulabel, 0) != IDN2_OK)
# else
if (idna_to_unicode_8z8z(alabel, &ulabel, 0) != IDNA_SUCCESS)
# endif
return ulabel;
#else
(void)alabel;
return NULL;
(void)alabel;
#endif
return NULL;
}