summaryrefslogtreecommitdiffstats
path: root/dbus/dbus-keyring.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2009-08-07 01:33:14 +0200
committerLennart Poettering <lennart@poettering.net>2009-10-17 00:28:31 +0200
commit1f179e0f27f656ed3c5d1ee2ac5e1bbfe26d9d94 (patch)
treef239fdaf9e72954e153d33b88e0c1fd2a04d90bf /dbus/dbus-keyring.c
parent2ed34f69d4400f863835c4149be4ecb82ffe1c72 (diff)
desktop-file: fix stat() race
_dbus_desktop_file_load() used to stat the desktop file before reading it, to verify its size. This is both racy and unnecessary since _dbus_file_get_contents() which it uses stats the file anyway -- does that however in a race-free fashion with fstat() instead of stat(). This patch gets rid of the redundant stat(). Also, since the desktop file change logic requires the mtime of the file it read we now export that in _dbus_file_get_contents(). This patch probably breaks Win32 builds, but afaik those are broken anyway.
Diffstat (limited to 'dbus/dbus-keyring.c')
-rw-r--r--dbus/dbus-keyring.c136
1 files changed, 68 insertions, 68 deletions
diff --git a/dbus/dbus-keyring.c b/dbus/dbus-keyring.c
index 6dc1e129..21bde3a5 100644
--- a/dbus/dbus-keyring.c
+++ b/dbus/dbus-keyring.c
@@ -4,7 +4,7 @@
* Copyright (C) 2003, 2004 Red Hat Inc.
*
* Licensed under the Academic Free License version 2.1
- *
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -14,7 +14,7 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
@@ -96,14 +96,14 @@ typedef struct
* as unix timestamp. signed long
* matches struct timeval.
*/
-
+
DBusString secret; /**< the actual key */
} DBusKey;
/**
* @brief Internals of DBusKeyring.
- *
+ *
* DBusKeyring internals. DBusKeyring is an opaque object, it must be
* used via accessor functions.
*/
@@ -126,7 +126,7 @@ _dbus_keyring_new (void)
keyring = dbus_new0 (DBusKeyring, 1);
if (keyring == NULL)
goto out_0;
-
+
if (!_dbus_string_init (&keyring->directory))
goto out_1;
@@ -135,7 +135,7 @@ _dbus_keyring_new (void)
if (!_dbus_string_init (&keyring->filename_lock))
goto out_3;
-
+
keyring->refcount = 1;
keyring->keys = NULL;
keyring->n_keys = 0;
@@ -161,7 +161,7 @@ free_keys (DBusKey *keys,
int i;
/* should be safe for args NULL, 0 */
-
+
i = 0;
while (i < n_keys)
{
@@ -197,7 +197,7 @@ static dbus_bool_t
_dbus_keyring_lock (DBusKeyring *keyring)
{
int n_timeouts;
-
+
n_timeouts = 0;
while (n_timeouts < MAX_LOCK_TIMEOUTS)
{
@@ -212,7 +212,7 @@ _dbus_keyring_lock (DBusKeyring *keyring)
dbus_error_free (&error);
_dbus_sleep_milliseconds (LOCK_TIMEOUT_MILLISECONDS);
-
+
++n_timeouts;
}
@@ -240,7 +240,7 @@ _dbus_keyring_lock (DBusKeyring *keyring)
return FALSE;
}
}
-
+
return TRUE;
}
@@ -269,7 +269,7 @@ find_key_by_id (DBusKey *keys,
{
if (keys[i].id == id)
return &keys[i];
-
+
++i;
}
@@ -291,7 +291,7 @@ add_new_key (DBusKey **keys_p,
int n_keys;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
-
+
if (!_dbus_string_init (&bytes))
{
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
@@ -301,10 +301,10 @@ add_new_key (DBusKey **keys_p,
keys = *keys_p;
n_keys = *n_keys_p;
retval = FALSE;
-
+
/* Generate an integer ID and then the actual key. */
retry:
-
+
if (!_dbus_generate_random_bytes (&bytes, 4))
{
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
@@ -312,7 +312,7 @@ add_new_key (DBusKey **keys_p,
}
s = (const unsigned char*) _dbus_string_get_const_data (&bytes);
-
+
id = s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24);
if (id < 0)
id = - id;
@@ -327,7 +327,7 @@ add_new_key (DBusKey **keys_p,
}
_dbus_verbose ("Creating key with ID %d\n", id);
-
+
#define KEY_LENGTH_BYTES 24
_dbus_string_set_length (&bytes, 0);
if (!_dbus_generate_random_bytes (&bytes, KEY_LENGTH_BYTES))
@@ -355,7 +355,7 @@ add_new_key (DBusKey **keys_p,
}
_dbus_get_current_time (&timestamp, NULL);
-
+
keys[n_keys-1].id = id;
keys[n_keys-1].creation_time = timestamp;
if (!_dbus_string_move (&bytes, 0,
@@ -367,12 +367,12 @@ add_new_key (DBusKey **keys_p,
n_keys -= 1;
goto out;
}
-
+
retval = TRUE;
-
+
out:
*n_keys_p = n_keys;
-
+
_dbus_string_free (&bytes);
return retval;
}
@@ -407,10 +407,10 @@ _dbus_keyring_reload (DBusKeyring *keyring,
DBusError tmp_error;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
-
+
if (!_dbus_check_dir_is_private_to_user (&keyring->directory, error))
return FALSE;
-
+
if (!_dbus_string_init (&contents))
{
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
@@ -423,14 +423,14 @@ _dbus_keyring_reload (DBusKeyring *keyring,
_dbus_string_free (&contents);
return FALSE;
}
-
+
keys = NULL;
n_keys = 0;
retval = FALSE;
have_lock = FALSE;
_dbus_get_current_time (&now, NULL);
-
+
if (add_new)
{
if (!_dbus_keyring_lock (keyring))
@@ -444,8 +444,9 @@ _dbus_keyring_reload (DBusKeyring *keyring,
}
dbus_error_init (&tmp_error);
- if (!_dbus_file_get_contents (&contents,
+ if (!_dbus_file_get_contents (&contents,
&keyring->filename,
+ NULL,
&tmp_error))
{
_dbus_verbose ("Failed to load keyring file: %s\n",
@@ -477,7 +478,7 @@ _dbus_keyring_reload (DBusKeyring *keyring,
/* Don't load more than the max. */
if (n_keys >= (add_new ? MAX_KEYS_IN_FILE - 1 : MAX_KEYS_IN_FILE))
break;
-
+
next = 0;
if (!_dbus_string_parse_int (&line, 0, &val, &next))
{
@@ -490,11 +491,11 @@ _dbus_keyring_reload (DBusKeyring *keyring,
_dbus_verbose ("invalid secret key ID at start of line\n");
continue;
}
-
+
id = val;
_dbus_string_skip_blank (&line, next, &next);
-
+
if (!_dbus_string_parse_int (&line, next, &timestamp, &next))
{
_dbus_verbose ("could not parse secret key timestamp\n");
@@ -509,7 +510,7 @@ _dbus_keyring_reload (DBusKeyring *keyring,
now - timestamp, timestamp, now);
continue;
}
-
+
_dbus_string_skip_blank (&line, next, &next);
len = _dbus_string_get_length (&line);
@@ -519,7 +520,7 @@ _dbus_keyring_reload (DBusKeyring *keyring,
_dbus_verbose ("no secret key after ID and timestamp\n");
continue;
}
-
+
/* We have all three parts */
new = dbus_realloc (keys, sizeof (DBusKey) * (n_keys + 1));
if (new == NULL)
@@ -537,7 +538,7 @@ _dbus_keyring_reload (DBusKeyring *keyring,
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
goto out;
}
-
+
keys[n_keys-1].id = id;
keys[n_keys-1].creation_time = timestamp;
if (!_dbus_string_hex_decode (&line, next, &end,
@@ -593,8 +594,8 @@ _dbus_keyring_reload (DBusKeyring *keyring,
goto nomem;
if (!_dbus_string_append_byte (&contents, '\n'))
- goto nomem;
-
+ goto nomem;
+
++i;
continue;
@@ -602,7 +603,7 @@ _dbus_keyring_reload (DBusKeyring *keyring,
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
goto out;
}
-
+
if (!_dbus_string_save_to_file (&contents, &keyring->filename,
error))
goto out;
@@ -614,13 +615,13 @@ _dbus_keyring_reload (DBusKeyring *keyring,
keyring->n_keys = n_keys;
keys = NULL;
n_keys = 0;
-
- retval = TRUE;
-
+
+ retval = TRUE;
+
out:
if (have_lock)
_dbus_keyring_unlock (keyring);
-
+
if (! ((retval == TRUE && (error == NULL || error->name == NULL)) ||
(retval == FALSE && (error == NULL || error->name != NULL))))
{
@@ -630,7 +631,7 @@ _dbus_keyring_reload (DBusKeyring *keyring,
retval, error, error->name ? error->name : "(none)");
_dbus_assert_not_reached ("didn't handle errors properly");
}
-
+
if (keys != NULL)
{
i = 0;
@@ -643,7 +644,7 @@ _dbus_keyring_reload (DBusKeyring *keyring,
dbus_free (keys);
}
-
+
_dbus_string_free (&contents);
_dbus_string_free (&line);
@@ -692,7 +693,7 @@ _dbus_keyring_unref (DBusKeyring *keyring)
_dbus_string_free (&keyring->filename_lock);
_dbus_string_free (&keyring->directory);
free_keys (keyring->keys, keyring->n_keys);
- dbus_free (keyring);
+ dbus_free (keyring);
}
}
@@ -716,13 +717,13 @@ _dbus_keyring_new_for_credentials (DBusCredentials *credentials,
dbus_bool_t error_set;
DBusError tmp_error;
DBusCredentials *our_credentials;
-
+
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
-
+
keyring = NULL;
error_set = FALSE;
our_credentials = NULL;
-
+
if (!_dbus_string_init (&ringdir))
{
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
@@ -737,7 +738,7 @@ _dbus_keyring_new_for_credentials (DBusCredentials *credentials,
{
our_credentials = _dbus_credentials_new_from_current_process ();
}
-
+
if (our_credentials == NULL)
goto failed;
@@ -746,11 +747,11 @@ _dbus_keyring_new_for_credentials (DBusCredentials *credentials,
if (!_dbus_credentials_add_from_current_process (our_credentials))
goto failed;
}
-
+
if (!_dbus_append_keyring_directory_for_credentials (&ringdir,
our_credentials))
goto failed;
-
+
keyring = _dbus_keyring_new ();
if (keyring == NULL)
goto failed;
@@ -758,7 +759,7 @@ _dbus_keyring_new_for_credentials (DBusCredentials *credentials,
_dbus_assert (keyring->credentials == NULL);
keyring->credentials = our_credentials;
our_credentials = NULL; /* so we don't unref it again later */
-
+
/* should have been validated already, but paranoia check here */
if (!_dbus_keyring_validate_context (context))
{
@@ -772,7 +773,7 @@ _dbus_keyring_new_for_credentials (DBusCredentials *credentials,
/* Save keyring dir in the keyring object */
if (!_dbus_string_copy (&ringdir, 0,
&keyring->directory, 0))
- goto failed;
+ goto failed;
/* Create keyring->filename based on keyring dir and context */
if (!_dbus_string_copy (&keyring->directory, 0,
@@ -799,7 +800,7 @@ _dbus_keyring_new_for_credentials (DBusCredentials *credentials,
tmp_error.message);
dbus_error_free (&tmp_error);
}
-
+
/* We don't fail fatally if we can't create the directory,
* but the keyring will probably always be empty
* unless someone else manages to create it
@@ -814,9 +815,9 @@ _dbus_keyring_new_for_credentials (DBusCredentials *credentials,
}
_dbus_string_free (&ringdir);
-
+
return keyring;
-
+
failed:
if (!error_set)
dbus_set_error_const (error,
@@ -858,8 +859,8 @@ _dbus_keyring_validate_context (const DBusString *context)
_dbus_verbose ("context not valid ascii\n");
return FALSE;
}
-
- /* no directory separators */
+
+ /* no directory separators */
if (_dbus_string_find (context, 0, "/", NULL))
{
_dbus_verbose ("context contains a slash\n");
@@ -899,7 +900,7 @@ _dbus_keyring_validate_context (const DBusString *context)
_dbus_verbose ("context contains a carriage return\n");
return FALSE;
}
-
+
return TRUE;
}
@@ -910,7 +911,7 @@ find_recent_key (DBusKeyring *keyring)
long tv_sec, tv_usec;
_dbus_get_current_time (&tv_sec, &tv_usec);
-
+
i = 0;
while (i < keyring->n_keys)
{
@@ -918,10 +919,10 @@ find_recent_key (DBusKeyring *keyring)
_dbus_verbose ("Key %d is %ld seconds old\n",
i, tv_sec - key->creation_time);
-
+
if ((tv_sec - NEW_KEY_TIMEOUT_SECONDS) < key->creation_time)
return key;
-
+
++i;
}
@@ -946,7 +947,7 @@ _dbus_keyring_get_best_key (DBusKeyring *keyring,
DBusKey *key;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
-
+
key = find_recent_key (keyring);
if (key)
return key->id;
@@ -1033,14 +1034,14 @@ _dbus_keyring_test (void)
ring1 = NULL;
ring2 = NULL;
-
+
/* Context validation */
-
+
_dbus_string_init_const (&context, "foo");
_dbus_assert (_dbus_keyring_validate_context (&context));
_dbus_string_init_const (&context, "org_freedesktop_blah");
_dbus_assert (_dbus_keyring_validate_context (&context));
-
+
_dbus_string_init_const (&context, "");
_dbus_assert (!_dbus_keyring_validate_context (&context));
_dbus_string_init_const (&context, ".foo");
@@ -1059,7 +1060,7 @@ _dbus_keyring_test (void)
_dbus_assert (_dbus_keyring_validate_context (&context));
_dbus_string_init_const (&context, "foo bar");
_dbus_assert (!_dbus_keyring_validate_context (&context));
-
+
if (!_dbus_string_init (&context))
_dbus_assert_not_reached ("no memory");
if (!_dbus_string_append_byte (&context, '\0'))
@@ -1089,7 +1090,7 @@ _dbus_keyring_test (void)
ring2 = _dbus_keyring_new_for_credentials (NULL, &context, &error);
_dbus_assert (ring2 != NULL);
_dbus_assert (error.name == NULL);
-
+
if (ring1->n_keys != ring2->n_keys)
{
fprintf (stderr, "Different number of keys in keyrings\n");
@@ -1107,7 +1108,7 @@ _dbus_keyring_test (void)
fprintf (stderr, "Keyring 1 has first key ID %d and keyring 2 has %d\n",
ring1->keys[i].id, ring2->keys[i].id);
goto failure;
- }
+ }
if (ring1->keys[i].creation_time != ring2->keys[i].creation_time)
{
@@ -1122,7 +1123,7 @@ _dbus_keyring_test (void)
fprintf (stderr, "Keyrings 1 and 2 have different secrets for same ID/timestamp\n");
goto failure;
}
-
+
++i;
}
@@ -1138,7 +1139,7 @@ _dbus_keyring_test (void)
/* really unref */
_dbus_keyring_unref (ring1);
_dbus_keyring_unref (ring2);
-
+
return TRUE;
failure:
@@ -1151,4 +1152,3 @@ _dbus_keyring_test (void)
}
#endif /* DBUS_BUILD_TESTS */
-