index.html
Main Page
|
modules.html
Modules
|
namespaces.html
Namespace List
|
hierarchy.html
Class Hierarchy
|
annotated.html
Data Structures
|
dirs.html
Directories
|
files.html
File List
|
namespacemembers.html
Namespace Members
|
functions.html
Data Fields
|
pages.html
Related Pages
dir_000004.html
dbus
dbus-keyring.c
00001
/* -*- mode: C; c-file-style: "gnu" -*- */
00002
/* dbus-keyring.c Store secret cookies in your homedir
00003
*
00004
* Copyright (C) 2003, 2004  Red Hat Inc.
00005
*
00006
* Licensed under the Academic Free License version 2.1
00007
*
00008
* This program is free software; you can redistribute it and/or modify
00009
* it under the terms of the GNU General Public License as published by
00010
* the Free Software Foundation; either version 2 of the License, or
00011
* (at your option) any later version.
00012
*
00013
* This program is distributed in the hope that it will be useful,
00014
* but WITHOUT ANY WARRANTY; without even the implied warranty of
00015
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016
* GNU General Public License for more details.
00017
*
00018
* You should have received a copy of the GNU General Public License
00019
* along with this program; if not, write to the Free Software
00020
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021
*
00022
*/
00023
00024
#include "dbus-keyring.h"
00025
#include "dbus-userdb.h"
00026
#include "dbus-protocol.h"
00027
#include <dbus/dbus-string.h>
00028
#include <dbus/dbus-list.h>
00029
#include <dbus/dbus-sysdeps.h>
00030
group__DBusKeyringInternals.html#ga7
00067
#define NEW_KEY_TIMEOUT_SECONDS     (60*5)
00068
group__DBusKeyringInternals.html#ga8
00073
#define EXPIRE_KEYS_TIMEOUT_SECONDS (NEW_KEY_TIMEOUT_SECONDS + (60*2))
00074
group__DBusKeyringInternals.html#ga9
00077
#define MAX_TIME_TRAVEL_SECONDS (60*5)
00078
00083
#ifdef DBUS_BUILD_TESTS
00084
#define MAX_KEYS_IN_FILE 10
00085
#else
group__DBusKeyringInternals.html#ga10
00086
#define MAX_KEYS_IN_FILE 256
00087
#endif
00088
structDBusKey.html
00092
typedef
struct
00093
{
structDBusKey.html#o0
00094
group__DBusTypes.html#ga4
dbus_int32_t
id;
structDBusKey.html#o1
00096
long
creation_time;
structDBusKey.html#o2
00101
structDBusString.html
DBusString
secret;
00103 }
structDBusKey.html
DBusKey
;
00104
structDBusKeyring.html
00111
struct
structDBusKeyring.html
DBusKeyring
00112 {
structDBusKeyring.html#o0
00113
int
structDBusKeyring.html#o0
refcount
;
structDBusKeyring.html#o1
00114
structDBusString.html
DBusString
structDBusKeyring.html#o1
username
;
structDBusKeyring.html#o2
00115
structDBusString.html
DBusString
structDBusKeyring.html#o2
directory
;
structDBusKeyring.html#o3
00116
structDBusString.html
DBusString
structDBusKeyring.html#o3
filename
;
structDBusKeyring.html#o4
00117
structDBusString.html
DBusString
structDBusKeyring.html#o4
filename_lock
;
structDBusKeyring.html#o5
00118
structDBusKey.html
DBusKey
*
structDBusKeyring.html#o5
keys
;
structDBusKeyring.html#o6
00119
int
structDBusKeyring.html#o6
n_keys
;
00120 };
00121
00122
static
structDBusKeyring.html
DBusKeyring
*
00123 _dbus_keyring_new (
void
)
00124 {
00125
structDBusKeyring.html
DBusKeyring
*keyring;
00126
00127   keyring =
group__DBusMemory.html#ga7
dbus_new0
(
structDBusKeyring.html
DBusKeyring
, 1);
00128
if
(keyring ==
group__DBusMacros.html#ga4
NULL
)
00129
goto
out_0;
00130
00131
if
(!
group__DBusString.html#ga6
_dbus_string_init
(&keyring->
structDBusKeyring.html#o2
directory
))
00132
goto
out_1;
00133
00134
if
(!
group__DBusString.html#ga6
_dbus_string_init
(&keyring->
structDBusKeyring.html#o3
filename
))
00135
goto
out_2;
00136
00137
if
(!
group__DBusString.html#ga6
_dbus_string_init
(&keyring->
structDBusKeyring.html#o4
filename_lock
))
00138
goto
out_3;
00139
00140
if
(!
group__DBusString.html#ga6
_dbus_string_init
(&keyring->
structDBusKeyring.html#o1
username
))
00141
goto
out_4;
00142
00143   keyring->
structDBusKeyring.html#o0
refcount
= 1;
00144   keyring->
structDBusKeyring.html#o5
keys
=
group__DBusMacros.html#ga4
NULL
;
00145   keyring->
structDBusKeyring.html#o6
n_keys
= 0;
00146
00147
return
keyring;
00148
00149  out_4:
00150
group__DBusString.html#ga9
_dbus_string_free
(&keyring->
structDBusKeyring.html#o4
filename_lock
);
00151  out_3:
00152
group__DBusString.html#ga9
_dbus_string_free
(&keyring->
structDBusKeyring.html#o3
filename
);
00153  out_2:
00154
group__DBusString.html#ga9
_dbus_string_free
(&keyring->
structDBusKeyring.html#o2
directory
);
00155  out_1:
00156
group__DBusMemory.html#ga3
dbus_free
(keyring);
00157  out_0:
00158
return
group__DBusMacros.html#ga4
NULL
;
00159 }
00160
00161
static
void
00162 free_keys (
structDBusKey.html
DBusKey
*keys,
00163
int
n_keys)
00164 {
00165
int
i;
00166
00167
/* should be safe for args NULL, 0 */
00168
00169   i = 0;
00170
while
(i < n_keys)
00171     {
00172
group__DBusString.html#ga9
_dbus_string_free
(&keys[i].secret);
00173       ++i;
00174     }
00175
00176
group__DBusMemory.html#ga3
dbus_free
(keys);
00177 }
00178
00179
/* Our locking scheme is highly unreliable.  However, there is
00180
* unfortunately no reliable locking scheme in user home directories;
00181
* between bugs in Linux NFS, people using Tru64 or other total crap
00182
* NFS, AFS, random-file-system-of-the-week, and so forth, fcntl() in
00183
* homedirs simply generates tons of bug reports. This has been
00184
* learned through hard experience with GConf, unfortunately.
00185
*
00186
* This bad hack might work better for the kind of lock we have here,
00187
* which we don't expect to hold for any length of time.  Crashing
00188
* while we hold it should be unlikely, and timing out such that we
00189
* delete a stale lock should also be unlikely except when the
00190
* filesystem is running really slowly.  Stuff might break in corner
00191
* cases but as long as it's not a security-level breakage it should
00192
* be OK.
00193
*/
00194
group__DBusKeyringInternals.html#ga11
00196
#define MAX_LOCK_TIMEOUTS 32
00197
group__DBusKeyringInternals.html#ga12
00198
#define LOCK_TIMEOUT_MILLISECONDS 250
00199
00200
static
group__DBusTypes.html#ga2
dbus_bool_t
00201 _dbus_keyring_lock (
structDBusKeyring.html
DBusKeyring
*keyring)
00202 {
00203
int
n_timeouts;
00204
00205   n_timeouts = 0;
00206
while
(n_timeouts <
group__DBusKeyringInternals.html#ga11
MAX_LOCK_TIMEOUTS
)
00207     {
00208
structDBusError.html
DBusError
error;
00209
00210
group__DBusErrors.html#ga0
dbus_error_init
(&error);
00211
if
(
group__DBusInternalsUtils.html#ga87
_dbus_create_file_exclusively
(&keyring->
structDBusKeyring.html#o4
filename_lock
,
00212                                          &error))
00213
break
;
00214
00215       _dbus_verbose (
"Did not get lock file, sleeping %d milliseconds (%s)\n"
,
00216
group__DBusKeyringInternals.html#ga12
LOCK_TIMEOUT_MILLISECONDS
, error.
structDBusError.html#o1
message
);
00217
group__DBusErrors.html#ga1
dbus_error_free
(&error);
00218
00219
group__DBusInternalsUtils.html#ga83
_dbus_sleep_milliseconds
(
group__DBusKeyringInternals.html#ga12
LOCK_TIMEOUT_MILLISECONDS
);
00220
00221       ++n_timeouts;
00222     }
00223
00224
if
(n_timeouts ==
group__DBusKeyringInternals.html#ga11
MAX_LOCK_TIMEOUTS
)
00225     {
00226
structDBusError.html
DBusError
error;
00227
00228       _dbus_verbose (
"Lock file timed out %d times, assuming stale\n"
,
00229                      n_timeouts);
00230
00231
group__DBusErrors.html#ga0
dbus_error_init
(&error);
00232
00233
if
(!
group__DBusInternalsUtils.html#ga88
_dbus_delete_file
(&keyring->
structDBusKeyring.html#o4
filename_lock
, &error))
00234         {
00235           _dbus_verbose (
"Couldn't delete old lock file: %s\n"
,
00236                          error.
structDBusError.html#o1
message
);
00237
group__DBusErrors.html#ga1
dbus_error_free
(&error);
00238
return
group__DBusMacros.html#ga3
FALSE
;
00239         }
00240
00241
if
(!
group__DBusInternalsUtils.html#ga87
_dbus_create_file_exclusively
(&keyring->
structDBusKeyring.html#o4
filename_lock
,
00242                                           &error))
00243         {
00244           _dbus_verbose (
"Couldn't create lock file after deleting stale one: %s\n"
,
00245                          error.
structDBusError.html#o1
message
);
00246
group__DBusErrors.html#ga1
dbus_error_free
(&error);
00247
return
group__DBusMacros.html#ga3
FALSE
;
00248         }
00249     }
00250
00251
return
group__DBusMacros.html#ga2
TRUE
;
00252 }
00253
00254
static
void
00255 _dbus_keyring_unlock (
structDBusKeyring.html
DBusKeyring
*keyring)
00256 {
00257
structDBusError.html
DBusError
error;
00258
group__DBusErrors.html#ga0
dbus_error_init
(&error);
00259
if
(!
group__DBusInternalsUtils.html#ga88
_dbus_delete_file
(&keyring->
structDBusKeyring.html#o4
filename_lock
, &error))
00260     {
00261
group__DBusInternalsUtils.html#ga7
_dbus_warn
(
"Failed to delete lock file: %s\n"
,
00262                   error.
structDBusError.html#o1
message
);
00263
group__DBusErrors.html#ga1
dbus_error_free
(&error);
00264     }
00265 }
00266
00267
static
structDBusKey.html
DBusKey
*
00268 find_key_by_id (
structDBusKey.html
DBusKey
*keys,
00269
int
n_keys,
00270
int
id
)
00271 {
00272
int
i;
00273
00274   i = 0;
00275
while
(i < n_keys)
00276     {
00277
if
(keys[i].
id
==
id
)
00278
return
&keys[i];
00279
00280       ++i;
00281     }
00282
00283
return
group__DBusMacros.html#ga4
NULL
;
00284 }
00285
00286
static
group__DBusTypes.html#ga2
dbus_bool_t
00287 add_new_key (
structDBusKey.html
DBusKey
**keys_p,
00288
int
*n_keys_p,
00289
structDBusError.html
DBusError
*error)
00290 {
00291
structDBusKey.html
DBusKey
*
new
;
00292
structDBusString.html
DBusString
bytes;
00293
int
id;
00294
long
timestamp;
00295
const
unsigned
char
*s;
00296
group__DBusTypes.html#ga2
dbus_bool_t
retval;
00297
structDBusKey.html
DBusKey
*keys;
00298
int
n_keys;
00299
00300   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00301
00302
if
(!
group__DBusString.html#ga6
_dbus_string_init
(&bytes))
00303     {
00304
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_NO_MEMORY,
group__DBusMacros.html#ga4
NULL
);
00305
return
group__DBusMacros.html#ga3
FALSE
;
00306     }
00307
00308   keys = *keys_p;
00309   n_keys = *n_keys_p;
00310   retval =
group__DBusMacros.html#ga3
FALSE
;
00311
00312
/* Generate an integer ID and then the actual key. */
00313  retry:
00314
00315
if
(!
group__DBusInternalsUtils.html#ga94
_dbus_generate_random_bytes
(&bytes, 4))
00316     {
00317
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_NO_MEMORY,
group__DBusMacros.html#ga4
NULL
);
00318
goto
out;
00319     }
00320
00321   s = (
const
unsigned
char
*) _dbus_string_get_const_data (&bytes);
00322
00323
id
= s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24);
00324
if
(
id
< 0)
00325
id
= - id;
00326
group__DBusInternalsUtils.html#ga130
_dbus_assert
(
id
>= 0);
00327
00328
if
(find_key_by_id (keys, n_keys,
id
) !=
group__DBusMacros.html#ga4
NULL
)
00329     {
00330
group__DBusString.html#ga21
_dbus_string_set_length
(&bytes, 0);
00331       _dbus_verbose (
"Key ID %d already existed, trying another one\n"
,
00332
id
);
00333
goto
retry;
00334     }
00335
00336   _dbus_verbose (
"Creating key with ID %d\n"
,
id
);
00337
00338
#define KEY_LENGTH_BYTES 24
00339
group__DBusString.html#ga21
_dbus_string_set_length
(&bytes, 0);
00340
if
(!
group__DBusInternalsUtils.html#ga94
_dbus_generate_random_bytes
(&bytes, KEY_LENGTH_BYTES))
00341     {
00342
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_NO_MEMORY,
group__DBusMacros.html#ga4
NULL
);
00343
goto
out;
00344     }
00345
00346
new
=
group__DBusMemory.html#ga2
dbus_realloc
(keys,
sizeof
(
structDBusKey.html
DBusKey
) * (n_keys + 1));
00347
if
(
new
==
group__DBusMacros.html#ga4
NULL
)
00348     {
00349
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_NO_MEMORY,
group__DBusMacros.html#ga4
NULL
);
00350
goto
out;
00351     }
00352
00353   keys =
new
;
00354   *keys_p = keys;
/* otherwise *keys_p ends up invalid */
00355   n_keys += 1;
00356
00357
if
(!
group__DBusString.html#ga6
_dbus_string_init
(&keys[n_keys-1].secret))
00358     {
00359       n_keys -= 1;
/* we don't want to free the one we didn't init */
00360
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_NO_MEMORY,
group__DBusMacros.html#ga4
NULL
);
00361
goto
out;
00362     }
00363
00364
group__DBusInternalsUtils.html#ga84
_dbus_get_current_time
(&timestamp,
group__DBusMacros.html#ga4
NULL
);
00365
00366   keys[n_keys-1].id = id;
00367   keys[n_keys-1].creation_time = timestamp;
00368
if
(!
group__DBusString.html#ga39
_dbus_string_move
(&bytes, 0,
00369                           &keys[n_keys-1].secret,
00370                           0))
00371     {
00372
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_NO_MEMORY,
group__DBusMacros.html#ga4
NULL
);
00373
group__DBusString.html#ga9
_dbus_string_free
(&keys[n_keys-1].secret);
00374       n_keys -= 1;
00375
goto
out;
00376     }
00377
00378   retval =
group__DBusMacros.html#ga2
TRUE
;
00379
00380  out:
00381   *n_keys_p = n_keys;
00382
00383
group__DBusString.html#ga9
_dbus_string_free
(&bytes);
00384
return
retval;
00385 }
00386
00401
static
group__DBusTypes.html#ga2
dbus_bool_t
00402 _dbus_keyring_reload (
structDBusKeyring.html
DBusKeyring
*keyring,
00403
group__DBusTypes.html#ga2
dbus_bool_t
add_new,
00404
structDBusError.html
DBusError
*error)
00405 {
00406
structDBusString.html
DBusString
contents;
00407
structDBusString.html
DBusString
line;
00408
group__DBusTypes.html#ga2
dbus_bool_t
retval;
00409
group__DBusTypes.html#ga2
dbus_bool_t
have_lock;
00410   DBusKey *keys;
00411
int
n_keys;
00412
int
i;
00413
long
now;
00414
structDBusError.html
DBusError
tmp_error;
00415
00416   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00417
00418
if
(!
group__DBusString.html#ga63
_dbus_check_dir_is_private_to_user
(&keyring->
structDBusKeyring.html#o2
directory
, error))
00419
return
group__DBusMacros.html#ga3
FALSE
;
00420
00421
if
(!
group__DBusString.html#ga6
_dbus_string_init
(&contents))
00422     {
00423
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_NO_MEMORY,
group__DBusMacros.html#ga4
NULL
);
00424
return
group__DBusMacros.html#ga3
FALSE
;
00425     }
00426
00427
if
(!
group__DBusString.html#ga6
_dbus_string_init
(&line))
00428     {
00429
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_NO_MEMORY,
group__DBusMacros.html#ga4
NULL
);
00430
group__DBusString.html#ga9
_dbus_string_free
(&contents);
00431
return
group__DBusMacros.html#ga3
FALSE
;
00432     }
00433
00434   keys =
group__DBusMacros.html#ga4
NULL
;
00435   n_keys = 0;
00436   retval =
group__DBusMacros.html#ga3
FALSE
;
00437   have_lock =
group__DBusMacros.html#ga3
FALSE
;
00438
00439
group__DBusInternalsUtils.html#ga84
_dbus_get_current_time
(&now,
group__DBusMacros.html#ga4
NULL
);
00440
00441
if
(add_new)
00442     {
00443
if
(!_dbus_keyring_lock (keyring))
00444         {
00445
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_FAILED,
00446
"Could not lock keyring file to add to it"
);
00447
goto
out;
00448         }
00449
00450       have_lock =
group__DBusMacros.html#ga2
TRUE
;
00451     }
00452
00453
group__DBusErrors.html#ga0
dbus_error_init
(&tmp_error);
00454
if
(!
group__DBusInternalsUtils.html#ga85
_dbus_file_get_contents
(&contents,
00455                                 &keyring->
structDBusKeyring.html#o3
filename
,
00456                                 &tmp_error))
00457     {
00458       _dbus_verbose (
"Failed to load keyring file: %s\n"
,
00459                      tmp_error.
structDBusError.html#o1
message
);
00460
/* continue with empty keyring file, so we recreate it */
00461
group__DBusErrors.html#ga1
dbus_error_free
(&tmp_error);
00462     }
00463
00464
if
(!
group__DBusString.html#ga55
_dbus_string_validate_ascii
(&contents, 0,
00465                                     _dbus_string_get_length (&contents)))
00466     {
00467
group__DBusInternalsUtils.html#ga7
_dbus_warn
(
"Secret keyring file contains non-ASCII! Ignoring existing contents\n"
);
00468
group__DBusString.html#ga21
_dbus_string_set_length
(&contents, 0);
00469     }
00470
00471
/* FIXME this is badly inefficient for large keyring files
00472
* (not that large keyring files exist outside of test suites)
00473
*/
00474
while
(
group__DBusString.html#ga48
_dbus_string_pop_line
(&contents, &line))
00475     {
00476
int
next;
00477
long
val;
00478
int
id;
00479
long
timestamp;
00480
int
len;
00481
int
end;
00482       DBusKey *
new
;
00483
00484
/* Don't load more than the max. */
00485
if
(n_keys >= (add_new ?
group__DBusKeyringInternals.html#ga10
MAX_KEYS_IN_FILE
:
group__DBusKeyringInternals.html#ga10
MAX_KEYS_IN_FILE
- 1))
00486
break
;
00487
00488       next = 0;
00489
if
(!
group__DBusString.html#ga62
_dbus_string_parse_int
(&line, 0, &val, &next))
00490         {
00491           _dbus_verbose (
"could not parse secret key ID at start of line\n"
);
00492
continue
;
00493         }
00494
00495
if
(val >
group__DBusInternalsUtils.html#ga140
_DBUS_INT32_MAX
|| val < 0)
00496         {
00497           _dbus_verbose (
"invalid secret key ID at start of line\n"
);
00498
continue
;
00499         }
00500
00501
id
= val;
00502
00503
group__DBusString.html#ga47
_dbus_string_skip_blank
(&line, next, &next);
00504
00505
if
(!
group__DBusString.html#ga62
_dbus_string_parse_int
(&line, next, &timestamp, &next))
00506         {
00507           _dbus_verbose (
"could not parse secret key timestamp\n"
);
00508
continue
;
00509         }
00510
00511
if
(timestamp < 0 ||
00512           (now +
group__DBusKeyringInternals.html#ga9
MAX_TIME_TRAVEL_SECONDS
) < timestamp ||
00513           (now -
group__DBusKeyringInternals.html#ga8
EXPIRE_KEYS_TIMEOUT_SECONDS
) > timestamp)
00514         {
00515           _dbus_verbose (
"dropping/ignoring %ld-seconds old key with timestamp %ld as current time is %ld\n"
,
00516                          now - timestamp, timestamp, now);
00517
continue
;
00518         }
00519
00520
group__DBusString.html#ga47
_dbus_string_skip_blank
(&line, next, &next);
00521
00522       len = _dbus_string_get_length (&line);
00523
00524
if
((len - next) == 0)
00525         {
00526           _dbus_verbose (
"no secret key after ID and timestamp\n"
);
00527
continue
;
00528         }
00529
00530
/* We have all three parts */
00531
new
=
group__DBusMemory.html#ga2
dbus_realloc
(keys,
sizeof
(DBusKey) * (n_keys + 1));
00532
if
(
new
==
group__DBusMacros.html#ga4
NULL
)
00533         {
00534
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_NO_MEMORY,
group__DBusMacros.html#ga4
NULL
);
00535
goto
out;
00536         }
00537
00538       keys =
new
;
00539       n_keys += 1;
00540
00541
if
(!
group__DBusString.html#ga6
_dbus_string_init
(&keys[n_keys-1].secret))
00542         {
00543           n_keys -= 1;
/* we don't want to free the one we didn't init */
00544
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_NO_MEMORY,
group__DBusMacros.html#ga4
NULL
);
00545
goto
out;
00546         }
00547
00548       keys[n_keys-1].
structDBusKey.html#o0
id
= id;
00549       keys[n_keys-1].
structDBusKey.html#o1
creation_time
= timestamp;
00550
if
(!
group__DBusString.html#ga54
_dbus_string_hex_decode
(&line, next, &end,
00551                                     &keys[n_keys-1].secret, 0))
00552         {
00553
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_NO_MEMORY,
group__DBusMacros.html#ga4
NULL
);
00554
goto
out;
00555         }
00556
00557
if
(_dbus_string_get_length (&line) != end)
00558         {
00559           _dbus_verbose (
"invalid hex encoding in keyring file\n"
);
00560
group__DBusString.html#ga9
_dbus_string_free
(&keys[n_keys - 1].secret);
00561           n_keys -= 1;
00562
continue
;
00563         }
00564     }
00565
00566   _dbus_verbose (
"Successfully loaded %d existing keys\n"
,
00567                  n_keys);
00568
00569
if
(add_new)
00570     {
00571
if
(!add_new_key (&keys, &n_keys, error))
00572         {
00573           _dbus_verbose (
"Failed to generate new key: %s\n"
,
00574                          error ?
"(unknown)"
: error->
structDBusError.html#o1
message
);
00575
goto
out;
00576         }
00577
00578
group__DBusString.html#ga21
_dbus_string_set_length
(&contents, 0);
00579
00580       i = 0;
00581
while
(i < n_keys)
00582         {
00583
if
(!
group__DBusString.html#ga60
_dbus_string_append_int
(&contents,
00584                                         keys[i].
id
))
00585
goto
nomem;
00586
00587
if
(!
group__DBusString.html#ga35
_dbus_string_append_byte
(&contents,
' '
))
00588
goto
nomem;
00589
00590
if
(!
group__DBusString.html#ga60
_dbus_string_append_int
(&contents,
00591                                         keys[i].creation_time))
00592
goto
nomem;
00593
00594
if
(!
group__DBusString.html#ga35
_dbus_string_append_byte
(&contents,
' '
))
00595
goto
nomem;
00596
00597
if
(!
group__DBusString.html#ga53
_dbus_string_hex_encode
(&keys[i].secret, 0,
00598                                         &contents,
00599                                         _dbus_string_get_length (&contents)))
00600
goto
nomem;
00601
00602
if
(!
group__DBusString.html#ga35
_dbus_string_append_byte
(&contents,
'\n'
))
00603
goto
nomem;
00604
00605           ++i;
00606
continue
;
00607
00608         nomem:
00609
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_NO_MEMORY,
group__DBusMacros.html#ga4
NULL
);
00610
goto
out;
00611         }
00612
00613
if
(!
group__DBusInternalsUtils.html#ga86
_dbus_string_save_to_file
(&contents, &keyring->
structDBusKeyring.html#o3
filename
,
00614                                       error))
00615
goto
out;
00616     }
00617
00618
if
(keyring->
structDBusKeyring.html#o5
keys
)
00619     free_keys (keyring->
structDBusKeyring.html#o5
keys
, keyring->
structDBusKeyring.html#o6
n_keys
);
00620   keyring->
structDBusKeyring.html#o5
keys
= keys;
00621   keyring->
structDBusKeyring.html#o6
n_keys
= n_keys;
00622   keys =
group__DBusMacros.html#ga4
NULL
;
00623   n_keys = 0;
00624
00625   retval =
group__DBusMacros.html#ga2
TRUE
;
00626
00627  out:
00628
if
(have_lock)
00629     _dbus_keyring_unlock (keyring);
00630
00631
if
(! ((retval ==
group__DBusMacros.html#ga2
TRUE
&& (error ==
group__DBusMacros.html#ga4
NULL
|| error->
structDBusError.html#o0
name
==
group__DBusMacros.html#ga4
NULL
)) ||
00632          (retval ==
group__DBusMacros.html#ga3
FALSE
&& (error ==
group__DBusMacros.html#ga4
NULL
|| error->
structDBusError.html#o0
name
!=
group__DBusMacros.html#ga4
NULL
))))
00633     {
00634
if
(error && error->
structDBusError.html#o0
name
)
00635         _dbus_verbose (
"error is %s: %s\n"
, error->
structDBusError.html#o0
name
, error->
structDBusError.html#o1
message
);
00636
group__DBusInternalsUtils.html#ga7
_dbus_warn
(
"returning %d but error pointer %p name %s\n"
,
00637                   retval, error, error->
structDBusError.html#o0
name
? error->
structDBusError.html#o0
name
:
"(none)"
);
00638
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"didn't handle errors properly"
);
00639     }
00640
00641
if
(keys !=
group__DBusMacros.html#ga4
NULL
)
00642     {
00643       i = 0;
00644
while
(i < n_keys)
00645         {
00646
group__DBusString.html#ga58
_dbus_string_zero
(&keys[i].secret);
00647
group__DBusString.html#ga9
_dbus_string_free
(&keys[i].secret);
00648           ++i;
00649         }
00650
00651
group__DBusMemory.html#ga3
dbus_free
(keys);
00652     }
00653
00654
group__DBusString.html#ga9
_dbus_string_free
(&contents);
00655
group__DBusString.html#ga9
_dbus_string_free
(&line);
00656
00657
return
retval;
00658 }
00659
/* end of internals */
00661
00674
structDBusKeyring.html
DBusKeyring
*
group__DBusKeyring.html#ga0
00675
group__DBusKeyring.html#ga0
_dbus_keyring_ref
(
structDBusKeyring.html
DBusKeyring
*keyring)
00676 {
00677   keyring->
structDBusKeyring.html#o0
refcount
+= 1;
00678
00679
return
keyring;
00680 }
00681
00688
void
group__DBusKeyring.html#ga1
00689
group__DBusKeyring.html#ga1
_dbus_keyring_unref
(
structDBusKeyring.html
DBusKeyring
*keyring)
00690 {
00691   keyring->
structDBusKeyring.html#o0
refcount
-= 1;
00692
00693
if
(keyring->
structDBusKeyring.html#o0
refcount
== 0)
00694     {
00695
group__DBusString.html#ga9
_dbus_string_free
(&keyring->
structDBusKeyring.html#o1
username
);
00696
group__DBusString.html#ga9
_dbus_string_free
(&keyring->
structDBusKeyring.html#o3
filename
);
00697
group__DBusString.html#ga9
_dbus_string_free
(&keyring->
structDBusKeyring.html#o4
filename_lock
);
00698
group__DBusString.html#ga9
_dbus_string_free
(&keyring->
structDBusKeyring.html#o2
directory
);
00699       free_keys (keyring->
structDBusKeyring.html#o5
keys
, keyring->
structDBusKeyring.html#o6
n_keys
);
00700
group__DBusMemory.html#ga3
dbus_free
(keyring);
00701     }
00702 }
00703
00714
structDBusKeyring.html
DBusKeyring
*
group__DBusKeyring.html#ga2
00715
group__DBusKeyring.html#ga2
_dbus_keyring_new_homedir
(
const
structDBusString.html
DBusString
*username,
00716
const
structDBusString.html
DBusString
*context,
00717
structDBusError.html
DBusError
*error)
00718 {
00719
structDBusString.html
DBusString
homedir;
00720
structDBusKeyring.html
DBusKeyring
*keyring;
00721
group__DBusTypes.html#ga2
dbus_bool_t
error_set;
00722
structDBusString.html
DBusString
dotdir;
00723
structDBusError.html
DBusError
tmp_error;
00724
00725   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00726
00727   keyring =
group__DBusMacros.html#ga4
NULL
;
00728   error_set =
group__DBusMacros.html#ga3
FALSE
;
00729
00730
if
(!
group__DBusString.html#ga6
_dbus_string_init
(&homedir))
00731     {
00732
group__DBusErrors.html#ga6
dbus_set_error
(error, DBUS_ERROR_NO_MEMORY,
group__DBusMacros.html#ga4
NULL
);
00733
return
group__DBusMacros.html#ga3
FALSE
;
00734     }
00735
00736
group__DBusString.html#ga7
_dbus_string_init_const
(&dotdir,
".dbus-keyrings"
);
00737
00738
if
(username ==
group__DBusMacros.html#ga4
NULL
)
00739     {
00740
const
structDBusString.html
DBusString
*const_homedir;
00741
00742
if
(!
group__DBusInternalsUtils.html#ga122
_dbus_username_from_current_process
(&username) ||
00743           !
group__DBusInternalsUtils.html#ga123
_dbus_homedir_from_current_process
(&const_homedir))
00744
goto
failed;
00745
00746
if
(!
group__DBusString.html#ga40
_dbus_string_copy
(const_homedir, 0,
00747                               &homedir, 0))
00748
goto
failed;
00749     }
00750
else
00751     {
00752
if
(!
group__DBusInternalsUtils.html#ga124
_dbus_homedir_from_username
(username, &homedir))
00753
goto
failed;
00754     }
00755
00756
#ifdef DBUS_BUILD_TESTS
00757
{
00758
const
char
*override;
00759
00760    override =
group__DBusInternalsUtils.html#ga57
_dbus_getenv
(
"DBUS_TEST_HOMEDIR"
);
00761
if
(override !=
group__DBusMacros.html#ga4
NULL
&& *override !=
'\0'
)
00762      {
00763
group__DBusString.html#ga21
_dbus_string_set_length
(&homedir, 0);
00764
if
(!
group__DBusString.html#ga27
_dbus_string_append
(&homedir, override))
00765
goto
failed;
00766
00767        _dbus_verbose (
"Using fake homedir for testing: %s\n"
,
00768                       _dbus_string_get_const_data (&homedir));
00769      }
00770
else
00771      {
00772
static
group__DBusTypes.html#ga2
dbus_bool_t
already_warned =
group__DBusMacros.html#ga3
FALSE
;
00773
if
(!already_warned)
00774          {
00775
group__DBusInternalsUtils.html#ga7
_dbus_warn
(
"Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n"
);
00776            already_warned =
group__DBusMacros.html#ga2
TRUE
;
00777          }
00778      }
00779  }
00780
#endif
00781
00782
group__DBusInternalsUtils.html#ga130
_dbus_assert
(username !=
group__DBusMacros.html#ga4
NULL
);
00783
00784   keyring = _dbus_keyring_new ();
00785
if
(keyring ==
group__DBusMacros.html#ga4
NULL
)
00786
goto
failed;
00787
00788
/* should have been validated already, but paranoia check here */
00789
if
(!
group__DBusKeyring.html#ga3
_dbus_keyring_validate_context
(context))
00790     {
00791       error_set =
group__DBusMacros.html#ga2
TRUE
;
00792
group__DBusErrors.html#ga2
dbus_set_error_const
(error,
00793                             DBUS_ERROR_FAILED,
00794
"Invalid context in keyring creation"
);
00795
goto
failed;
00796     }
00797
00798
if
(!
group__DBusString.html#ga40
_dbus_string_copy
(username, 0,
00799                           &keyring->
structDBusKeyring.html#o1
username
, 0))
00800
goto
failed;
00801
00802
if
(!
group__DBusString.html#ga40
_dbus_string_copy
(&homedir, 0,
00803                           &keyring->
structDBusKeyring.html#o2
directory
, 0))
00804
goto
failed;
00805
00806
if
(!
group__DBusInternalsUtils.html#ga90
_dbus_concat_dir_and_file
(&keyring->
structDBusKeyring.html#o2
directory
,
00807                                   &dotdir))
00808
goto
failed;
00809
00810
if
(!
group__DBusString.html#ga40
_dbus_string_copy
(&keyring->
structDBusKeyring.html#o2
directory
, 0,
00811                           &keyring->
structDBusKeyring.html#o3
filename
, 0))
00812
goto
failed;
00813
00814
if
(!
group__DBusInternalsUtils.html#ga90
_dbus_concat_dir_and_file
(&keyring->
structDBusKeyring.html#o3
filename
,
00815                                   context))
00816
goto
failed;
00817
00818
if
(!
group__DBusString.html#ga40
_dbus_string_copy
(&keyring->
structDBusKeyring.html#o3
filename
, 0,
00819                           &keyring->
structDBusKeyring.html#o4
filename_lock
, 0))
00820
goto
failed;
00821
00822
if
(!
group__DBusString.html#ga27
_dbus_string_append
(&keyring->
structDBusKeyring.html#o4
filename_lock
,
".lock"
))
00823
goto
failed;
00824
00825
group__DBusErrors.html#ga0
dbus_error_init
(&tmp_error);
00826
if
(!_dbus_keyring_reload (keyring,
group__DBusMacros.html#ga3
FALSE
, &tmp_error))
00827     {
00828       _dbus_verbose (
"didn't load an existing keyring: %s\n"
,
00829                      tmp_error.
structDBusError.html#o1
message
);
00830
group__DBusErrors.html#ga1
dbus_error_free
(&tmp_error);
00831     }
00832
00833
/* We don't fail fatally if we can't create the directory,
00834
* but the keyring will probably always be empty
00835
* unless someone else manages to create it
00836
*/
00837
group__DBusErrors.html#ga0
dbus_error_init
(&tmp_error);
00838
if
(!
group__DBusInternalsUtils.html#ga89
_dbus_create_directory
(&keyring->directory,
00839                                &tmp_error))
00840     {
00841       _dbus_verbose (
"Creating keyring directory: %s\n"
,
00842                      tmp_error.
structDBusError.html#o1
message
);
00843
group__DBusErrors.html#ga1
dbus_error_free
(&tmp_error);
00844     }
00845
00846
group__DBusString.html#ga9
_dbus_string_free
(&homedir);
00847
00848
return
keyring;
00849
00850  failed:
00851
if
(!error_set)
00852
group__DBusErrors.html#ga2
dbus_set_error_const
(error,
00853                           DBUS_ERROR_NO_MEMORY,
00854
group__DBusMacros.html#ga4
NULL
);
00855
if
(keyring)
00856
group__DBusKeyring.html#ga1
_dbus_keyring_unref
(keyring);
00857
group__DBusString.html#ga9
_dbus_string_free
(&homedir);
00858
return
group__DBusMacros.html#ga3
FALSE
;
00859
00860 }
00861
00874
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusKeyring.html#ga3
00875
group__DBusKeyring.html#ga3
_dbus_keyring_validate_context
(
const
structDBusString.html
DBusString
*context)
00876 {
00877
if
(_dbus_string_get_length (context) == 0)
00878     {
00879       _dbus_verbose (
"context is zero-length\n"
);
00880
return
group__DBusMacros.html#ga3
FALSE
;
00881     }
00882
00883
if
(!
group__DBusString.html#ga55
_dbus_string_validate_ascii
(context, 0,
00884                                     _dbus_string_get_length (context)))
00885     {
00886       _dbus_verbose (
"context not valid ascii\n"
);
00887
return
group__DBusMacros.html#ga3
FALSE
;
00888     }
00889
00890
/* no directory separators */
00891
if
(
group__DBusString.html#ga44
_dbus_string_find
(context, 0,
"/"
,
group__DBusMacros.html#ga4
NULL
))
00892     {
00893       _dbus_verbose (
"context contains a slash\n"
);
00894
return
group__DBusMacros.html#ga3
FALSE
;
00895     }
00896
00897
if
(
group__DBusString.html#ga44
_dbus_string_find
(context, 0,
"\\"
,
group__DBusMacros.html#ga4
NULL
))
00898     {
00899       _dbus_verbose (
"context contains a backslash\n"
);
00900
return
group__DBusMacros.html#ga3
FALSE
;
00901     }
00902
00903
/* prevent attempts to use dotfiles or ".." or ".lock"
00904
* all of which might allow some kind of attack
00905
*/
00906
if
(
group__DBusString.html#ga44
_dbus_string_find
(context, 0,
"."
,
group__DBusMacros.html#ga4
NULL
))
00907     {
00908       _dbus_verbose (
"context contains a dot\n"
);
00909
return
group__DBusMacros.html#ga3
FALSE
;
00910     }
00911
00912
/* no spaces/tabs, those are used for separators in the protocol */
00913
if
(
group__DBusString.html#ga46
_dbus_string_find_blank
(context, 0,
group__DBusMacros.html#ga4
NULL
))
00914     {
00915       _dbus_verbose (
"context contains a blank\n"
);
00916
return
group__DBusMacros.html#ga3
FALSE
;
00917     }
00918
00919
if
(
group__DBusString.html#ga44
_dbus_string_find
(context, 0,
"\n"
,
group__DBusMacros.html#ga4
NULL
))
00920     {
00921       _dbus_verbose (
"context contains a newline\n"
);
00922
return
group__DBusMacros.html#ga3
FALSE
;
00923     }
00924
00925
if
(
group__DBusString.html#ga44
_dbus_string_find
(context, 0,
"\r"
,
group__DBusMacros.html#ga4
NULL
))
00926     {
00927       _dbus_verbose (
"context contains a carriage return\n"
);
00928
return
group__DBusMacros.html#ga3
FALSE
;
00929     }
00930
00931
return
group__DBusMacros.html#ga2
TRUE
;
00932 }
00933
00934
static
DBusKey*
00935 find_recent_key (
structDBusKeyring.html
DBusKeyring
*keyring)
00936 {
00937
int
i;
00938
long
tv_sec, tv_usec;
00939
00940
group__DBusInternalsUtils.html#ga84
_dbus_get_current_time
(&tv_sec, &tv_usec);
00941
00942   i = 0;
00943
while
(i < keyring->n_keys)
00944     {
00945       DBusKey *key = &keyring->
structDBusKeyring.html#o5
keys
[i];
00946
00947       _dbus_verbose (
"Key %d is %ld seconds old\n"
,
00948                      i, tv_sec - key->
structDBusKey.html#o1
creation_time
);
00949
00950
if
((tv_sec -
group__DBusKeyringInternals.html#ga7
NEW_KEY_TIMEOUT_SECONDS
) < key->
structDBusKey.html#o1
creation_time
)
00951
return
key;
00952
00953       ++i;
00954     }
00955
00956
return
group__DBusMacros.html#ga4
NULL
;
00957 }
00958
00970
int
group__DBusKeyring.html#ga5
00971
group__DBusKeyring.html#ga5
_dbus_keyring_get_best_key
(
structDBusKeyring.html
DBusKeyring
*keyring,
00972
structDBusError.html
DBusError
*error)
00973 {
00974   DBusKey *key;
00975
00976   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00977
00978   key = find_recent_key (keyring);
00979
if
(key)
00980
return
key->
structDBusKey.html#o0
id
;
00981
00982
/* All our keys are too old, or we've never loaded the
00983
* keyring. Create a new one.
00984
*/
00985
if
(!_dbus_keyring_reload (keyring,
group__DBusMacros.html#ga2
TRUE
,
00986                              error))
00987
return
-1;
00988
00989   key = find_recent_key (keyring);
00990
if
(key)
00991
return
key->
structDBusKey.html#o0
id
;
00992
else
00993     {
00994
group__DBusErrors.html#ga2
dbus_set_error_const
(error,
00995                             DBUS_ERROR_FAILED,
00996
"No recent-enough key found in keyring, and unable to create a new key"
);
00997
return
-1;
00998     }
00999 }
01000
01009
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusKeyring.html#ga6
01010
group__DBusKeyring.html#ga6
_dbus_keyring_is_for_user
(
structDBusKeyring.html
DBusKeyring
*keyring,
01011
const
structDBusString.html
DBusString
*username)
01012 {
01013
return
group__DBusString.html#ga49
_dbus_string_equal
(&keyring->
structDBusKeyring.html#o1
username
,
01014                              username);
01015 }
01016
01028
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusKeyring.html#ga7
01029
group__DBusKeyring.html#ga7
_dbus_keyring_get_hex_key
(
structDBusKeyring.html
DBusKeyring
*keyring,
01030
int
key_id,
01031
structDBusString.html
DBusString
*hex_key)
01032 {
01033   DBusKey *key;
01034
01035   key = find_key_by_id (keyring->
structDBusKeyring.html#o5
keys
,
01036                         keyring->
structDBusKeyring.html#o6
n_keys
,
01037                         key_id);
01038
if
(key ==
group__DBusMacros.html#ga4
NULL
)
01039
return
group__DBusMacros.html#ga2
TRUE
;
/* had enough memory, so TRUE */
01040
01041
return
group__DBusString.html#ga53
_dbus_string_hex_encode
(&key->
structDBusKey.html#o2
secret
, 0,
01042                                   hex_key,
01043                                   _dbus_string_get_length (hex_key));
01044 }
01045
/* end of exposed API */
01047
01048
#ifdef DBUS_BUILD_TESTS
01049
#include "dbus-test.h"
01050
#include <stdio.h>
01051
01052
group__DBusTypes.html#ga2
dbus_bool_t
01053 _dbus_keyring_test (
void
)
01054 {
01055
structDBusString.html
DBusString
context;
01056
structDBusKeyring.html
DBusKeyring
*ring1;
01057
structDBusKeyring.html
DBusKeyring
*ring2;
01058
int
id;
01059
structDBusError.html
DBusError
error;
01060
int
i;
01061
01062   ring1 =
group__DBusMacros.html#ga4
NULL
;
01063   ring2 =
group__DBusMacros.html#ga4
NULL
;
01064
01065
/* Context validation */
01066
01067
group__DBusString.html#ga7
_dbus_string_init_const
(&context,
"foo"
);
01068
group__DBusInternalsUtils.html#ga130
_dbus_assert
(
group__DBusKeyring.html#ga3
_dbus_keyring_validate_context
(&context));
01069
group__DBusString.html#ga7
_dbus_string_init_const
(&context,
"org_freedesktop_blah"
);
01070
group__DBusInternalsUtils.html#ga130
_dbus_assert
(
group__DBusKeyring.html#ga3
_dbus_keyring_validate_context
(&context));
01071
01072
group__DBusString.html#ga7
_dbus_string_init_const
(&context,
""
);
01073
group__DBusInternalsUtils.html#ga130
_dbus_assert
(!
group__DBusKeyring.html#ga3
_dbus_keyring_validate_context
(&context));
01074
group__DBusString.html#ga7
_dbus_string_init_const
(&context,
".foo"
);
01075
group__DBusInternalsUtils.html#ga130
_dbus_assert
(!
group__DBusKeyring.html#ga3
_dbus_keyring_validate_context
(&context));
01076
group__DBusString.html#ga7
_dbus_string_init_const
(&context,
"bar.foo"
);
01077
group__DBusInternalsUtils.html#ga130
_dbus_assert
(!
group__DBusKeyring.html#ga3
_dbus_keyring_validate_context
(&context));
01078
group__DBusString.html#ga7
_dbus_string_init_const
(&context,
"bar/foo"
);
01079
group__DBusInternalsUtils.html#ga130
_dbus_assert
(!
group__DBusKeyring.html#ga3
_dbus_keyring_validate_context
(&context));
01080
group__DBusString.html#ga7
_dbus_string_init_const
(&context,
"bar\\foo"
);
01081
group__DBusInternalsUtils.html#ga130
_dbus_assert
(!
group__DBusKeyring.html#ga3
_dbus_keyring_validate_context
(&context));
01082
group__DBusString.html#ga7
_dbus_string_init_const
(&context,
"foo\xfa\xf0"
);
01083
group__DBusInternalsUtils.html#ga130
_dbus_assert
(!
group__DBusKeyring.html#ga3
_dbus_keyring_validate_context
(&context));
01084
group__DBusString.html#ga7
_dbus_string_init_const
(&context,
"foo\x80"
);
01085
group__DBusInternalsUtils.html#ga130
_dbus_assert
(!
group__DBusKeyring.html#ga3
_dbus_keyring_validate_context
(&context));
01086
group__DBusString.html#ga7
_dbus_string_init_const
(&context,
"foo\x7f"
);
01087
group__DBusInternalsUtils.html#ga130
_dbus_assert
(
group__DBusKeyring.html#ga3
_dbus_keyring_validate_context
(&context));
01088
group__DBusString.html#ga7
_dbus_string_init_const
(&context,
"foo bar"
);
01089
group__DBusInternalsUtils.html#ga130
_dbus_assert
(!
group__DBusKeyring.html#ga3
_dbus_keyring_validate_context
(&context));
01090
01091
if
(!
group__DBusString.html#ga6
_dbus_string_init
(&context))
01092
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"no memory"
);
01093
if
(!
group__DBusString.html#ga35
_dbus_string_append_byte
(&context,
'\0'
))
01094
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"no memory"
);
01095
group__DBusInternalsUtils.html#ga130
_dbus_assert
(!
group__DBusKeyring.html#ga3
_dbus_keyring_validate_context
(&context));
01096
group__DBusString.html#ga9
_dbus_string_free
(&context);
01097
01098
/* Now verify that if we create a key in keyring 1,
01099
* it is properly loaded in keyring 2
01100
*/
01101
01102
group__DBusString.html#ga7
_dbus_string_init_const
(&context,
"org_freedesktop_dbus_testsuite"
);
01103
group__DBusErrors.html#ga0
dbus_error_init
(&error);
01104   ring1 =
group__DBusKeyring.html#ga2
_dbus_keyring_new_homedir
(
group__DBusMacros.html#ga4
NULL
, &context,
01105                                      &error);
01106
group__DBusInternalsUtils.html#ga130
_dbus_assert
(ring1);
01107
group__DBusInternalsUtils.html#ga130
_dbus_assert
(error.
structDBusError.html#o0
name
==
group__DBusMacros.html#ga4
NULL
);
01108
01109
id
=
group__DBusKeyring.html#ga5
_dbus_keyring_get_best_key
(ring1, &error);
01110
if
(
id
< 0)
01111     {
01112       fprintf (stderr,
"Could not load keyring: %s\n"
, error.
structDBusError.html#o1
message
);
01113
group__DBusErrors.html#ga1
dbus_error_free
(&error);
01114
goto
failure;
01115     }
01116
01117   ring2 =
group__DBusKeyring.html#ga2
_dbus_keyring_new_homedir
(
group__DBusMacros.html#ga4
NULL
, &context, &error);
01118
group__DBusInternalsUtils.html#ga130
_dbus_assert
(ring2);
01119
group__DBusInternalsUtils.html#ga130
_dbus_assert
(error.
structDBusError.html#o0
name
==
group__DBusMacros.html#ga4
NULL
);
01120
01121
if
(ring1->
structDBusKeyring.html#o6
n_keys
!= ring2->
structDBusKeyring.html#o6
n_keys
)
01122     {
01123       fprintf (stderr,
"Different number of keys in keyrings\n"
);
01124
goto
failure;
01125     }
01126
01127
/* We guarantee we load and save keeping keys in a fixed
01128
* order
01129
*/
01130   i = 0;
01131
while
(i < ring1->n_keys)
01132     {
01133
if
(ring1->
structDBusKeyring.html#o5
keys
[i].
structDBusKey.html#o0
id
!= ring2->
structDBusKeyring.html#o5
keys
[i].
structDBusKey.html#o0
id
)
01134         {
01135           fprintf (stderr,
"Keyring 1 has first key ID %d and keyring 2 has %d\n"
,
01136                    ring1->
structDBusKeyring.html#o5
keys
[i].
structDBusKey.html#o0
id
, ring2->
structDBusKeyring.html#o5
keys
[i].
structDBusKey.html#o0
id
);
01137
goto
failure;
01138         }
01139
01140
if
(ring1->
structDBusKeyring.html#o5
keys
[i].
structDBusKey.html#o1
creation_time
!= ring2->
structDBusKeyring.html#o5
keys
[i].
structDBusKey.html#o1
creation_time
)
01141         {
01142           fprintf (stderr,
"Keyring 1 has first key time %ld and keyring 2 has %ld\n"
,
01143                    ring1->
structDBusKeyring.html#o5
keys
[i].
structDBusKey.html#o1
creation_time
, ring2->
structDBusKeyring.html#o5
keys
[i].
structDBusKey.html#o1
creation_time
);
01144
goto
failure;
01145         }
01146
01147
if
(!
group__DBusString.html#ga49
_dbus_string_equal
(&ring1->
structDBusKeyring.html#o5
keys
[i].
structDBusKey.html#o2
secret
,
01148                                &ring2->
structDBusKeyring.html#o5
keys
[i].
structDBusKey.html#o2
secret
))
01149         {
01150           fprintf (stderr,
"Keyrings 1 and 2 have different secrets for same ID/timestamp\n"
);
01151
goto
failure;
01152         }
01153
01154       ++i;
01155     }
01156
01157   printf (
" %d keys in test\n"
, ring1->
structDBusKeyring.html#o6
n_keys
);
01158
01159
/* Test ref/unref */
01160
group__DBusKeyring.html#ga0
_dbus_keyring_ref
(ring1);
01161
group__DBusKeyring.html#ga0
_dbus_keyring_ref
(ring2);
01162
group__DBusKeyring.html#ga1
_dbus_keyring_unref
(ring1);
01163
group__DBusKeyring.html#ga1
_dbus_keyring_unref
(ring2);
01164
01165
01166
/* really unref */
01167
group__DBusKeyring.html#ga1
_dbus_keyring_unref
(ring1);
01168
group__DBusKeyring.html#ga1
_dbus_keyring_unref
(ring2);
01169
01170
return
group__DBusMacros.html#ga2
TRUE
;
01171
01172  failure:
01173
if
(ring1)
01174
group__DBusKeyring.html#ga1
_dbus_keyring_unref
(ring1);
01175
if
(ring2)
01176
group__DBusKeyring.html#ga1
_dbus_keyring_unref
(ring2);
01177
01178
return
group__DBusMacros.html#ga3
FALSE
;
01179 }
01180
01181
#endif
/* DBUS_BUILD_TESTS */
01182
Generated on Tue Sep 13 01:28:07 2005 for D-BUS by
http://www.doxygen.org/index.html
doxygen
1.4.4
