/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* dbus-keyring.c Store secret cookies in your homedir
 *
 * Copyright (C) 2003, 2004  Red Hat Inc.
 *
 * Licensed under the Academic Free License version 2.1
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include <config.h>
#include "dbus-keyring.h"
#include "dbus-protocol.h"
#include <dbus/dbus-string.h>
#include <dbus/dbus-list.h>
#include <dbus/dbus-sysdeps.h>

/**
 * @defgroup DBusKeyring keyring class
 * @ingroup  DBusInternals
 * @brief DBusKeyring data structure
 *
 * Types and functions related to DBusKeyring. DBusKeyring is intended
 * to manage cookies used to authenticate clients to servers.  This is
 * essentially the "verify that client can read the user's homedir"
 * authentication mechanism.  Both client and server must have access
 * to the homedir.
 *
 * The secret keys are not kept in locked memory, and are written to a
 * file in the user's homedir. However they are transient (only used
 * by a single server instance for a fixed period of time, then
 * discarded). Also, the keys are not sent over the wire.
 *
 * @todo there's a memory leak on some codepath in here, I saw it once
 * when running make check - probably some specific initial cookies
 * present in the cookie file, then depending on what we do with them.
 */

/**
 * @defgroup DBusKeyringInternals DBusKeyring implementation details
 * @ingroup  DBusInternals
 * @brief DBusKeyring implementation details
 *
 * The guts of DBusKeyring.
 *
 * @{
 */

/** The maximum age of a key before we create a new key to use in
 * challenges.  This isn't super-reliably enforced, since system
 * clocks can change or be wrong, but we make a best effort to only
 * use keys for a short time.
 */
#define NEW_KEY_TIMEOUT_SECONDS     (60*5)
/**
 * The time after which we drop a key from the secrets file.
 * The EXPIRE_KEYS_TIMEOUT_SECONDS - NEW_KEY_TIMEOUT_SECONDS is the minimum
 * time window a client has to complete authentication.
 */
#define EXPIRE_KEYS_TIMEOUT_SECONDS (NEW_KEY_TIMEOUT_SECONDS + (60*2))
/**
 * The maximum amount of time a key can be in the future.
 */
#define MAX_TIME_TRAVEL_SECONDS (60*5)

/**
 * Maximum number of keys in the keyring before
 * we just ignore the rest
 */
#ifdef DBUS_BUILD_TESTS
#define MAX_KEYS_IN_FILE 10
#else
#define MAX_KEYS_IN_FILE 256
#endif

/**
 * A single key from the cookie file
 */
typedef struct
{
  dbus_int32_t id; /**< identifier used to refer to the key */

  long creation_time; /**< when the key was generated,
                       *   as unix timestamp. signed long
                       *   matches struct timeval.
                       */
  
  DBusString secret; /**< the actual key */

} DBusKey;

/**
 * @brief Internals of DBusKeyring.
 * 
 * DBusKeyring internals. DBusKeyring is an opaque object, it must be
 * used via accessor functions.
 */
struct DBusKeyring
{
  int refcount;             /**< Reference count */
  DBusString directory;     /**< Directory the below two items are inside */
  DBusString filename;      /**< Keyring filename */
  DBusString filename_lock; /**< Name of lockfile */
  DBusKey *keys; /**< Keys loaded from the file */
  int n_keys;    /**< Number of keys */
  DBusCredentials *credentials; /**< Credentials containing user the keyring is for */
};

static DBusKeyring*
_dbus_keyring_new (void)
{
  DBusKeyring *keyring;

  keyring = dbus_new0 (DBusKeyring, 1);
  if (keyring == NULL)
    goto out_0;
  
  if (!_dbus_string_init (&keyring->directory))
    goto out_1;

  if (!_dbus_string_init (&keyring->filename))
    goto out_2;

  if (!_dbus_string_init (&keyring->filename_lock))
    goto out_3;
  
  keyring->refcount = 1;
  keyring->keys = NULL;
  keyring->n_keys = 0;

  return keyring;

 out_3:
  _dbus_string_free (&keyring->filename);
 out_2:
  _dbus_string_free (&keyring->directory);
 out_1:
  dbus_free (keyring);
 out_0:
  return NULL;
}

static void
free_keys (DBusKey *keys,
           int      n_keys)
{
  int i;

  /* should be safe for args NULL, 0 */
  
  i = 0;
  while (i < n_keys)
    {
      _dbus_string_free (&keys[i].secret);
      ++i;
    }

  dbus_free (keys);
}

/* Our locking scheme is highly unreliable.  However, there is
 * unfortunately no reliable locking scheme in user home directories;
 * between bugs in Linux NFS, people using Tru64 or other total crap
 * NFS, AFS, random-file-system-of-the-week, and so forth, fcntl() in
 * homedirs simply generates tons of bug reports. This has been
 * learned through hard experience with GConf, unfortunately.
 *
 * This bad hack might work better for the kind of lock we have here,
 * which we don't expect to hold for any length of time.  Crashing
 * while we hold it should be unlikely, and timing out such that we
 * delete a stale lock should also be unlikely except when the
 * filesystem is running really slowly.  Stuff might break in corner
 * cases but as long as it's not a security-level breakage it should
 * be OK.
 */

/** Maximum number of timeouts waiting for lock before we decide it's stale */
#define MAX_LOCK_TIMEOUTS 32
/** Length of each timeout while waiting for a lock */
#define LOCK_TIMEOUT_MILLISECONDS 250

static dbus_bool_t
_dbus_keyring_lock (DBusKeyring *keyring)
{
  int n_timeouts;
  
  n_timeouts = 0;
  while (n_timeouts < MAX_LOCK_TIMEOUTS)
    {
      DBusError error = DBUS_ERROR_INIT;

      if (_dbus_create_file_exclusively (&keyring->filename_lock,
                                         &error))
        break;

      _dbus_verbose ("Did not get lock file, sleeping %d milliseconds (%s)\n",
                     LOCK_TIMEOUT_MILLISECONDS, error.message);
      dbus_error_free (&error);

      _dbus_sleep_milliseconds (LOCK_TIMEOUT_MILLISECONDS);
      
      ++n_timeouts;
    }

  if (n_timeouts == MAX_LOCK_TIMEOUTS)
    {
      DBusError error = DBUS_ERROR_INIT;

      _dbus_verbose ("Lock file timed out %d times, assuming stale\n",
                     n_timeouts);

      if (!_dbus_delete_file (&keyring->filename_lock, &error))
        {
          _dbus_verbose ("Couldn't delete old lock file: %s\n",
                         error.message);
          dbus_error_free (&error);
          return FALSE;
        }

      if (!_dbus_create_file_exclusively (&keyring->filename_lock,
                                          &error))
        {
          _dbus_verbose ("Couldn't create lock file after deleting stale one: %s\n",
                         error.message);
          dbus_error_free (&error);
          return FALSE;
        }
    }
  
  return TRUE;
}

static void
_dbus_keyring_unlock (DBusKeyring *keyring)
{
  DBusError error = DBUS_ERROR_INIT;

  if (!_dbus_delete_file (&keyring->filename_lock, &error))
    {
      _dbus_warn ("Failed to delete lock file: %s\n",
                  error.message);
      dbus_error_free (&error);
    }
}

static DBusKey*
find_key_by_id (DBusKey *keys,
                int      n_keys,
                int      id)
{
  int i;

  i = 0;
  while (i < n_keys)
    {
      if (keys[i].id == id)
        return &keys[i];
      
      ++i;
    }

  return NULL;
}

static dbus_bool_t
add_new_key (DBusKey  **keys_p,
             int       *n_keys_p,
             DBusError *error)
{
  DBusKey *new;
  DBusString bytes;
  int id;
  long timestamp;
  const unsigned char *s;
  dbus_bool_t retval;
  DBusKey *keys;
  int n_keys;

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
  
  if (!_dbus_string_init (&bytes))
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      return FALSE;
    }

  keys = *keys_p;
  n_keys = *n_keys_p;
  retval = FALSE;
      
  /* Generate an integer ID and then the actual key. */
 retry:
      
  if (!_dbus_generate_random_bytes (&bytes, 4))
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      goto out;
    }

  s = (const unsigned char*) _dbus_string_get_const_data (&bytes);
      
  id = s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24);
  if (id < 0)
    id = - id;
  _dbus_assert (id >= 0);

  if (find_key_by_id (keys, n_keys, id) != NULL)
    {
      _dbus_string_set_length (&bytes, 0);
      _dbus_verbose ("Key ID %d already existed, trying another one\n",
                     id);
      goto retry;
    }

  _dbus_verbose ("Creating key with ID %d\n", id);
      
#define KEY_LENGTH_BYTES 24
  _dbus_string_set_length (&bytes, 0);
  if (!_dbus_generate_random_bytes (&bytes, KEY_LENGTH_BYTES))
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      goto out;
    }

  new = dbus_realloc (keys, sizeof (DBusKey) * (n_keys + 1));
  if (new == NULL)
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      goto out;
    }

  keys = new;
  *keys_p = keys; /* otherwise *keys_p ends up invalid */
  n_keys += 1;

  if (!_dbus_string_init (&keys[n_keys-1].secret))
    {
      n_keys -= 1; /* we don't want to free the one we didn't init */
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      goto out;
    }

  _dbus_get_current_time (&timestamp, NULL);
      
  keys[n_keys-1].id = id;
  keys[n_keys-1].creation_time = timestamp;
  if (!_dbus_string_move (&bytes, 0,
                          &keys[n_keys-1].secret,
                          0))
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      _dbus_string_free (&keys[n_keys-1].secret);
      n_keys -= 1;
      goto out;
    }
  
  retval = TRUE;
  
 out:
  *n_keys_p = n_keys;
  
  _dbus_string_free (&bytes);
  return retval;
}

/**
 * Reloads the keyring file, optionally adds one new key to the file,
 * removes all expired keys from the file iff a key was added, then
 * resaves the file.  Stores the keys from the file in keyring->keys.
 * Note that the file is only resaved (written to) if a key is added,
 * this means that only servers ever write to the file and need to
 * lock it, which avoids a lot of lock contention at login time and
 * such.
 *
 * @param keyring the keyring
 * @param add_new #TRUE to add a new key to the file, expire keys, and resave
 * @param error return location for errors
 * @returns #FALSE on failure
 */
static dbus_bool_t
_dbus_keyring_reload (DBusKeyring *keyring,
                      dbus_bool_t  add_new,
                      DBusError   *error)
{
  DBusString contents;
  DBusString line;
  dbus_bool_t retval;
  dbus_bool_t have_lock;
  DBusKey *keys;
  int n_keys;
  int i;
  long now;
  DBusError tmp_error;

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
  
  if (!_dbus_check_dir_is_private_to_user (&keyring->directory, error))
    return FALSE;
    
  if (!_dbus_string_init (&contents))
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      return FALSE;
    }

  if (!_dbus_string_init (&line))
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      _dbus_string_free (&contents);
      return FALSE;
    }
   
  keys = NULL;
  n_keys = 0;
  retval = FALSE;
  have_lock = FALSE;

  _dbus_get_current_time (&now, NULL);
  
  if (add_new)
    {
      if (!_dbus_keyring_lock (keyring))
        {
          dbus_set_error (error, DBUS_ERROR_FAILED,
                          "Could not lock keyring file to add to it");
          goto out;
        }

      have_lock = TRUE;
    }

  dbus_error_init (&tmp_error);
  if (!_dbus_file_get_contents (&contents, 
                                &keyring->filename,
                                &tmp_error))
    {
      _dbus_verbose ("Failed to load keyring file: %s\n",
                     tmp_error.message);
      /* continue with empty keyring file, so we recreate it */
      dbus_error_free (&tmp_error);
    }

  if (!_dbus_string_validate_ascii (&contents, 0,
                                    _dbus_string_get_length (&contents)))
    {
      _dbus_warn ("Secret keyring file contains non-ASCII! Ignoring existing contents\n");
      _dbus_string_set_length (&contents, 0);
    }

  /* FIXME this is badly inefficient for large keyring files
   * (not that large keyring files exist outside of test suites)
   */
  while (_dbus_string_pop_line (&contents, &line))
    {
      int next;
      long val;
      int id;
      long timestamp;
      int len;
      int end;
      DBusKey *new;

      /* Don't load more than the max. */
      if (n_keys >= (add_new ? MAX_KEYS_IN_FILE - 1 : MAX_KEYS_IN_FILE))
        break;
      
      next = 0;
      if (!_dbus_string_parse_int (&line, 0, &val, &next))
        {
          _dbus_verbose ("could not parse secret key ID at start of line\n");
          continue;
        }

      if (val > _DBUS_INT32_MAX || val < 0)
        {
          _dbus_verbose ("invalid secret key ID at start of line\n");
          continue;
        }
      
      id = val;

      _dbus_string_skip_blank (&line, next, &next);
      
      if (!_dbus_string_parse_int (&line, next, &timestamp, &next))
        {
          _dbus_verbose ("could not parse secret key timestamp\n");
          continue;
        }

      if (timestamp < 0 ||
          (now + MAX_TIME_TRAVEL_SECONDS) < timestamp ||
          (now - EXPIRE_KEYS_TIMEOUT_SECONDS) > timestamp)
        {
          _dbus_verbose ("dropping/ignoring %ld-seconds old key with timestamp %ld as current time is %ld\n",
                         now - timestamp, timestamp, now);
          continue;
        }
      
      _dbus_string_skip_blank (&line, next, &next);

      len = _dbus_string_get_length (&line);

      if ((len - next) == 0)
        {
          _dbus_verbose ("no secret key after ID and timestamp\n");
          continue;
        }
      
      /* We have all three parts */
      new = dbus_realloc (keys, sizeof (DBusKey) * (n_keys + 1));
      if (new == NULL)
        {
          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
          goto out;
        }

      keys = new;
      n_keys += 1;

      if (!_dbus_string_init (&keys[n_keys-1].secret))
        {
          n_keys -= 1; /* we don't want to free the one we didn't init */
          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
          goto out;
        }
      
      keys[n_keys-1].id = id;
      keys[n_keys-1].creation_time = timestamp;
      if (!_dbus_string_hex_decode (&line, next, &end,
                                    &keys[n_keys-1].secret, 0))
	{
	  dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
	  goto out;
	}

      if (_dbus_string_get_length (&line) != end)
	{
	  _dbus_verbose ("invalid hex encoding in keyring file\n");
	  _dbus_string_free (&keys[n_keys - 1].secret);
	  n_keys -= 1;
	  continue;
	}
    }

  _dbus_verbose ("Successfully loaded %d existing keys\n",
                 n_keys);

  if (add_new)
    {
      if (!add_new_key (&keys, &n_keys, error))
        {
          _dbus_verbose ("Failed to generate new key: %s\n",
                         error ? error->message : "(unknown)");
          goto out;
        }

      _dbus_string_set_length (&contents, 0);

      i = 0;
      while (i < n_keys)
        {
          if (!_dbus_string_append_int (&contents,
                                        keys[i].id))
            goto nomem;

          if (!_dbus_string_append_byte (&contents, ' '))
            goto nomem;

          if (!_dbus_string_append_int (&contents,
                                        keys[i].creation_time))
            goto nomem;

          if (!_dbus_string_append_byte (&contents, ' '))
            goto nomem;

          if (!_dbus_string_hex_encode (&keys[i].secret, 0,
                                        &contents,
                                        _dbus_string_get_length (&contents)))
            goto nomem;

          if (!_dbus_string_append_byte (&contents, '\n'))
            goto nomem;          
          
          ++i;
          continue;

        nomem:
          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
          goto out;
        }
      
      if (!_dbus_string_save_to_file (&contents, &keyring->filename,
                                      FALSE, error))
        goto out;
    }

  if (keyring->keys)
    free_keys (keyring->keys, keyring->n_keys);
  keyring->keys = keys;
  keyring->n_keys = n_keys;
  keys = NULL;
  n_keys = 0;
  
  retval = TRUE;  
  
 out:
  if (have_lock)
    _dbus_keyring_unlock (keyring);
  
  if (! ((retval == TRUE && (error == NULL || error->name == NULL)) ||
         (retval == FALSE && (error == NULL || error->name != NULL))))
    {
      if (error && error->name)
        _dbus_verbose ("error is %s: %s\n", error->name, error->message);
      _dbus_warn ("returning %d but error pointer %p name %s\n",
                  retval, error, error->name ? error->name : "(none)");
      _dbus_assert_not_reached ("didn't handle errors properly");
    }
  
  if (keys != NULL)
    {
      i = 0;
      while (i < n_keys)
        {
          _dbus_string_zero (&keys[i].secret);
          _dbus_string_free (&keys[i].secret);
          ++i;
        }

      dbus_free (keys);
    }
  
  _dbus_string_free (&contents);
  _dbus_string_free (&line);

  return retval;
}

/** @} */ /* end of internals */

/**
 * @addtogroup DBusKeyring
 *
 * @{
 */

/**
 * Increments reference count of the keyring
 *
 * @param keyring the keyring
 * @returns the keyring
 */
DBusKeyring *
_dbus_keyring_ref (DBusKeyring *keyring)
{
  keyring->refcount += 1;

  return keyring;
}

/**
 * Decrements refcount and finalizes if it reaches
 * zero.
 *
 * @param keyring the keyring
 */
void
_dbus_keyring_unref (DBusKeyring *keyring)
{
  keyring->refcount -= 1;

  if (keyring->refcount == 0)
    {
      if (keyring->credentials)
        _dbus_credentials_unref (keyring->credentials);

      _dbus_string_free (&keyring->filename);
      _dbus_string_free (&keyring->filename_lock);
      _dbus_string_free (&keyring->directory);
      free_keys (keyring->keys, keyring->n_keys);
      dbus_free (keyring);      
    }
}

/**
 * Creates a new keyring that lives in the ~/.dbus-keyrings directory
 * of the given user credentials. If the credentials are #NULL or
 * empty, uses those of the current process.
 *
 * @param username username to get keyring for, or #NULL
 * @param context which keyring to get
 * @param error return location for errors
 * @returns the keyring or #NULL on error
 */
DBusKeyring*
_dbus_keyring_new_for_credentials (DBusCredentials  *credentials,
                                   const DBusString *context,
                                   DBusError        *error)
{
  DBusString ringdir;
  DBusKeyring *keyring;
  dbus_bool_t error_set;
  DBusError tmp_error;
  DBusCredentials *our_credentials;
  
  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
  
  keyring = NULL;
  error_set = FALSE;
  our_credentials = NULL;
  
  if (!_dbus_string_init (&ringdir))
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      return NULL;
    }

  if (credentials != NULL)
    {
      our_credentials = _dbus_credentials_copy (credentials);
    }
  else
    {
      our_credentials = _dbus_credentials_new_from_current_process ();
    }
  
  if (our_credentials == NULL)
    goto failed;

  if (_dbus_credentials_are_anonymous (our_credentials))
    {
      if (!_dbus_credentials_add_from_current_process (our_credentials))
        goto failed;
    }
  
  if (!_dbus_append_keyring_directory_for_credentials (&ringdir,
                                                       our_credentials))
    goto failed;
  
  keyring = _dbus_keyring_new ();
  if (keyring == NULL)
    goto failed;

  _dbus_assert (keyring->credentials == NULL);
  keyring->credentials = our_credentials;
  our_credentials = NULL; /* so we don't unref it again later */
  
  /* should have been validated already, but paranoia check here */
  if (!_dbus_keyring_validate_context (context))
    {
      error_set = TRUE;
      dbus_set_error_const (error,
                            DBUS_ERROR_FAILED,
                            "Invalid context in keyring creation");
      goto failed;
    }

  /* Save keyring dir in the keyring object */
  if (!_dbus_string_copy (&ringdir, 0,
                          &keyring->directory, 0))
    goto failed;  

  /* Create keyring->filename based on keyring dir and context */
  if (!_dbus_string_copy (&keyring->directory, 0,
                          &keyring->filename, 0))
    goto failed;

  if (!_dbus_concat_dir_and_file (&keyring->filename,
                                  context))
    goto failed;

  /* Create lockfile name */
  if (!_dbus_string_copy (&keyring->filename, 0,
                          &keyring->filename_lock, 0))
    goto failed;

  if (!_dbus_string_append (&keyring->filename_lock, ".lock"))
    goto failed;

  /* Reload keyring */
  dbus_error_init (&tmp_error);
  if (!_dbus_keyring_reload (keyring, FALSE, &tmp_error))
    {
      _dbus_verbose ("didn't load an existing keyring: %s\n",
                     tmp_error.message);
      dbus_error_free (&tmp_error);
    }
  
  /* We don't fail fatally if we can't create the directory,
   * but the keyring will probably always be empty
   * unless someone else manages to create it
   */
  dbus_error_init (&tmp_error);
  if (!_dbus_create_directory (&keyring->directory,
                               &tmp_error))
    {
      _dbus_verbose ("Creating keyring directory: %s\n",
                     tmp_error.message);
      dbus_error_free (&tmp_error);
    }

  _dbus_string_free (&ringdir);
  
  return keyring;
  
 failed:
  if (!error_set)
    dbus_set_error_const (error,
                          DBUS_ERROR_NO_MEMORY,
                          NULL);
  if (our_credentials)
    _dbus_credentials_unref (our_credentials);
  if (keyring)
    _dbus_keyring_unref (keyring);
  _dbus_string_free (&ringdir);
  return NULL;

}

/**
 * Checks whether the context is a valid context.
 * Contexts that might cause confusion when used
 * in filenames are not allowed (contexts can't
 * start with a dot or contain dir separators).
 *
 * @todo this is the most inefficient implementation
 * imaginable.
 *
 * @param context the context
 * @returns #TRUE if valid
 */
dbus_bool_t
_dbus_keyring_validate_context (const DBusString *context)
{
  if (_dbus_string_get_length (context) == 0)
    {
      _dbus_verbose ("context is zero-length\n");
      return FALSE;
    }

  if (!_dbus_string_validate_ascii (context, 0,
                                    _dbus_string_get_length (context)))
    {
      _dbus_verbose ("context not valid ascii\n");
      return FALSE;
    }
  
  /* no directory separators */  
  if (_dbus_string_find (context, 0, "/", NULL))
    {
      _dbus_verbose ("context contains a slash\n");
      return FALSE;
    }

  if (_dbus_string_find (context, 0, "\\", NULL))
    {
      _dbus_verbose ("context contains a backslash\n");
      return FALSE;
    }

  /* prevent attempts to use dotfiles or ".." or ".lock"
   * all of which might allow some kind of attack
   */
  if (_dbus_string_find (context, 0, ".", NULL))
    {
      _dbus_verbose ("context contains a dot\n");
      return FALSE;
    }

  /* no spaces/tabs, those are used for separators in the protocol */
  if (_dbus_string_find_blank (context, 0, NULL))
    {
      _dbus_verbose ("context contains a blank\n");
      return FALSE;
    }

  if (_dbus_string_find (context, 0, "\n", NULL))
    {
      _dbus_verbose ("context contains a newline\n");
      return FALSE;
    }

  if (_dbus_string_find (context, 0, "\r", NULL))
    {
      _dbus_verbose ("context contains a carriage return\n");
      return FALSE;
    }
  
  return TRUE;
}

static DBusKey*
find_recent_key (DBusKeyring *keyring)
{
  int i;
  long tv_sec, tv_usec;

  _dbus_get_current_time (&tv_sec, &tv_usec);
  
  i = 0;
  while (i < keyring->n_keys)
    {
      DBusKey *key = &keyring->keys[i];

      _dbus_verbose ("Key %d is %ld seconds old\n",
                     i, tv_sec - key->creation_time);
      
      if ((tv_sec - NEW_KEY_TIMEOUT_SECONDS) < key->creation_time)
        return key;
      
      ++i;
    }

  return NULL;
}

/**
 * Gets a recent key to use for authentication.
 * If no recent key exists, creates one. Returns
 * the key ID. If a key can't be written to the keyring
 * file so no recent key can be created, returns -1.
 * All valid keys are > 0.
 *
 * @param keyring the keyring
 * @param error error on failure
 * @returns key ID to use for auth, or -1 on failure
 */
int
_dbus_keyring_get_best_key (DBusKeyring  *keyring,
                            DBusError    *error)
{
  DBusKey *key;

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
  
  key = find_recent_key (keyring);
  if (key)
    return key->id;

  /* All our keys are too old, or we've never loaded the
   * keyring. Create a new one.
   */
  if (!_dbus_keyring_reload (keyring, TRUE,
                             error))
    return -1;

  key = find_recent_key (keyring);
  if (key)
    return key->id;
  else
    {
      dbus_set_error_const (error,
                            DBUS_ERROR_FAILED,
                            "No recent-enough key found in keyring, and unable to create a new key");
      return -1;
    }
}

/**
 * Checks whether the keyring is for the same user as the given credentials.
 *
 * @param keyring the keyring
 * @param credentials the credentials to check
 *
 * @returns #TRUE if the keyring belongs to the given user
 */
dbus_bool_t
_dbus_keyring_is_for_credentials (DBusKeyring           *keyring,
                                  DBusCredentials       *credentials)
{
  return _dbus_credentials_same_user (keyring->credentials,
                                      credentials);
}

/**
 * Gets the hex-encoded secret key for the given ID.
 * Returns #FALSE if not enough memory. Returns #TRUE
 * but empty key on any other error such as unknown
 * key ID.
 *
 * @param keyring the keyring
 * @param key_id the key ID
 * @param hex_key string to append hex-encoded key to
 * @returns #TRUE if we had enough memory
 */
dbus_bool_t
_dbus_keyring_get_hex_key (DBusKeyring       *keyring,
                           int                key_id,
                           DBusString        *hex_key)
{
  DBusKey *key;

  key = find_key_by_id (keyring->keys,
                        keyring->n_keys,
                        key_id);
  if (key == NULL)
    return TRUE; /* had enough memory, so TRUE */

  return _dbus_string_hex_encode (&key->secret, 0,
                                  hex_key,
                                  _dbus_string_get_length (hex_key));
}

/** @} */ /* end of exposed API */

#ifdef DBUS_BUILD_TESTS
#include "dbus-test.h"
#include <stdio.h>

dbus_bool_t
_dbus_keyring_test (void)
{
  DBusString context;
  DBusKeyring *ring1;
  DBusKeyring *ring2;
  int id;
  DBusError error;
  int i;

  ring1 = NULL;
  ring2 = NULL;
  
  /* Context validation */
  
  _dbus_string_init_const (&context, "foo");
  _dbus_assert (_dbus_keyring_validate_context (&context));
  _dbus_string_init_const (&context, "org_freedesktop_blah");
  _dbus_assert (_dbus_keyring_validate_context (&context));
  
  _dbus_string_init_const (&context, "");
  _dbus_assert (!_dbus_keyring_validate_context (&context));
  _dbus_string_init_const (&context, ".foo");
  _dbus_assert (!_dbus_keyring_validate_context (&context));
  _dbus_string_init_const (&context, "bar.foo");
  _dbus_assert (!_dbus_keyring_validate_context (&context));
  _dbus_string_init_const (&context, "bar/foo");
  _dbus_assert (!_dbus_keyring_validate_context (&context));
  _dbus_string_init_const (&context, "bar\\foo");
  _dbus_assert (!_dbus_keyring_validate_context (&context));
  _dbus_string_init_const (&context, "foo\xfa\xf0");
  _dbus_assert (!_dbus_keyring_validate_context (&context));
  _dbus_string_init_const (&context, "foo\x80");
  _dbus_assert (!_dbus_keyring_validate_context (&context));
  _dbus_string_init_const (&context, "foo\x7f");
  _dbus_assert (_dbus_keyring_validate_context (&context));
  _dbus_string_init_const (&context, "foo bar");
  _dbus_assert (!_dbus_keyring_validate_context (&context));
  
  if (!_dbus_string_init (&context))
    _dbus_assert_not_reached ("no memory");
  if (!_dbus_string_append_byte (&context, '\0'))
    _dbus_assert_not_reached ("no memory");
  _dbus_assert (!_dbus_keyring_validate_context (&context));
  _dbus_string_free (&context);

  /* Now verify that if we create a key in keyring 1,
   * it is properly loaded in keyring 2
   */

  _dbus_string_init_const (&context, "org_freedesktop_dbus_testsuite");
  dbus_error_init (&error);
  ring1 = _dbus_keyring_new_for_credentials (NULL, &context,
                                             &error);
  _dbus_assert (ring1 != NULL);
  _dbus_assert (error.name == NULL);

  id = _dbus_keyring_get_best_key (ring1, &error);
  if (id < 0)
    {
      fprintf (stderr, "Could not load keyring: %s\n", error.message);
      dbus_error_free (&error);
      goto failure;
    }

  ring2 = _dbus_keyring_new_for_credentials (NULL, &context, &error);
  _dbus_assert (ring2 != NULL);
  _dbus_assert (error.name == NULL);
  
  if (ring1->n_keys != ring2->n_keys)
    {
      fprintf (stderr, "Different number of keys in keyrings\n");
      goto failure;
    }

  /* We guarantee we load and save keeping keys in a fixed
   * order
   */
  i = 0;
  while (i < ring1->n_keys)
    {
      if (ring1->keys[i].id != ring2->keys[i].id)
        {
          fprintf (stderr, "Keyring 1 has first key ID %d and keyring 2 has %d\n",
                   ring1->keys[i].id, ring2->keys[i].id);
          goto failure;
        }      

      if (ring1->keys[i].creation_time != ring2->keys[i].creation_time)
        {
          fprintf (stderr, "Keyring 1 has first key time %ld and keyring 2 has %ld\n",
                   ring1->keys[i].creation_time, ring2->keys[i].creation_time);
          goto failure;
        }

      if (!_dbus_string_equal (&ring1->keys[i].secret,
                               &ring2->keys[i].secret))
        {
          fprintf (stderr, "Keyrings 1 and 2 have different secrets for same ID/timestamp\n");
          goto failure;
        }
      
      ++i;
    }

  printf (" %d keys in test\n", ring1->n_keys);

  /* Test ref/unref */
  _dbus_keyring_ref (ring1);
  _dbus_keyring_ref (ring2);
  _dbus_keyring_unref (ring1);
  _dbus_keyring_unref (ring2);


  /* really unref */
  _dbus_keyring_unref (ring1);
  _dbus_keyring_unref (ring2);
  
  return TRUE;

 failure:
  if (ring1)
    _dbus_keyring_unref (ring1);
  if (ring2)
    _dbus_keyring_unref (ring2);

  return FALSE;
}

#endif /* DBUS_BUILD_TESTS */
     
