Coverage report for dbus/dbus-keyring.c.gcov
-: 0:Source:dbus-keyring.c
-: 0:Graph:.libs/dbus-keyring.gcno
-: 0:Data:.libs/dbus-keyring.gcda
-: 0:Runs:11813
-: 0:Programs:5
-: 1:/* -*- mode: C; c-file-style: "gnu" -*- */
-: 2:/* dbus-keyring.c Store secret cookies in your homedir
-: 3: *
-: 4: * Copyright (C) 2003, 2004 Red Hat Inc.
-: 5: *
-: 6: * Licensed under the Academic Free License version 2.1
-: 7: *
-: 8: * This program is free software; you can redistribute it and/or modify
-: 9: * it under the terms of the GNU General Public License as published by
-: 10: * the Free Software Foundation; either version 2 of the License, or
-: 11: * (at your option) any later version.
-: 12: *
-: 13: * This program is distributed in the hope that it will be useful,
-: 14: * but WITHOUT ANY WARRANTY; without even the implied warranty of
-: 15: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-: 16: * GNU General Public License for more details.
-: 17: *
-: 18: * You should have received a copy of the GNU General Public License
-: 19: * along with this program; if not, write to the Free Software
-: 20: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-: 21: *
-: 22: */
-: 23:
-: 24:#include "dbus-keyring.h"
-: 25:#include "dbus-userdb.h"
-: 26:#include "dbus-protocol.h"
-: 27:#include <dbus/dbus-string.h>
-: 28:#include <dbus/dbus-list.h>
-: 29:#include <dbus/dbus-sysdeps.h>
-: 30:
-: 31:/**
-: 32: * @defgroup DBusKeyring keyring class
-: 33: * @ingroup DBusInternals
-: 34: * @brief DBusKeyring data structure
-: 35: *
-: 36: * Types and functions related to DBusKeyring. DBusKeyring is intended
-: 37: * to manage cookies used to authenticate clients to servers. This is
-: 38: * essentially the "verify that client can read the user's homedir"
-: 39: * authentication mechanism. Both client and server must have access
-: 40: * to the homedir.
-: 41: *
-: 42: * The secret keys are not kept in locked memory, and are written to a
-: 43: * file in the user's homedir. However they are transient (only used
-: 44: * by a single server instance for a fixed period of time, then
-: 45: * discarded). Also, the keys are not sent over the wire.
-: 46: *
-: 47: * @todo there's a memory leak on some codepath in here, I saw it once
-: 48: * when running make check - probably some specific initial cookies
-: 49: * present in the cookie file, then depending on what we do with them.
-: 50: */
-: 51:
-: 52:/**
-: 53: * @defgroup DBusKeyringInternals DBusKeyring implementation details
-: 54: * @ingroup DBusInternals
-: 55: * @brief DBusKeyring implementation details
-: 56: *
-: 57: * The guts of DBusKeyring.
-: 58: *
-: 59: * @{
-: 60: */
-: 61:
-: 62:/** The maximum age of a key before we create a new key to use in
-: 63: * challenges. This isn't super-reliably enforced, since system
-: 64: * clocks can change or be wrong, but we make a best effort to only
-: 65: * use keys for a short time.
-: 66: */
-: 67:#define NEW_KEY_TIMEOUT_SECONDS (60*5)
-: 68:/**
-: 69: * The time after which we drop a key from the secrets file.
-: 70: * The EXPIRE_KEYS_TIMEOUT_SECONDS - NEW_KEY_TIMEOUT_SECONDS is the minimum
-: 71: * time window a client has to complete authentication.
-: 72: */
-: 73:#define EXPIRE_KEYS_TIMEOUT_SECONDS (NEW_KEY_TIMEOUT_SECONDS + (60*2))
-: 74:/**
-: 75: * The maximum amount of time a key can be in the future.
-: 76: */
-: 77:#define MAX_TIME_TRAVEL_SECONDS (60*5)
-: 78:
-: 79:/**
-: 80: * Maximum number of keys in the keyring before
-: 81: * we just ignore the rest
-: 82: */
-: 83:#ifdef DBUS_BUILD_TESTS
-: 84:#define MAX_KEYS_IN_FILE 10
-: 85:#else
-: 86:#define MAX_KEYS_IN_FILE 256
-: 87:#endif
-: 88:
-: 89:/**
-: 90: * A single key from the cookie file
-: 91: */
-: 92:typedef struct
-: 93:{
-: 94: dbus_int32_t id; /**< identifier used to refer to the key */
-: 95:
-: 96: long creation_time; /**< when the key was generated,
-: 97: * as unix timestamp. signed long
-: 98: * matches struct timeval.
-: 99: */
-: 100:
-: 101: DBusString secret; /**< the actual key */
-: 102:
-: 103:} DBusKey;
-: 104:
-: 105:/**
-: 106: * @brief Internals of DBusKeyring.
-: 107: *
-: 108: * DBusKeyring internals. DBusKeyring is an opaque object, it must be
-: 109: * used via accessor functions.
-: 110: */
-: 111:struct DBusKeyring
-: 112:{
-: 113: int refcount; /**< Reference count */
-: 114: DBusString username; /**< Username keyring is for */
-: 115: DBusString directory; /**< Directory the below two items are inside */
-: 116: DBusString filename; /**< Keyring filename */
-: 117: DBusString filename_lock; /**< Name of lockfile */
-: 118: DBusKey *keys; /**< Keys loaded from the file */
-: 119: int n_keys; /**< Number of keys */
-: 120:};
-: 121:
-: 122:static DBusKeyring*
-: 123:_dbus_keyring_new (void)
function _dbus_keyring_new called 6888 returned 100% blocks executed 100%
6888: 124:{
-: 125: DBusKeyring *keyring;
-: 126:
6888: 127: keyring = dbus_new0 (DBusKeyring, 1);
call 0 returned 100%
6888: 128: if (keyring == NULL)
branch 0 taken 1% (fallthrough)
branch 1 taken 99%
6: 129: goto out_0;
-: 130:
6882: 131: if (!_dbus_string_init (&keyring->directory))
call 0 returned 100%
branch 1 taken 1% (fallthrough)
branch 2 taken 99%
6: 132: goto out_1;
-: 133:
6876: 134: if (!_dbus_string_init (&keyring->filename))
call 0 returned 100%
branch 1 taken 1% (fallthrough)
branch 2 taken 99%
6: 135: goto out_2;
-: 136:
6870: 137: if (!_dbus_string_init (&keyring->filename_lock))
call 0 returned 100%
branch 1 taken 1% (fallthrough)
branch 2 taken 99%
6: 138: goto out_3;
-: 139:
6864: 140: if (!_dbus_string_init (&keyring->username))
call 0 returned 100%
branch 1 taken 99% (fallthrough)
branch 2 taken 1%
6: 141: goto out_4;
-: 142:
6858: 143: keyring->refcount = 1;
6858: 144: keyring->keys = NULL;
6858: 145: keyring->n_keys = 0;
-: 146:
6858: 147: return keyring;
-: 148:
6: 149: out_4:
6: 150: _dbus_string_free (&keyring->filename_lock);
call 0 returned 100%
12: 151: out_3:
12: 152: _dbus_string_free (&keyring->filename);
call 0 returned 100%
18: 153: out_2:
18: 154: _dbus_string_free (&keyring->directory);
call 0 returned 100%
24: 155: out_1:
24: 156: dbus_free (keyring);
call 0 returned 100%
30: 157: out_0:
30: 158: return NULL;
-: 159:}
-: 160:
-: 161:static void
-: 162:free_keys (DBusKey *keys,
-: 163: int n_keys)
function free_keys called 6858 returned 100% blocks executed 100%
6858: 164:{
-: 165: int i;
-: 166:
-: 167: /* should be safe for args NULL, 0 */
-: 168:
6858: 169: i = 0;
54189: 170: while (i < n_keys)
branch 0 taken 86%
branch 1 taken 14% (fallthrough)
-: 171: {
40473: 172: _dbus_string_free (&keys[i].secret);
call 0 returned 100%
40473: 173: ++i;
-: 174: }
-: 175:
6858: 176: dbus_free (keys);
call 0 returned 100%
6858: 177:}
-: 178:
-: 179:/* Our locking scheme is highly unreliable. However, there is
-: 180: * unfortunately no reliable locking scheme in user home directories;
-: 181: * between bugs in Linux NFS, people using Tru64 or other total crap
-: 182: * NFS, AFS, random-file-system-of-the-week, and so forth, fcntl() in
-: 183: * homedirs simply generates tons of bug reports. This has been
-: 184: * learned through hard experience with GConf, unfortunately.
-: 185: *
-: 186: * This bad hack might work better for the kind of lock we have here,
-: 187: * which we don't expect to hold for any length of time. Crashing
-: 188: * while we hold it should be unlikely, and timing out such that we
-: 189: * delete a stale lock should also be unlikely except when the
-: 190: * filesystem is running really slowly. Stuff might break in corner
-: 191: * cases but as long as it's not a security-level breakage it should
-: 192: * be OK.
-: 193: */
-: 194:
-: 195:/** Maximum number of timeouts waiting for lock before we decide it's stale */
-: 196:#define MAX_LOCK_TIMEOUTS 32
-: 197:/** Length of each timeout while waiting for a lock */
-: 198:#define LOCK_TIMEOUT_MILLISECONDS 250
-: 199:
-: 200:static dbus_bool_t
-: 201:_dbus_keyring_lock (DBusKeyring *keyring)
function _dbus_keyring_lock called 310 returned 100% blocks executed 36%
310: 202:{
-: 203: int n_timeouts;
-: 204:
310: 205: n_timeouts = 0;
620: 206: while (n_timeouts < MAX_LOCK_TIMEOUTS)
branch 0 taken 100%
branch 1 taken 0% (fallthrough)
-: 207: {
-: 208: DBusError error;
-: 209:
310: 210: dbus_error_init (&error);
call 0 returned 100%
310: 211: if (_dbus_create_file_exclusively (&keyring->filename_lock,
call 0 returned 100%
branch 1 taken 100% (fallthrough)
branch 2 taken 0%
-: 212: &error))
310: 213: break;
-: 214:
#####: 215: _dbus_verbose ("Did not get lock file, sleeping %d milliseconds (%s)\n",
call 0 never executed
-: 216: LOCK_TIMEOUT_MILLISECONDS, error.message);
#####: 217: dbus_error_free (&error);
call 0 never executed
-: 218:
#####: 219: _dbus_sleep_milliseconds (LOCK_TIMEOUT_MILLISECONDS);
call 0 never executed
-: 220:
#####: 221: ++n_timeouts;
-: 222: }
-: 223:
310: 224: if (n_timeouts == MAX_LOCK_TIMEOUTS)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
-: 225: {
-: 226: DBusError error;
-: 227:
#####: 228: _dbus_verbose ("Lock file timed out %d times, assuming stale\n",
call 0 never executed
-: 229: n_timeouts);
-: 230:
#####: 231: dbus_error_init (&error);
call 0 never executed
-: 232:
#####: 233: if (!_dbus_delete_file (&keyring->filename_lock, &error))
call 0 never executed
branch 1 never executed
branch 2 never executed
-: 234: {
#####: 235: _dbus_verbose ("Couldn't delete old lock file: %s\n",
call 0 never executed
-: 236: error.message);
#####: 237: dbus_error_free (&error);
call 0 never executed
#####: 238: return FALSE;
-: 239: }
-: 240:
#####: 241: if (!_dbus_create_file_exclusively (&keyring->filename_lock,
call 0 never executed
branch 1 never executed
branch 2 never executed
-: 242: &error))
-: 243: {
#####: 244: _dbus_verbose ("Couldn't create lock file after deleting stale one: %s\n",
call 0 never executed
-: 245: error.message);
#####: 246: dbus_error_free (&error);
call 0 never executed
#####: 247: return FALSE;
-: 248: }
-: 249: }
-: 250:
310: 251: return TRUE;
-: 252:}
-: 253:
-: 254:static void
-: 255:_dbus_keyring_unlock (DBusKeyring *keyring)
function _dbus_keyring_unlock called 310 returned 100% blocks executed 67%
310: 256:{
-: 257: DBusError error;
310: 258: dbus_error_init (&error);
call 0 returned 100%
310: 259: if (!_dbus_delete_file (&keyring->filename_lock, &error))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 260: {
#####: 261: _dbus_warn ("Failed to delete lock file: %s\n",
call 0 never executed
-: 262: error.message);
#####: 263: dbus_error_free (&error);
call 0 never executed
-: 264: }
310: 265:}
-: 266:
-: 267:static DBusKey*
-: 268:find_key_by_id (DBusKey *keys,
-: 269: int n_keys,
-: 270: int id)
function find_key_by_id called 6504 returned 100% blocks executed 100%
6504: 271:{
-: 272: int i;
-: 273:
6504: 274: i = 0;
15744: 275: while (i < n_keys)
branch 0 taken 90%
branch 1 taken 10% (fallthrough)
-: 276: {
8361: 277: if (keys[i].id == id)
branch 0 taken 67% (fallthrough)
branch 1 taken 33%
5625: 278: return &keys[i];
-: 279:
2736: 280: ++i;
-: 281: }
-: 282:
879: 283: return NULL;
-: 284:}
-: 285:
-: 286:static dbus_bool_t
-: 287:add_new_key (DBusKey **keys_p,
-: 288: int *n_keys_p,
-: 289: DBusError *error)
function add_new_key called 310 returned 100% blocks executed 65%
310: 290:{
-: 291: DBusKey *new;
-: 292: DBusString bytes;
-: 293: int id;
-: 294: long timestamp;
-: 295: const unsigned char *s;
-: 296: dbus_bool_t retval;
-: 297: DBusKey *keys;
-: 298: int n_keys;
-: 299:
310: 300: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
call 2 returned 100%
branch 3 taken 100% (fallthrough)
branch 4 taken 0%
call 5 returned 100%
-: 301:
310: 302: if (!_dbus_string_init (&bytes))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 303: {
#####: 304: dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
call 0 never executed
#####: 305: return FALSE;
-: 306: }
-: 307:
310: 308: keys = *keys_p;
310: 309: n_keys = *n_keys_p;
310: 310: retval = FALSE;
-: 311:
-: 312: /* Generate an integer ID and then the actual key. */
310: 313: retry:
-: 314:
310: 315: if (!_dbus_generate_random_bytes (&bytes, 4))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 316: {
#####: 317: dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
call 0 never executed
#####: 318: goto out;
-: 319: }
-: 320:
310: 321: s = (const unsigned char*) _dbus_string_get_const_data (&bytes);
call 0 returned 100%
-: 322:
310: 323: id = s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24);
310: 324: if (id < 0)
branch 0 taken 50% (fallthrough)
branch 1 taken 50%
154: 325: id = - id;
310: 326: _dbus_assert (id >= 0);
call 0 returned 100%
-: 327:
310: 328: if (find_key_by_id (keys, n_keys, id) != NULL)
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 329: {
#####: 330: _dbus_string_set_length (&bytes, 0);
call 0 never executed
#####: 331: _dbus_verbose ("Key ID %d already existed, trying another one\n",
call 0 never executed
-: 332: id);
#####: 333: goto retry;
-: 334: }
-: 335:
310: 336: _dbus_verbose ("Creating key with ID %d\n", id);
call 0 returned 100%
-: 337:
-: 338:#define KEY_LENGTH_BYTES 24
310: 339: _dbus_string_set_length (&bytes, 0);
call 0 returned 100%
310: 340: if (!_dbus_generate_random_bytes (&bytes, KEY_LENGTH_BYTES))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 341: {
#####: 342: dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
call 0 never executed
#####: 343: goto out;
-: 344: }
-: 345:
310: 346: new = dbus_realloc (keys, sizeof (DBusKey) * (n_keys + 1));
call 0 returned 100%
310: 347: if (new == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
-: 348: {
#####: 349: dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
call 0 never executed
#####: 350: goto out;
-: 351: }
-: 352:
310: 353: keys = new;
310: 354: *keys_p = keys; /* otherwise *keys_p ends up invalid */
310: 355: n_keys += 1;
-: 356:
310: 357: if (!_dbus_string_init (&keys[n_keys-1].secret))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 358: {
#####: 359: n_keys -= 1; /* we don't want to free the one we didn't init */
#####: 360: dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
call 0 never executed
#####: 361: goto out;
-: 362: }
-: 363:
310: 364: _dbus_get_current_time (×tamp, NULL);
call 0 returned 100%
-: 365:
310: 366: keys[n_keys-1].id = id;
310: 367: keys[n_keys-1].creation_time = timestamp;
310: 368: if (!_dbus_string_move (&bytes, 0,
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 369: &keys[n_keys-1].secret,
-: 370: 0))
-: 371: {
#####: 372: dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
call 0 never executed
#####: 373: _dbus_string_free (&keys[n_keys-1].secret);
call 0 never executed
#####: 374: n_keys -= 1;
#####: 375: goto out;
-: 376: }
-: 377:
310: 378: retval = TRUE;
-: 379:
310: 380: out:
310: 381: *n_keys_p = n_keys;
-: 382:
310: 383: _dbus_string_free (&bytes);
call 0 returned 100%
310: 384: return retval;
-: 385:}
-: 386:
-: 387:/**
-: 388: * Reloads the keyring file, optionally adds one new key to the file,
-: 389: * removes all expired keys from the file iff a key was added, then
-: 390: * resaves the file. Stores the keys from the file in keyring->keys.
-: 391: * Note that the file is only resaved (written to) if a key is added,
-: 392: * this means that only servers ever write to the file and need to
-: 393: * lock it, which avoids a lot of lock contention at login time and
-: 394: * such.
-: 395: *
-: 396: * @param keyring the keyring
-: 397: * @param add_new #TRUE to add a new key to the file, expire keys, and resave
-: 398: * @param error return location for errors
-: 399: * @returns #FALSE on failure
-: 400: */
-: 401:static dbus_bool_t
-: 402:_dbus_keyring_reload (DBusKeyring *keyring,
-: 403: dbus_bool_t add_new,
-: 404: DBusError *error)
function _dbus_keyring_reload called 7387 returned 100% blocks executed 73%
7387: 405:{
-: 406: DBusString contents;
-: 407: DBusString line;
-: 408: dbus_bool_t retval;
-: 409: dbus_bool_t have_lock;
-: 410: DBusKey *keys;
-: 411: int n_keys;
-: 412: int i;
-: 413: long now;
-: 414: DBusError tmp_error;
-: 415:
7387: 416: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
call 2 returned 100%
branch 3 taken 100% (fallthrough)
branch 4 taken 0%
call 5 returned 100%
-: 417:
7387: 418: if (!_dbus_check_dir_is_private_to_user (&keyring->directory, error))
call 0 returned 100%
branch 1 taken 1% (fallthrough)
branch 2 taken 99%
1: 419: return FALSE;
-: 420:
7386: 421: if (!_dbus_string_init (&contents))
call 0 returned 100%
branch 1 taken 4% (fallthrough)
branch 2 taken 96%
-: 422: {
280: 423: dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
call 0 returned 100%
280: 424: return FALSE;
-: 425: }
-: 426:
7106: 427: if (!_dbus_string_init (&line))
call 0 returned 100%
branch 1 taken 1% (fallthrough)
branch 2 taken 99%
-: 428: {
8: 429: dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
call 0 returned 100%
8: 430: _dbus_string_free (&contents);
call 0 returned 100%
8: 431: return FALSE;
-: 432: }
-: 433:
7098: 434: keys = NULL;
7098: 435: n_keys = 0;
7098: 436: retval = FALSE;
7098: 437: have_lock = FALSE;
-: 438:
7098: 439: _dbus_get_current_time (&now, NULL);
call 0 returned 100%
-: 440:
7098: 441: if (add_new)
branch 0 taken 4% (fallthrough)
branch 1 taken 96%
-: 442: {
310: 443: if (!_dbus_keyring_lock (keyring))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 444: {
#####: 445: dbus_set_error (error, DBUS_ERROR_FAILED,
call 0 never executed
-: 446: "Could not lock keyring file to add to it");
#####: 447: goto out;
-: 448: }
-: 449:
310: 450: have_lock = TRUE;
-: 451: }
-: 452:
7098: 453: dbus_error_init (&tmp_error);
call 0 returned 100%
7098: 454: if (!_dbus_file_get_contents (&contents,
call 0 returned 100%
branch 1 taken 1% (fallthrough)
branch 2 taken 99%
-: 455: &keyring->filename,
-: 456: &tmp_error))
-: 457: {
8: 458: _dbus_verbose ("Failed to load keyring file: %s\n",
call 0 returned 100%
-: 459: tmp_error.message);
-: 460: /* continue with empty keyring file, so we recreate it */
8: 461: dbus_error_free (&tmp_error);
call 0 returned 100%
-: 462: }
-: 463:
7098: 464: if (!_dbus_string_validate_ascii (&contents, 0,
call 0 returned 100%
call 1 returned 100%
branch 2 taken 0% (fallthrough)
branch 3 taken 100%
-: 465: _dbus_string_get_length (&contents)))
-: 466: {
#####: 467: _dbus_warn ("Secret keyring file contains non-ASCII! Ignoring existing contents\n");
call 0 never executed
#####: 468: _dbus_string_set_length (&contents, 0);
call 0 never executed
-: 469: }
-: 470:
-: 471: /* FIXME this is badly inefficient for large keyring files
-: 472: * (not that large keyring files exist outside of test suites)
-: 473: */
59159: 474: while (_dbus_string_pop_line (&contents, &line))
call 0 returned 100%
branch 1 taken 89%
branch 2 taken 11% (fallthrough)
-: 475: {
-: 476: int next;
-: 477: long val;
-: 478: int id;
-: 479: long timestamp;
-: 480: int len;
-: 481: int end;
-: 482: DBusKey *new;
-: 483:
-: 484: /* Don't load more than the max. */
46389: 485: if (n_keys >= (add_new ? MAX_KEYS_IN_FILE - 1 : MAX_KEYS_IN_FILE))
branch 0 taken 7% (fallthrough)
branch 1 taken 93%
branch 2 taken 1% (fallthrough)
branch 3 taken 99%
299: 486: break;
-: 487:
46090: 488: next = 0;
46090: 489: if (!_dbus_string_parse_int (&line, 0, &val, &next))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 490: {
#####: 491: _dbus_verbose ("could not parse secret key ID at start of line\n");
call 0 never executed
#####: 492: continue;
-: 493: }
-: 494:
46090: 495: if (val > _DBUS_INT32_MAX || val < 0)
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
branch 2 taken 0% (fallthrough)
branch 3 taken 100%
-: 496: {
#####: 497: _dbus_verbose ("invalid secret key ID at start of line\n");
call 0 never executed
#####: 498: continue;
-: 499: }
-: 500:
46090: 501: id = val;
-: 502:
46090: 503: _dbus_string_skip_blank (&line, next, &next);
call 0 returned 100%
-: 504:
46090: 505: if (!_dbus_string_parse_int (&line, next, ×tamp, &next))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 506: {
#####: 507: _dbus_verbose ("could not parse secret key timestamp\n");
call 0 never executed
#####: 508: continue;
-: 509: }
-: 510:
46090: 511: if (timestamp < 0 ||
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
branch 2 taken 100% (fallthrough)
branch 3 taken 0%
branch 4 taken 0% (fallthrough)
branch 5 taken 100%
-: 512: (now + MAX_TIME_TRAVEL_SECONDS) < timestamp ||
-: 513: (now - EXPIRE_KEYS_TIMEOUT_SECONDS) > timestamp)
-: 514: {
#####: 515: _dbus_verbose ("dropping/ignoring %ld-seconds old key with timestamp %ld as current time is %ld\n",
call 0 never executed
-: 516: now - timestamp, timestamp, now);
#####: 517: continue;
-: 518: }
-: 519:
46090: 520: _dbus_string_skip_blank (&line, next, &next);
call 0 returned 100%
-: 521:
46090: 522: len = _dbus_string_get_length (&line);
call 0 returned 100%
-: 523:
46090: 524: if ((len - next) == 0)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
-: 525: {
#####: 526: _dbus_verbose ("no secret key after ID and timestamp\n");
call 0 never executed
#####: 527: continue;
-: 528: }
-: 529:
-: 530: /* We have all three parts */
46090: 531: new = dbus_realloc (keys, sizeof (DBusKey) * (n_keys + 1));
call 0 returned 100%
46090: 532: if (new == NULL)
branch 0 taken 1% (fallthrough)
branch 1 taken 99%
-: 533: {
44: 534: dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
call 0 returned 100%
44: 535: goto out;
-: 536: }
-: 537:
46046: 538: keys = new;
46046: 539: n_keys += 1;
-: 540:
46046: 541: if (!_dbus_string_init (&keys[n_keys-1].secret))
call 0 returned 100%
branch 1 taken 1% (fallthrough)
branch 2 taken 99%
-: 542: {
43: 543: n_keys -= 1; /* we don't want to free the one we didn't init */
43: 544: dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
call 0 returned 100%
43: 545: goto out;
-: 546: }
-: 547:
46003: 548: keys[n_keys-1].id = id;
46003: 549: keys[n_keys-1].creation_time = timestamp;
46003: 550: if (!_dbus_string_hex_decode (&line, next, &end,
call 0 returned 100%
branch 1 taken 2% (fallthrough)
branch 2 taken 98%
-: 551: &keys[n_keys-1].secret, 0))
-: 552: {
1040: 553: dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
call 0 returned 100%
1040: 554: goto out;
-: 555: }
-: 556:
44963: 557: if (_dbus_string_get_length (&line) != end)
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 558: {
#####: 559: _dbus_verbose ("invalid hex encoding in keyring file\n");
call 0 never executed
#####: 560: _dbus_string_free (&keys[n_keys - 1].secret);
call 0 never executed
#####: 561: n_keys -= 1;
#####: 562: continue;
-: 563: }
-: 564: }
-: 565:
5971: 566: _dbus_verbose ("Successfully loaded %d existing keys\n",
call 0 returned 100%
-: 567: n_keys);
-: 568:
5971: 569: if (add_new)
branch 0 taken 5% (fallthrough)
branch 1 taken 95%
-: 570: {
310: 571: if (!add_new_key (&keys, &n_keys, error))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 572: {
#####: 573: _dbus_verbose ("Failed to generate new key: %s\n",
branch 0 never executed
branch 1 never executed
call 2 never executed
-: 574: error ? error->message : "(unknown)");
#####: 575: goto out;
-: 576: }
-: 577:
310: 578: _dbus_string_set_length (&contents, 0);
call 0 returned 100%
-: 579:
310: 580: i = 0;
3666: 581: while (i < n_keys)
branch 0 taken 91%
branch 1 taken 9% (fallthrough)
-: 582: {
3046: 583: if (!_dbus_string_append_int (&contents,
call 0 returned 100%
branch 1 taken 100% (fallthrough)
branch 2 taken 0%
-: 584: keys[i].id))
#####: 585: goto nomem;
-: 586:
3046: 587: if (!_dbus_string_append_byte (&contents, ' '))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
#####: 588: goto nomem;
-: 589:
3046: 590: if (!_dbus_string_append_int (&contents,
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 591: keys[i].creation_time))
#####: 592: goto nomem;
-: 593:
3046: 594: if (!_dbus_string_append_byte (&contents, ' '))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
#####: 595: goto nomem;
-: 596:
3046: 597: if (!_dbus_string_hex_encode (&keys[i].secret, 0,
call 0 returned 100%
call 1 returned 100%
branch 2 taken 0% (fallthrough)
branch 3 taken 100%
-: 598: &contents,
-: 599: _dbus_string_get_length (&contents)))
#####: 600: goto nomem;
-: 601:
3046: 602: if (!_dbus_string_append_byte (&contents, '\n'))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
#####: 603: goto nomem;
-: 604:
3046: 605: ++i;
3046: 606: continue;
-: 607:
#####: 608: nomem:
#####: 609: dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
call 0 never executed
#####: 610: goto out;
-: 611: }
-: 612:
310: 613: if (!_dbus_string_save_to_file (&contents, &keyring->filename,
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 614: error))
#####: 615: goto out;
-: 616: }
-: 617:
5971: 618: if (keyring->keys)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 619: free_keys (keyring->keys, keyring->n_keys);
call 0 never executed
5971: 620: keyring->keys = keys;
5971: 621: keyring->n_keys = n_keys;
5971: 622: keys = NULL;
5971: 623: n_keys = 0;
-: 624:
5971: 625: retval = TRUE;
-: 626:
7098: 627: out:
7098: 628: if (have_lock)
branch 0 taken 4% (fallthrough)
branch 1 taken 96%
310: 629: _dbus_keyring_unlock (keyring);
call 0 returned 100%
-: 630:
7098: 631: if (! ((retval == TRUE && (error == NULL || error->name == NULL)) ||
branch 0 taken 84% (fallthrough)
branch 1 taken 16%
branch 2 taken 100% (fallthrough)
branch 3 taken 0%
branch 4 taken 0% (fallthrough)
branch 5 taken 100%
branch 6 taken 100% (fallthrough)
branch 7 taken 0%
branch 8 taken 100% (fallthrough)
branch 9 taken 0%
branch 10 taken 0% (fallthrough)
branch 11 taken 100%
-: 632: (retval == FALSE && (error == NULL || error->name != NULL))))
-: 633: {
#####: 634: if (error && error->name)
branch 0 never executed
branch 1 never executed
branch 2 never executed
branch 3 never executed
#####: 635: _dbus_verbose ("error is %s: %s\n", error->name, error->message);
call 0 never executed
#####: 636: _dbus_warn ("returning %d but error pointer %p name %s\n",
branch 0 never executed
branch 1 never executed
call 2 never executed
-: 637: retval, error, error->name ? error->name : "(none)");
#####: 638: _dbus_assert_not_reached ("didn't handle errors properly");
call 0 never executed
-: 639: }
-: 640:
7098: 641: if (keys != NULL)
branch 0 taken 16% (fallthrough)
branch 1 taken 84%
-: 642: {
1120: 643: i = 0;
8080: 644: while (i < n_keys)
branch 0 taken 84%
branch 1 taken 16% (fallthrough)
-: 645: {
5840: 646: _dbus_string_zero (&keys[i].secret);
call 0 returned 100%
5840: 647: _dbus_string_free (&keys[i].secret);
call 0 returned 100%
5840: 648: ++i;
-: 649: }
-: 650:
1120: 651: dbus_free (keys);
call 0 returned 100%
-: 652: }
-: 653:
7098: 654: _dbus_string_free (&contents);
call 0 returned 100%
7098: 655: _dbus_string_free (&line);
call 0 returned 100%
-: 656:
7098: 657: return retval;
-: 658:}
-: 659:
-: 660:/** @} */ /* end of internals */
-: 661:
-: 662:/**
-: 663: * @addtogroup DBusKeyring
-: 664: *
-: 665: * @{
-: 666: */
-: 667:
-: 668:/**
-: 669: * Increments reference count of the keyring
-: 670: *
-: 671: * @param keyring the keyring
-: 672: * @returns the keyring
-: 673: */
-: 674:DBusKeyring *
-: 675:_dbus_keyring_ref (DBusKeyring *keyring)
function _dbus_keyring_ref called 2 returned 100% blocks executed 100%
2: 676:{
2: 677: keyring->refcount += 1;
-: 678:
2: 679: return keyring;
-: 680:}
-: 681:
-: 682:/**
-: 683: * Decrements refcount and finalizes if it reaches
-: 684: * zero.
-: 685: *
-: 686: * @param keyring the keyring
-: 687: */
-: 688:void
-: 689:_dbus_keyring_unref (DBusKeyring *keyring)
function _dbus_keyring_unref called 6860 returned 100% blocks executed 100%
6860: 690:{
6860: 691: keyring->refcount -= 1;
-: 692:
6860: 693: if (keyring->refcount == 0)
branch 0 taken 99% (fallthrough)
branch 1 taken 1%
-: 694: {
6858: 695: _dbus_string_free (&keyring->username);
call 0 returned 100%
6858: 696: _dbus_string_free (&keyring->filename);
call 0 returned 100%
6858: 697: _dbus_string_free (&keyring->filename_lock);
call 0 returned 100%
6858: 698: _dbus_string_free (&keyring->directory);
call 0 returned 100%
6858: 699: free_keys (keyring->keys, keyring->n_keys);
call 0 returned 100%
6858: 700: dbus_free (keyring);
call 0 returned 100%
-: 701: }
6860: 702:}
-: 703:
-: 704:/**
-: 705: * Creates a new keyring that lives in the ~/.dbus-keyrings
-: 706: * directory of the given user. If the username is #NULL,
-: 707: * uses the user owning the current process.
-: 708: *
-: 709: * @param username username to get keyring for, or #NULL
-: 710: * @param context which keyring to get
-: 711: * @param error return location for errors
-: 712: * @returns the keyring or #NULL on error
-: 713: */
-: 714:DBusKeyring*
-: 715:_dbus_keyring_new_homedir (const DBusString *username,
-: 716: const DBusString *context,
-: 717: DBusError *error)
function _dbus_keyring_new_homedir called 6903 returned 100% blocks executed 89%
6903: 718:{
-: 719: DBusString homedir;
-: 720: DBusKeyring *keyring;
-: 721: dbus_bool_t error_set;
-: 722: DBusString dotdir;
-: 723: DBusError tmp_error;
-: 724:
6903: 725: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
call 2 returned 100%
branch 3 taken 100% (fallthrough)
branch 4 taken 0%
call 5 returned 100%
-: 726:
6903: 727: keyring = NULL;
6903: 728: error_set = FALSE;
-: 729:
6903: 730: if (!_dbus_string_init (&homedir))
call 0 returned 100%
branch 1 taken 1% (fallthrough)
branch 2 taken 99%
-: 731: {
6: 732: dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
call 0 returned 100%
6: 733: return NULL;
-: 734: }
-: 735:
6897: 736: _dbus_string_init_const (&dotdir, ".dbus-keyrings");
call 0 returned 100%
-: 737:
6897: 738: if (username == NULL)
branch 0 taken 44% (fallthrough)
branch 1 taken 56%
-: 739: {
-: 740: const DBusString *const_homedir;
-: 741:
3009: 742: if (!_dbus_username_from_current_process (&username) ||
call 0 returned 100%
branch 1 taken 100% (fallthrough)
branch 2 taken 0%
call 3 returned 100%
branch 4 taken 100% (fallthrough)
branch 5 taken 0%
-: 743: !_dbus_homedir_from_current_process (&const_homedir))
-: 744: goto failed;
-: 745:
3009: 746: if (!_dbus_string_copy (const_homedir, 0,
call 0 returned 100%
branch 1 taken 99% (fallthrough)
branch 2 taken 1%
-: 747: &homedir, 0))
3: 748: goto failed;
-: 749: }
-: 750: else
-: 751: {
3888: 752: if (!_dbus_homedir_from_username (username, &homedir))
call 0 returned 100%
branch 1 taken 1% (fallthrough)
branch 2 taken 99%
6: 753: goto failed;
-: 754: }
-: 755:
-: 756:#ifdef DBUS_BUILD_TESTS
-: 757: {
-: 758: const char *override;
-: 759:
6888: 760: override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
call 0 returned 100%
13776: 761: if (override != NULL && *override != '\0')
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
branch 2 taken 100% (fallthrough)
branch 3 taken 0%
-: 762: {
6888: 763: _dbus_string_set_length (&homedir, 0);
call 0 returned 100%
6888: 764: if (!_dbus_string_append (&homedir, override))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
#####: 765: goto failed;
-: 766:
6888: 767: _dbus_verbose ("Using fake homedir for testing: %s\n",
call 0 returned 100%
call 1 returned 100%
-: 768: _dbus_string_get_const_data (&homedir));
-: 769: }
-: 770: else
-: 771: {
-: 772: static dbus_bool_t already_warned = FALSE;
#####: 773: if (!already_warned)
branch 0 never executed
branch 1 never executed
-: 774: {
#####: 775: _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
call 0 never executed
#####: 776: already_warned = TRUE;
-: 777: }
-: 778: }
-: 779: }
-: 780:#endif
-: 781:
6888: 782: _dbus_assert (username != NULL);
call 0 returned 100%
-: 783:
6888: 784: keyring = _dbus_keyring_new ();
call 0 returned 100%
6888: 785: if (keyring == NULL)
branch 0 taken 1% (fallthrough)
branch 1 taken 99%
30: 786: goto failed;
-: 787:
-: 788: /* should have been validated already, but paranoia check here */
6858: 789: if (!_dbus_keyring_validate_context (context))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 790: {
#####: 791: error_set = TRUE;
#####: 792: dbus_set_error_const (error,
call 0 never executed
-: 793: DBUS_ERROR_FAILED,
-: 794: "Invalid context in keyring creation");
#####: 795: goto failed;
-: 796: }
-: 797:
6858: 798: if (!_dbus_string_copy (username, 0,
call 0 returned 100%
branch 1 taken 1% (fallthrough)
branch 2 taken 99%
-: 799: &keyring->username, 0))
6: 800: goto failed;
-: 801:
6852: 802: if (!_dbus_string_copy (&homedir, 0,
call 0 returned 100%
branch 1 taken 1% (fallthrough)
branch 2 taken 99%
-: 803: &keyring->directory, 0))
6: 804: goto failed;
-: 805:
6846: 806: if (!_dbus_concat_dir_and_file (&keyring->directory,
call 0 returned 100%
branch 1 taken 1% (fallthrough)
branch 2 taken 99%
-: 807: &dotdir))
11: 808: goto failed;
-: 809:
6835: 810: if (!_dbus_string_copy (&keyring->directory, 0,
call 0 returned 100%
branch 1 taken 1% (fallthrough)
branch 2 taken 99%
-: 811: &keyring->filename, 0))
8: 812: goto failed;
-: 813:
6827: 814: if (!_dbus_concat_dir_and_file (&keyring->filename,
call 0 returned 100%
branch 1 taken 1% (fallthrough)
branch 2 taken 99%
-: 815: context))
13: 816: goto failed;
-: 817:
6814: 818: if (!_dbus_string_copy (&keyring->filename, 0,
call 0 returned 100%
branch 1 taken 1% (fallthrough)
branch 2 taken 99%
-: 819: &keyring->filename_lock, 0))
4: 820: goto failed;
-: 821:
6810: 822: if (!_dbus_string_append (&keyring->filename_lock, ".lock"))
call 0 returned 100%
branch 1 taken 1% (fallthrough)
branch 2 taken 99%
8: 823: goto failed;
-: 824:
6802: 825: dbus_error_init (&tmp_error);
call 0 returned 100%
6802: 826: if (!_dbus_keyring_reload (keyring, FALSE, &tmp_error))
call 0 returned 100%
branch 1 taken 17% (fallthrough)
branch 2 taken 83%
-: 827: {
1141: 828: _dbus_verbose ("didn't load an existing keyring: %s\n",
call 0 returned 100%
-: 829: tmp_error.message);
1141: 830: dbus_error_free (&tmp_error);
call 0 returned 100%
-: 831: }
-: 832:
-: 833: /* We don't fail fatally if we can't create the directory,
-: 834: * but the keyring will probably always be empty
-: 835: * unless someone else manages to create it
-: 836: */
6802: 837: dbus_error_init (&tmp_error);
call 0 returned 100%
6802: 838: if (!_dbus_create_directory (&keyring->directory,
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 839: &tmp_error))
-: 840: {
#####: 841: _dbus_verbose ("Creating keyring directory: %s\n",
call 0 never executed
-: 842: tmp_error.message);
#####: 843: dbus_error_free (&tmp_error);
call 0 never executed
-: 844: }
-: 845:
6802: 846: _dbus_string_free (&homedir);
call 0 returned 100%
-: 847:
6802: 848: return keyring;
-: 849:
95: 850: failed:
95: 851: if (!error_set)
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
95: 852: dbus_set_error_const (error,
call 0 returned 100%
-: 853: DBUS_ERROR_NO_MEMORY,
-: 854: NULL);
95: 855: if (keyring)
branch 0 taken 59% (fallthrough)
branch 1 taken 41%
56: 856: _dbus_keyring_unref (keyring);
call 0 returned 100%
95: 857: _dbus_string_free (&homedir);
call 0 returned 100%
95: 858: return NULL;
-: 859:
-: 860:}
-: 861:
-: 862:/**
-: 863: * Checks whether the context is a valid context.
-: 864: * Contexts that might cause confusion when used
-: 865: * in filenames are not allowed (contexts can't
-: 866: * start with a dot or contain dir separators).
-: 867: *
-: 868: * @todo this is the most inefficient implementation
-: 869: * imaginable.
-: 870: *
-: 871: * @param context the context
-: 872: * @returns #TRUE if valid
-: 873: */
-: 874:dbus_bool_t
-: 875:_dbus_keyring_validate_context (const DBusString *context)
function _dbus_keyring_validate_context called 11016 returned 100% blocks executed 89%
11016: 876:{
11016: 877: if (_dbus_string_get_length (context) == 0)
call 0 returned 100%
branch 1 taken 1% (fallthrough)
branch 2 taken 99%
-: 878: {
1: 879: _dbus_verbose ("context is zero-length\n");
call 0 returned 100%
1: 880: return FALSE;
-: 881: }
-: 882:
11015: 883: if (!_dbus_string_validate_ascii (context, 0,
call 0 returned 100%
call 1 returned 100%
branch 2 taken 1% (fallthrough)
branch 3 taken 99%
-: 884: _dbus_string_get_length (context)))
-: 885: {
3: 886: _dbus_verbose ("context not valid ascii\n");
call 0 returned 100%
3: 887: return FALSE;
-: 888: }
-: 889:
-: 890: /* no directory separators */
11012: 891: if (_dbus_string_find (context, 0, "/", NULL))
call 0 returned 100%
branch 1 taken 1% (fallthrough)
branch 2 taken 99%
-: 892: {
1: 893: _dbus_verbose ("context contains a slash\n");
call 0 returned 100%
1: 894: return FALSE;
-: 895: }
-: 896:
11011: 897: if (_dbus_string_find (context, 0, "\\", NULL))
call 0 returned 100%
branch 1 taken 1% (fallthrough)
branch 2 taken 99%
-: 898: {
1: 899: _dbus_verbose ("context contains a backslash\n");
call 0 returned 100%
1: 900: return FALSE;
-: 901: }
-: 902:
-: 903: /* prevent attempts to use dotfiles or ".." or ".lock"
-: 904: * all of which might allow some kind of attack
-: 905: */
11010: 906: if (_dbus_string_find (context, 0, ".", NULL))
call 0 returned 100%
branch 1 taken 1% (fallthrough)
branch 2 taken 99%
-: 907: {
2: 908: _dbus_verbose ("context contains a dot\n");
call 0 returned 100%
2: 909: return FALSE;
-: 910: }
-: 911:
-: 912: /* no spaces/tabs, those are used for separators in the protocol */
11008: 913: if (_dbus_string_find_blank (context, 0, NULL))
call 0 returned 100%
branch 1 taken 1% (fallthrough)
branch 2 taken 99%
-: 914: {
1: 915: _dbus_verbose ("context contains a blank\n");
call 0 returned 100%
1: 916: return FALSE;
-: 917: }
-: 918:
11007: 919: if (_dbus_string_find (context, 0, "\n", NULL))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 920: {
#####: 921: _dbus_verbose ("context contains a newline\n");
call 0 never executed
#####: 922: return FALSE;
-: 923: }
-: 924:
11007: 925: if (_dbus_string_find (context, 0, "\r", NULL))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 926: {
#####: 927: _dbus_verbose ("context contains a carriage return\n");
call 0 never executed
#####: 928: return FALSE;
-: 929: }
-: 930:
11007: 931: return TRUE;
-: 932:}
-: 933:
-: 934:static DBusKey*
-: 935:find_recent_key (DBusKeyring *keyring)
function find_recent_key called 4158 returned 100% blocks executed 89%
4158: 936:{
-: 937: int i;
-: 938: long tv_sec, tv_usec;
-: 939:
4158: 940: _dbus_get_current_time (&tv_sec, &tv_usec);
call 0 returned 100%
-: 941:
4158: 942: i = 0;
8316: 943: while (i < keyring->n_keys)
branch 0 taken 86%
branch 1 taken 14% (fallthrough)
-: 944: {
3573: 945: DBusKey *key = &keyring->keys[i];
-: 946:
3573: 947: _dbus_verbose ("Key %d is %ld seconds old\n",
call 0 returned 100%
-: 948: i, tv_sec - key->creation_time);
-: 949:
3573: 950: if ((tv_sec - NEW_KEY_TIMEOUT_SECONDS) < key->creation_time)
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
3573: 951: return key;
-: 952:
#####: 953: ++i;
-: 954: }
-: 955:
585: 956: return NULL;
-: 957:}
-: 958:
-: 959:/**
-: 960: * Gets a recent key to use for authentication.
-: 961: * If no recent key exists, creates one. Returns
-: 962: * the key ID. If a key can't be written to the keyring
-: 963: * file so no recent key can be created, returns -1.
-: 964: * All valid keys are > 0.
-: 965: *
-: 966: * @param keyring the keyring
-: 967: * @param error error on failure
-: 968: * @returns key ID to use for auth, or -1 on failure
-: 969: */
-: 970:int
-: 971:_dbus_keyring_get_best_key (DBusKeyring *keyring,
-: 972: DBusError *error)
function _dbus_keyring_get_best_key called 3848 returned 100% blocks executed 83%
3848: 973:{
-: 974: DBusKey *key;
-: 975:
3848: 976: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
call 2 returned 100%
branch 3 taken 100% (fallthrough)
branch 4 taken 0%
call 5 returned 100%
-: 977:
3848: 978: key = find_recent_key (keyring);
call 0 returned 100%
3848: 979: if (key)
branch 0 taken 85% (fallthrough)
branch 1 taken 15%
3263: 980: return key->id;
-: 981:
-: 982: /* All our keys are too old, or we've never loaded the
-: 983: * keyring. Create a new one.
-: 984: */
585: 985: if (!_dbus_keyring_reload (keyring, TRUE,
call 0 returned 100%
branch 1 taken 47% (fallthrough)
branch 2 taken 53%
-: 986: error))
275: 987: return -1;
-: 988:
310: 989: key = find_recent_key (keyring);
call 0 returned 100%
310: 990: if (key)
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
310: 991: return key->id;
-: 992: else
-: 993: {
#####: 994: dbus_set_error_const (error,
call 0 never executed
-: 995: DBUS_ERROR_FAILED,
-: 996: "No recent-enough key found in keyring, and unable to create a new key");
#####: 997: return -1;
-: 998: }
-: 999:}
-: 1000:
-: 1001:/**
-: 1002: * Checks whether the keyring is for the given username.
-: 1003: *
-: 1004: * @param keyring the keyring
-: 1005: * @param username the username to check
-: 1006: *
-: 1007: * @returns #TRUE if the keyring belongs to the given user
-: 1008: */
-: 1009:dbus_bool_t
-: 1010:_dbus_keyring_is_for_user (DBusKeyring *keyring,
-: 1011: const DBusString *username)
function _dbus_keyring_is_for_user called 0 returned 0% blocks executed 0%
#####: 1012:{
#####: 1013: return _dbus_string_equal (&keyring->username,
call 0 never executed
-: 1014: username);
-: 1015:}
-: 1016:
-: 1017:/**
-: 1018: * Gets the hex-encoded secret key for the given ID.
-: 1019: * Returns #FALSE if not enough memory. Returns #TRUE
-: 1020: * but empty key on any other error such as unknown
-: 1021: * key ID.
-: 1022: *
-: 1023: * @param keyring the keyring
-: 1024: * @param key_id the key ID
-: 1025: * @param hex_key string to append hex-encoded key to
-: 1026: * @returns #TRUE if we had enough memory
-: 1027: */
-: 1028:dbus_bool_t
-: 1029:_dbus_keyring_get_hex_key (DBusKeyring *keyring,
-: 1030: int key_id,
-: 1031: DBusString *hex_key)
function _dbus_keyring_get_hex_key called 6194 returned 100% blocks executed 100%
6194: 1032:{
-: 1033: DBusKey *key;
-: 1034:
6194: 1035: key = find_key_by_id (keyring->keys,
call 0 returned 100%
-: 1036: keyring->n_keys,
-: 1037: key_id);
6194: 1038: if (key == NULL)
branch 0 taken 9% (fallthrough)
branch 1 taken 91%
569: 1039: return TRUE; /* had enough memory, so TRUE */
-: 1040:
5625: 1041: return _dbus_string_hex_encode (&key->secret, 0,
call 0 returned 100%
call 1 returned 100%
-: 1042: hex_key,
-: 1043: _dbus_string_get_length (hex_key));
-: 1044:}
-: 1045:
-: 1046:/** @} */ /* end of exposed API */
-: 1047:
-: 1048:#ifdef DBUS_BUILD_TESTS
-: 1049:#include "dbus-test.h"
-: 1050:#include <stdio.h>
-: 1051:
-: 1052:dbus_bool_t
-: 1053:_dbus_keyring_test (void)
function _dbus_keyring_test called 1 returned 100% blocks executed 79%
1: 1054:{
-: 1055: DBusString context;
-: 1056: DBusKeyring *ring1;
-: 1057: DBusKeyring *ring2;
-: 1058: int id;
-: 1059: DBusError error;
-: 1060: int i;
-: 1061:
1: 1062: ring1 = NULL;
1: 1063: ring2 = NULL;
-: 1064:
-: 1065: /* Context validation */
-: 1066:
1: 1067: _dbus_string_init_const (&context, "foo");
call 0 returned 100%
1: 1068: _dbus_assert (_dbus_keyring_validate_context (&context));
call 0 returned 100%
call 1 returned 100%
1: 1069: _dbus_string_init_const (&context, "org_freedesktop_blah");
call 0 returned 100%
1: 1070: _dbus_assert (_dbus_keyring_validate_context (&context));
call 0 returned 100%
call 1 returned 100%
-: 1071:
1: 1072: _dbus_string_init_const (&context, "");
call 0 returned 100%
1: 1073: _dbus_assert (!_dbus_keyring_validate_context (&context));
call 0 returned 100%
call 1 returned 100%
1: 1074: _dbus_string_init_const (&context, ".foo");
call 0 returned 100%
1: 1075: _dbus_assert (!_dbus_keyring_validate_context (&context));
call 0 returned 100%
call 1 returned 100%
1: 1076: _dbus_string_init_const (&context, "bar.foo");
call 0 returned 100%
1: 1077: _dbus_assert (!_dbus_keyring_validate_context (&context));
call 0 returned 100%
call 1 returned 100%
1: 1078: _dbus_string_init_const (&context, "bar/foo");
call 0 returned 100%
1: 1079: _dbus_assert (!_dbus_keyring_validate_context (&context));
call 0 returned 100%
call 1 returned 100%
1: 1080: _dbus_string_init_const (&context, "bar\\foo");
call 0 returned 100%
1: 1081: _dbus_assert (!_dbus_keyring_validate_context (&context));
call 0 returned 100%
call 1 returned 100%
1: 1082: _dbus_string_init_const (&context, "foo\xfa\xf0");
call 0 returned 100%
1: 1083: _dbus_assert (!_dbus_keyring_validate_context (&context));
call 0 returned 100%
call 1 returned 100%
1: 1084: _dbus_string_init_const (&context, "foo\x80");
call 0 returned 100%
1: 1085: _dbus_assert (!_dbus_keyring_validate_context (&context));
call 0 returned 100%
call 1 returned 100%
1: 1086: _dbus_string_init_const (&context, "foo\x7f");
call 0 returned 100%
1: 1087: _dbus_assert (_dbus_keyring_validate_context (&context));
call 0 returned 100%
call 1 returned 100%
1: 1088: _dbus_string_init_const (&context, "foo bar");
call 0 returned 100%
1: 1089: _dbus_assert (!_dbus_keyring_validate_context (&context));
call 0 returned 100%
call 1 returned 100%
-: 1090:
1: 1091: if (!_dbus_string_init (&context))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
#####: 1092: _dbus_assert_not_reached ("no memory");
call 0 never executed
1: 1093: if (!_dbus_string_append_byte (&context, '\0'))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
#####: 1094: _dbus_assert_not_reached ("no memory");
call 0 never executed
1: 1095: _dbus_assert (!_dbus_keyring_validate_context (&context));
call 0 returned 100%
call 1 returned 100%
1: 1096: _dbus_string_free (&context);
call 0 returned 100%
-: 1097:
-: 1098: /* Now verify that if we create a key in keyring 1,
-: 1099: * it is properly loaded in keyring 2
-: 1100: */
-: 1101:
1: 1102: _dbus_string_init_const (&context, "org_freedesktop_dbus_testsuite");
call 0 returned 100%
1: 1103: dbus_error_init (&error);
call 0 returned 100%
1: 1104: ring1 = _dbus_keyring_new_homedir (NULL, &context,
call 0 returned 100%
-: 1105: &error);
1: 1106: _dbus_assert (ring1);
call 0 returned 100%
1: 1107: _dbus_assert (error.name == NULL);
call 0 returned 100%
-: 1108:
1: 1109: id = _dbus_keyring_get_best_key (ring1, &error);
call 0 returned 100%
1: 1110: if (id < 0)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
-: 1111: {
#####: 1112: fprintf (stderr, "Could not load keyring: %s\n", error.message);
call 0 never executed
#####: 1113: dbus_error_free (&error);
call 0 never executed
#####: 1114: goto failure;
-: 1115: }
-: 1116:
1: 1117: ring2 = _dbus_keyring_new_homedir (NULL, &context, &error);
call 0 returned 100%
1: 1118: _dbus_assert (ring2);
call 0 returned 100%
1: 1119: _dbus_assert (error.name == NULL);
call 0 returned 100%
-: 1120:
1: 1121: if (ring1->n_keys != ring2->n_keys)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
-: 1122: {
#####: 1123: fprintf (stderr, "Different number of keys in keyrings\n");
call 0 never executed
#####: 1124: goto failure;
-: 1125: }
-: 1126:
-: 1127: /* We guarantee we load and save keeping keys in a fixed
-: 1128: * order
-: 1129: */
1: 1130: i = 0;
3: 1131: while (i < ring1->n_keys)
branch 0 taken 50%
branch 1 taken 50% (fallthrough)
-: 1132: {
1: 1133: if (ring1->keys[i].id != ring2->keys[i].id)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
-: 1134: {
#####: 1135: fprintf (stderr, "Keyring 1 has first key ID %d and keyring 2 has %d\n",
call 0 never executed
-: 1136: ring1->keys[i].id, ring2->keys[i].id);
#####: 1137: goto failure;
-: 1138: }
-: 1139:
1: 1140: if (ring1->keys[i].creation_time != ring2->keys[i].creation_time)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
-: 1141: {
#####: 1142: fprintf (stderr, "Keyring 1 has first key time %ld and keyring 2 has %ld\n",
call 0 never executed
-: 1143: ring1->keys[i].creation_time, ring2->keys[i].creation_time);
#####: 1144: goto failure;
-: 1145: }
-: 1146:
1: 1147: if (!_dbus_string_equal (&ring1->keys[i].secret,
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 1148: &ring2->keys[i].secret))
-: 1149: {
#####: 1150: fprintf (stderr, "Keyrings 1 and 2 have different secrets for same ID/timestamp\n");
call 0 never executed
#####: 1151: goto failure;
-: 1152: }
-: 1153:
1: 1154: ++i;
-: 1155: }
-: 1156:
1: 1157: printf (" %d keys in test\n", ring1->n_keys);
call 0 returned 100%
-: 1158:
-: 1159: /* Test ref/unref */
1: 1160: _dbus_keyring_ref (ring1);
call 0 returned 100%
1: 1161: _dbus_keyring_ref (ring2);
call 0 returned 100%
1: 1162: _dbus_keyring_unref (ring1);
call 0 returned 100%
1: 1163: _dbus_keyring_unref (ring2);
call 0 returned 100%
-: 1164:
-: 1165:
-: 1166: /* really unref */
1: 1167: _dbus_keyring_unref (ring1);
call 0 returned 100%
1: 1168: _dbus_keyring_unref (ring2);
call 0 returned 100%
-: 1169:
1: 1170: return TRUE;
-: 1171:
#####: 1172: failure:
#####: 1173: if (ring1)
branch 0 never executed
branch 1 never executed
#####: 1174: _dbus_keyring_unref (ring1);
call 0 never executed
#####: 1175: if (ring2)
branch 0 never executed
branch 1 never executed
#####: 1176: _dbus_keyring_unref (ring2);
call 0 never executed
-: 1177:
#####: 1178: return FALSE;
-: 1179:}
-: 1180:
-: 1181:#endif /* DBUS_BUILD_TESTS */
-: 1182: