/* 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.1 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;
  gsize          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;
  gsize offset, length;
  guint i;

  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)
    {
      length = 0;
      if (g_hostname_is_non_ascii (host))
        host = ascii_host = g_hostname_to_ascii (host);
      if (host)
        length = strlen (host);

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

          if (domain->length > length)
            continue;

	  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;
      gint port;

      if (g_uri_split_network (uri, G_URI_FLAGS_NONE, NULL,
                               &host, &port, NULL) &&
          ignore_host (resolver, host, port > 0 ? port : 0))
        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: (nullable): the default proxy to use, eg
 *     "socks://192.168.1.1"
 * @ignore_hosts: (nullable): 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));
}
