/*
 * platform-cros.c - CrOS platform DBus integration
 * Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "config.h"

#include <ctype.h>
#include <dbus/dbus.h>
#include <errno.h>
#include <signal.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <time.h>

#include <event2/event.h>

#include "src/dbus.h"
#include "src/platform.h"
#include "src/tlsdate.h"
#include "src/util.h"

static const char kMatchFormatData[] = "interface='%s',member='%s',arg0='%s'";
static const char *kMatchFormat = kMatchFormatData;
static const char kMatchNoArgFormatData[] = "interface='%s',member='%s'";
static const char *kMatchNoArgFormat = kMatchNoArgFormatData;

static const char kLibCrosDestData[] = "org.chromium.LibCrosService";
static const char *kLibCrosDest = kLibCrosDestData;
static const char kLibCrosInterfaceData[] = "org.chromium.LibCrosServiceInterface";
static const char *kLibCrosInterface = kLibCrosInterfaceData;
static const char kLibCrosPathData[] = "/org/chromium/LibCrosService";
static const char *kLibCrosPath = kLibCrosPathData;
static const char kResolveNetworkProxyData[] = "ResolveNetworkProxy";
static const char *kResolveNetworkProxy = kResolveNetworkProxyData;

static const char kDBusInterfaceData[] = "org.freedesktop.DBus";
static const char *kDBusInterface = kDBusInterfaceData;
static const char kNameOwnerChangedData[] = "NameOwnerChanged";
static const char *kNameOwnerChanged = kNameOwnerChangedData;
static const char kNameAcquiredData[] = "NameAcquired";
static const char *kNameAcquired = kNameAcquiredData;

static const char kManagerInterfaceData[] = "org.chromium.flimflam.Manager";
static const char *kManagerInterface = kManagerInterfaceData;

static const char kServiceInterfaceData[] = "org.chromium.flimflam.Service";
static const char *kServiceInterface = kServiceInterfaceData;
static const char kMemberData[] = "PropertyChanged";
static const char *kMember = kMemberData;

static const char kProxyConfigData[] = "ProxyConfig";
static const char *kProxyConfig = kProxyConfigData;
static const char kDefaultServiceData[] = "DefaultService";
static const char *kDefaultService = kDefaultServiceData;

static const char kResolveInterfaceData[] = "org.torproject.tlsdate.Resolver";
static const char *kResolveInterface = kResolveInterfaceData;
static const char kResolveMemberData[] = "ProxyChange";
static const char *kResolveMember = kResolveMemberData;

/* TODO(wad) Integrate with cros_system_api/dbus/service_constants.h */
static const char kPowerManagerInterfaceData[] = "org.chromium.PowerManager";
static const char *kPowerManagerInterface = kPowerManagerInterfaceData;
static const char kSuspendDoneData[] = "SuspendDone";
static const char *kSuspendDone = kSuspendDoneData;

static const char kErrorServiceUnknownData[] = "org.freedesktop.DBus.Error.ServiceUnknown";
static const char *kErrorServiceUnknown = kErrorServiceUnknownData;

struct platform_state
{
  struct event_base *base;
  struct state *state;
  DBusMessage **resolve_msg;
  int resolve_msg_count;
  uint32_t resolve_network_proxy_serial;
};

static
bool
get_valid_hostport (const char *hostport, char *out, size_t len)
{
  bool host = true;
  const char *end = hostport + strlen (hostport);
  const char *c;
  *out = '\0';
  /* Hosts begin with alphanumeric only. */
  if (!isalnum (*hostport))
    {
      info ("Host does not start with alnum");
      return false;
    }
  *out++ = *hostport;
  for (c = hostport + 1;  c < end && len > 0; ++c, ++out, --len)
    {
      *out = *c;
      if (host)
        {
          if (isalnum (*c) || *c == '-' || *c == '.')
            {
              continue;
            }
          if (*c == ':')
            {
              host = false;
              continue;
            }
        }
      else
        {
          if (isdigit (*c))
            continue;
        }
      *out = '\0';
      return false;
    }
  *out = '\0';
  return true;
}

/* Convert PAC return format to tlsdated url format */
/* TODO(wad) support multiple proxies when Chromium does:
 * PROXY x.x.x.x:yyyy; PROXY z.z.z.z:aaaaa
 */
static
void
canonicalize_pac (const char *pac_fmt, char *proxy_url, size_t len)
{
  size_t type_len;
  int copied = 0;
  const char *space;
  /* host[255]:port[6]\0 */
  char hostport[6 + 255 + 2];
  proxy_url[0] = '\0';
  if (len < 1)
    return;
  if (!strcmp (pac_fmt, "DIRECT"))
    {
      return;
    }
  /* Find type */
  space = strchr (pac_fmt, ' ');
  if (!space)
    return;
  type_len = space - pac_fmt;
  if (!get_valid_hostport (space + 1, hostport, sizeof (hostport)))
    {
      error ("invalid host:port: %s", space + 1);
      return;
    }
  proxy_url[0] = '\0';
  if (!strncmp (pac_fmt, "PROXY", type_len))
    {
      copied = snprintf (proxy_url, len, "http://%s", hostport);
    }
  else if (!strncmp (pac_fmt, "SOCKS", type_len))
    {
      copied = snprintf (proxy_url, len, "socks4://%s", hostport);
    }
  else if (!strncmp (pac_fmt, "SOCKS5", type_len))
    {
      copied = snprintf (proxy_url, len, "socks5://%s", hostport);
    }
  else if (!strncmp (pac_fmt, "HTTPS", type_len))
    {
      copied = snprintf (proxy_url, len, "https://%s", hostport);
    }
  else
    {
      error ("pac_fmt unmatched: '%s' %zu", pac_fmt, type_len);
    }
  if (copied < 0 || ((size_t) copied) >= len)
    {
      error ("canonicalize_pac: truncation '%s'", proxy_url);
      proxy_url[0] = '\0';
      return;
    }
}

static
DBusHandlerResult
handle_service_change (DBusConnection *connection,
                       DBusMessage *message,
                       struct platform_state *ctx)
{
  DBusMessageIter iter, subiter;
  DBusError error;
  const char *pname;
  const char *pval;
  const char *service;
  dbus_error_init (&error);
  verb_debug ("[event:cros:%s]: fired", __func__);
  /* TODO(wad) Track the current DefaultService only fire when it changes */
  service = dbus_message_get_path (message);
  if (!service)
    return DBUS_HANDLER_RESULT_HANDLED;
  /* Shill emits string:ProxyConfig variant string:"..." */
  if (!dbus_message_iter_init (message, &iter))
    return DBUS_HANDLER_RESULT_HANDLED;
  if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
    return DBUS_HANDLER_RESULT_HANDLED;
  dbus_message_iter_get_basic (&iter, &pname);
  /* Make sure we are only firing on a ProxyConfig property change. */
  if (strcmp (pname, kProxyConfig))
    return DBUS_HANDLER_RESULT_HANDLED;
  if (!dbus_message_iter_next (&iter))
    return DBUS_HANDLER_RESULT_HANDLED;
  if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_VARIANT)
    return DBUS_HANDLER_RESULT_HANDLED;
  dbus_message_iter_recurse (&iter, &subiter);
  if (dbus_message_iter_get_arg_type (&subiter) != DBUS_TYPE_STRING)
    return DBUS_HANDLER_RESULT_HANDLED;
  dbus_message_iter_get_basic (&subiter, &pval);
  /* Right now, nothing is done with the Shill proxy value because
   * Chromium handles .pac resolution.  This may be more useful for
   * ignoring incomplete proxy values sent while a user is typing.
   */
  action_kickoff_time_sync (-1, EV_TIMEOUT, ctx->state);
  return DBUS_HANDLER_RESULT_HANDLED;
}

static
DBusHandlerResult
handle_manager_change (DBusConnection *connection,
                       DBusMessage *message,
                       struct platform_state *ctx)
{
  DBusMessageIter iter, subiter;
  DBusError error;
  const char *pname;
  const char *pval;
  verb_debug ("[event:cros:%s]: fired", __func__);
  dbus_error_init (&error);
  if (!dbus_message_iter_init (message, &iter))
    return DBUS_HANDLER_RESULT_HANDLED;
  if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
    return DBUS_HANDLER_RESULT_HANDLED;
  dbus_message_iter_get_basic (&iter, &pname);
  /* Make sure we caught the right property. */
  if (strcmp (pname, kDefaultService))
    return DBUS_HANDLER_RESULT_HANDLED;
  if (!dbus_message_iter_next (&iter))
    return DBUS_HANDLER_RESULT_HANDLED;
  if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_VARIANT)
    return DBUS_HANDLER_RESULT_HANDLED;
  dbus_message_iter_recurse (&iter, &subiter);
  if (dbus_message_iter_get_arg_type (&subiter) != DBUS_TYPE_OBJECT_PATH)
    return DBUS_HANDLER_RESULT_HANDLED;
  dbus_message_iter_get_basic (&subiter, &pval);
  /* TODO(wad) Filter on the currently active service in pval. */
  verb_debug ("[event:cros:%s] service change on path %s",
         __func__, pval);
  action_kickoff_time_sync (-1, EV_TIMEOUT, ctx->state);
  return DBUS_HANDLER_RESULT_HANDLED;
}

static
DBusHandlerResult
handle_suspend_done (DBusConnection *connection,
                     DBusMessage *message,
                     struct platform_state *ctx)
{
  verb_debug ("[event:cros:%s]: fired", __func__);
  /* Coming back from resume, trigger a continuity and time
   * check just in case none of the other events happen.
   */
  action_kickoff_time_sync (-1, EV_TIMEOUT, ctx->state);
  return DBUS_HANDLER_RESULT_HANDLED;
}

static
DBusHandlerResult
handle_proxy_change (DBusConnection *connection,
                     DBusMessage *message,
                     struct platform_state *ctx)
{
  DBusMessageIter iter;
  DBusError error;
  const char *pname;
  const char *pval;
  char time_host[MAX_PROXY_URL];
  int url_len = 0;
  struct source *src = ctx->state->opts.sources;
  verb_debug ("[event:cros:%s]: fired", __func__);
  if (ctx->state->opts.cur_source && ctx->state->opts.cur_source->next)
    src = ctx->state->opts.cur_source->next;
  if (!ctx->state->resolving)
    {
      info ("[event:cros:%s] Unexpected ResolveNetworkProxy signal seen",
            __func__);
      return DBUS_HANDLER_RESULT_HANDLED;
    }
  dbus_error_init (&error);
  /* Shill emits string:ProxyConfig variant string:"..." */
  if (!dbus_message_iter_init (message, &iter))
    return DBUS_HANDLER_RESULT_HANDLED;
  if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
    return DBUS_HANDLER_RESULT_HANDLED;
  dbus_message_iter_get_basic (&iter, &pname);
  /* Make sure this was the resolution we asked for */
  url_len = snprintf (time_host, sizeof (time_host), "https://%s:%s",
                      src->host, src->port);
  if (url_len < 0 || ((size_t) url_len) >= sizeof (time_host))
    {
      error ("[event:cros:%s]: current source url is too long",
             __func__);
    }
  if (strcmp (pname, time_host))
    {
      error ("[event:cros:%s]: resolved host mismatch: %s v %s",
             __func__, pname, time_host);
      return DBUS_HANDLER_RESULT_HANDLED;
    }
  if (!dbus_message_iter_next (&iter))
    return DBUS_HANDLER_RESULT_HANDLED;
  if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
    return DBUS_HANDLER_RESULT_HANDLED;
  dbus_message_iter_get_basic (&iter, &pval);
  ctx->state->resolving = 0;
  canonicalize_pac (pval, ctx->state->dynamic_proxy, sizeof (ctx->state->dynamic_proxy));
  trigger_event (ctx->state, E_TLSDATE, 1);
  return DBUS_HANDLER_RESULT_HANDLED;
}

static
DBusHandlerResult
handle_dbus_change (DBusConnection *connection,
                    DBusMessage *message,
                    struct platform_state *ctx)
{
  DBusMessageIter iter;
  DBusError error;
  const char *pname;
  verb_debug ("[event:cros:%s]: fired", __func__);
  dbus_error_init (&error);
  if (!dbus_message_iter_init (message, &iter))
    return DBUS_HANDLER_RESULT_HANDLED;
  if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
    return DBUS_HANDLER_RESULT_HANDLED;
  dbus_message_iter_get_basic (&iter, &pname);
  /* Make sure we caught the right property. */
  if (strcmp (pname, kLibCrosDest))
    return DBUS_HANDLER_RESULT_HANDLED;
  action_kickoff_time_sync (-1, EV_TIMEOUT, ctx->state);
  return DBUS_HANDLER_RESULT_HANDLED;
}

static
void
action_resolve_proxy (evutil_socket_t fd, short what, void *arg)
{
  struct platform_state *ctx = arg;
  struct dbus_state *dbus_state = ctx->state->dbus;
  DBusConnection *conn = dbus_state->conn;
  struct source *src = ctx->state->opts.sources;
  verb_debug ("[event:%s] fired", __func__);
  /* Emulate tlsdate-monitor.c:build_argv and choose the next source */
  if (ctx->state->opts.cur_source && ctx->state->opts.cur_source->next)
    src = ctx->state->opts.cur_source->next;
  if (ctx->state->resolving || ctx->resolve_network_proxy_serial)
    {
      /* Note, this is not the same as the response signal. It just avoids
       * multiple requests in a single dispatch window.
       */
      info ("[event:%s] no resolve_proxy sent; pending method_reply",
            __func__);
      return;
    }
  ctx->state->dynamic_proxy[0] = '\0';
  if (ctx->resolve_msg[src->id] == NULL)
    {
      info ("[event:%s] no dynamic proxy for %s:%s", __func__,
            src->host, src->port);
      trigger_event (ctx->state, E_TLSDATE, 1);
      return;
    }
  info ("[event:%s] resolving proxy for %s:%s", __func__,
        src->host, src->port);
  ctx->state->resolving = 1;
  if (!dbus_connection_send (conn,
                             ctx->resolve_msg[src->id],
                             &ctx->resolve_network_proxy_serial))
    {
      error ("[event:%s] cannot send ResolveNetworkProxy query!", __func__);
      return;
    }
}

static
DBusHandlerResult
dbus_filter (DBusConnection *connection, DBusMessage *message, void *data)
{
  struct platform_state *state = data;
  /* Terminate gracefully if DBus goes away. */
  if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected"))
    {
      error ("[cros] DBus system bus has become inaccessible. Terminating.");
      /* Trigger a graceful teardown. */
      kill (getpid(), SIGINT);
      return DBUS_HANDLER_RESULT_HANDLED;
    }
  /* Hand it over to the service dispatcher. */
  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

  /* Handle explicitly defined signals only. */
  if (dbus_message_is_signal (message, kDBusInterface, kNameAcquired))
    {
      info ("[cros] DBus name acquired successfully");
      return DBUS_HANDLER_RESULT_HANDLED;
    }
  if (dbus_message_is_signal (message, kServiceInterface, kMember))
    return handle_service_change (connection, message, state);
  if (dbus_message_is_signal (message, kManagerInterface, kMember))
    return handle_manager_change (connection, message, state);
  if (dbus_message_is_signal (message, kResolveInterface, kResolveMember))
    return handle_proxy_change (connection, message, state);
  if (dbus_message_is_signal (message, kDBusInterface, kNameOwnerChanged))
    return handle_dbus_change (connection, message, state);
  if (dbus_message_is_signal (message, kPowerManagerInterface, kSuspendDone))
    return handle_suspend_done (connection, message, state);
  if (dbus_message_is_error (message, kErrorServiceUnknown))
    {
      info ("[cros] org.chromium.LibCrosService.ResolveNetworkProxy is missing");
      info ("[cros] skipping proxy resolution for now");
      /* Fire off tlsdate rather than letting it fail silently. */
      state->resolve_network_proxy_serial = 0;
      state->state->resolving = 0;
      trigger_event (state->state, E_TLSDATE, 1);
      return DBUS_HANDLER_RESULT_HANDLED;
    }
  /* Indicates a successful resolve request was issued. */
  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
    {
      uint32_t serial = dbus_message_get_reply_serial (message);
      if (serial == state->resolve_network_proxy_serial)
        {
          state->resolve_network_proxy_serial = 0;
          return DBUS_HANDLER_RESULT_HANDLED;
        }
      info ("[cros] unknown DBus METHOD_RETURN seen: %u", serial);
      return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    }
  verb_debug ("[cros] unknown message received: "
         "type=%s dest=%s interface=%s member=%s path=%s sig=%s error_name=%s",
         dbus_message_type_to_string (dbus_message_get_type (message)),
         dbus_message_get_destination (message),
         dbus_message_get_interface (message),
         dbus_message_get_member (message),
         dbus_message_get_path (message),
         dbus_message_get_signature (message),
         dbus_message_get_error_name (message));
  return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

int
add_match (DBusConnection *conn, const char *interface, const char *member,
           const char *arg0)
{
  char match[1024];
  DBusError error;
  int len;
  dbus_error_init (&error);
  if (arg0)
    {
      len = snprintf (match, sizeof (match), kMatchFormat,
                      interface, member, arg0);
    }
  else
    {
      len = snprintf (match, sizeof (match), kMatchNoArgFormat,
                      interface, member);
    }
  if (len < 0 || ((size_t) len) >= sizeof (match))
    {
      error ("[dbus] match truncated for '%s,%s'", interface, member);
      return 1;
    }
  dbus_bus_add_match (conn, match, &error);
  if (dbus_error_is_set (&error))
    {
      error ("[dbus] failed to add_match for '%s,%s'; error: %s, %s",
             interface, member, error.name, error.message);
      dbus_error_free (&error);
      return 1;
    }
  return 0;
}

DBusMessage *
new_resolver_message(const struct source *src)
{
  char time_host[MAX_PROXY_URL];
  void *time_host_ptr = &time_host;
  int url_len;
  DBusMessage *res;
  DBusMessageIter args;
  if (!src->proxy || strcmp (src->proxy, "dynamic"))
    {
      return NULL;
    }
  res = dbus_message_new_method_call (kLibCrosDest, kLibCrosPath,
                                      kLibCrosInterface, kResolveNetworkProxy);
  if (!res)
    {
      error ("[cros] could not setup dynamic proxy for source %d", src->id);
      return NULL;
    }
  /* Build the time_host */
  url_len = snprintf (time_host, sizeof (time_host), "https://%s:%s",
                      src->host, src->port);
  if (url_len < 0 || ((size_t) url_len) >= sizeof (time_host))
    {
      fatal ("[cros] source %d url is too long! (%d)", src->id, url_len);
    }
  /* Finish the message */
  dbus_message_iter_init_append (res, &args);
  if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &time_host_ptr) ||
      !dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &kResolveInterface) ||
      !dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &kResolveMember))
    {
      fatal ("[cros could not append arguments for resolver message");
    }
  return res;
}

int
platform_init_cros (struct state *state)
{
  /* Watch for per-service ProxyConfig property changes */
  struct event_base *base = state->base;
  struct dbus_state *dbus_state = state->dbus;
  if (!dbus_state)
    {
      info ("[cros] DBus not connected, skipping platform initialization.");
      return 0;
    }
  struct source *src = NULL;
  int sources = 0;
  DBusConnection *conn = dbus_state->conn;
  DBusError error;
  struct platform_state *platform_state =
      calloc (1, sizeof (struct platform_state));
  if (!platform_state)
    {
      error ("[cros] could not allocate platform_state");
      return -1;
    }
  /* TODO(wad) Follow up with dbus_error_free() where needed. */
  dbus_error_init (&error);
  /* Add watches for: proxy changes, default service changes, proxy resolution,
   * LibCrosService ownership, and power state changes.
   */
  if (add_match (conn, kServiceInterface, kMember, kProxyConfig) ||
      add_match (conn, kManagerInterface, kMember, kDefaultService) ||
      add_match (conn, kResolveInterface, kResolveMember, NULL) ||
      add_match (conn, kDBusInterface, kNameOwnerChanged, kLibCrosDest) ||
      add_match (conn, kPowerManagerInterface, kSuspendDone, NULL))
    return 1;

  /* Allocate one per source */
  for (src = state->opts.sources; src; src = src->next, ++sources);
  platform_state->resolve_msg_count = sources;
  platform_state->resolve_msg = calloc (sources, sizeof (DBusMessage *));
  if (!platform_state->resolve_msg)
    {
      error ("[cros] cannot allocate resolver messages");
      free (platform_state);
      return -1;
    }
  for (src = state->opts.sources; src; src = src->next)
    {
      if (src->id >= sources)
        fatal ("Source ID is greater than available sources!");
      platform_state->resolve_msg[src->id] = new_resolver_message (src);
      if (platform_state->resolve_msg[src->id])
        src->proxy = state->dynamic_proxy;
    }
  state->dynamic_proxy[0] = '\0';
  if (state->opts.proxy && !strcmp (state->opts.proxy, "dynamic"))
    {
      info ("[cros] default dynamic proxy support");
      state->opts.proxy = state->dynamic_proxy;
    }
  platform_state->base = base;
  platform_state->state = state;
  /* Add the dynamic resolver if tlsdate doesn't already have one. */
  if (!state->events[E_RESOLVER])
    {
      state->events[E_RESOLVER] = event_new (base, -1, EV_TIMEOUT,
                                             action_resolve_proxy,
                                             platform_state);
      if (!state->events[E_RESOLVER])
        /* Let's not clean up DBus. */
        fatal ("Could not allocated resolver event");
      /* Wake up as a NET event since it'll self-block until DBus has a chance
       * to send it.
       */
      event_priority_set (state->events[E_RESOLVER], PRI_NET);
    }
  /* Each platform can attach their own filter, but the filter func needs to be
   * willing to DBUS_HANDLER_RESULT_NOT_YET_HANDLED on unexpected events.
   */
  /* TODO(wad) add the clean up function as the callback. */
  if (!dbus_connection_add_filter (conn,
                                   dbus_filter, platform_state, NULL))
    {
      error ("Failed to register signal handler callback");
      return 1;
    }
  return 0;
}
