/* GDBus - GLib D-Bus Library
 *
 * Copyright (C) 2008-2010 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.
 *
 * Author: David Zeuthen <davidz@redhat.com>
 */

#include "config.h"

#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef _WIN32
#include <io.h>
#endif

#include <glib/gstdio.h>

#include "gdbusauthmechanismsha1.h"
#include "gcredentials.h"
#include "gdbuserror.h"
#include "gioenumtypes.h"
#include "gioerror.h"
#include "gdbusprivate.h"

#include "glibintl.h"

struct _GDBusAuthMechanismSha1Private
{
  gboolean is_client;
  gboolean is_server;
  GDBusAuthMechanismState state;

  /* used on the client side */
  gchar *to_send;

  /* used on the server side */
  gchar *cookie;
  gchar *server_challenge;
};

static gint                     mechanism_get_priority              (void);
static const gchar             *mechanism_get_name                  (void);

static gboolean                 mechanism_is_supported              (GDBusAuthMechanism   *mechanism);
static gchar                   *mechanism_encode_data               (GDBusAuthMechanism   *mechanism,
                                                                     const gchar          *data,
                                                                     gsize                 data_len,
                                                                     gsize                *out_data_len);
static gchar                   *mechanism_decode_data               (GDBusAuthMechanism   *mechanism,
                                                                     const gchar          *data,
                                                                     gsize                 data_len,
                                                                     gsize                *out_data_len);
static GDBusAuthMechanismState  mechanism_server_get_state          (GDBusAuthMechanism   *mechanism);
static void                     mechanism_server_initiate           (GDBusAuthMechanism   *mechanism,
                                                                     const gchar          *initial_response,
                                                                     gsize                 initial_response_len);
static void                     mechanism_server_data_receive       (GDBusAuthMechanism   *mechanism,
                                                                     const gchar          *data,
                                                                     gsize                 data_len);
static gchar                   *mechanism_server_data_send          (GDBusAuthMechanism   *mechanism,
                                                                     gsize                *out_data_len);
static gchar                   *mechanism_server_get_reject_reason  (GDBusAuthMechanism   *mechanism);
static void                     mechanism_server_shutdown           (GDBusAuthMechanism   *mechanism);
static GDBusAuthMechanismState  mechanism_client_get_state          (GDBusAuthMechanism   *mechanism);
static gchar                   *mechanism_client_initiate           (GDBusAuthMechanism   *mechanism,
                                                                     gsize                *out_initial_response_len);
static void                     mechanism_client_data_receive       (GDBusAuthMechanism   *mechanism,
                                                                     const gchar          *data,
                                                                     gsize                 data_len);
static gchar                   *mechanism_client_data_send          (GDBusAuthMechanism   *mechanism,
                                                                     gsize                *out_data_len);
static void                     mechanism_client_shutdown           (GDBusAuthMechanism   *mechanism);

/* ---------------------------------------------------------------------------------------------------- */

G_DEFINE_TYPE (GDBusAuthMechanismSha1, _g_dbus_auth_mechanism_sha1, G_TYPE_DBUS_AUTH_MECHANISM);

/* ---------------------------------------------------------------------------------------------------- */

static void
_g_dbus_auth_mechanism_sha1_finalize (GObject *object)
{
  GDBusAuthMechanismSha1 *mechanism = G_DBUS_AUTH_MECHANISM_SHA1 (object);

  g_free (mechanism->priv->to_send);

  g_free (mechanism->priv->cookie);
  g_free (mechanism->priv->server_challenge);

  if (G_OBJECT_CLASS (_g_dbus_auth_mechanism_sha1_parent_class)->finalize != NULL)
    G_OBJECT_CLASS (_g_dbus_auth_mechanism_sha1_parent_class)->finalize (object);
}

static void
_g_dbus_auth_mechanism_sha1_class_init (GDBusAuthMechanismSha1Class *klass)
{
  GObjectClass *gobject_class;
  GDBusAuthMechanismClass *mechanism_class;

  g_type_class_add_private (klass, sizeof (GDBusAuthMechanismSha1Private));

  gobject_class = G_OBJECT_CLASS (klass);
  gobject_class->finalize = _g_dbus_auth_mechanism_sha1_finalize;

  mechanism_class = G_DBUS_AUTH_MECHANISM_CLASS (klass);
  mechanism_class->get_priority              = mechanism_get_priority;
  mechanism_class->get_name                  = mechanism_get_name;
  mechanism_class->is_supported              = mechanism_is_supported;
  mechanism_class->encode_data               = mechanism_encode_data;
  mechanism_class->decode_data               = mechanism_decode_data;
  mechanism_class->server_get_state          = mechanism_server_get_state;
  mechanism_class->server_initiate           = mechanism_server_initiate;
  mechanism_class->server_data_receive       = mechanism_server_data_receive;
  mechanism_class->server_data_send          = mechanism_server_data_send;
  mechanism_class->server_get_reject_reason  = mechanism_server_get_reject_reason;
  mechanism_class->server_shutdown           = mechanism_server_shutdown;
  mechanism_class->client_get_state          = mechanism_client_get_state;
  mechanism_class->client_initiate           = mechanism_client_initiate;
  mechanism_class->client_data_receive       = mechanism_client_data_receive;
  mechanism_class->client_data_send          = mechanism_client_data_send;
  mechanism_class->client_shutdown           = mechanism_client_shutdown;
}

static void
_g_dbus_auth_mechanism_sha1_init (GDBusAuthMechanismSha1 *mechanism)
{
  mechanism->priv = G_TYPE_INSTANCE_GET_PRIVATE (mechanism,
                                                 G_TYPE_DBUS_AUTH_MECHANISM_SHA1,
                                                 GDBusAuthMechanismSha1Private);
}

/* ---------------------------------------------------------------------------------------------------- */

static gint
mechanism_get_priority (void)
{
  return 0;
}

static const gchar *
mechanism_get_name (void)
{
  return "DBUS_COOKIE_SHA1";
}

static gboolean
mechanism_is_supported (GDBusAuthMechanism *mechanism)
{
  g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_SHA1 (mechanism), FALSE);
  return TRUE;
}

static gchar *
mechanism_encode_data (GDBusAuthMechanism   *mechanism,
                       const gchar          *data,
                       gsize                 data_len,
                       gsize                *out_data_len)
{
  return NULL;
}


static gchar *
mechanism_decode_data (GDBusAuthMechanism   *mechanism,
                       const gchar          *data,
                       gsize                 data_len,
                       gsize                *out_data_len)
{
  return NULL;
}

/* ---------------------------------------------------------------------------------------------------- */

static gint
random_ascii (void)
{
  gint ret;
  ret = g_random_int_range (0, 60);
  if (ret < 25)
    ret += 'A';
  else if (ret < 50)
    ret += 'a' - 25;
  else
    ret += '0' - 50;
  return ret;
}

static gchar *
random_ascii_string (guint len)
{
  GString *challenge;
  guint n;

  challenge = g_string_new (NULL);
  for (n = 0; n < len; n++)
    g_string_append_c (challenge, random_ascii ());
  return g_string_free (challenge, FALSE);
}

static gchar *
random_blob (guint len)
{
  GString *challenge;
  guint n;

  challenge = g_string_new (NULL);
  for (n = 0; n < len; n++)
    g_string_append_c (challenge, g_random_int_range (0, 256));
  return g_string_free (challenge, FALSE);
}

/* ---------------------------------------------------------------------------------------------------- */

/* ensure keyring dir exists and permissions are correct */
static gchar *
ensure_keyring_directory (GError **error)
{
  gchar *path;
  const gchar *e;

  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  e = g_getenv ("G_DBUS_COOKIE_SHA1_KEYRING_DIR");
  if (e != NULL)
    {
      path = g_strdup (e);
    }
  else
    {
      path = g_build_filename (g_get_home_dir (),
                               ".dbus-keyrings",
                               NULL);
    }

  if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
    {
      if (g_getenv ("G_DBUS_COOKIE_SHA1_KEYRING_DIR_IGNORE_PERMISSION") == NULL)
        {
#ifdef G_OS_UNIX
          struct stat statbuf;
          if (stat (path, &statbuf) != 0)
            {
              g_set_error (error,
                           G_IO_ERROR,
                           g_io_error_from_errno (errno),
                           _("Error when getting information for directory `%s': %s"),
                           path,
                           strerror (errno));
              g_free (path);
              path = NULL;
              goto out;
            }
          if ((statbuf.st_mode  & 0777) != 0700)
            {
              g_set_error (error,
                           G_IO_ERROR,
                           G_IO_ERROR_FAILED,
                           _("Permissions on directory `%s' are malformed. Expected mode 0700, got 0%o"),
                           path,
                           statbuf.st_mode & 0777);
              g_free (path);
              path = NULL;
              goto out;
            }
#else
#ifdef __GNUC__
#warning Please implement permission checking on this non-UNIX platform
#endif
#endif
        }
        goto out;
    }

  if (g_mkdir (path, 0700) != 0)
    {
      g_set_error (error,
                   G_IO_ERROR,
                   g_io_error_from_errno (errno),
                   _("Error creating directory `%s': %s"),
                   path,
                   strerror (errno));
      g_free (path);
      path = NULL;
      goto out;
    }

out:
  return path;
}

/* ---------------------------------------------------------------------------------------------------- */

static void
append_nibble (GString *s, gint val)
{
  g_string_append_c (s, val >= 10 ? ('a' + val - 10) : ('0' + val));
}

static gchar *
hexencode (const gchar *str,
           gssize       len)
{
  guint n;
  GString *s;

  if (len == -1)
    len = strlen (str);

  s = g_string_new (NULL);
  for (n = 0; n < len; n++)
    {
      gint val;
      gint upper_nibble;
      gint lower_nibble;

      val = ((const guchar *) str)[n];
      upper_nibble = val >> 4;
      lower_nibble = val & 0x0f;

      append_nibble (s, upper_nibble);
      append_nibble (s, lower_nibble);
    }

  return g_string_free (s, FALSE);
}

/* ---------------------------------------------------------------------------------------------------- */

/* looks up an entry in the keyring */
static gchar *
keyring_lookup_entry (const gchar  *cookie_context,
                      gint          cookie_id,
                      GError      **error)
{
  gchar *ret;
  gchar *keyring_dir;
  gchar *contents;
  gchar *path;
  guint n;
  gchar **lines;

  g_return_val_if_fail (cookie_context != NULL, NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  ret = NULL;
  path = NULL;
  contents = NULL;
  lines = NULL;

  keyring_dir = ensure_keyring_directory (error);
  if (keyring_dir == NULL)
    goto out;

  path = g_build_filename (keyring_dir, cookie_context, NULL);

  if (!g_file_get_contents (path,
                            &contents,
                            NULL,
                            error))
    {
      g_prefix_error (error,
                      _("Error opening keyring `%s' for reading: "),
                      path);
      goto out;
    }
  g_assert (contents != NULL);

  lines = g_strsplit (contents, "\n", 0);
  for (n = 0; lines[n] != NULL; n++)
    {
      const gchar *line = lines[n];
      gchar **tokens;
      gchar *endp;
      gint line_id;
      guint64 line_when;

      if (line[0] == '\0')
        continue;

      tokens = g_strsplit (line, " ", 0);
      if (g_strv_length (tokens) != 3)
        {
          g_set_error (error,
                       G_IO_ERROR,
                       G_IO_ERROR_FAILED,
                       _("Line %d of the keyring at `%s' with content `%s' is malformed"),
                       n + 1,
                       path,
                       line);
          g_strfreev (tokens);
          goto out;
        }

      line_id = g_ascii_strtoll (tokens[0], &endp, 10);
      if (*endp != '\0')
        {
          g_set_error (error,
                       G_IO_ERROR,
                       G_IO_ERROR_FAILED,
                       _("First token of line %d of the keyring at `%s' with content `%s' is malformed"),
                       n + 1,
                       path,
                       line);
          g_strfreev (tokens);
          goto out;
        }

      line_when = g_ascii_strtoll (tokens[1], &endp, 10);
      line_when = line_when; /* To avoid -Wunused-but-set-variable */
      if (*endp != '\0')
        {
          g_set_error (error,
                       G_IO_ERROR,
                       G_IO_ERROR_FAILED,
                       _("Second token of line %d of the keyring at `%s' with content `%s' is malformed"),
                       n + 1,
                       path,
                       line);
          g_strfreev (tokens);
          goto out;
        }

      if (line_id == cookie_id)
        {
          /* YAY, success */
          ret = tokens[2]; /* steal pointer */
          tokens[2] = NULL;
          g_strfreev (tokens);
          goto out;
        }

      g_strfreev (tokens);
    }

  /* BOOH, didn't find the cookie */
  g_set_error (error,
               G_IO_ERROR,
               G_IO_ERROR_FAILED,
               _("Didn't find cookie with id %d in the keyring at `%s'"),
               cookie_id,
               path);

 out:
  g_free (keyring_dir);
  g_free (path);
  g_free (contents);
  g_strfreev (lines);
  return ret;
}

/* function for logging important events that the system administrator should take notice of */
static void
_log (const gchar *message,
      ...)
{
  gchar *s;
  va_list var_args;

  va_start (var_args, message);
  s = g_strdup_vprintf (message, var_args);
  va_end (var_args);

  /* TODO: might want to send this to syslog instead */
  g_printerr ("GDBus-DBUS_COOKIE_SHA1: %s\n", s);
  g_free (s);
}

static gint
keyring_acquire_lock (const gchar  *path,
                      GError      **error)
{
  gchar *lock;
  gint ret;
  guint num_tries;
  guint num_create_tries;

  g_return_val_if_fail (path != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  ret = -1;
  lock = g_strdup_printf ("%s.lock", path);

  /* This is what the D-Bus spec says
   *
   *  Create a lockfile name by appending ".lock" to the name of the
   *  cookie file. The server should attempt to create this file using
   *  O_CREAT | O_EXCL. If file creation fails, the lock
   *  fails. Servers should retry for a reasonable period of time,
   *  then they may choose to delete an existing lock to keep users
   *  from having to manually delete a stale lock. [1]
   *
   *  [1] : Lockfiles are used instead of real file locking fcntl() because
   *         real locking implementations are still flaky on network filesystems
   */

  num_create_tries = 0;
#ifdef EEXISTS
 again:
#endif
  num_tries = 0;
  while (g_file_test (lock, G_FILE_TEST_EXISTS))
    {
      /* sleep 10ms, then try again */
      g_usleep (1000*10);
      num_tries++;
      if (num_tries == 50)
        {
          /* ok, we slept 50*10ms = 0.5 seconds. Conclude that the lock file must be
           * stale (nuke the it from orbit)
           */
          if (g_unlink (lock) != 0)
            {
              g_set_error (error,
                           G_IO_ERROR,
                           g_io_error_from_errno (errno),
                           _("Error deleting stale lock file `%s': %s"),
                           lock,
                           strerror (errno));
              goto out;
            }
          _log ("Deleted stale lock file `%s'", lock);
          break;
        }
    }

  ret = g_open (lock, O_CREAT |
#ifdef O_EXCL
                O_EXCL,
#else
                0,
#endif
                0700);
  if (ret == -1)
    {
#ifdef EEXISTS
      /* EEXIST: pathname already exists and O_CREAT and O_EXCL were used. */
      if (errno == EEXISTS)
        {
          num_create_tries++;
          if (num_create_tries < 5)
            goto again;
        }
#endif
      num_create_tries = num_create_tries; /* To avoid -Wunused-but-set-variable */
      g_set_error (error,
                   G_IO_ERROR,
                   g_io_error_from_errno (errno),
                   _("Error creating lock file `%s': %s"),
                   lock,
                   strerror (errno));
      goto out;
    }

 out:
  g_free (lock);
  return ret;
}

static gboolean
keyring_release_lock (const gchar  *path,
                      gint          lock_fd,
                      GError      **error)
{
  gchar *lock;
  gboolean ret;

  g_return_val_if_fail (path != NULL, FALSE);
  g_return_val_if_fail (lock_fd != -1, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  ret = FALSE;
  lock = g_strdup_printf ("%s.lock", path);
  if (close (lock_fd) != 0)
    {
      g_set_error (error,
                   G_IO_ERROR,
                   g_io_error_from_errno (errno),
                   _("Error closing (unlinked) lock file `%s': %s"),
                   lock,
                   strerror (errno));
      goto out;
    }
  if (g_unlink (lock) != 0)
    {
      g_set_error (error,
                   G_IO_ERROR,
                   g_io_error_from_errno (errno),
                   _("Error unlinking lock file `%s': %s"),
                   lock,
                   strerror (errno));
      goto out;
    }

  ret = TRUE;

 out:
  g_free (lock);
  return ret;
}


/* adds an entry to the keyring, taking care of locking and deleting stale/future entries */
static gboolean
keyring_generate_entry (const gchar  *cookie_context,
                        gint         *out_id,
                        gchar       **out_cookie,
                        GError      **error)
{
  gboolean ret;
  gchar *keyring_dir;
  gchar *path;
  gchar *contents;
  GError *local_error;
  gchar **lines;
  gint max_line_id;
  GString *new_contents;
  guint64 now;
  gboolean have_id;
  gint use_id;
  gchar *use_cookie;
  gboolean changed_file;
  gint lock_fd;

  g_return_val_if_fail (cookie_context != NULL, FALSE);
  g_return_val_if_fail (out_id != NULL, FALSE);
  g_return_val_if_fail (out_cookie != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  ret = FALSE;
  path = NULL;
  contents = NULL;
  lines = NULL;
  new_contents = NULL;
  have_id = FALSE;
  use_id = 0;
  use_cookie = NULL;
  lock_fd = -1;

  keyring_dir = ensure_keyring_directory (error);
  if (keyring_dir == NULL)
    goto out;

  path = g_build_filename (keyring_dir, cookie_context, NULL);

  lock_fd = keyring_acquire_lock (path, error);
  if (lock_fd == -1)
    goto out;

  local_error = NULL;
  contents = NULL;
  if (!g_file_get_contents (path,
                            &contents,
                            NULL,
                            &local_error))
    {
      if (local_error->domain == G_FILE_ERROR && local_error->code == G_FILE_ERROR_NOENT)
        {
          /* file doesn't have to exist */
          g_error_free (local_error);
        }
      else
        {
          g_propagate_prefixed_error (error,
                                      local_error,
                                      _("Error opening keyring `%s' for writing: "),
                                      path);
          goto out;
        }
    }

  new_contents = g_string_new (NULL);
  now = time (NULL);
  changed_file = FALSE;

  max_line_id = 0;
  if (contents != NULL)
    {
      guint n;
      lines = g_strsplit (contents, "\n", 0);
      for (n = 0; lines[n] != NULL; n++)
        {
          const gchar *line = lines[n];
          gchar **tokens;
          gchar *endp;
          gint line_id;
          guint64 line_when;
          gboolean keep_entry;

          if (line[0] == '\0')
            continue;

          tokens = g_strsplit (line, " ", 0);
          if (g_strv_length (tokens) != 3)
            {
              g_set_error (error,
                           G_IO_ERROR,
                           G_IO_ERROR_FAILED,
                           _("Line %d of the keyring at `%s' with content `%s' is malformed"),
                           n + 1,
                           path,
                           line);
              g_strfreev (tokens);
              goto out;
            }

          line_id = g_ascii_strtoll (tokens[0], &endp, 10);
          if (*endp != '\0')
            {
              g_set_error (error,
                           G_IO_ERROR,
                           G_IO_ERROR_FAILED,
                           _("First token of line %d of the keyring at `%s' with content `%s' is malformed"),
                           n + 1,
                           path,
                           line);
              g_strfreev (tokens);
              goto out;
            }

          line_when = g_ascii_strtoll (tokens[1], &endp, 10);
          if (*endp != '\0')
            {
              g_set_error (error,
                           G_IO_ERROR,
                           G_IO_ERROR_FAILED,
                           _("Second token of line %d of the keyring at `%s' with content `%s' is malformed"),
                           n + 1,
                           path,
                           line);
              g_strfreev (tokens);
              goto out;
            }
          line_when = line_when; /* To avoid -Wunused-but-set-variable */


          /* D-Bus spec says:
           *
           *  Once the lockfile has been created, the server loads the
           *  cookie file. It should then delete any cookies that are
           *  old (the timeout can be fairly short), or more than a
           *  reasonable time in the future (so that cookies never
           *  accidentally become permanent, if the clock was set far
           *  into the future at some point). If no recent keys remain,
           *  the server may generate a new key.
           *
           */
          keep_entry = TRUE;
          if (line_when > now)
            {
              /* Oddball case: entry is more recent than our current wall-clock time..
               * This is OK, it means that another server on another machine but with
               * same $HOME wrote the entry.
               *
               * So discard the entry if it's more than 1 day in the future ("reasonable
               * time in the future").
               */
              if (line_when - now > 24*60*60)
                {
                  keep_entry = FALSE;
                  _log ("Deleted SHA1 cookie from %" G_GUINT64_FORMAT " seconds in the future", line_when - now);
                }
            }
          else
            {
              /* Discard entry if it's older than 15 minutes ("can be fairly short") */
              if (now - line_when > 15*60)
                {
                  keep_entry = FALSE;
                }
            }

          if (!keep_entry)
            {
              changed_file = FALSE;
            }
          else
            {
              g_string_append_printf (new_contents,
                                      "%d %" G_GUINT64_FORMAT " %s\n",
                                      line_id,
                                      line_when,
                                      tokens[2]);
              max_line_id = MAX (line_id, max_line_id);
              /* Only reuse entry if not older than 10 minutes.
               *
               * (We need a bit of grace time compared to 15 minutes above.. otherwise
               * there's a race where we reuse the 14min59.9 secs old entry and a
               * split-second later another server purges the now 15 minute old entry.)
               */
              if (now - line_when < 10 * 60)
                {
                  if (!have_id)
                    {
                      use_id = line_id;
                      use_cookie = tokens[2]; /* steal memory */
                      tokens[2] = NULL;
                      have_id = TRUE;
                    }
                }
            }
          g_strfreev (tokens);
        }
    } /* for each line */

  ret = TRUE;

  if (have_id)
    {
      *out_id = use_id;
      *out_cookie = use_cookie;
      use_cookie = NULL;
    }
  else
    {
      gchar *raw_cookie;
      *out_id = max_line_id + 1;
      raw_cookie = random_blob (32);
      *out_cookie = hexencode (raw_cookie, 32);
      g_free (raw_cookie);

      g_string_append_printf (new_contents,
                              "%d %" G_GUINT64_FORMAT " %s\n",
                              *out_id,
                              (guint64) time (NULL),
                              *out_cookie);
      changed_file = TRUE;
    }

  /* and now actually write the cookie file if there are changes (this is atomic) */
  if (changed_file)
    {
      if (!g_file_set_contents (path,
                                new_contents->str,
                                -1,
                                error))
        {
          *out_id = 0;
          *out_cookie = 0;
          g_free (*out_cookie);
          ret = FALSE;
          goto out;
        }
    }

 out:

  if (lock_fd != -1)
    {
      GError *local_error;
      local_error = NULL;
      if (!keyring_release_lock (path, lock_fd, &local_error))
        {
          if (error != NULL)
            {
              if (*error == NULL)
                {
                  *error = local_error;
                }
              else
                {
                  g_prefix_error (error,
                                  _("(Additionally, releasing the lock for `%s' also failed: %s) "),
                                  path,
                                  local_error->message);
                }
            }
          else
            {
              g_error_free (local_error);
            }
        }
    }

  g_free (keyring_dir);
  g_free (path);
  g_strfreev (lines);
  g_free (contents);
  if (new_contents != NULL)
    g_string_free (new_contents, TRUE);
  g_free (use_cookie);
  return ret;
}

/* ---------------------------------------------------------------------------------------------------- */

static gchar *
generate_sha1 (const gchar *server_challenge,
               const gchar *client_challenge,
               const gchar *cookie)
{
  GString *str;
  gchar *sha1;

  str = g_string_new (server_challenge);
  g_string_append_c (str, ':');
  g_string_append (str, client_challenge);
  g_string_append_c (str, ':');
  g_string_append (str, cookie);
  sha1 = g_compute_checksum_for_string (G_CHECKSUM_SHA1, str->str, -1);
  g_string_free (str, TRUE);

  return sha1;
}

/* ---------------------------------------------------------------------------------------------------- */

static GDBusAuthMechanismState
mechanism_server_get_state (GDBusAuthMechanism   *mechanism)
{
  GDBusAuthMechanismSha1 *m = G_DBUS_AUTH_MECHANISM_SHA1 (mechanism);

  g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_SHA1 (mechanism), G_DBUS_AUTH_MECHANISM_STATE_INVALID);
  g_return_val_if_fail (m->priv->is_server && !m->priv->is_client, G_DBUS_AUTH_MECHANISM_STATE_INVALID);

  return m->priv->state;
}

static void
mechanism_server_initiate (GDBusAuthMechanism   *mechanism,
                           const gchar          *initial_response,
                           gsize                 initial_response_len)
{
  GDBusAuthMechanismSha1 *m = G_DBUS_AUTH_MECHANISM_SHA1 (mechanism);

  g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_SHA1 (mechanism));
  g_return_if_fail (!m->priv->is_server && !m->priv->is_client);

  m->priv->is_server = TRUE;
  m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED;

  if (initial_response != NULL && strlen (initial_response) > 0)
    {
#ifdef G_OS_UNIX
      gint64 uid;
      gchar *endp;

      uid = g_ascii_strtoll (initial_response, &endp, 10);
      if (*endp == '\0')
        {
          if (uid == getuid ())
            {
              m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND;
            }
        }
#elif defined(G_OS_WIN32)
      gchar *sid;
      sid = _g_dbus_win32_get_user_sid ();
      if (g_strcmp0 (initial_response, sid) == 0)
        m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND;
      g_free (sid);
#else
#error Please implement for your OS
#endif
    }
}

static void
mechanism_server_data_receive (GDBusAuthMechanism   *mechanism,
                               const gchar          *data,
                               gsize                 data_len)
{
  GDBusAuthMechanismSha1 *m = G_DBUS_AUTH_MECHANISM_SHA1 (mechanism);
  gchar **tokens;
  const gchar *client_challenge;
  const gchar *alleged_sha1;
  gchar *sha1;

  g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_SHA1 (mechanism));
  g_return_if_fail (m->priv->is_server && !m->priv->is_client);
  g_return_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA);

  tokens = NULL;
  sha1 = NULL;

  tokens = g_strsplit (data, " ", 0);
  if (g_strv_length (tokens) != 2)
    {
      g_warning ("Malformed data `%s'", data);
      m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED;
      goto out;
    }

  client_challenge = tokens[0];
  alleged_sha1 = tokens[1];

  sha1 = generate_sha1 (m->priv->server_challenge, client_challenge, m->priv->cookie);

  if (g_strcmp0 (sha1, alleged_sha1) == 0)
    {
      m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED;
    }
  else
    {
      m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED;
    }

 out:
  g_strfreev (tokens);
  g_free (sha1);
}

static gchar *
mechanism_server_data_send (GDBusAuthMechanism   *mechanism,
                            gsize                *out_data_len)
{
  GDBusAuthMechanismSha1 *m = G_DBUS_AUTH_MECHANISM_SHA1 (mechanism);
  gchar *s;
  gint cookie_id;
  const gchar *cookie_context;
  GError *error;

  g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_SHA1 (mechanism), NULL);
  g_return_val_if_fail (m->priv->is_server && !m->priv->is_client, NULL);
  g_return_val_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND, NULL);

  s = NULL;

  /* TODO: use GDBusAuthObserver here to get the cookie context to use? */
  cookie_context = "org_gtk_gdbus_general";

  cookie_id = -1;
  error = NULL;
  if (!keyring_generate_entry (cookie_context,
                               &cookie_id,
                               &m->priv->cookie,
                               &error))
    {
      g_warning ("Error adding entry to keyring: %s", error->message);
      g_error_free (error);
      m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED;
      goto out;
    }

  m->priv->server_challenge = random_ascii_string (16);
  s = g_strdup_printf ("%s %d %s",
                       cookie_context,
                       cookie_id,
                       m->priv->server_challenge);

  m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA;

 out:
  return s;
}

static gchar *
mechanism_server_get_reject_reason (GDBusAuthMechanism   *mechanism)
{
  GDBusAuthMechanismSha1 *m = G_DBUS_AUTH_MECHANISM_SHA1 (mechanism);

  g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_SHA1 (mechanism), NULL);
  g_return_val_if_fail (m->priv->is_server && !m->priv->is_client, NULL);
  g_return_val_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_REJECTED, NULL);

  /* can never end up here because we are never in the REJECTED state */
  g_assert_not_reached ();

  return NULL;
}

static void
mechanism_server_shutdown (GDBusAuthMechanism   *mechanism)
{
  GDBusAuthMechanismSha1 *m = G_DBUS_AUTH_MECHANISM_SHA1 (mechanism);

  g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_SHA1 (mechanism));
  g_return_if_fail (m->priv->is_server && !m->priv->is_client);

  m->priv->is_server = FALSE;
}

/* ---------------------------------------------------------------------------------------------------- */

static GDBusAuthMechanismState
mechanism_client_get_state (GDBusAuthMechanism   *mechanism)
{
  GDBusAuthMechanismSha1 *m = G_DBUS_AUTH_MECHANISM_SHA1 (mechanism);

  g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_SHA1 (mechanism), G_DBUS_AUTH_MECHANISM_STATE_INVALID);
  g_return_val_if_fail (m->priv->is_client && !m->priv->is_server, G_DBUS_AUTH_MECHANISM_STATE_INVALID);

  return m->priv->state;
}

static gchar *
mechanism_client_initiate (GDBusAuthMechanism   *mechanism,
                           gsize                *out_initial_response_len)
{
  GDBusAuthMechanismSha1 *m = G_DBUS_AUTH_MECHANISM_SHA1 (mechanism);
  gchar *initial_response;

  g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_SHA1 (mechanism), NULL);
  g_return_val_if_fail (!m->priv->is_server && !m->priv->is_client, NULL);

  m->priv->is_client = TRUE;
  m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA;

  *out_initial_response_len = -1;

#ifdef G_OS_UNIX
  initial_response = g_strdup_printf ("%" G_GINT64_FORMAT, (gint64) getuid ());
#elif defined (G_OS_WIN32)
initial_response = _g_dbus_win32_get_user_sid ();
#else
#error Please implement for your OS
#endif
  g_assert (initial_response != NULL);

  return initial_response;
}

static void
mechanism_client_data_receive (GDBusAuthMechanism   *mechanism,
                               const gchar          *data,
                               gsize                 data_len)
{
  GDBusAuthMechanismSha1 *m = G_DBUS_AUTH_MECHANISM_SHA1 (mechanism);
  gchar **tokens;
  const gchar *cookie_context;
  guint cookie_id;
  const gchar *server_challenge;
  gchar *client_challenge;
  gchar *endp;
  gchar *cookie;
  GError *error;
  gchar *sha1;

  g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_SHA1 (mechanism));
  g_return_if_fail (m->priv->is_client && !m->priv->is_server);
  g_return_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA);

  tokens = NULL;
  cookie = NULL;
  client_challenge = NULL;

  tokens = g_strsplit (data, " ", 0);
  if (g_strv_length (tokens) != 3)
    {
      g_warning ("Malformed data `%s'", data);
      m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED;
      goto out;
    }

  cookie_context = tokens[0];
  cookie_id = g_ascii_strtoll (tokens[1], &endp, 10);
  if (*endp != '\0')
    {
      g_warning ("Malformed cookie_id `%s'", tokens[1]);
      m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED;
      goto out;
    }
  server_challenge = tokens[2];

  error = NULL;
  cookie = keyring_lookup_entry (cookie_context, cookie_id, &error);
  if (cookie == NULL)
    {
      g_warning ("Problems looking up entry in keyring: %s", error->message);
      g_error_free (error);
      m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED;
      goto out;
    }

  client_challenge = random_ascii_string (16);
  sha1 = generate_sha1 (server_challenge, client_challenge, cookie);
  m->priv->to_send = g_strdup_printf ("%s %s", client_challenge, sha1);
  g_free (sha1);
  m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND;

 out:
  g_strfreev (tokens);
  g_free (cookie);
  g_free (client_challenge);
}

static gchar *
mechanism_client_data_send (GDBusAuthMechanism   *mechanism,
                            gsize                *out_data_len)
{
  GDBusAuthMechanismSha1 *m = G_DBUS_AUTH_MECHANISM_SHA1 (mechanism);

  g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_SHA1 (mechanism), NULL);
  g_return_val_if_fail (m->priv->is_client && !m->priv->is_server, NULL);
  g_return_val_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND, NULL);

  g_assert (m->priv->to_send != NULL);

  m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED;

  return g_strdup (m->priv->to_send);
}

static void
mechanism_client_shutdown (GDBusAuthMechanism   *mechanism)
{
  GDBusAuthMechanismSha1 *m = G_DBUS_AUTH_MECHANISM_SHA1 (mechanism);

  g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_SHA1 (mechanism));
  g_return_if_fail (m->priv->is_client && !m->priv->is_server);

  m->priv->is_client = FALSE;
}

/* ---------------------------------------------------------------------------------------------------- */
