From a07bc460ae1a3d3582a6dac7e48ed1ea117990ef Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Wed, 5 Feb 2003 05:56:53 +0000 Subject: 2003-02-02 Havoc Pennington * dbus/dbus-keyring.c, dbus/dbus-keyring.h: template files for code to manage cookies in your home directory * dbus/dbus-sysdeps.c (_dbus_generate_random_bytes): new function * dbus/dbus-auth.c (get_state): impose a maximum number of tries to authenticate, then disconnect the client. --- ChangeLog | 10 ++++++ dbus/dbus-auth.c | 24 +++++++++++++- dbus/dbus-keyring.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++ dbus/dbus-keyring.h | 50 ++++++++++++++++++++++++++++ dbus/dbus-string.c | 10 +++++- dbus/dbus-sysdeps.c | 63 +++++++++++++++++++++++++++++++++++ dbus/dbus-sysdeps.h | 3 ++ 7 files changed, 253 insertions(+), 2 deletions(-) create mode 100644 dbus/dbus-keyring.c create mode 100644 dbus/dbus-keyring.h diff --git a/ChangeLog b/ChangeLog index da8aa67c..0c01740e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2003-02-02 Havoc Pennington + + * dbus/dbus-keyring.c, dbus/dbus-keyring.h: template files + for code to manage cookies in your home directory + + * dbus/dbus-sysdeps.c (_dbus_generate_random_bytes): new function + + * dbus/dbus-auth.c (get_state): impose a maximum number of tries + to authenticate, then disconnect the client. + 2003-02-03 Alexander Larsson * dbus/dbus-message.c (dbus_message_append_fields): diff --git a/dbus/dbus-auth.c b/dbus/dbus-auth.c index 348cd27c..55b2c9b5 100644 --- a/dbus/dbus-auth.c +++ b/dbus/dbus-auth.c @@ -147,7 +147,7 @@ typedef struct { DBusAuth base; - DBusList *mechs_to_try; + DBusList *mechs_to_try; /**< Mechanisms we got from the server that we're going to try using */ } DBusAuthClient; @@ -155,6 +155,9 @@ typedef struct { DBusAuth base; + int failures; /**< Number of times client has been rejected */ + int max_failures; /**< Number of times we reject before disconnect */ + } DBusAuthServer; static dbus_bool_t process_auth (DBusAuth *auth, @@ -283,6 +286,11 @@ _dbus_auth_new (int size) static DBusAuthState get_state (DBusAuth *auth) { + if (DBUS_AUTH_IS_SERVER (auth) && + DBUS_AUTH_SERVER (auth)->failures >= + DBUS_AUTH_SERVER (auth)->max_failures) + auth->need_disconnect = TRUE; + if (auth->need_disconnect) return DBUS_AUTH_STATE_NEED_DISCONNECT; else if (auth->authenticated) @@ -585,6 +593,7 @@ static dbus_bool_t send_rejected (DBusAuth *auth) { DBusString command; + DBusAuthServer *server_auth; int i; if (!_dbus_string_init (&command, _DBUS_INT_MAX)) @@ -614,6 +623,10 @@ send_rejected (DBusAuth *auth) if (!_dbus_string_copy (&command, 0, &auth->outgoing, _dbus_string_get_length (&auth->outgoing))) goto nomem; + + _dbus_assert (DBUS_AUTH_IS_SERVER (auth)); + server_auth = DBUS_AUTH_SERVER (auth); + server_auth->failures += 1; return TRUE; @@ -1170,12 +1183,21 @@ DBusAuth* _dbus_auth_server_new (void) { DBusAuth *auth; + DBusAuthServer *server_auth; auth = _dbus_auth_new (sizeof (DBusAuthServer)); if (auth == NULL) return NULL; auth->handlers = server_handlers; + + server_auth = DBUS_AUTH_SERVER (auth); + + /* perhaps this should be per-mechanism with a lower + * max + */ + server_auth->failures = 0; + server_auth->max_failures = 6; return auth; } diff --git a/dbus/dbus-keyring.c b/dbus/dbus-keyring.c new file mode 100644 index 00000000..32695bb9 --- /dev/null +++ b/dbus/dbus-keyring.c @@ -0,0 +1,95 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* dbus-keyring.c Store secret cookies in your homedir + * + * Copyright (C) 2003 Red Hat Inc. + * + * Licensed under the Academic Free License version 1.2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "dbus-keyring.h" +#include +#include +#include + +/** + * @defgroup DBusKeyring keyring class + * @ingroup DBusInternals + * @brief DBusKeyring data structure + * + * Types and functions related to DBusKeyring. DBusKeyring is intended + * to manage cookies used to authenticate clients to servers. This is + * essentially the "verify that client can read the user's homedir" + * authentication mechanism. Both client and server must have access + * to the homedir. + * + * The secret keys are not kept in locked memory, and are written to a + * file in the user's homedir. However they are transient (only used + * by a single server instance for a fixed period of time, then + * discarded). Also, the keys are not sent over the wire. + */ + +/** + * @defgroup DBusKeyringInternals DBusKeyring implementation details + * @ingroup DBusInternals + * @brief DBusKeyring implementation details + * + * The guts of DBusKeyring. + * + * @{ + */ + +typedef struct +{ + dbus_uint32_t id; /**< identifier used to refer to the key */ + + unsigned long creation_time; /**< when the key was generated, + * as unix timestamp + */ + + DBusString context; /**< Name of kind of server using this + * key, for example "desktop_session_bus" + */ + + DBusString secret; /**< the actual key */ + +} DBusKey; + +/** + * @brief Internals of DBusKeyring. + * + * DBusKeyring internals. DBusKeyring is an opaque object, it must be + * used via accessor functions. + */ +struct DBusKeyring +{ + DBusString filename; + DBusString lock_filename; + + +}; + +/** @} */ /* end of internals */ + +/** + * @addtogroup DBusKeyring + * + * @{ + */ + + +/** @} */ /* end of public API */ diff --git a/dbus/dbus-keyring.h b/dbus/dbus-keyring.h new file mode 100644 index 00000000..c60c64ef --- /dev/null +++ b/dbus/dbus-keyring.h @@ -0,0 +1,50 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* dbus-keyring.h Store secret cookies in your homedir + * + * Copyright (C) 2003 Red Hat Inc. + * + * Licensed under the Academic Free License version 1.2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef DBUS_KEYRING_H +#define DBUS_KEYRING_H + +#include +#include + +DBUS_BEGIN_DECLS; + +typedef struct DBusKeyring DBusKeyring; + + +DBusKeyring* _dbus_keyring_load (const char *context, + DBusResultCode *result); +void _dbus_keyring_ref (DBusKeyring *keyring); +void _dbus_keyring_unref (DBusKeyring *keyring); +dbus_bool_t _dbus_keyring_create_challenge (DBusKeyring *keyring, + DBusString *challenge); +dbus_bool_t _dbus_keyring_compute_response (DBusKeyring *keyring, + const DBusString *challenge, + DBusString *response); +dbus_bool_t _dbus_keyring_check_response (DBusKeyring *keyring, + const DBusString *challenge, + const DBusString *response); + + +DBUS_END_DECLS; + +#endif /* DBUS_KEYRING_H */ diff --git a/dbus/dbus-string.c b/dbus/dbus-string.c index 17a7d918..a5bf3ebc 100644 --- a/dbus/dbus-string.c +++ b/dbus/dbus-string.c @@ -374,7 +374,11 @@ _dbus_string_get_data (DBusString *str, } /** - * Gets the raw character buffer from a const string. + * Gets the raw character buffer from a const string. + * + * @todo should return the const char* instead of using an out param; + * the temporary variable encourages a bug where you use const data + * after modifying the string and possibly causing a realloc. * * @param str the string * @param data_return location to store returned data @@ -420,6 +424,10 @@ _dbus_string_get_data_len (DBusString *str, /** * const version of _dbus_string_get_data_len(). * + * @todo should return the const char* instead of using an out param; + * the temporary variable encourages a bug where you use const data + * after modifying the string and possibly causing a realloc. + * * @param str the string * @param data_return location to return the buffer * @param start byte offset to return diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c index db5118a5..38efb0cd 100644 --- a/dbus/dbus-sysdeps.c +++ b/dbus/dbus-sysdeps.c @@ -1336,5 +1336,68 @@ _dbus_directory_close (DBusDirIter *iter) dbus_free (iter); } +/** + * Generates the given number of random bytes, + * using the best mechanism we can come up with. + * + * @param str the string + * @param n_bytes the number of random bytes to append to string + * @returns #TRUE on success, #FALSE if no memory or other failure + */ +dbus_bool_t +_dbus_generate_random_bytes (DBusString *str, + int n_bytes) +{ + int old_len; + int fd; + + old_len = _dbus_string_get_length (str); + fd = -1; + + /* note, urandom on linux will fall back to pseudorandom */ + fd = open ("/dev/urandom", O_RDONLY); + if (fd < 0) + { + unsigned long tv_usec; + int i; + + /* fall back to pseudorandom */ + + _dbus_get_current_time (NULL, &tv_usec); + srand (tv_usec); + + i = 0; + while (i < n_bytes) + { + double r; + int b; + + r = rand (); + b = (r / (double) RAND_MAX) * 255.0; + + if (!_dbus_string_append_byte (str, b)) + goto failed; + + ++i; + } + + return TRUE; + } + else + { + if (_dbus_read (fd, str, n_bytes) != n_bytes) + goto failed; + + close (fd); + + return TRUE; + } + + failed: + _dbus_string_set_length (str, old_len); + if (fd >= 0) + close (fd); + return FALSE; +} /** @} end of sysdeps */ diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index fd0d93de..3212a237 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -140,6 +140,9 @@ dbus_bool_t _dbus_directory_get_next_file (DBusDirIter *iter, void _dbus_directory_close (DBusDirIter *iter); +dbus_bool_t _dbus_generate_random_bytes (DBusString *str, + int n_bytes); + DBUS_END_DECLS; #endif /* DBUS_SYSDEPS_H */ -- cgit