/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright 2010, 2013 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, see
 * <http://www.gnu.org/licenses/>.
 */

#include "config.h"

#include <stdlib.h>
#include <string.h>

#include "gsimpleproxyresolver.h"
#include "ginetaddress.h"
#include "ginetaddressmask.h"
#include "gnetworkingprivate.h"
#include "gtask.h"

#include "glibintl.h"

/**
 * SECTION:gsimpleproxyresolver
 * @short_description: Simple proxy resolver implementation
 * @include: gio/gio.h
 * @see_also: g_socket_client_set_proxy_resolver()
 *
 * #GSimpleProxyResolver is a simple #GProxyResolver implementation
 * that handles a single default proxy, multiple URI-scheme-specific
 * proxies, and a list of hosts that proxies should not be used for.
 *
 * #GSimpleProxyResolver is never the default proxy resolver, but it
 * can be used as the base class for another proxy resolver
 * implementation, or it can be created and used manually, such as
 * with g_socket_client_set_proxy_resolver().
 *
 * Since: 2.36
 */

typedef struct {
  gchar        *name;
  gint          length;
  gushort       port;
} GSimpleProxyResolverDomain;

struct _GSimpleProxyResolverPrivate {
  gchar *default_proxy, **ignore_hosts;
  GHashTable *uri_proxies;

  GPtrArray *ignore_ips;
  GSimpleProxyResolverDomain *ignore_domains;
};

static void g_simple_proxy_resolver_iface_init (GProxyResolverInterface *iface);

G_DEFINE_TYPE_WITH_CODE (GSimpleProxyResolver, g_simple_proxy_resolver, G_TYPE_OBJECT,
                         G_ADD_PRIVATE (GSimpleProxyResolver)
                         G_IMPLEMENT_INTERFACE (G_TYPE_PROXY_RESOLVER,
                                                g_simple_proxy_resolver_iface_init))

enum
{
  PROP_0,
  PROP_DEFAULT_PROXY,
  PROP_IGNORE_HOSTS
};

static void reparse_ignore_hosts (GSimpleProxyResolver *resolver);

static void
g_simple_proxy_resolver_finalize (GObject *object)
{
  GSimpleProxyResolver *resolver = G_SIMPLE_PROXY_RESOLVER (object);
  GSimpleProxyResolverPrivate *priv = resolver->priv;

  g_free (priv->default_proxy);
  g_hash_table_destroy (priv->uri_proxies);

  g_clear_pointer (&priv->ignore_hosts, g_strfreev);
  /* This will free ignore_ips and ignore_domains */
  reparse_ignore_hosts (resolver);

  G_OBJECT_CLASS (g_simple_proxy_resolver_parent_class)->finalize (object);
}

static void
g_simple_proxy_resolver_init (GSimpleProxyResolver *resolver)
{
  resolver->priv = g_simple_proxy_resolver_get_instance_private (resolver);
  resolver->priv->uri_proxies = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                       g_free, g_free);
}

static void
g_simple_proxy_resolver_set_property (GObject      *object,
                                      guint         prop_id,
                                      const GValue *value,
                                      GParamSpec   *pspec)
{
  GSimpleProxyResolver *resolver = G_SIMPLE_PROXY_RESOLVER (object);

  switch (prop_id)
    {
      case PROP_DEFAULT_PROXY:
        g_simple_proxy_resolver_set_default_proxy (resolver, g_value_get_string (value));
	break;

      case PROP_IGNORE_HOSTS:
        g_simple_proxy_resolver_set_ignore_hosts (resolver, g_value_get_boxed (value));
	break;

      default:
	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    }
}

static void
g_simple_proxy_resolver_get_property (GObject    *object,
                                      guint       prop_id,
                                      GValue     *value,
                                      GParamSpec *pspec)
{
  GSimpleProxyResolver *resolver = G_SIMPLE_PROXY_RESOLVER (object);

  switch (prop_id)
    {
      case PROP_DEFAULT_PROXY:
	g_value_set_string (value, resolver->priv->default_proxy);
	break;

      case PROP_IGNORE_HOSTS:
	g_value_set_boxed (value, resolver->priv->ignore_hosts);
	break;

      default:
	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    }
}

static void
reparse_ignore_hosts (GSimpleProxyResolver *resolver)
{
  GSimpleProxyResolverPrivate *priv = resolver->priv;
  GPtrArray *ignore_ips;
  GArray *ignore_domains;
  gchar *host, *tmp, *colon, *bracket;
  GInetAddress *iaddr;
  GInetAddressMask *mask;
  GSimpleProxyResolverDomain domain;
  gushort port;
  int i;

  if (priv->ignore_ips)
    g_ptr_array_free (priv->ignore_ips, TRUE);
  if (priv->ignore_domains)
    {
      for (i = 0; priv->ignore_domains[i].name; i++)
	g_free (priv->ignore_domains[i].name);
      g_free (priv->ignore_domains);
    }
  priv->ignore_ips = NULL;
  priv->ignore_domains = NULL;

  if (!priv->ignore_hosts || !priv->ignore_hosts[0])
    return;

  ignore_ips = g_ptr_array_new_with_free_func (g_object_unref);
  ignore_domains = g_array_new (TRUE, FALSE, sizeof (GSimpleProxyResolverDomain));

  for (i = 0; priv->ignore_hosts[i]; i++)
    {
      host = g_strchomp (priv->ignore_hosts[i]);

      /* See if it's an IP address or IP/length mask */
      mask = g_inet_address_mask_new_from_string (host, NULL);
      if (mask)
        {
          g_ptr_array_add (ignore_ips, mask);
          continue;
        }

      port = 0;

      if (*host == '[')
        {
          /* [IPv6]:port */
          host++;
          bracket = strchr (host, ']');
          if (!bracket || !bracket[1] || bracket[1] != ':')
            goto bad;

          port = strtoul (bracket + 2, &tmp, 10);
          if (*tmp)
            goto bad;

          *bracket = '\0';
        }
      else
        {
          colon = strchr (host, ':');
          if (colon && !strchr (colon + 1, ':'))
            {
              /* hostname:port or IPv4:port */
              port = strtoul (colon + 1, &tmp, 10);
              if (*tmp)
                goto bad;
              *colon = '\0';
            }
        }

      iaddr = g_inet_address_new_from_string (host);
      if (iaddr)
        g_object_unref (iaddr);
      else
        {
          if (g_str_has_prefix (host, "*."))
            host += 2;
          else if (*host == '.')
            host++;
        }

      memset (&domain, 0, sizeof (domain));
      domain.name = g_strdup (host);
      domain.length = strlen (domain.name);
      domain.port = port;
      g_array_append_val (ignore_domains, domain);
      continue;

    bad:
      g_warning ("Ignoring invalid ignore_hosts value '%s'", host);
    }

  if (ignore_ips->len)
    priv->ignore_ips = ignore_ips;
  else
    g_ptr_array_free (ignore_ips, TRUE);

  if (ignore_domains->len)
    priv->ignore_domains = (GSimpleProxyResolverDomain *)ignore_domains->data;
  g_array_free (ignore_domains, ignore_domains->len == 0);
}

static gboolean
ignore_host (GSimpleProxyResolver *resolver,
	     const gchar          *host,
	     gushort               port)
{
  GSimpleProxyResolverPrivate *priv = resolver->priv;
  gchar *ascii_host = NULL;
  gboolean ignore = FALSE;
  gint i, length, offset;

  if (priv->ignore_ips)
    {
      GInetAddress *iaddr;

      iaddr = g_inet_address_new_from_string (host);
      if (iaddr)
	{
	  for (i = 0; i < priv->ignore_ips->len; i++)
	    {
	      GInetAddressMask *mask = priv->ignore_ips->pdata[i];

	      if (g_inet_address_mask_matches (mask, iaddr))
		{
		  ignore = TRUE;
		  break;
		}
	    }

	  g_object_unref (iaddr);
	  if (ignore)
	    return TRUE;
	}
    }

  if (priv->ignore_domains)
    {
      if (g_hostname_is_non_ascii (host))
        host = ascii_host = g_hostname_to_ascii (host);
      length = strlen (host);

      for (i = 0; priv->ignore_domains[i].length; i++)
	{
	  GSimpleProxyResolverDomain *domain = &priv->ignore_domains[i];

	  offset = length - domain->length;
	  if ((domain->port == 0 || domain->port == port) &&
	      (offset == 0 || (offset > 0 && host[offset - 1] == '.')) &&
	      (g_ascii_strcasecmp (domain->name, host + offset) == 0))
	    {
	      ignore = TRUE;
	      break;
	    }
	}

      g_free (ascii_host);
    }

  return ignore;
}

static gchar **
g_simple_proxy_resolver_lookup (GProxyResolver  *proxy_resolver,
                                const gchar     *uri,
                                GCancellable    *cancellable,
                                GError         **error)
{
  GSimpleProxyResolver *resolver = G_SIMPLE_PROXY_RESOLVER (proxy_resolver);
  GSimpleProxyResolverPrivate *priv = resolver->priv;
  const gchar *proxy = NULL;
  gchar **proxies;

  if (priv->ignore_ips || priv->ignore_domains)
    {
      gchar *host = NULL;
      gushort port;

      if (_g_uri_parse_authority (uri, &host, &port, NULL) &&
          ignore_host (resolver, host, port))
        proxy = "direct://";

      g_free (host);
    }

  if (!proxy && g_hash_table_size (priv->uri_proxies))
    {
      gchar *scheme = g_ascii_strdown (uri, strcspn (uri, ":"));

      proxy = g_hash_table_lookup (priv->uri_proxies, scheme);
      g_free (scheme);
    }

  if (!proxy)
    proxy = priv->default_proxy;
  if (!proxy)
    proxy = "direct://";

  if (!strncmp (proxy, "socks://", 8))
    {
      proxies = g_new0 (gchar *, 4);
      proxies[0] = g_strdup_printf ("socks5://%s", proxy + 8);
      proxies[1] = g_strdup_printf ("socks4a://%s", proxy + 8);
      proxies[2] = g_strdup_printf ("socks4://%s", proxy + 8);
      proxies[3] = NULL;
    }
  else
    {
      proxies = g_new0 (gchar *, 2);
      proxies[0] = g_strdup (proxy);
    }

  return proxies;
}

static void
g_simple_proxy_resolver_lookup_async (GProxyResolver      *proxy_resolver,
                                      const gchar         *uri,
                                      GCancellable        *cancellable,
                                      GAsyncReadyCallback  callback,
                                      gpointer             user_data)
{
  GSimpleProxyResolver *resolver = G_SIMPLE_PROXY_RESOLVER (proxy_resolver);
  GTask *task;
  GError *error = NULL;
  char **proxies;

  task = g_task_new (resolver, cancellable, callback, user_data);
  g_task_set_source_tag (task, g_simple_proxy_resolver_lookup_async);

  proxies = g_simple_proxy_resolver_lookup (proxy_resolver, uri,
                                            cancellable, &error);
  if (proxies)
    g_task_return_pointer (task, proxies, (GDestroyNotify)g_strfreev);
  else
    g_task_return_error (task, error);
  g_object_unref (task);
}

static gchar **
g_simple_proxy_resolver_lookup_finish (GProxyResolver  *resolver,
                                       GAsyncResult    *result,
                                       GError         **error)
{
  g_return_val_if_fail (g_task_is_valid (result, resolver), NULL);

  return g_task_propagate_pointer (G_TASK (result), error);
}

static void
g_simple_proxy_resolver_class_init (GSimpleProxyResolverClass *resolver_class)
{
  GObjectClass *object_class = G_OBJECT_CLASS (resolver_class);

  object_class->get_property = g_simple_proxy_resolver_get_property;
  object_class->set_property = g_simple_proxy_resolver_set_property;
  object_class->finalize = g_simple_proxy_resolver_finalize;

  /**
   * GSimpleProxyResolver:default-proxy:
   *
   * The default proxy URI that will be used for any URI that doesn't
   * match #GSimpleProxyResolver:ignore-hosts, and doesn't match any
   * of the schemes set with g_simple_proxy_resolver_set_uri_proxy().
   *
   * Note that as a special case, if this URI starts with
   * "socks://", #GSimpleProxyResolver will treat it as referring
   * to all three of the socks5, socks4a, and socks4 proxy types.
   */
  g_object_class_install_property (object_class, PROP_DEFAULT_PROXY,
				   g_param_spec_string ("default-proxy",
                                                        P_("Default proxy"),
                                                        P_("The default proxy URI"),
                                                        NULL,
                                                        G_PARAM_READWRITE |
                                                        G_PARAM_STATIC_STRINGS));

  /**
   * GSimpleProxyResolver:ignore-hosts:
   *
   * A list of hostnames and IP addresses that the resolver should
   * allow direct connections to.
   *
   * Entries can be in one of 4 formats:
   *
   * - A hostname, such as "example.com", ".example.com", or
   *   "*.example.com", any of which match "example.com" or
   *   any subdomain of it.
   *
   * - An IPv4 or IPv6 address, such as "192.168.1.1",
   *   which matches only that address.
   *
   * - A hostname or IP address followed by a port, such as
   *   "example.com:80", which matches whatever the hostname or IP
   *   address would match, but only for URLs with the (explicitly)
   *   indicated port. In the case of an IPv6 address, the address
   *   part must appear in brackets: "[::1]:443"
   *
   * - An IP address range, given by a base address and prefix length,
   *   such as "fe80::/10", which matches any address in that range.
   *
   * Note that when dealing with Unicode hostnames, the matching is
   * done against the ASCII form of the name.
   *
   * Also note that hostname exclusions apply only to connections made
   * to hosts identified by name, and IP address exclusions apply only
   * to connections made to hosts identified by address. That is, if
   * example.com has an address of 192.168.1.1, and the :ignore-hosts list
   * contains only "192.168.1.1", then a connection to "example.com"
   * (eg, via a #GNetworkAddress) will use the proxy, and a connection to
   * "192.168.1.1" (eg, via a #GInetSocketAddress) will not.
   *
   * These rules match the "ignore-hosts"/"noproxy" rules most
   * commonly used by other applications.
   */
  g_object_class_install_property (object_class, PROP_IGNORE_HOSTS,
				   g_param_spec_boxed ("ignore-hosts",
                                                       P_("Ignore hosts"),
                                                       P_("Hosts that will not use the proxy"),
                                                       G_TYPE_STRV,
                                                       G_PARAM_READWRITE |
                                                       G_PARAM_STATIC_STRINGS));

}

static void
g_simple_proxy_resolver_iface_init (GProxyResolverInterface *iface)
{
  iface->lookup = g_simple_proxy_resolver_lookup;
  iface->lookup_async = g_simple_proxy_resolver_lookup_async;
  iface->lookup_finish = g_simple_proxy_resolver_lookup_finish;
}

/**
 * g_simple_proxy_resolver_new:
 * @default_proxy: (allow-none): the default proxy to use, eg
 *     "socks://192.168.1.1"
 * @ignore_hosts: (allow-none): an optional list of hosts/IP addresses
 *     to not use a proxy for.
 *
 * Creates a new #GSimpleProxyResolver. See
 * #GSimpleProxyResolver:default-proxy and
 * #GSimpleProxyResolver:ignore-hosts for more details on how the
 * arguments are interpreted.
 *
 * Returns: (transfer full) a new #GSimpleProxyResolver
 *
 * Since: 2.36
 */
GProxyResolver *
g_simple_proxy_resolver_new (const gchar  *default_proxy,
                             gchar       **ignore_hosts)
{
  return g_object_new (G_TYPE_SIMPLE_PROXY_RESOLVER,
                       "default-proxy", default_proxy,
                       "ignore-hosts", ignore_hosts,
                       NULL);
}

/**
 * g_simple_proxy_resolver_set_default_proxy:
 * @resolver: a #GSimpleProxyResolver
 * @default_proxy: the default proxy to use
 *
 * Sets the default proxy on @resolver, to be used for any URIs that
 * don't match #GSimpleProxyResolver:ignore-hosts or a proxy set
 * via g_simple_proxy_resolver_set_uri_proxy().
 *
 * If @default_proxy starts with "socks://",
 * #GSimpleProxyResolver will treat it as referring to all three of
 * the socks5, socks4a, and socks4 proxy types.
 *
 * Since: 2.36
 */
void
g_simple_proxy_resolver_set_default_proxy (GSimpleProxyResolver *resolver,
                                           const gchar          *default_proxy)
{
  g_return_if_fail (G_IS_SIMPLE_PROXY_RESOLVER (resolver));

  g_free (resolver->priv->default_proxy);
  resolver->priv->default_proxy = g_strdup (default_proxy);
  g_object_notify (G_OBJECT (resolver), "default-proxy");
}

/**
 * g_simple_proxy_resolver_set_ignore_hosts:
 * @resolver: a #GSimpleProxyResolver
 * @ignore_hosts: %NULL-terminated list of hosts/IP addresses
 *     to not use a proxy for
 *
 * Sets the list of ignored hosts.
 *
 * See #GSimpleProxyResolver:ignore-hosts for more details on how the
 * @ignore_hosts argument is interpreted.
 *
 * Since: 2.36
 */
void
g_simple_proxy_resolver_set_ignore_hosts (GSimpleProxyResolver  *resolver,
                                          gchar                **ignore_hosts)
{
  g_return_if_fail (G_IS_SIMPLE_PROXY_RESOLVER (resolver));

  g_strfreev (resolver->priv->ignore_hosts);
  resolver->priv->ignore_hosts = g_strdupv (ignore_hosts);
  reparse_ignore_hosts (resolver);
  g_object_notify (G_OBJECT (resolver), "ignore-hosts");
}

/**
 * g_simple_proxy_resolver_set_uri_proxy:
 * @resolver: a #GSimpleProxyResolver
 * @uri_scheme: the URI scheme to add a proxy for
 * @proxy: the proxy to use for @uri_scheme
 *
 * Adds a URI-scheme-specific proxy to @resolver; URIs whose scheme
 * matches @uri_scheme (and which don't match
 * #GSimpleProxyResolver:ignore-hosts) will be proxied via @proxy.
 *
 * As with #GSimpleProxyResolver:default-proxy, if @proxy starts with
 * "socks://", #GSimpleProxyResolver will treat it
 * as referring to all three of the socks5, socks4a, and socks4 proxy
 * types.
 *
 * Since: 2.36
 */
void
g_simple_proxy_resolver_set_uri_proxy (GSimpleProxyResolver *resolver,
                                       const gchar          *uri_scheme,
                                       const gchar          *proxy)
{
  g_return_if_fail (G_IS_SIMPLE_PROXY_RESOLVER (resolver));

  g_hash_table_replace (resolver->priv->uri_proxies,
                        g_ascii_strdown (uri_scheme, -1),
                        g_strdup (proxy));
}
