# HG changeset patch # User Mikael Berthe # Date 1256509514 -3600 # Node ID d9913c1b35e72fc56be4cb3c384b83004f632d95 # Parent 3b3b5c1f83274dbda64edb06dc066764c7bf1b38 Add support for libidn diff -r 3b3b5c1f8327 -r d9913c1b35e7 mcabber/configure.ac --- a/mcabber/configure.ac Sun Oct 25 01:15:31 2009 +0200 +++ b/mcabber/configure.ac Sun Oct 25 23:25:14 2009 +0100 @@ -152,6 +152,21 @@ AC_SUBST(LOUDMOUTH_CFLAGS) AC_SUBST(LOUDMOUTH_LIBS) +# Check for libidn +AC_ARG_WITH(libidn, AC_HELP_STRING([--with-libidn=[DIR]], + [Support IDN (needs GNU Libidn)]), + libidn=$withval, libidn=yes) +if test "$libidn" != "no" ; then + PKG_CHECK_MODULES(LIBIDN, libidn >= 0.0.0, [libidn=yes], [libidn=no]) + if test "$libidn" != "yes" ; then + libidn=no + AC_MSG_WARN([Libidn not found]) + else + libidn=yes + AC_DEFINE(HAVE_LIBIDN, 1, [Define to 1 if you want Libidn.]) + fi +fi + # Check for gpgme AC_ARG_ENABLE(gpgme, AC_HELP_STRING([--disable-gpgme], [disable GPGME support]), [ if test x"$enableval" = x"no"; then diff -r 3b3b5c1f8327 -r d9913c1b35e7 mcabber/src/utils.c --- a/mcabber/src/utils.c Sun Oct 25 01:15:31 2009 +0200 +++ b/mcabber/src/utils.c Sun Oct 25 23:25:14 2009 +0100 @@ -21,11 +21,20 @@ * USA */ +#include + #include #include #include #include +#ifdef HAVE_LIBIDN +#include +#include +static char idnprep[1024]; +#endif + +#include #include /* For Cygwin (thanks go to Yitzchak Scott-Thoennes) */ @@ -38,9 +47,7 @@ #include #include #include -#include -#include #include "utils.h" #include "logprint.h" @@ -402,6 +409,10 @@ const char *str; const char *domain, *resource; int domlen; +#ifdef HAVE_LIBIDN + char *idnpp, *ascidnp; + int r; +#endif if (!fjid) return 1; @@ -416,6 +427,28 @@ return 1; domain++; +#ifdef HAVE_LIBIDN + idnpp = idnprep; + str = fjid; + while (*str != JID_DOMAIN_SEPARATOR) + *idnpp++ = *str++; + *idnpp = 0; + + r = stringprep(idnprep, 1023, 0, stringprep_xmpp_nodeprep); + if (r != STRINGPREP_OK || !idnprep[0]) + return 1; + + // check the string hasn't been modified, in which case we consider + // it's a failure (as fjid is read-only) + idnpp = idnprep; + str = fjid; + while (*idnpp) { + if (*idnpp++ != *str++) + return 1; + } + scr_LogPrint(LPRINT_LOGNORM, "Stringprep'd node: [%s]", idnprep); // XXX + /* the username looks okay */ +#else /* check for low and invalid ascii characters in the username */ for (str = fjid; *str != JID_DOMAIN_SEPARATOR; str++) { if (*str <= ' ' || *str == ':' || *str == JID_DOMAIN_SEPARATOR || @@ -425,6 +458,7 @@ } } /* the username is okay as far as we can tell without LIBIDN */ +#endif } resource = strchr(domain, JID_RESOURCE_SEPARATOR); @@ -436,6 +470,12 @@ /* resources may not be longer than 1023 bytes */ if ((*resource == '\0') || strlen(resource) > 1023) return 1; +#ifdef HAVE_LIBIDN + strncpy(idnprep, resource, sizeof(idnprep)); + r = stringprep(idnprep, 1023, 0, stringprep_xmpp_resourceprep); + if (r != STRINGPREP_OK || !idnprep[0]) + return 1; +#endif } else { domlen = strlen(domain); } @@ -446,13 +486,40 @@ /* and it must not be longer than 1023 bytes */ if (domlen > 1023) return 1; +#ifdef HAVE_LIBIDN + idnpp = idnprep; + str = domain; + while (*str != '\0' && *str != JID_RESOURCE_SEPARATOR) + *idnpp++ = *str++; + *idnpp = 0; + + r = stringprep_nameprep(idnprep, 1023); + if (r != STRINGPREP_OK || !idnprep[0]) + return 1; + + if (idna_to_ascii_8z(idnprep, &ascidnp, IDNA_USE_STD3_ASCII_RULES) != + IDNA_SUCCESS) + return 1; + else + free(ascidnp); + + // check the string hasn't been modified, in which case we consider + // it's a failure (as fjid is read-only) + idnpp = idnprep; + str = domain; + while (*idnpp) { + if (*idnpp++ != *str++) + return 1; + } +#else /* make sure the hostname is valid characters */ for (str = domain; *str != '\0' && *str != JID_RESOURCE_SEPARATOR; str++) { if (!(isalnum(*str) || *str == '.' || *str == '-' || *str == '_')) return 1; } +#endif - /* it's okay as far as we can tell without LIBIDN */ + /* it's okay as far as we can tell */ return 0; }