summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2003-02-05 05:56:53 +0000
committerHavoc Pennington <hp@redhat.com>2003-02-05 05:56:53 +0000
commita07bc460ae1a3d3582a6dac7e48ed1ea117990ef (patch)
tree951980157d356ce81ef1aadc9b860dce85acd4a9
parent69824400caa9ff2a1f24e06728f27e0f50f0033d (diff)
2003-02-02 Havoc Pennington <hp@pobox.com>
* 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.
-rw-r--r--ChangeLog10
-rw-r--r--dbus/dbus-auth.c24
-rw-r--r--dbus/dbus-keyring.c95
-rw-r--r--dbus/dbus-keyring.h50
-rw-r--r--dbus/dbus-string.c10
-rw-r--r--dbus/dbus-sysdeps.c63
-rw-r--r--dbus/dbus-sysdeps.h3
7 files changed, 253 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index da8aa67c..0c01740e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2003-02-02 Havoc Pennington <hp@pobox.com>
+
+ * 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 <alexl@redhat.com>
* 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 <dbus/dbus-string.h>
+#include <dbus/dbus-list.h>
+#include <dbus/dbus-sysdeps.h>
+
+/**
+ * @defgroup DBusKeyring keyring class
+ * @ingroup DBusInternals
+ * @brief DBusKeyring data structure
+ *
+ * Types and functions related to DBusKeyring. DBusKeyring is intended
+ * to manage cookies used to authenticate clients to servers. This is
+ * essentially the "verify that client can read the user's homedir"
+ * authentication mechanism. Both client and server must have access
+ * to the homedir.
+ *
+ * The secret keys are not kept in locked memory, and are written to a
+ * file in the user's homedir. However they are transient (only used
+ * by a single server instance for a fixed period of time, then
+ * discarded). Also, the keys are not sent over the wire.
+ */
+
+/**
+ * @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 <dbus/dbus-macros.h>
+#include <dbus/dbus-errors.h>
+
+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 */