Mercurial > hg
changeset 1639:d9913c1b35e7
Add support for libidn
author | Mikael Berthe <mikael@lilotux.net> |
---|---|
date | Sun, 25 Oct 2009 23:25:14 +0100 |
parents | 3b3b5c1f8327 |
children | bf2258e29834 |
files | mcabber/configure.ac mcabber/src/utils.c |
diffstat | 2 files changed, 85 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- 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
--- 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 <config.h> + #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> +#ifdef HAVE_LIBIDN +#include <idna.h> +#include <stringprep.h> +static char idnprep[1024]; +#endif + +#include <glib.h> #include <glib/gprintf.h> /* For Cygwin (thanks go to Yitzchak Scott-Thoennes) */ @@ -38,9 +47,7 @@ #include <sys/types.h> #include <sys/stat.h> #include <ctype.h> -#include <glib.h> -#include <config.h> #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; }