/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */

/* GLIB - Library of useful routines for C programming
 * Copyright (C) 2008 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "config.h"

#include <string.h>

#include "ghostutils.h"

#include "garray.h"
#include "gmem.h"
#include "gstring.h"
#include "gstrfuncs.h"
#include "glibintl.h"


/**
 * SECTION:ghostutils
 * @short_description: Internet hostname utilities
 *
 * Functions for manipulating internet hostnames; in particular, for
 * converting between Unicode and ASCII-encoded forms of
 * Internationalized Domain Names (IDNs).
 *
 * The <ulink
 * url="http://www.ietf.org/rfc/rfc3490.txt">Internationalized Domain
 * Names for Applications (IDNA)</ulink> standards allow for the use
 * of Unicode domain names in applications, while providing
 * backward-compatibility with the old ASCII-only DNS, by defining an
 * ASCII-Compatible Encoding of any given Unicode name, which can be
 * used with non-IDN-aware applications and protocols. (For example,
 * "Παν語.org" maps to "xn--4wa8awb4637h.org".)
 **/

#define IDNA_ACE_PREFIX     "xn--"
#define IDNA_ACE_PREFIX_LEN 4

/* Punycode constants, from RFC 3492. */

#define PUNYCODE_BASE          36
#define PUNYCODE_TMIN           1
#define PUNYCODE_TMAX          26
#define PUNYCODE_SKEW          38
#define PUNYCODE_DAMP         700
#define PUNYCODE_INITIAL_BIAS  72
#define PUNYCODE_INITIAL_N   0x80

#define PUNYCODE_IS_BASIC(cp) ((guint)(cp) < 0x80)

/* Encode/decode a single base-36 digit */
static inline gchar
encode_digit (guint dig)
{
  if (dig < 26)
    return dig + 'a';
  else
    return dig - 26 + '0';
}

static inline guint
decode_digit (gchar dig)
{
  if (dig >= 'A' && dig <= 'Z')
    return dig - 'A';
  else if (dig >= 'a' && dig <= 'z')
    return dig - 'a';
  else if (dig >= '0' && dig <= '9')
    return dig - '0' + 26;
  else
    return G_MAXUINT;
}

/* Punycode bias adaptation algorithm, RFC 3492 section 6.1 */
static guint
adapt (guint    delta,
       guint    numpoints,
       gboolean firsttime)
{
  guint k;

  delta = firsttime ? delta / PUNYCODE_DAMP : delta / 2;
  delta += delta / numpoints;

  k = 0;
  while (delta > ((PUNYCODE_BASE - PUNYCODE_TMIN) * PUNYCODE_TMAX) / 2)
    {
      delta /= PUNYCODE_BASE - PUNYCODE_TMIN;
      k += PUNYCODE_BASE;
    }

  return k + ((PUNYCODE_BASE - PUNYCODE_TMIN + 1) * delta /
	      (delta + PUNYCODE_SKEW));
}

/* Punycode encoder, RFC 3492 section 6.3. The algorithm is
 * sufficiently bizarre that it's not really worth trying to explain
 * here.
 */
static gboolean
punycode_encode (const gchar *input_utf8,
                 gsize        input_utf8_length,
		 GString     *output)
{
  guint delta, handled_chars, num_basic_chars, bias, j, q, k, t, digit;
  gunichar n, m, *input;
  glong input_length;
  gboolean success = FALSE;

  /* Convert from UTF-8 to Unicode code points */
  input = g_utf8_to_ucs4 (input_utf8, input_utf8_length, NULL,
			  &input_length, NULL);
  if (!input)
    return FALSE;

  /* Copy basic chars */
  for (j = num_basic_chars = 0; j < input_length; j++)
    {
      if (PUNYCODE_IS_BASIC (input[j]))
	{
	  g_string_append_c (output, g_ascii_tolower (input[j]));
	  num_basic_chars++;
	}
    }
  if (num_basic_chars)
    g_string_append_c (output, '-');

  handled_chars = num_basic_chars;

  /* Encode non-basic chars */
  delta = 0;
  bias = PUNYCODE_INITIAL_BIAS;
  n = PUNYCODE_INITIAL_N;
  while (handled_chars < input_length)
    {
      /* let m = the minimum {non-basic} code point >= n in the input */
      for (m = G_MAXUINT, j = 0; j < input_length; j++)
	{
	  if (input[j] >= n && input[j] < m)
	    m = input[j];
	}

      if (m - n > (G_MAXUINT - delta) / (handled_chars + 1))
	goto fail;
      delta += (m - n) * (handled_chars + 1);
      n = m;

      for (j = 0; j < input_length; j++)
	{
	  if (input[j] < n)
	    {
	      if (++delta == 0)
		goto fail;
	    }
	  else if (input[j] == n)
	    {
	      q = delta;
	      for (k = PUNYCODE_BASE; ; k += PUNYCODE_BASE)
		{
		  if (k <= bias)
		    t = PUNYCODE_TMIN;
		  else if (k >= bias + PUNYCODE_TMAX)
		    t = PUNYCODE_TMAX;
		  else
		    t = k - bias;
		  if (q < t)
		    break;
		  digit = t + (q - t) % (PUNYCODE_BASE - t);
		  g_string_append_c (output, encode_digit (digit));
		  q = (q - t) / (PUNYCODE_BASE - t);
		}

	      g_string_append_c (output, encode_digit (q));
	      bias = adapt (delta, handled_chars + 1, handled_chars == num_basic_chars);
	      delta = 0;
	      handled_chars++;
	    }
	}

      delta++;
      n++;
    }

  success = TRUE;

 fail:
  g_free (input);
  return success;
}

/* From RFC 3454, Table B.1 */
#define idna_is_junk(ch) ((ch) == 0x00AD || (ch) == 0x1806 || (ch) == 0x200B || (ch) == 0x2060 || (ch) == 0xFEFF || (ch) == 0x034F || (ch) == 0x180B || (ch) == 0x180C || (ch) == 0x180D || (ch) == 0x200C || (ch) == 0x200D || ((ch) >= 0xFE00 && (ch) <= 0xFE0F))

/* Scan @str for "junk" and return a cleaned-up string if any junk
 * is found. Else return %NULL.
 */
static gchar *
remove_junk (const gchar *str,
             gint         len)
{
  GString *cleaned = NULL;
  const gchar *p;
  gunichar ch;

  for (p = str; len == -1 ? *p : p < str + len; p = g_utf8_next_char (p))
    {
      ch = g_utf8_get_char (p);
      if (idna_is_junk (ch))
	{
	  if (!cleaned)
	    {
	      cleaned = g_string_new (NULL);
	      g_string_append_len (cleaned, str, p - str);
	    }
	}
      else if (cleaned)
	g_string_append_unichar (cleaned, ch);
    }

  if (cleaned)
    return g_string_free (cleaned, FALSE);
  else
    return NULL;
}

static inline gboolean
contains_uppercase_letters (const gchar *str,
                            gint         len)
{
  const gchar *p;

  for (p = str; len == -1 ? *p : p < str + len; p = g_utf8_next_char (p))
    {
      if (g_unichar_isupper (g_utf8_get_char (p)))
	return TRUE;
    }
  return FALSE;
}

static inline gboolean
contains_non_ascii (const gchar *str,
                    gint         len)
{
  const gchar *p;

  for (p = str; len == -1 ? *p : p < str + len; p++)
    {
      if ((guchar)*p > 0x80)
	return TRUE;
    }
  return FALSE;
}

/* RFC 3454, Appendix C. ish. */
static inline gboolean
idna_is_prohibited (gunichar ch)
{
  switch (g_unichar_type (ch))
    {
    case G_UNICODE_CONTROL:
    case G_UNICODE_FORMAT:
    case G_UNICODE_UNASSIGNED:
    case G_UNICODE_PRIVATE_USE:
    case G_UNICODE_SURROGATE:
    case G_UNICODE_LINE_SEPARATOR:
    case G_UNICODE_PARAGRAPH_SEPARATOR:
    case G_UNICODE_SPACE_SEPARATOR:
      return TRUE;

    case G_UNICODE_OTHER_SYMBOL:
      if (ch == 0xFFFC || ch == 0xFFFD ||
	  (ch >= 0x2FF0 && ch <= 0x2FFB))
	return TRUE;
      return FALSE;

    case G_UNICODE_NON_SPACING_MARK:
      if (ch == 0x0340 || ch == 0x0341)
	return TRUE;
      return FALSE;

    default:
      return FALSE;
    }
}

/* RFC 3491 IDN cleanup algorithm. */
static gchar *
nameprep (const gchar *hostname,
          gint         len,
          gboolean    *is_unicode)
{
  gchar *name, *tmp = NULL, *p;

  /* It would be nice if we could do this without repeatedly
   * allocating strings and converting back and forth between
   * gunichars and UTF-8... The code does at least avoid doing most of
   * the sub-operations when they would just be equivalent to a
   * g_strdup().
   */

  /* Remove presentation-only characters */
  name = remove_junk (hostname, len);
  if (name)
    {
      tmp = name;
      len = -1;
    }
  else
    name = (gchar *)hostname;

  /* Convert to lowercase */
  if (contains_uppercase_letters (name, len))
    {
      name = g_utf8_strdown (name, len);
      g_free (tmp);
      tmp = name;
      len = -1;
    }

  /* If there are no UTF8 characters, we're done. */
  if (!contains_non_ascii (name, len))
    {
      *is_unicode = FALSE;
      if (name == (gchar *)hostname)
        return len == -1 ? g_strdup (hostname) : g_strndup (hostname, len);
      else
        return name;
    }

  *is_unicode = TRUE;

  /* Normalize */
  name = g_utf8_normalize (name, len, G_NORMALIZE_NFKC);
  g_free (tmp);
  tmp = name;

  if (!name)
    return NULL;

  /* KC normalization may have created more capital letters (eg,
   * angstrom -> capital A with ring). So we have to lowercasify a
   * second time. (This is more-or-less how the nameprep algorithm
   * does it. If tolower(nfkc(tolower(X))) is guaranteed to be the
   * same as tolower(nfkc(X)), then we could skip the first tolower,
   * but I'm not sure it is.)
   */
  if (contains_uppercase_letters (name, -1))
    {
      name = g_utf8_strdown (name, -1);
      g_free (tmp);
      tmp = name;
    }

  /* Check for prohibited characters */
  for (p = name; *p; p = g_utf8_next_char (p))
    {
      if (idna_is_prohibited (g_utf8_get_char (p)))
	{
	  name = NULL;
          g_free (tmp);
	  goto done;
	}
    }

  /* FIXME: We're supposed to verify certain constraints on bidi
   * characters, but glib does not appear to have that information.
   */

 done:
  return name;
}

/* RFC 3490, section 3.1 says '.', 0x3002, 0xFF0E, and 0xFF61 count as
 * label-separating dots. @str must be '\0'-terminated.
 */
#define idna_is_dot(str) ( \
  ((guchar)(str)[0] == '.') ||                                                 \
  ((guchar)(str)[0] == 0xE3 && (guchar)(str)[1] == 0x80 && (guchar)(str)[2] == 0x82) || \
  ((guchar)(str)[0] == 0xEF && (guchar)(str)[1] == 0xBC && (guchar)(str)[2] == 0x8E) || \
  ((guchar)(str)[0] == 0xEF && (guchar)(str)[1] == 0xBD && (guchar)(str)[2] == 0xA1) )

static const gchar *
idna_end_of_label (const gchar *str)
{
  for (; *str; str = g_utf8_next_char (str))
    {
      if (idna_is_dot (str))
        return str;
    }
  return str;
}

/**
 * g_hostname_to_ascii:
 * @hostname: a valid UTF-8 or ASCII hostname
 *
 * Converts @hostname to its canonical ASCII form; an ASCII-only
 * string containing no uppercase letters and not ending with a
 * trailing dot.
 *
 * Return value: an ASCII hostname, which must be freed, or %NULL if
 * @hostname is in some way invalid.
 *
 * Since: 2.22
 **/
gchar *
g_hostname_to_ascii (const gchar *hostname)
{
  gchar *name, *label, *p;
  GString *out;
  gssize llen, oldlen;
  gboolean unicode;

  label = name = nameprep (hostname, -1, &unicode);
  if (!name || !unicode)
    return name;

  out = g_string_new (NULL);

  do
    {
      unicode = FALSE;
      for (p = label; *p && !idna_is_dot (p); p++)
	{
	  if ((guchar)*p > 0x80)
	    unicode = TRUE;
	}

      oldlen = out->len;
      llen = p - label;
      if (unicode)
	{
          if (!strncmp (label, IDNA_ACE_PREFIX, IDNA_ACE_PREFIX_LEN))
            goto fail;

	  g_string_append (out, IDNA_ACE_PREFIX);
	  if (!punycode_encode (label, llen, out))
	    goto fail;
	}
      else
        g_string_append_len (out, label, llen);

      if (out->len - oldlen > 63)
	goto fail;

      label += llen;
      if (*label)
        label = g_utf8_next_char (label);
      if (*label)
        g_string_append_c (out, '.');
    }
  while (*label);

  g_free (name);
  return g_string_free (out, FALSE);

 fail:
  g_free (name);
  g_string_free (out, TRUE);
  return NULL;
}

/**
 * g_hostname_is_non_ascii:
 * @hostname: a hostname
 *
 * Tests if @hostname contains Unicode characters. If this returns
 * %TRUE, you need to encode the hostname with g_hostname_to_ascii()
 * before using it in non-IDN-aware contexts.
 *
 * Note that a hostname might contain a mix of encoded and unencoded
 * segments, and so it is possible for g_hostname_is_non_ascii() and
 * g_hostname_is_ascii_encoded() to both return %TRUE for a name.
 *
 * Return value: %TRUE if @hostname contains any non-ASCII characters
 *
 * Since: 2.22
 **/
gboolean
g_hostname_is_non_ascii (const gchar *hostname)
{
  return contains_non_ascii (hostname, -1);
}

/* Punycode decoder, RFC 3492 section 6.2. As with punycode_encode(),
 * read the RFC if you want to understand what this is actually doing.
 */
static gboolean
punycode_decode (const gchar *input,
                 gsize        input_length,
                 GString     *output)
{
  GArray *output_chars;
  gunichar n;
  guint i, bias;
  guint oldi, w, k, digit, t;
  const gchar *split;

  n = PUNYCODE_INITIAL_N;
  i = 0;
  bias = PUNYCODE_INITIAL_BIAS;

  split = input + input_length - 1;
  while (split > input && *split != '-')
    split--;
  if (split > input)
    {
      output_chars = g_array_sized_new (FALSE, FALSE, sizeof (gunichar),
					split - input);
      input_length -= (split - input) + 1;
      while (input < split)
	{
	  gunichar ch = (gunichar)*input++;
	  if (!PUNYCODE_IS_BASIC (ch))
	    goto fail;
	  g_array_append_val (output_chars, ch);
	}
      input++;
    }
  else
    output_chars = g_array_new (FALSE, FALSE, sizeof (gunichar));

  while (input_length)
    {
      oldi = i;
      w = 1;
      for (k = PUNYCODE_BASE; ; k += PUNYCODE_BASE)
	{
	  if (!input_length--)
	    goto fail;
	  digit = decode_digit (*input++);
	  if (digit >= PUNYCODE_BASE)
	    goto fail;
	  if (digit > (G_MAXUINT - i) / w)
	    goto fail;
	  i += digit * w;
	  if (k <= bias)
	    t = PUNYCODE_TMIN;
	  else if (k >= bias + PUNYCODE_TMAX)
	    t = PUNYCODE_TMAX;
	  else
	    t = k - bias;
	  if (digit < t)
	    break;
	  if (w > G_MAXUINT / (PUNYCODE_BASE - t))
	    goto fail;
	  w *= (PUNYCODE_BASE - t);
	}

      bias = adapt (i - oldi, output_chars->len + 1, oldi == 0);

      if (i / (output_chars->len + 1) > G_MAXUINT - n)
	goto fail;
      n += i / (output_chars->len + 1);
      i %= (output_chars->len + 1);

      g_array_insert_val (output_chars, i++, n);
    }

  for (i = 0; i < output_chars->len; i++)
    g_string_append_unichar (output, g_array_index (output_chars, gunichar, i));
  g_array_free (output_chars, TRUE);
  return TRUE;

 fail:
  g_array_free (output_chars, TRUE);
  return FALSE;
}

/**
 * g_hostname_to_unicode:
 * @hostname: a valid UTF-8 or ASCII hostname
 *
 * Converts @hostname to its canonical presentation form; a UTF-8
 * string in Unicode normalization form C, containing no uppercase
 * letters, no forbidden characters, and no ASCII-encoded segments,
 * and not ending with a trailing dot.
 *
 * Of course if @hostname is not an internationalized hostname, then
 * the canonical presentation form will be entirely ASCII.
 *
 * Return value: a UTF-8 hostname, which must be freed, or %NULL if
 * @hostname is in some way invalid.
 *
 * Since: 2.22
 **/
gchar *
g_hostname_to_unicode (const gchar *hostname)
{
  GString *out;
  gssize llen;

  out = g_string_new (NULL);

  do
    {
      llen = idna_end_of_label (hostname) - hostname;
      if (!g_ascii_strncasecmp (hostname, IDNA_ACE_PREFIX, IDNA_ACE_PREFIX_LEN))
	{
	  hostname += IDNA_ACE_PREFIX_LEN;
	  llen -= IDNA_ACE_PREFIX_LEN;
	  if (!punycode_decode (hostname, llen, out))
	    {
	      g_string_free (out, TRUE);
	      return NULL;
	    }
	}
      else
        {
          gboolean unicode;
          gchar *canonicalized = nameprep (hostname, llen, &unicode);

          if (!canonicalized)
            {
              g_string_free (out, TRUE);
              return NULL;
            }
          g_string_append (out, canonicalized);
          g_free (canonicalized);
        }

      hostname += llen;
      if (*hostname)
        hostname = g_utf8_next_char (hostname);
      if (*hostname)
        g_string_append_c (out, '.');
    }
  while (*hostname);

  return g_string_free (out, FALSE);
}

/**
 * g_hostname_is_ascii_encoded:
 * @hostname: a hostname
 *
 * Tests if @hostname contains segments with an ASCII-compatible
 * encoding of an Internationalized Domain Name. If this returns
 * %TRUE, you should decode the hostname with g_hostname_to_unicode()
 * before displaying it to the user.
 *
 * Note that a hostname might contain a mix of encoded and unencoded
 * segments, and so it is possible for g_hostname_is_non_ascii() and
 * g_hostname_is_ascii_encoded() to both return %TRUE for a name.
 *
 * Return value: %TRUE if @hostname contains any ASCII-encoded
 * segments.
 *
 * Since: 2.22
 **/
gboolean
g_hostname_is_ascii_encoded (const gchar *hostname)
{
  while (1)
    {
      if (!g_ascii_strncasecmp (hostname, IDNA_ACE_PREFIX, IDNA_ACE_PREFIX_LEN))
	return TRUE;
      hostname = idna_end_of_label (hostname);
      if (*hostname)
        hostname = g_utf8_next_char (hostname);
      if (!*hostname)
	return FALSE;
    }
}

/**
 * g_hostname_is_ip_address:
 * @hostname: a hostname (or IP address in string form)
 *
 * Tests if @hostname is the string form of an IPv4 or IPv6 address.
 * (Eg, "192.168.0.1".)
 *
 * Return value: %TRUE if @hostname is an IP address
 *
 * Since: 2.22
 **/
gboolean
g_hostname_is_ip_address (const gchar *hostname)
{
  gchar *p, *end;
  gint nsegments, octet;

  /* On Linux we could implement this using inet_pton, but the Windows
   * equivalent of that requires linking against winsock, so we just
   * figure this out ourselves. Tested by tests/hostutils.c.
   */

  p = (char *)hostname;

  if (strchr (p, ':'))
    {
      gboolean skipped;

      /* If it contains a ':', it's an IPv6 address (assuming it's an
       * IP address at all). This consists of eight ':'-separated
       * segments, each containing a 1-4 digit hex number, except that
       * optionally: (a) the last two segments can be replaced by an
       * IPv4 address, and (b) a single span of 1 to 8 "0000" segments
       * can be replaced with just "::".
       */

      nsegments = 0;
      skipped = FALSE;
      while (*p && nsegments < 8)
        {
          /* Each segment after the first must be preceded by a ':'.
           * (We also handle half of the "string starts with ::" case
           * here.)
           */
          if (p != (char *)hostname || (p[0] == ':' && p[1] == ':'))
            {
              if (*p != ':')
                return FALSE;
              p++;
            }

          /* If there's another ':', it means we're skipping some segments */
          if (*p == ':' && !skipped)
            {
              skipped = TRUE;
              nsegments++;

              /* Handle the "string ends with ::" case */
              if (!p[1])
                p++;

              continue;
            }

          /* Read the segment, make sure it's valid. */
          for (end = p; g_ascii_isxdigit (*end); end++)
            ;
          if (end == p || end > p + 4)
            return FALSE;

          if (*end == '.')
            {
              if ((nsegments == 6 && !skipped) || (nsegments <= 6 && skipped))
                goto parse_ipv4;
              else
                return FALSE;
            }

          nsegments++;
          p = end;
        }

      return !*p && (nsegments == 8 || skipped);
    }

 parse_ipv4:

  /* Parse IPv4: N.N.N.N, where each N <= 255 and doesn't have leading 0s. */
  for (nsegments = 0; nsegments < 4; nsegments++)
    {
      if (nsegments != 0)
        {
          if (*p != '.')
            return FALSE;
          p++;
        }

      /* Check the segment; a little tricker than the IPv6 case since
       * we can't allow extra leading 0s, and we can't assume that all
       * strings of valid length are within range.
       */
      octet = 0;
      if (*p == '0')
        end = p + 1;
      else
        {
          for (end = p; g_ascii_isdigit (*end); end++)
            octet = 10 * octet + (*end - '0');
        }
      if (end == p || end > p + 3 || octet > 255)
        return FALSE;

      p = end;
    }

  /* If there's nothing left to parse, then it's ok. */
  return !*p;
}
