mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 07:38:49 -05:00
idn: switch to libidn2 use and IDNA2008 support
CVE-2016-8625 Bug: https://curl.haxx.se/docs/adv_20161102K.html Reported-by: Christian Heimes
This commit is contained in:
parent
42b650b9ea
commit
9c91ec7781
@ -449,7 +449,7 @@ if(NOT CURL_DISABLE_LDAPS)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Check for idn
|
# Check for idn
|
||||||
check_library_exists_concat("idn" idna_to_ascii_lz HAVE_LIBIDN)
|
check_library_exists_concat("idn2" idn2_lookup_ul HAVE_LIBIDN2)
|
||||||
|
|
||||||
# Check for symbol dlopen (same as HAVE_LIBDL)
|
# Check for symbol dlopen (same as HAVE_LIBDL)
|
||||||
check_library_exists("${CURL_LIBS}" dlopen "" HAVE_DLOPEN)
|
check_library_exists("${CURL_LIBS}" dlopen "" HAVE_DLOPEN)
|
||||||
@ -618,7 +618,7 @@ check_include_file_concat("des.h" HAVE_DES_H)
|
|||||||
check_include_file_concat("err.h" HAVE_ERR_H)
|
check_include_file_concat("err.h" HAVE_ERR_H)
|
||||||
check_include_file_concat("errno.h" HAVE_ERRNO_H)
|
check_include_file_concat("errno.h" HAVE_ERRNO_H)
|
||||||
check_include_file_concat("fcntl.h" HAVE_FCNTL_H)
|
check_include_file_concat("fcntl.h" HAVE_FCNTL_H)
|
||||||
check_include_file_concat("idn-free.h" HAVE_IDN_FREE_H)
|
check_include_file_concat("idn2.h" HAVE_IDN2_H)
|
||||||
check_include_file_concat("ifaddrs.h" HAVE_IFADDRS_H)
|
check_include_file_concat("ifaddrs.h" HAVE_IFADDRS_H)
|
||||||
check_include_file_concat("io.h" HAVE_IO_H)
|
check_include_file_concat("io.h" HAVE_IO_H)
|
||||||
check_include_file_concat("krb.h" HAVE_KRB_H)
|
check_include_file_concat("krb.h" HAVE_KRB_H)
|
||||||
@ -648,7 +648,6 @@ check_include_file_concat("stropts.h" HAVE_STROPTS_H)
|
|||||||
check_include_file_concat("termio.h" HAVE_TERMIO_H)
|
check_include_file_concat("termio.h" HAVE_TERMIO_H)
|
||||||
check_include_file_concat("termios.h" HAVE_TERMIOS_H)
|
check_include_file_concat("termios.h" HAVE_TERMIOS_H)
|
||||||
check_include_file_concat("time.h" HAVE_TIME_H)
|
check_include_file_concat("time.h" HAVE_TIME_H)
|
||||||
check_include_file_concat("tld.h" HAVE_TLD_H)
|
|
||||||
check_include_file_concat("unistd.h" HAVE_UNISTD_H)
|
check_include_file_concat("unistd.h" HAVE_UNISTD_H)
|
||||||
check_include_file_concat("utime.h" HAVE_UTIME_H)
|
check_include_file_concat("utime.h" HAVE_UTIME_H)
|
||||||
check_include_file_concat("x509.h" HAVE_X509_H)
|
check_include_file_concat("x509.h" HAVE_X509_H)
|
||||||
@ -662,9 +661,6 @@ check_include_file_concat("netinet/if_ether.h" HAVE_NETINET_IF_ETHER_H)
|
|||||||
check_include_file_concat("stdint.h" HAVE_STDINT_H)
|
check_include_file_concat("stdint.h" HAVE_STDINT_H)
|
||||||
check_include_file_concat("sockio.h" HAVE_SOCKIO_H)
|
check_include_file_concat("sockio.h" HAVE_SOCKIO_H)
|
||||||
check_include_file_concat("sys/utsname.h" HAVE_SYS_UTSNAME_H)
|
check_include_file_concat("sys/utsname.h" HAVE_SYS_UTSNAME_H)
|
||||||
check_include_file_concat("idna.h" HAVE_IDNA_H)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
check_type_size(size_t SIZEOF_SIZE_T)
|
check_type_size(size_t SIZEOF_SIZE_T)
|
||||||
check_type_size(ssize_t SIZEOF_SSIZE_T)
|
check_type_size(ssize_t SIZEOF_SSIZE_T)
|
||||||
@ -811,9 +807,6 @@ check_symbol_exists(pipe "${CURL_INCLUDES}" HAVE_PIPE)
|
|||||||
check_symbol_exists(ftruncate "${CURL_INCLUDES}" HAVE_FTRUNCATE)
|
check_symbol_exists(ftruncate "${CURL_INCLUDES}" HAVE_FTRUNCATE)
|
||||||
check_symbol_exists(getprotobyname "${CURL_INCLUDES}" HAVE_GETPROTOBYNAME)
|
check_symbol_exists(getprotobyname "${CURL_INCLUDES}" HAVE_GETPROTOBYNAME)
|
||||||
check_symbol_exists(getrlimit "${CURL_INCLUDES}" HAVE_GETRLIMIT)
|
check_symbol_exists(getrlimit "${CURL_INCLUDES}" HAVE_GETRLIMIT)
|
||||||
check_symbol_exists(idn_free "${CURL_INCLUDES}" HAVE_IDN_FREE)
|
|
||||||
check_symbol_exists(idna_strerror "${CURL_INCLUDES}" HAVE_IDNA_STRERROR)
|
|
||||||
check_symbol_exists(tld_strerror "${CURL_INCLUDES}" HAVE_TLD_STRERROR)
|
|
||||||
check_symbol_exists(setlocale "${CURL_INCLUDES}" HAVE_SETLOCALE)
|
check_symbol_exists(setlocale "${CURL_INCLUDES}" HAVE_SETLOCALE)
|
||||||
check_symbol_exists(setrlimit "${CURL_INCLUDES}" HAVE_SETRLIMIT)
|
check_symbol_exists(setrlimit "${CURL_INCLUDES}" HAVE_SETRLIMIT)
|
||||||
check_symbol_exists(fcntl "${CURL_INCLUDES}" HAVE_FCNTL)
|
check_symbol_exists(fcntl "${CURL_INCLUDES}" HAVE_FCNTL)
|
||||||
@ -1078,7 +1071,7 @@ _add_if("IPv6" ENABLE_IPV6)
|
|||||||
_add_if("unix-sockets" USE_UNIX_SOCKETS)
|
_add_if("unix-sockets" USE_UNIX_SOCKETS)
|
||||||
_add_if("libz" HAVE_LIBZ)
|
_add_if("libz" HAVE_LIBZ)
|
||||||
_add_if("AsynchDNS" USE_ARES OR USE_THREADS_POSIX OR USE_THREADS_WIN32)
|
_add_if("AsynchDNS" USE_ARES OR USE_THREADS_POSIX OR USE_THREADS_WIN32)
|
||||||
_add_if("IDN" HAVE_LIBIDN)
|
_add_if("IDN" HAVE_LIBIDN2)
|
||||||
_add_if("Largefile" (CURL_SIZEOF_CURL_OFF_T GREATER 4) AND
|
_add_if("Largefile" (CURL_SIZEOF_CURL_OFF_T GREATER 4) AND
|
||||||
((SIZEOF_OFF_T GREATER 4) OR USE_WIN32_LARGE_FILES))
|
((SIZEOF_OFF_T GREATER 4) OR USE_WIN32_LARGE_FILES))
|
||||||
# TODO SSP1 (WinSSL) check is missing
|
# TODO SSP1 (WinSSL) check is missing
|
||||||
|
76
configure.ac
76
configure.ac
@ -157,7 +157,7 @@ curl_tls_srp_msg="no (--enable-tls-srp)"
|
|||||||
curl_res_msg="default (--enable-ares / --enable-threaded-resolver)"
|
curl_res_msg="default (--enable-ares / --enable-threaded-resolver)"
|
||||||
curl_ipv6_msg="no (--enable-ipv6)"
|
curl_ipv6_msg="no (--enable-ipv6)"
|
||||||
curl_unix_sockets_msg="no (--enable-unix-sockets)"
|
curl_unix_sockets_msg="no (--enable-unix-sockets)"
|
||||||
curl_idn_msg="no (--with-{libidn,winidn})"
|
curl_idn_msg="no (--with-{libidn2,winidn})"
|
||||||
curl_manual_msg="no (--enable-manual)"
|
curl_manual_msg="no (--enable-manual)"
|
||||||
curl_libcurl_msg="enabled (--disable-libcurl-option)"
|
curl_libcurl_msg="enabled (--disable-libcurl-option)"
|
||||||
curl_verbose_msg="enabled (--disable-verbose)"
|
curl_verbose_msg="enabled (--disable-verbose)"
|
||||||
@ -2830,15 +2830,15 @@ dnl **********************************************************************
|
|||||||
dnl Check for the presence of IDN libraries and headers
|
dnl Check for the presence of IDN libraries and headers
|
||||||
dnl **********************************************************************
|
dnl **********************************************************************
|
||||||
|
|
||||||
AC_MSG_CHECKING([whether to build with libidn])
|
AC_MSG_CHECKING([whether to build with libidn2])
|
||||||
OPT_IDN="default"
|
OPT_IDN="default"
|
||||||
AC_ARG_WITH(libidn,
|
AC_ARG_WITH(libidn,
|
||||||
AC_HELP_STRING([--with-libidn=PATH],[Enable libidn usage])
|
AC_HELP_STRING([--with-libidn2=PATH],[Enable libidn2 usage])
|
||||||
AC_HELP_STRING([--without-libidn],[Disable libidn usage]),
|
AC_HELP_STRING([--without-libidn2],[Disable libidn2 usage]),
|
||||||
[OPT_IDN=$withval])
|
[OPT_IDN=$withval])
|
||||||
case "$OPT_IDN" in
|
case "$OPT_IDN" in
|
||||||
no)
|
no)
|
||||||
dnl --without-libidn option used
|
dnl --without-libidn2 option used
|
||||||
want_idn="no"
|
want_idn="no"
|
||||||
AC_MSG_RESULT([no])
|
AC_MSG_RESULT([no])
|
||||||
;;
|
;;
|
||||||
@ -2849,13 +2849,13 @@ case "$OPT_IDN" in
|
|||||||
AC_MSG_RESULT([(assumed) yes])
|
AC_MSG_RESULT([(assumed) yes])
|
||||||
;;
|
;;
|
||||||
yes)
|
yes)
|
||||||
dnl --with-libidn option used without path
|
dnl --with-libidn2 option used without path
|
||||||
want_idn="yes"
|
want_idn="yes"
|
||||||
want_idn_path="default"
|
want_idn_path="default"
|
||||||
AC_MSG_RESULT([yes])
|
AC_MSG_RESULT([yes])
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
dnl --with-libidn option used with path
|
dnl --with-libidn2 option used with path
|
||||||
want_idn="yes"
|
want_idn="yes"
|
||||||
want_idn_path="$withval"
|
want_idn_path="$withval"
|
||||||
AC_MSG_RESULT([yes ($withval)])
|
AC_MSG_RESULT([yes ($withval)])
|
||||||
@ -2872,33 +2872,33 @@ if test "$want_idn" = "yes"; then
|
|||||||
if test "$want_idn_path" != "default"; then
|
if test "$want_idn_path" != "default"; then
|
||||||
dnl path has been specified
|
dnl path has been specified
|
||||||
IDN_PCDIR="$want_idn_path/lib$libsuff/pkgconfig"
|
IDN_PCDIR="$want_idn_path/lib$libsuff/pkgconfig"
|
||||||
CURL_CHECK_PKGCONFIG(libidn, [$IDN_PCDIR])
|
CURL_CHECK_PKGCONFIG(libidn2, [$IDN_PCDIR])
|
||||||
if test "$PKGCONFIG" != "no"; then
|
if test "$PKGCONFIG" != "no"; then
|
||||||
IDN_LIBS=`CURL_EXPORT_PCDIR([$IDN_PCDIR]) dnl
|
IDN_LIBS=`CURL_EXPORT_PCDIR([$IDN_PCDIR]) dnl
|
||||||
$PKGCONFIG --libs-only-l libidn 2>/dev/null`
|
$PKGCONFIG --libs-only-l libidn2 2>/dev/null`
|
||||||
IDN_LDFLAGS=`CURL_EXPORT_PCDIR([$IDN_PCDIR]) dnl
|
IDN_LDFLAGS=`CURL_EXPORT_PCDIR([$IDN_PCDIR]) dnl
|
||||||
$PKGCONFIG --libs-only-L libidn 2>/dev/null`
|
$PKGCONFIG --libs-only-L libidn2 2>/dev/null`
|
||||||
IDN_CPPFLAGS=`CURL_EXPORT_PCDIR([$IDN_PCDIR]) dnl
|
IDN_CPPFLAGS=`CURL_EXPORT_PCDIR([$IDN_PCDIR]) dnl
|
||||||
$PKGCONFIG --cflags-only-I libidn 2>/dev/null`
|
$PKGCONFIG --cflags-only-I libidn2 2>/dev/null`
|
||||||
IDN_DIR=`echo $IDN_LDFLAGS | $SED -e 's/-L//'`
|
IDN_DIR=`echo $IDN_LDFLAGS | $SED -e 's/-L//'`
|
||||||
else
|
else
|
||||||
dnl pkg-config not available or provides no info
|
dnl pkg-config not available or provides no info
|
||||||
IDN_LIBS="-lidn"
|
IDN_LIBS="-lidn2"
|
||||||
IDN_LDFLAGS="-L$want_idn_path/lib$libsuff"
|
IDN_LDFLAGS="-L$want_idn_path/lib$libsuff"
|
||||||
IDN_CPPFLAGS="-I$want_idn_path/include"
|
IDN_CPPFLAGS="-I$want_idn_path/include"
|
||||||
IDN_DIR="$want_idn_path/lib$libsuff"
|
IDN_DIR="$want_idn_path/lib$libsuff"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
dnl path not specified
|
dnl path not specified
|
||||||
CURL_CHECK_PKGCONFIG(libidn)
|
CURL_CHECK_PKGCONFIG(libidn2)
|
||||||
if test "$PKGCONFIG" != "no"; then
|
if test "$PKGCONFIG" != "no"; then
|
||||||
IDN_LIBS=`$PKGCONFIG --libs-only-l libidn 2>/dev/null`
|
IDN_LIBS=`$PKGCONFIG --libs-only-l libidn2 2>/dev/null`
|
||||||
IDN_LDFLAGS=`$PKGCONFIG --libs-only-L libidn 2>/dev/null`
|
IDN_LDFLAGS=`$PKGCONFIG --libs-only-L libidn2 2>/dev/null`
|
||||||
IDN_CPPFLAGS=`$PKGCONFIG --cflags-only-I libidn 2>/dev/null`
|
IDN_CPPFLAGS=`$PKGCONFIG --cflags-only-I libidn2 2>/dev/null`
|
||||||
IDN_DIR=`echo $IDN_LDFLAGS | $SED -e 's/-L//'`
|
IDN_DIR=`echo $IDN_LDFLAGS | $SED -e 's/-L//'`
|
||||||
else
|
else
|
||||||
dnl pkg-config not available or provides no info
|
dnl pkg-config not available or provides no info
|
||||||
IDN_LIBS="-lidn"
|
IDN_LIBS="-lidn2"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
#
|
#
|
||||||
@ -2918,9 +2918,9 @@ if test "$want_idn" = "yes"; then
|
|||||||
LDFLAGS="$IDN_LDFLAGS $LDFLAGS"
|
LDFLAGS="$IDN_LDFLAGS $LDFLAGS"
|
||||||
LIBS="$IDN_LIBS $LIBS"
|
LIBS="$IDN_LIBS $LIBS"
|
||||||
#
|
#
|
||||||
AC_MSG_CHECKING([if idna_to_ascii_4i can be linked])
|
AC_MSG_CHECKING([if idn2_lookup_ul can be linked])
|
||||||
AC_LINK_IFELSE([
|
AC_LINK_IFELSE([
|
||||||
AC_LANG_FUNC_LINK_TRY([idna_to_ascii_4i])
|
AC_LANG_FUNC_LINK_TRY([idn2_lookup_ul])
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT([yes])
|
AC_MSG_RESULT([yes])
|
||||||
tst_links_libidn="yes"
|
tst_links_libidn="yes"
|
||||||
@ -2928,37 +2928,19 @@ if test "$want_idn" = "yes"; then
|
|||||||
AC_MSG_RESULT([no])
|
AC_MSG_RESULT([no])
|
||||||
tst_links_libidn="no"
|
tst_links_libidn="no"
|
||||||
])
|
])
|
||||||
if test "$tst_links_libidn" = "no"; then
|
|
||||||
AC_MSG_CHECKING([if idna_to_ascii_lz can be linked])
|
|
||||||
AC_LINK_IFELSE([
|
|
||||||
AC_LANG_FUNC_LINK_TRY([idna_to_ascii_lz])
|
|
||||||
],[
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
tst_links_libidn="yes"
|
|
||||||
],[
|
|
||||||
AC_MSG_RESULT([no])
|
|
||||||
tst_links_libidn="no"
|
|
||||||
])
|
|
||||||
fi
|
|
||||||
#
|
#
|
||||||
|
AC_CHECK_HEADERS( idn2.h )
|
||||||
|
|
||||||
if test "$tst_links_libidn" = "yes"; then
|
if test "$tst_links_libidn" = "yes"; then
|
||||||
AC_DEFINE(HAVE_LIBIDN, 1, [Define to 1 if you have the `idn' library (-lidn).])
|
AC_DEFINE(HAVE_LIBIDN2, 1, [Define to 1 if you have the `idn2' library (-lidn2).])
|
||||||
dnl different versions of libidn have different setups of these:
|
dnl different versions of libidn have different setups of these:
|
||||||
AC_CHECK_FUNCS( idn_free idna_strerror tld_strerror )
|
|
||||||
AC_CHECK_HEADERS( idn-free.h tld.h )
|
AC_SUBST([IDN_ENABLED], [1])
|
||||||
if test "x$ac_cv_header_tld_h" = "xyes"; then
|
curl_idn_msg="enabled (libidn2)"
|
||||||
AC_SUBST([IDN_ENABLED], [1])
|
if test -n "$IDN_DIR" -a "x$cross_compiling" != "xyes"; then
|
||||||
curl_idn_msg="enabled"
|
LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$IDN_DIR"
|
||||||
if test -n "$IDN_DIR" -a "x$cross_compiling" != "xyes"; then
|
export LD_LIBRARY_PATH
|
||||||
LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$IDN_DIR"
|
AC_MSG_NOTICE([Added $IDN_DIR to LD_LIBRARY_PATH])
|
||||||
export LD_LIBRARY_PATH
|
|
||||||
AC_MSG_NOTICE([Added $IDN_DIR to LD_LIBRARY_PATH])
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
AC_MSG_WARN([Libraries for IDN support too old: IDN disabled])
|
|
||||||
CPPFLAGS="$clean_CPPFLAGS"
|
|
||||||
LDFLAGS="$clean_LDFLAGS"
|
|
||||||
LIBS="$clean_LIBS"
|
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
AC_MSG_WARN([Cannot find libraries for IDN support: IDN disabled])
|
AC_MSG_WARN([Cannot find libraries for IDN support: IDN disabled])
|
||||||
|
@ -599,10 +599,9 @@ int netware_init(void);
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_LIBIDN) && defined(HAVE_TLD_H)
|
#if defined(HAVE_LIBIDN2) && defined(HAVE_IDN2_H)
|
||||||
/* The lib was present and the tld.h header (which is missing in libidn 0.3.X
|
/* The lib and header are present */
|
||||||
but we only work with libidn 0.4.1 or later) */
|
#define USE_LIBIDN2
|
||||||
#define USE_LIBIDN
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef SIZEOF_TIME_T
|
#ifndef SIZEOF_TIME_T
|
||||||
|
26
lib/easy.c
26
lib/easy.c
@ -144,28 +144,6 @@ static CURLcode win32_init(void)
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_LIBIDN
|
|
||||||
/*
|
|
||||||
* Initialise use of IDNA library.
|
|
||||||
* It falls back to ASCII if $CHARSET isn't defined. This doesn't work for
|
|
||||||
* idna_to_ascii_lz().
|
|
||||||
*/
|
|
||||||
static void idna_init (void)
|
|
||||||
{
|
|
||||||
#ifdef WIN32
|
|
||||||
char buf[60];
|
|
||||||
UINT cp = GetACP();
|
|
||||||
|
|
||||||
if(!getenv("CHARSET") && cp > 0) {
|
|
||||||
snprintf(buf, sizeof(buf), "CHARSET=cp%u", cp);
|
|
||||||
putenv(buf);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
/* to do? */
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif /* USE_LIBIDN */
|
|
||||||
|
|
||||||
/* true globals -- for curl_global_init() and curl_global_cleanup() */
|
/* true globals -- for curl_global_init() and curl_global_cleanup() */
|
||||||
static unsigned int initialized;
|
static unsigned int initialized;
|
||||||
static long init_flags;
|
static long init_flags;
|
||||||
@ -262,10 +240,6 @@ static CURLcode global_init(long flags, bool memoryfuncs)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_LIBIDN
|
|
||||||
idna_init();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(Curl_resolver_global_init()) {
|
if(Curl_resolver_global_init()) {
|
||||||
DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n"));
|
DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n"));
|
||||||
return CURLE_FAILED_INIT;
|
return CURLE_FAILED_INIT;
|
||||||
|
@ -35,8 +35,8 @@
|
|||||||
|
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
#ifdef USE_LIBIDN
|
#ifdef USE_LIBIDN2
|
||||||
#include <idna.h>
|
#include <idn2.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_WINDOWS_SSPI
|
#ifdef USE_WINDOWS_SSPI
|
||||||
@ -726,83 +726,6 @@ const char *Curl_strerror(struct connectdata *conn, int err)
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_LIBIDN
|
|
||||||
/*
|
|
||||||
* Return error-string for libidn status as returned from idna_to_ascii_lz().
|
|
||||||
*/
|
|
||||||
const char *Curl_idn_strerror (struct connectdata *conn, int err)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_IDNA_STRERROR
|
|
||||||
(void)conn;
|
|
||||||
return idna_strerror((Idna_rc) err);
|
|
||||||
#else
|
|
||||||
const char *str;
|
|
||||||
char *buf;
|
|
||||||
size_t max;
|
|
||||||
|
|
||||||
DEBUGASSERT(conn);
|
|
||||||
|
|
||||||
buf = conn->syserr_buf;
|
|
||||||
max = sizeof(conn->syserr_buf)-1;
|
|
||||||
*buf = '\0';
|
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
|
||||||
switch ((Idna_rc)err) {
|
|
||||||
case IDNA_SUCCESS:
|
|
||||||
str = "No error";
|
|
||||||
break;
|
|
||||||
case IDNA_STRINGPREP_ERROR:
|
|
||||||
str = "Error in string preparation";
|
|
||||||
break;
|
|
||||||
case IDNA_PUNYCODE_ERROR:
|
|
||||||
str = "Error in Punycode operation";
|
|
||||||
break;
|
|
||||||
case IDNA_CONTAINS_NON_LDH:
|
|
||||||
str = "Illegal ASCII characters";
|
|
||||||
break;
|
|
||||||
case IDNA_CONTAINS_MINUS:
|
|
||||||
str = "Contains minus";
|
|
||||||
break;
|
|
||||||
case IDNA_INVALID_LENGTH:
|
|
||||||
str = "Invalid output length";
|
|
||||||
break;
|
|
||||||
case IDNA_NO_ACE_PREFIX:
|
|
||||||
str = "No ACE prefix (\"xn--\")";
|
|
||||||
break;
|
|
||||||
case IDNA_ROUNDTRIP_VERIFY_ERROR:
|
|
||||||
str = "Round trip verify error";
|
|
||||||
break;
|
|
||||||
case IDNA_CONTAINS_ACE_PREFIX:
|
|
||||||
str = "Already have ACE prefix (\"xn--\")";
|
|
||||||
break;
|
|
||||||
case IDNA_ICONV_ERROR:
|
|
||||||
str = "Locale conversion failed";
|
|
||||||
break;
|
|
||||||
case IDNA_MALLOC_ERROR:
|
|
||||||
str = "Allocation failed";
|
|
||||||
break;
|
|
||||||
case IDNA_DLOPEN_ERROR:
|
|
||||||
str = "dlopen() error";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
snprintf(buf, max, "error %d", err);
|
|
||||||
str = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if((Idna_rc)err == IDNA_SUCCESS)
|
|
||||||
str = "No error";
|
|
||||||
else
|
|
||||||
str = "Error";
|
|
||||||
#endif
|
|
||||||
if(str)
|
|
||||||
strncpy(buf, str, max);
|
|
||||||
buf[max] = '\0';
|
|
||||||
return (buf);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif /* USE_LIBIDN */
|
|
||||||
|
|
||||||
#ifdef USE_WINDOWS_SSPI
|
#ifdef USE_WINDOWS_SSPI
|
||||||
const char *Curl_sspi_strerror (struct connectdata *conn, int err)
|
const char *Curl_sspi_strerror (struct connectdata *conn, int err)
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
const char *Curl_strerror (struct connectdata *conn, int err);
|
const char *Curl_strerror (struct connectdata *conn, int err);
|
||||||
|
|
||||||
#ifdef USE_LIBIDN
|
#ifdef USE_LIBIDN2
|
||||||
const char *Curl_idn_strerror (struct connectdata *conn, int err);
|
const char *Curl_idn_strerror (struct connectdata *conn, int err);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
99
lib/url.c
99
lib/url.c
@ -59,24 +59,15 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_LIBIDN
|
#ifdef USE_LIBIDN2
|
||||||
#include <idna.h>
|
#include <idn2.h>
|
||||||
#include <tld.h>
|
|
||||||
#include <stringprep.h>
|
|
||||||
#ifdef HAVE_IDN_FREE_H
|
|
||||||
#include <idn-free.h>
|
|
||||||
#else
|
|
||||||
/* prototype from idn-free.h, not provided by libidn 0.4.5's make install! */
|
|
||||||
void idn_free (void *ptr);
|
|
||||||
#endif
|
|
||||||
#ifndef HAVE_IDN_FREE
|
|
||||||
/* if idn_free() was not found in this version of libidn use free() instead */
|
|
||||||
#define idn_free(x) (free)(x)
|
|
||||||
#endif
|
|
||||||
#elif defined(USE_WIN32_IDN)
|
#elif defined(USE_WIN32_IDN)
|
||||||
/* prototype for curl_win32_idn_to_ascii() */
|
/* prototype for curl_win32_idn_to_ascii() */
|
||||||
bool curl_win32_idn_to_ascii(const char *in, char **out);
|
bool curl_win32_idn_to_ascii(const char *in, char **out);
|
||||||
#endif /* USE_LIBIDN */
|
#endif /* USE_LIBIDN2 */
|
||||||
|
|
||||||
|
#include <idn2.h>
|
||||||
|
|
||||||
#include "urldata.h"
|
#include "urldata.h"
|
||||||
#include "netrc.h"
|
#include "netrc.h"
|
||||||
@ -3771,58 +3762,15 @@ static bool is_ASCII_name(const char *hostname)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_LIBIDN
|
|
||||||
/*
|
|
||||||
* Check if characters in hostname is allowed in Top Level Domain.
|
|
||||||
*/
|
|
||||||
static bool tld_check_name(struct Curl_easy *data,
|
|
||||||
const char *ace_hostname)
|
|
||||||
{
|
|
||||||
size_t err_pos;
|
|
||||||
char *uc_name = NULL;
|
|
||||||
int rc;
|
|
||||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
|
||||||
const char *tld_errmsg = "<no msg>";
|
|
||||||
#else
|
|
||||||
(void)data;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Convert (and downcase) ACE-name back into locale's character set */
|
|
||||||
rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0);
|
|
||||||
if(rc != IDNA_SUCCESS)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* Warning: err_pos receives "the decoded character offset rather than the
|
|
||||||
byte position in the string." And as of libidn 1.32 that character offset
|
|
||||||
is for UTF-8, even if the passed in string is another locale. */
|
|
||||||
rc = tld_check_lz(uc_name, &err_pos, NULL);
|
|
||||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
|
||||||
#ifdef HAVE_TLD_STRERROR
|
|
||||||
if(rc != TLD_SUCCESS)
|
|
||||||
tld_errmsg = tld_strerror((Tld_rc)rc);
|
|
||||||
#endif
|
|
||||||
if(rc != TLD_SUCCESS)
|
|
||||||
infof(data, "WARNING: TLD check for %s failed; %s\n",
|
|
||||||
uc_name, tld_errmsg);
|
|
||||||
#endif /* CURL_DISABLE_VERBOSE_STRINGS */
|
|
||||||
if(uc_name)
|
|
||||||
idn_free(uc_name);
|
|
||||||
if(rc != TLD_SUCCESS)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Perform any necessary IDN conversion of hostname
|
* Perform any necessary IDN conversion of hostname
|
||||||
*/
|
*/
|
||||||
static void fix_hostname(struct Curl_easy *data,
|
static void fix_hostname(struct connectdata *conn, struct hostname *host)
|
||||||
struct connectdata *conn, struct hostname *host)
|
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
|
struct Curl_easy *data = conn->data;
|
||||||
|
|
||||||
#ifndef USE_LIBIDN
|
#ifndef USE_LIBIDN2
|
||||||
(void)data;
|
(void)data;
|
||||||
(void)conn;
|
(void)conn;
|
||||||
#elif defined(CURL_DISABLE_VERBOSE_STRINGS)
|
#elif defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||||
@ -3840,25 +3788,18 @@ static void fix_hostname(struct Curl_easy *data,
|
|||||||
|
|
||||||
/* Check name for non-ASCII and convert hostname to ACE form if we can */
|
/* Check name for non-ASCII and convert hostname to ACE form if we can */
|
||||||
if(!is_ASCII_name(host->name)) {
|
if(!is_ASCII_name(host->name)) {
|
||||||
#ifdef USE_LIBIDN
|
#ifdef USE_LIBIDN2
|
||||||
if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
|
if(idn2_check_version(IDN2_VERSION)) {
|
||||||
char *ace_hostname = NULL;
|
char *ace_hostname = NULL;
|
||||||
|
int rc = idn2_lookup_ul((const char *)host->name, &ace_hostname, 0);
|
||||||
int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0);
|
if(rc == IDN2_OK) {
|
||||||
infof(data, "Input domain encoded as `%s'\n",
|
host->encalloc = (char *)ace_hostname;
|
||||||
stringprep_locale_charset());
|
|
||||||
if(rc == IDNA_SUCCESS) {
|
|
||||||
/* tld_check_name() displays a warning if the host name contains
|
|
||||||
"illegal" characters for this TLD */
|
|
||||||
(void)tld_check_name(data, ace_hostname);
|
|
||||||
|
|
||||||
host->encalloc = ace_hostname;
|
|
||||||
/* change the name pointer to point to the encoded hostname */
|
/* change the name pointer to point to the encoded hostname */
|
||||||
host->name = host->encalloc;
|
host->name = host->encalloc;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
infof(data, "Failed to convert %s to ACE; %s\n", host->name,
|
infof(data, "Failed to convert %s to ACE; %s\n", host->name,
|
||||||
Curl_idn_strerror(conn, rc));
|
idn2_strerror(rc));
|
||||||
}
|
}
|
||||||
#elif defined(USE_WIN32_IDN)
|
#elif defined(USE_WIN32_IDN)
|
||||||
char *ace_hostname = NULL;
|
char *ace_hostname = NULL;
|
||||||
@ -3881,9 +3822,9 @@ static void fix_hostname(struct Curl_easy *data,
|
|||||||
*/
|
*/
|
||||||
static void free_fixed_hostname(struct hostname *host)
|
static void free_fixed_hostname(struct hostname *host)
|
||||||
{
|
{
|
||||||
#if defined(USE_LIBIDN)
|
#if defined(USE_LIBIDN2)
|
||||||
if(host->encalloc) {
|
if(host->encalloc) {
|
||||||
idn_free(host->encalloc); /* must be freed with idn_free() since this was
|
idn2_free(host->encalloc); /* must be freed with idn2_free() since this was
|
||||||
allocated by libidn */
|
allocated by libidn */
|
||||||
host->encalloc = NULL;
|
host->encalloc = NULL;
|
||||||
}
|
}
|
||||||
@ -6046,11 +5987,11 @@ static CURLcode create_conn(struct Curl_easy *data,
|
|||||||
/*************************************************************
|
/*************************************************************
|
||||||
* IDN-fix the hostnames
|
* IDN-fix the hostnames
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
fix_hostname(data, conn, &conn->host);
|
fix_hostname(conn, &conn->host);
|
||||||
if(conn->bits.conn_to_host)
|
if(conn->bits.conn_to_host)
|
||||||
fix_hostname(data, conn, &conn->conn_to_host);
|
fix_hostname(conn, &conn->conn_to_host);
|
||||||
if(conn->proxy.name && *conn->proxy.name)
|
if(conn->proxy.name && *conn->proxy.name)
|
||||||
fix_hostname(data, conn, &conn->proxy);
|
fix_hostname(conn, &conn->proxy);
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* Check whether the host and the "connect to host" are equal.
|
* Check whether the host and the "connect to host" are equal.
|
||||||
|
@ -36,8 +36,8 @@
|
|||||||
# include <ares.h>
|
# include <ares.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_LIBIDN
|
#ifdef USE_LIBIDN2
|
||||||
#include <stringprep.h>
|
#include <idn2.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_LIBPSL
|
#ifdef USE_LIBPSL
|
||||||
@ -111,9 +111,9 @@ char *curl_version(void)
|
|||||||
left -= len;
|
left -= len;
|
||||||
ptr += len;
|
ptr += len;
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_LIBIDN
|
#ifdef USE_LIBIDN2
|
||||||
if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
|
if(idn2_check_version(IDN2_VERSION)) {
|
||||||
len = snprintf(ptr, left, " libidn/%s", stringprep_check_version(NULL));
|
len = snprintf(ptr, left, " libidn2/%s", idn2_check_version(NULL));
|
||||||
left -= len;
|
left -= len;
|
||||||
ptr += len;
|
ptr += len;
|
||||||
}
|
}
|
||||||
@ -365,10 +365,10 @@ curl_version_info_data *curl_version_info(CURLversion stamp)
|
|||||||
version_info.ares_num = aresnum;
|
version_info.ares_num = aresnum;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_LIBIDN
|
#ifdef USE_LIBIDN2
|
||||||
/* This returns a version string if we use the given version or later,
|
/* This returns a version string if we use the given version or later,
|
||||||
otherwise it returns NULL */
|
otherwise it returns NULL */
|
||||||
version_info.libidn = stringprep_check_version(LIBIDN_REQUIRED_VERSION);
|
version_info.libidn = idn2_check_version(IDN2_VERSION);
|
||||||
if(version_info.libidn)
|
if(version_info.libidn)
|
||||||
version_info.features |= CURL_VERSION_IDN;
|
version_info.features |= CURL_VERSION_IDN;
|
||||||
#elif defined(USE_WIN32_IDN)
|
#elif defined(USE_WIN32_IDN)
|
||||||
|
Loading…
Reference in New Issue
Block a user