[gnome-keyring] [daemon] Large refactoring of prompting for pkcs11 logins.
- From: Stefan Walter <stefw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-keyring] [daemon] Large refactoring of prompting for pkcs11 logins.
- Date: Sat, 19 Dec 2009 19:07:21 +0000 (UTC)
commit 9ea8eaa48fb22201e2f63d78ff4a331c1d3ce0ca
Author: Stef Walter <stef memberwebs com>
Date: Sat Dec 19 19:00:01 2009 +0000
[daemon] Large refactoring of prompting for pkcs11 logins.
* Remove old ask code.
* Remove old async code, location code daemon util code.
* Move our custom GtkEntryBuffer into egg.
* Remove old EggSecureEntry stuff.
* Rework how threading works in pkcs11 daemon auth and prompting.
* Use new prompting stuff for pkcs11 logins.
* Make several fixes to the daemon/login code.
configure.in | 3 -
daemon/Makefile.am | 6 +-
daemon/dbus/gkd-dbus-secrets.c | 4 +-
daemon/gkd-main.c | 19 +-
daemon/login/gkd-login.c | 30 +-
daemon/pkcs11/Makefile.am | 11 +-
.../{gkr-pkcs11-auth-ep.c => gkd-pkcs11-auth.c} | 860 +++++--
.../{gkr-pkcs11-daemon.h => gkd-pkcs11-auth.h} | 32 +-
daemon/pkcs11/gkd-pkcs11-data.c | 263 ++
daemon/pkcs11/gkd-pkcs11-data.h | 52 +
.../pkcs11/{gkr-pkcs11-daemon.c => gkd-pkcs11.c} | 168 +-
.../pkcs11/{gkr-pkcs11-daemon.h => gkd-pkcs11.h} | 32 +-
daemon/pkcs11/gkr-pkcs11-auth.c | 657 -----
daemon/pkcs11/gkr-pkcs11-auth.h | 96 -
daemon/prompt/Makefile.am | 2 +-
daemon/prompt/gkd-prompt-buffer.h | 59 -
daemon/prompt/gkd-prompt-tool.c | 4 +-
daemon/prompt/gkd-prompt.c | 55 +-
daemon/prompt/gkd-prompt.h | 7 +
daemon/prompt/gkd-prompt.ui | 13 +-
daemon/ui/.gitignore | 7 -
daemon/ui/Makefile.am | 48 -
daemon/ui/gkr-ask-daemon.c | 194 --
daemon/ui/gkr-ask-daemon.h | 37 -
daemon/ui/gkr-ask-marshal.list | 1 -
daemon/ui/gkr-ask-request.c | 967 -------
daemon/ui/gkr-ask-request.h | 145 -
daemon/ui/gkr-ask-tool-widgets.c | 201 --
daemon/ui/gkr-ask-tool.c | 862 ------
daemon/ui/gkr-ask-tool.h | 33 -
daemon/ui/test-input.txt | 8 -
daemon/util/.gitignore | 5 -
daemon/util/Makefile.am | 31 -
daemon/util/gkr-daemon-async.c | 633 -----
daemon/util/gkr-daemon-async.h | 171 --
daemon/util/gkr-daemon-util.c | 230 --
daemon/util/gkr-daemon-util.h | 70 -
daemon/util/gkr-location.c | 959 -------
daemon/util/gkr-location.h | 130 -
daemon/util/tests/.gitignore | 7 -
daemon/util/tests/Makefile.am | 12 -
daemon/util/tests/unit-test-async.c | 222 --
daemon/util/tests/unit-test-location.c | 209 --
egg/Makefile.am | 14 +-
.../gkd-prompt-buffer.c => egg/egg-entry-buffer.c | 61 +-
egg/egg-entry-buffer.h | 59 +
egg/egg-secure-entry.c | 2754 --------------------
egg/egg-secure-entry.h | 187 --
gcr/Makefile.am | 2 +-
gcr/gcr-certificate.c | 2 +-
gcr/gcr-import-dialog.c | 15 +-
51 files changed, 1230 insertions(+), 9419 deletions(-)
---
diff --git a/configure.in b/configure.in
index 81c1c0d..a4bc774 100644
--- a/configure.in
+++ b/configure.in
@@ -558,9 +558,6 @@ daemon/login/Makefile
daemon/pkcs11/Makefile
daemon/prompt/Makefile
daemon/prompt/tests/Makefile
-daemon/ui/Makefile
-daemon/util/Makefile
-daemon/util/tests/Makefile
docs/Makefile
docs/reference/Makefile
docs/reference/gcr/Makefile
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 5e3143f..979715f 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -1,6 +1,4 @@
SUBDIRS = \
- util \
- ui \
prompt \
login \
control \
@@ -30,13 +28,11 @@ gnome_keyring_daemon_SOURCES = \
gkd-util.c gkd-util.h
gnome_keyring_daemon_LDADD = \
- $(top_builddir)/daemon/pkcs11/libgkr-pkcs11.la \
+ $(top_builddir)/daemon/pkcs11/libgkd-pkcs11.la \
$(top_builddir)/daemon/dbus/libgkr-dbus.la \
$(top_builddir)/daemon/login/libgkd-login.la \
- $(top_builddir)/daemon/ui/libgkr-ui.la \
$(top_builddir)/daemon/control/libgkd-control.la \
$(top_builddir)/daemon/prompt/libgkd-prompt.la \
- $(top_builddir)/daemon/util/libgkr-daemon-util.la \
$(top_builddir)/pkcs11/plex-layer/libgck-plex-layer.la \
$(top_builddir)/pkcs11/roots-store/libgck-roots-store.la \
$(top_builddir)/pkcs11/rpc-layer/libgck-rpc-layer.la \
diff --git a/daemon/dbus/gkd-dbus-secrets.c b/daemon/dbus/gkd-dbus-secrets.c
index e049d2a..68ab9f7 100644
--- a/daemon/dbus/gkd-dbus-secrets.c
+++ b/daemon/dbus/gkd-dbus-secrets.c
@@ -26,7 +26,7 @@
#include "gkd-dbus-private.h"
#include "gkd-secret-service.h"
-#include "daemon/pkcs11/gkr-pkcs11-daemon.h"
+#include "daemon/pkcs11/gkd-pkcs11.h"
#include "gp11/gp11.h"
@@ -40,7 +40,7 @@ calculate_secrets_slot (void)
GList *slots, *l;
GP11SlotInfo *info;
- module = gp11_module_new (gkr_pkcs11_daemon_get_functions ());
+ module = gp11_module_new (gkd_pkcs11_get_functions ());
g_return_val_if_fail (module, NULL);
/*
diff --git a/daemon/gkd-main.c b/daemon/gkd-main.c
index 01d297b..f88362f 100644
--- a/daemon/gkd-main.c
+++ b/daemon/gkd-main.c
@@ -37,11 +37,7 @@
#include "login/gkd-login.h"
-#include "pkcs11/gkr-pkcs11-daemon.h"
-
-#include "ui/gkr-ask-daemon.h"
-
-#include "util/gkr-daemon-async.h"
+#include "pkcs11/gkd-pkcs11.h"
#include <errno.h>
#include <fcntl.h>
@@ -635,13 +631,13 @@ gkr_daemon_startup_steps (void)
/* Startup the appropriate components, creates sockets etc.. */
#ifdef WITH_SSH
if (check_run_component ("ssh")) {
- if (!gkr_pkcs11_daemon_startup_ssh ())
+ if (!gkd_pkcs11_startup_ssh ())
return FALSE;
}
#endif
if (check_run_component ("pkcs11")) {
- if (!gkr_pkcs11_daemon_startup_pkcs11 ())
+ if (!gkd_pkcs11_startup_pkcs11 ())
return FALSE;
}
@@ -653,7 +649,7 @@ static gboolean
gkr_daemon_initialize_steps (void)
{
/* Initialize new style PKCS#11 components */
- if (!gkr_pkcs11_daemon_initialize ())
+ if (!gkd_pkcs11_initialize ())
return FALSE;
/*
@@ -756,7 +752,6 @@ main (int argc, char *argv[])
/* Initialize our daemon main loop and threading */
loop = g_main_loop_new (NULL, FALSE);
ctx = g_main_loop_get_context (loop);
- gkr_daemon_async_workers_init (loop);
/* Initialize our control socket */
if (!gkd_control_listen ())
@@ -800,15 +795,9 @@ main (int argc, char *argv[])
g_main_loop_run (loop);
- /* Make sure no other threads are running */
- gkr_daemon_async_workers_stop_all ();
-
/* This wraps everything up in order */
egg_cleanup_perform ();
- /* Final shutdown of anything workers running about */
- gkr_daemon_async_workers_uninit ();
-
/* Wrap up signal handling here */
cleanup_signal_handling ();
diff --git a/daemon/login/gkd-login.c b/daemon/login/gkd-login.c
index f327e34..772916b 100644
--- a/daemon/login/gkd-login.c
+++ b/daemon/login/gkd-login.c
@@ -25,7 +25,7 @@
#include "egg/egg-secure-memory.h"
-#include "pkcs11/gkr-pkcs11-daemon.h"
+#include "pkcs11/gkd-pkcs11.h"
#include "pkcs11/pkcs11i.h"
#include <string.h>
@@ -41,7 +41,7 @@ note_that_unlock_failed (void)
static GP11Module*
module_instance (void)
{
- GP11Module *module = gp11_module_new (gkr_pkcs11_daemon_get_base_functions ());
+ GP11Module *module = gp11_module_new (gkd_pkcs11_get_base_functions ());
gp11_module_set_pool_sessions (module, FALSE);
gp11_module_set_auto_authenticate (module, FALSE);
g_return_val_if_fail (module, NULL);
@@ -52,14 +52,20 @@ static GP11Session*
open_and_login_session (GP11Slot *slot, CK_USER_TYPE user_type, GError **error)
{
GP11Session *session;
+ GError *err = NULL;
g_return_val_if_fail (GP11_IS_SLOT (slot), NULL);
+ if (!error)
+ error = &err;
+
session = gp11_slot_open_session (slot, CKF_RW_SESSION, error);
if (session != NULL) {
if (!gp11_session_login (session, user_type, NULL, 0, error)) {
- g_object_unref (session);
- session = NULL;
+ if ((*error)->code != CKR_USER_ALREADY_LOGGED_IN) {
+ g_object_unref (session);
+ session = NULL;
+ }
}
}
@@ -458,7 +464,7 @@ gkd_login_is_usable (void)
login = lookup_login_keyring (session);
if (login) {
data = gp11_object_get_data (login, CKA_G_LOCKED, &n_data, NULL);
- usable = (data && n_data == sizeof (CK_BBOOL) && *((CK_BBOOL*)data));
+ usable = (data && n_data == sizeof (CK_BBOOL) && !*((CK_BBOOL*)data));
g_free (data);
g_object_unref (login);
}
@@ -491,7 +497,7 @@ static GP11Object*
find_login_keyring_item (GP11Session *session, GP11Attribute *fields)
{
GP11Object *search;
- GP11Object *item;
+ GP11Object *item = NULL;
GList *objects;
GError *error = NULL;
gpointer data;
@@ -503,6 +509,7 @@ find_login_keyring_item (GP11Session *session, GP11Attribute *fields)
search = gp11_session_create_object (session, &error,
CKA_CLASS, GP11_ULONG, CKO_G_SEARCH,
CKA_G_COLLECTION, 5, "login",
+ CKA_TOKEN, GP11_BOOLEAN, FALSE,
CKA_G_FIELDS, fields->length, fields->value,
GP11_INVALID);
@@ -591,12 +598,11 @@ gkd_login_attach_secret (const gchar *display_name, const gchar *secret,
gchar*
gkd_login_lookup_secret (const gchar *first, ...)
{
- GError *error = NULL;
GP11Attribute fields;
GP11Session *session;
GP11Module *module;
GP11Object* item;
- gpointer data;
+ gpointer data = NULL;
gsize n_data;
va_list va;
@@ -609,9 +615,9 @@ gkd_login_lookup_secret (const gchar *first, ...)
va_end(va);
item = find_login_keyring_item (session, &fields);
- if (item == NULL) {
- data = gp11_object_get_data_full (item, CKA_VALUE, egg_secure_realloc, NULL, &n_data, &error);
- if (!g_utf8_validate (data, n_data, NULL)) {
+ if (item != NULL) {
+ data = gp11_object_get_data_full (item, CKA_VALUE, egg_secure_realloc, NULL, &n_data, NULL);
+ if (data && !g_utf8_validate (data, n_data, NULL)) {
g_warning ("expected string, but found binary secret in login keyring");
egg_secure_clear (data, n_data);
egg_secure_free (data);
@@ -646,7 +652,7 @@ gkd_login_remove_secret (const gchar *first, ...)
va_end(va);
item = find_login_keyring_item (session, &fields);
- if (item == NULL) {
+ if (item != NULL) {
if (!gp11_object_destroy (item, &error)) {
g_warning ("couldn't remove stored secret from login keyring: %s", error->message);
g_clear_error (&error);
diff --git a/daemon/pkcs11/Makefile.am b/daemon/pkcs11/Makefile.am
index bcae8ce..f096027 100644
--- a/daemon/pkcs11/Makefile.am
+++ b/daemon/pkcs11/Makefile.am
@@ -8,14 +8,15 @@ INCLUDES = \
$(GLIB_CFLAGS)
DAEMON_SRCS = \
- gkr-pkcs11-auth.c gkr-pkcs11-auth.h gkr-pkcs11-auth-ep.c \
- gkr-pkcs11-daemon.c gkr-pkcs11-daemon.h
+ gkd-pkcs11-auth.c gkd-pkcs11-auth.h \
+ gkd-pkcs11-data.c gkd-pkcs11-data.h \
+ gkd-pkcs11.c gkd-pkcs11.h
-noinst_LTLIBRARIES = libgkr-pkcs11.la
+noinst_LTLIBRARIES = libgkd-pkcs11.la
-libgkr_pkcs11_la_SOURCES = $(DAEMON_SRCS)
+libgkd_pkcs11_la_SOURCES = $(DAEMON_SRCS)
-libgkr_pkcs11_la_LIBADD = \
+libgkd_pkcs11_la_LIBADD = \
$(GLIB_LIBS) \
$(GOBJECT_LIBS)
diff --git a/daemon/pkcs11/gkr-pkcs11-auth-ep.c b/daemon/pkcs11/gkd-pkcs11-auth.c
similarity index 63%
rename from daemon/pkcs11/gkr-pkcs11-auth-ep.c
rename to daemon/pkcs11/gkd-pkcs11-auth.c
index 984b297..599e212 100644
--- a/daemon/pkcs11/gkr-pkcs11-auth-ep.c
+++ b/daemon/pkcs11/gkd-pkcs11-auth.c
@@ -1,65 +1,81 @@
-/*
+/*
* gnome-keyring
- *
+ *
* Copyright (C) 2008 Stefan Walter
- *
- * This program is free software; you can redistribute it and/or modify
+ *
+ * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General License as
* published by the Free Software Foundation; either version 2.1 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
* Lesser General License for more details.
- *
- * You should have received a copy of the GNU Lesser General
+ *
+ * You should have received a copy of the GNU Lesser General
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * 02111-1307, USA.
*/
#include "config.h"
-#include "gkr-pkcs11-auth.h"
+#include "gkd-pkcs11-auth.h"
+#include "gkd-pkcs11-data.h"
+
+#include "egg/egg-secure-memory.h"
-#include "daemon/util/gkr-daemon-async.h"
+#include "login/gkd-login.h"
#include "pkcs11/pkcs11.h"
#include "pkcs11/pkcs11g.h"
#include "pkcs11/pkcs11i.h"
+#include "prompt/gkd-prompt.h"
+
#include <glib.h>
+#include <glib/gi18n.h>
#include <string.h>
/*
- * All these function entry points operate outside of any threading locks.
- * Any calls to parts of the daemon must be locked inside blocks of:
- *
- * DAEMON_ENTER ();
- *
- * ...
- *
- * DAEMON_LEAVE ();
+ * All these function entry points operate outside of any threading locks.
+ * Only calls that may be made to gkd_*() functions are to gkd_pkcs11_auth_*()
+ * functions.
*/
static CK_FUNCTION_LIST_PTR pkcs11_lower = NULL;
-#define DAEMON_ENTER() \
- gkr_daemon_async_end_concurrent ()
+typedef struct _AuthObject {
+ CK_OBJECT_HANDLE handle;
+ CK_OBJECT_CLASS klass;
+ CK_SLOT_ID slot;
+ CK_BBOOL token;
+ gchar *label;
+ gchar *unique;
+ gchar *digest;
+} AuthObject;
-#define DAEMON_LEAVE() \
- gkr_daemon_async_begin_concurrent ()
+static void
+auth_object_free (gpointer data)
+{
+ AuthObject *object = data;
+ g_assert (object);
+ g_free (object->label);
+ g_free (object->unique);
+ g_free (object->digest);
+ g_free (object);
+}
/* --------------------------------------------------------------------------------------
- * HELPERS
+ * HELPERS
*/
-static GkrPkcs11AuthObject*
+static AuthObject*
auth_object_for_context_specific (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE object)
{
- GkrPkcs11AuthObject *info = NULL;
+ AuthObject *info = NULL;
CK_SESSION_INFO session_info;
CK_ATTRIBUTE attrs[6];
CK_OBJECT_CLASS klass;
@@ -92,19 +108,19 @@ auth_object_for_context_specific (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE obj
attrs[4].type = CKA_ALWAYS_AUTHENTICATE;
attrs[4].pValue = &always;
attrs[4].ulValueLen = sizeof (always);
-
+
token = CK_FALSE;
attrs[5].type = CKA_TOKEN;
attrs[5].pValue = &token;
attrs[5].ulValueLen = sizeof (token);
-
+
n_attrs = 6;
-
+
/* Get attribute sizes */
rv = (pkcs11_lower->C_GetAttributeValue) (handle, object, attrs, n_attrs);
if (rv != CKR_OK && rv != CKR_ATTRIBUTE_TYPE_INVALID)
return NULL;
-
+
/* If this isn't an always auth object, then skip */
if (always != CK_TRUE)
return NULL;
@@ -121,7 +137,7 @@ auth_object_for_context_specific (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE obj
attrs[1].pValue = unique = g_malloc0 (attrs[1].ulValueLen + 1);
if (attrs[2].ulValueLen != (CK_ULONG)-1)
attrs[2].pValue = digest = g_malloc0 (attrs[2].ulValueLen + 1);
-
+
/* Get actual attributes */
rv = (pkcs11_lower->C_GetAttributeValue) (handle, object, attrs, n_attrs);
if (rv != CKR_OK && rv != CKR_ATTRIBUTE_TYPE_INVALID) {
@@ -130,9 +146,9 @@ auth_object_for_context_specific (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE obj
g_free (digest);
return NULL;
}
-
- info = g_new0 (GkrPkcs11AuthObject, 1);
-
+
+ info = g_new0 (AuthObject, 1);
+
if (attrs[0].ulValueLen != (CK_ULONG)-1) {
info->label = label;
label = NULL;
@@ -142,7 +158,7 @@ auth_object_for_context_specific (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE obj
info->unique = unique;
unique = NULL;
}
-
+
if (attrs[2].ulValueLen != (CK_ULONG)-1) {
info->digest = digest;
digest = NULL;
@@ -152,11 +168,11 @@ auth_object_for_context_specific (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE obj
info->klass = klass;
info->handle = object;
info->slot = session_info.slotID;
-
+
g_free (label);
g_free (unique);
g_free (digest);
-
+
return info;
}
@@ -183,6 +199,464 @@ auth_create_credential (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object,
g_message ("failed to create credential object (code: %lu)", (gulong)rv);
}
+static void
+password_to_pin (const gchar *password, CK_UTF8CHAR_PTR *pin, CK_ULONG *pin_len)
+{
+ g_assert (pin);
+ g_assert (pin_len);
+
+ if (password == NULL) {
+ *pin = NULL;
+ *pin_len = 0;
+ } else {
+ *pin = (CK_UTF8CHAR_PTR)password;
+ *pin_len = strlen (password);
+ }
+}
+
+static void
+convert_upper_case (gchar *str)
+{
+ for (; *str; ++str)
+ *str = g_ascii_toupper (*str);
+}
+
+static GkdPrompt*
+on_prompt_attention (gpointer user_data)
+{
+ /* We were passed the prompt */
+ return g_object_ref (user_data);
+}
+
+static void
+clear_user_login (CK_TOKEN_INFO *info)
+{
+ gchar *manufacturer;
+ gchar *serial;
+
+ g_assert (info);
+
+ if (gkd_login_is_usable ()) {
+ /*
+ * The manufacturer and serial number together uniquely identify token
+ * They're stored with space padded in the token info structure.
+ */
+
+ manufacturer = g_strndup ((gchar*)info->manufacturerID, sizeof (info->manufacturerID));
+ g_strchomp (manufacturer);
+
+ serial = g_strndup ((gchar*)info->serialNumber, sizeof (info->serialNumber));
+ g_strchomp (serial);
+
+ gkd_login_remove_secret ("manufacturer", manufacturer,
+ "serial-number", serial,
+ NULL);
+
+ g_free (manufacturer);
+ g_free (serial);
+ }
+}
+
+static gboolean
+init_user_prompt (CK_SESSION_HANDLE handle, CK_TOKEN_INFO *info,
+ CK_UTF8CHAR_PTR *pin, CK_ULONG *pin_len)
+{
+ GkdPrompt *prompt;
+ gchar *password;
+ gchar *label;
+ gchar *secondary;
+ gchar *manufacturer;
+ gchar *serial;
+ gboolean ret = TRUE;
+
+ g_assert (info);
+ g_assert (pin);
+ g_assert (pin_len);
+
+ /*
+ * The manufacturer and serial number together uniquely identify token
+ * They're stored with space padded in the token info structure.
+ */
+
+ manufacturer = g_strndup ((gchar*)info->manufacturerID, sizeof (info->manufacturerID));
+ g_strchomp (manufacturer);
+
+ serial = g_strndup ((gchar*)info->serialNumber, sizeof (info->serialNumber));
+ g_strchomp (serial);
+
+ label = g_strndup ((gchar*)info->label, sizeof (info->label));
+ g_strchomp (label);
+
+ /* Build up the prompt */
+ prompt = gkd_prompt_new ();
+ gkd_prompt_show_widget (prompt, "password_area");
+ gkd_prompt_show_widget (prompt, "confirm_area");
+ gkd_prompt_set_title (prompt, _("New Password Required"));
+ gkd_prompt_set_primary_text (prompt, _("New password required for secure storage"));
+
+ secondary = g_strdup_printf (_("In order to prepare '%s' for storage of certificates or keys, a password is required"), label);
+ gkd_prompt_set_secondary_text (prompt, secondary);
+ g_free (secondary);
+
+#if 0
+ if (gkd_login_is_usable ())
+ gkd_ask_request_set_check_option (ask, _("Automatically unlock secure storage when I log in."));
+#endif
+
+ /* Prompt the user */
+ gkd_prompt_request_attention_async (NULL, on_prompt_attention, prompt, NULL);
+
+ if (!gkd_prompt_has_response (prompt)) {
+ ret = FALSE;
+
+ } else if (gkd_prompt_get_response (prompt) != GKD_RESPONSE_OK) {
+ ret = FALSE;
+
+ /* Successful response */
+ } else {
+ password = gkd_prompt_get_password (prompt, "password");
+ password_to_pin (password, pin, pin_len);
+
+#if 0
+ if (ask->checked) {
+ gkd_login_attach_secret (label, ask->typed_password,
+ "manufacturer", manufacturer,
+ "serial-number", serial,
+ NULL);
+ }
+#endif
+
+ ret = TRUE;
+ }
+
+ g_free (manufacturer);
+ g_free (serial);
+ g_free (label);
+
+ g_object_unref (prompt);
+ return ret;
+}
+
+static void
+init_user_done (CK_SESSION_HANDLE handle, CK_TOKEN_INFO *token_info,
+ CK_UTF8CHAR_PTR *pin, CK_ULONG *pin_len, CK_RV rv)
+{
+ g_assert (pin);
+ g_assert (pin_len);
+
+ if (rv != CKR_OK)
+ clear_user_login (token_info);
+
+ egg_secure_strfree ((gchar*)*pin);
+
+ *pin = NULL;
+ *pin_len = 0;
+}
+
+static const gchar*
+prepare_specific_title (CK_OBJECT_CLASS klass)
+{
+ switch (klass) {
+ case CKO_PRIVATE_KEY:
+ return _("Unlock private key");
+ case CKO_CERTIFICATE:
+ return _("Unlock certificate");
+ case CKO_PUBLIC_KEY:
+ return _("Unlock public key");
+ default:
+ return _("Unlock");
+ }
+}
+
+static const gchar*
+prepare_specific_primary (CK_OBJECT_CLASS klass)
+{
+ switch (klass) {
+ case CKO_PRIVATE_KEY:
+ return _("Enter password to unlock the private key");
+ case CKO_CERTIFICATE:
+ return _("Enter password to unlock the certificate");
+ case CKO_PUBLIC_KEY:
+ return _("Enter password to unlock the public key");
+ default:
+ return _("Enter password to unlock");
+ }
+}
+
+static gchar*
+prepare_specific_secondary (CK_OBJECT_CLASS klass, const gchar *label)
+{
+ switch (klass) {
+ case CKO_PRIVATE_KEY:
+ /* TRANSLATORS: The private key is locked */
+ return g_strdup_printf (_("An application wants access to the private key '%s', but it is locked"), label);
+ case CKO_CERTIFICATE:
+ /* TRANSLATORS: The certificate is locked */
+ return g_strdup_printf (_("An application wants access to the certificate '%s', but it is locked"), label);
+ case CKO_PUBLIC_KEY:
+ /* TRANSLATORS: The public key is locked */
+ return g_strdup_printf (_("An application wants access to the public key '%s', but it is locked"), label);
+ default:
+ /* TRANSLATORS: The object '%s' is locked */
+ return g_strdup_printf (_("An application wants access to '%s', but it is locked"), label);
+ }
+}
+
+static void
+login_specific_prepare (CK_SESSION_HANDLE handle, AuthObject *object)
+{
+ gkd_pkcs11_data_session_store (object->slot, handle, object, auth_object_free);
+}
+
+static gboolean
+login_specific_prompt (CK_SESSION_HANDLE handle, CK_SESSION_INFO *info,
+ CK_UTF8CHAR_PTR *pin, CK_ULONG *pin_len,
+ CK_OBJECT_HANDLE_PTR specific)
+{
+ AuthObject *object;
+ const gchar *password;
+ GkdPrompt *prompt;
+ gchar *secondary;
+ gboolean ret;
+
+ g_assert (info);
+ g_assert (pin);
+ g_assert (pin_len);
+
+ /* Because we should have been notified of open session */
+ object = gkd_pkcs11_data_session_lookup (info->slotID, handle);
+ if (object == NULL)
+ return FALSE;
+
+ if (specific)
+ *specific = object->handle;
+
+ /* See if we can just use the login keyring password for this */
+ if (object->unique && object->token) {
+ password = gkd_login_lookup_secret ("unique", object->unique, NULL);
+ if (password != NULL) {
+ password_to_pin (password, pin, pin_len);
+ return TRUE;
+ }
+ }
+
+ /* COMPAT: Check old method of storing secrets for objects in login keyring */
+ if (object->digest) {
+ convert_upper_case (object->digest);
+ password = gkd_login_lookup_secret ("object-digest", object->digest, NULL);
+ if (password != NULL) {
+ if (object->unique)
+ gkd_login_attach_secret (object->label, password,
+ "unique", object->unique, NULL);
+ password_to_pin (password, pin, pin_len);
+ return TRUE;
+ }
+ }
+
+ /* Build up the prompt */
+ prompt = gkd_prompt_new ();
+ gkd_prompt_show_widget (prompt, "password_area");
+ gkd_prompt_hide_widget (prompt, "confirm_area");
+ gkd_prompt_hide_widget (prompt, "original_area");
+ gkd_prompt_set_title (prompt, prepare_specific_title (object->klass));
+ gkd_prompt_set_primary_text (prompt, prepare_specific_primary (object->klass));
+
+ secondary = prepare_specific_secondary (object->klass, object->label);
+ gkd_prompt_set_secondary_text (prompt, secondary);
+ g_free (secondary);
+
+#if 0
+ if (object->unique && gkd_login_is_usable ())
+ gkd_ask_request_set_check_option (ask, prepare_specific_check (object->klass));
+#endif
+
+ /* Prompt the user */
+ gkd_prompt_request_attention_sync (NULL, on_prompt_attention, prompt, NULL);
+
+ if (!gkd_prompt_has_response (prompt))
+ ret = FALSE;
+
+ /* Successful response */
+ else if (gkd_prompt_get_response (prompt) == GKD_RESPONSE_OK) {
+ password = gkd_prompt_get_password (prompt, "password");
+ password_to_pin (password, pin, pin_len);
+ ret = TRUE;
+
+#if 0
+ /* Store forever */
+ if (ask->checked && object->unique && object->token) {
+ gkd_login_attach_secret (object->label, ask->typed_password,
+ "unique", object->unique, NULL);
+ }
+#endif
+
+ /* Other failures etc... */
+ } else {
+ ret = FALSE;
+ }
+
+ g_object_unref (prompt);
+ return ret;
+}
+
+static void
+login_specific_done (CK_SESSION_HANDLE handle, CK_SESSION_INFO *info,
+ CK_UTF8CHAR_PTR *pin, CK_ULONG *pin_len, CK_RV rv)
+{
+ AuthObject *object;
+
+ g_assert (pin);
+ g_assert (pin_len);
+
+ /* Because we should have been notified of open session */
+ object = gkd_pkcs11_data_session_lookup (info->slotID, handle);
+ g_return_if_fail (object);
+
+ switch (rv) {
+ case CKR_PIN_INCORRECT:
+ case CKR_PIN_EXPIRED:
+ case CKR_PIN_INVALID:
+ case CKR_PIN_LEN_RANGE:
+ case CKR_PIN_LOCKED:
+ if (object->unique && object->token)
+ gkd_login_remove_secret ("unique", object->unique, NULL);
+ break;
+
+ case CKR_OK:
+ gkd_pkcs11_data_session_remove (info->slotID, handle);
+ break;
+
+ default:
+ break;
+ }
+
+ egg_secure_strfree ((gchar*)*pin);
+
+ *pin = NULL;
+ *pin_len = 0;
+}
+
+
+static gboolean
+login_user_prompt (CK_SESSION_HANDLE handle, CK_TOKEN_INFO *info,
+ CK_UTF8CHAR_PTR *pin, CK_ULONG *pin_len)
+{
+ GkdPrompt *prompt;
+ gchar *label;
+ gchar *secondary;
+ gchar *manufacturer;
+ gchar *serial;
+ const gchar *password;
+ gboolean ret = TRUE;
+
+ g_assert (info);
+ g_assert (pin);
+ g_assert (pin_len);
+
+ /*
+ * The manufacturer and serial number together uniquely identify token
+ * They're stored with space padded in the token info structure.
+ */
+
+ manufacturer = g_strndup ((gchar*)info->manufacturerID, sizeof (info->manufacturerID));
+ g_strchomp (manufacturer);
+
+ serial = g_strndup ((gchar*)info->serialNumber, sizeof (info->serialNumber));
+ g_strchomp (serial);
+
+ label = g_strndup ((gchar*)info->label, sizeof (info->label));
+ g_strchomp (label);
+
+ if (gkd_login_is_usable ()) {
+
+ password = gkd_login_lookup_secret ("manufacturer", manufacturer,
+ "serial-number", serial,
+ NULL);
+ if (password != NULL) {
+ password_to_pin (password, pin, pin_len);
+ g_free (manufacturer);
+ g_free (serial);
+ g_free (label);
+ return TRUE;
+ }
+ }
+
+ /* Build up the prompt */
+ prompt = gkd_prompt_new ();
+ gkd_prompt_show_widget (prompt, "password_area");
+ gkd_prompt_hide_widget (prompt, "confirm_area");
+ gkd_prompt_hide_widget (prompt, "original_area");
+ gkd_prompt_set_title (prompt, _("Unlock certificate/key storage"));
+ gkd_prompt_set_primary_text (prompt, _("Enter password to unlock the certificate/key storage"));
+
+ /* TRANSLATORS: The storage is locked, and needs unlocking before the application can use it. */
+ secondary = g_strdup_printf (_("An application wants access to the certificate/key storage '%s', but it is locked"), label);
+ gkd_prompt_set_secondary_text (prompt, secondary);
+ g_free (secondary);
+
+#if 0
+ if (gkd_login_is_usable ())
+ gkd_ask_request_set_check_option (ask, _("Automatically unlock secure storage when I log in."));
+#endif
+
+ /* Prompt the user */
+ gkd_prompt_request_attention_sync (NULL, on_prompt_attention, prompt, NULL);
+
+ if (!gkd_prompt_has_response (prompt)) {
+ ret = FALSE;
+
+ /* User cancelled or failure */
+ } else if (gkd_prompt_get_response (prompt) != GKD_RESPONSE_OK) {
+ ret = FALSE;
+
+ /* Successful response */
+ } else {
+ password = gkd_prompt_get_password (prompt, "password");
+ password_to_pin (password, pin, pin_len);
+ ret = TRUE;
+#if 0
+ /* Store forever */
+ if (ask->checked) {
+ gkd_login_attach_secret (label, ask->typed_password,
+ "manufacturer", manufacturer,
+ "serial-number", serial,
+ NULL);
+ }
+#endif
+ }
+
+ g_free (manufacturer);
+ g_free (serial);
+ g_free (label);
+
+ g_object_unref (prompt);
+ return ret;
+}
+
+
+static void
+login_user_done (CK_SESSION_HANDLE handle, CK_TOKEN_INFO *info,
+ CK_UTF8CHAR_PTR *pin, CK_ULONG *pin_len, CK_RV rv)
+{
+ g_assert (pin);
+ g_assert (pin_len);
+
+ switch (rv) {
+ case CKR_PIN_INCORRECT:
+ case CKR_PIN_EXPIRED:
+ case CKR_PIN_INVALID:
+ case CKR_PIN_LEN_RANGE:
+ case CKR_PIN_LOCKED:
+ clear_user_login (info);
+ break;
+ }
+
+ egg_secure_strfree ((gchar*)*pin);
+
+ *pin = NULL;
+ *pin_len = 0;
+}
+
/* --------------------------------------------------------------------------------------
* PKCS#11 ENTRY POINTS
*/
@@ -193,42 +667,37 @@ auth_C_Initialize (CK_VOID_PTR init_args)
CK_C_INITIALIZE_ARGS_PTR args = (CK_C_INITIALIZE_ARGS_PTR)init_args;
gboolean supplied_ok;
CK_RV rv;
-
+
if (args) {
-
+
/* ALL supplied function pointers need to have the value either NULL or non-NULL. */
supplied_ok = (args->CreateMutex == NULL && args->DestroyMutex == NULL &&
args->LockMutex == NULL && args->UnlockMutex == NULL) ||
(args->CreateMutex != NULL && args->DestroyMutex != NULL &&
args->LockMutex != NULL && args->UnlockMutex != NULL);
-
+
if (!supplied_ok) {
g_message ("invalid set of mutex calls supplied");
return CKR_ARGUMENTS_BAD;
}
-
+
if (!(args->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS)) {
g_message ("must be able to create our own threads");
return CKR_NEED_TO_CREATE_THREADS;
}
-
+
if (!(args->flags & CKF_OS_LOCKING_OK)) {
g_message ("must be able to use our own locking and multi-thread primitives");
return CKR_CANT_LOCK;
}
}
-
+
rv = pkcs11_lower->C_Initialize (init_args);
-
- if (rv == CKR_OK) {
- DAEMON_ENTER ();
-
- /* Let our auth caches/storage know we're initializing */
- gkr_pkcs11_auth_initialized ();
-
- DAEMON_LEAVE ();
- }
-
+
+ /* Let our auth caches/storage know we're initializing */
+ if (rv == CKR_OK)
+ gkd_pkcs11_data_initialized ();
+
return rv;
}
@@ -236,17 +705,12 @@ static CK_RV
auth_C_Finalize (CK_VOID_PTR reserved)
{
CK_RV rv;
-
+
rv = (pkcs11_lower->C_Finalize) (reserved);
-
- if (rv == CKR_OK) {
- DAEMON_ENTER ();
-
- /* Let our auth caches/storage know we're initializing */
- gkr_pkcs11_auth_finalized ();
-
- DAEMON_LEAVE ();
- }
+
+ /* Let our auth caches/storage know we're initializing */
+ if (rv == CKR_OK)
+ gkd_pkcs11_data_finalized ();
return rv;
}
@@ -262,7 +726,7 @@ auth_C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list)
{
if (!list)
return CKR_ARGUMENTS_BAD;
- *list = gkr_pkcs11_auth_get_functions ();
+ *list = gkd_pkcs11_auth_get_functions ();
return CKR_OK;
}
@@ -313,7 +777,7 @@ auth_C_WaitForSlotEvent (CK_FLAGS flags, CK_SLOT_ID_PTR slot, CK_VOID_PTR reserv
}
static CK_RV
-auth_C_OpenSession (CK_SLOT_ID id, CK_FLAGS flags, CK_VOID_PTR user_data,
+auth_C_OpenSession (CK_SLOT_ID id, CK_FLAGS flags, CK_VOID_PTR user_data,
CK_NOTIFY callback, CK_SESSION_HANDLE_PTR handle)
{
CK_SESSION_INFO session_info;
@@ -321,16 +785,11 @@ auth_C_OpenSession (CK_SLOT_ID id, CK_FLAGS flags, CK_VOID_PTR user_data,
rv = (pkcs11_lower->C_OpenSession) (id, flags, user_data, callback, handle);
if (rv == CKR_OK) {
- if ((pkcs11_lower->C_GetSessionInfo) (*handle, &session_info) == CKR_OK) {
- DAEMON_ENTER ();
-
- /* Track this session in our auth layer */
- gkr_pkcs11_auth_session_opened (*handle, &session_info);
-
- DAEMON_LEAVE ();
- }
+ /* Track this session in our auth layer */
+ if ((pkcs11_lower->C_GetSessionInfo) (*handle, &session_info) == CKR_OK)
+ gkd_pkcs11_data_session_opened (session_info.slotID, *handle);
}
-
+
return rv;
}
@@ -340,38 +799,29 @@ auth_C_CloseSession (CK_SESSION_HANDLE handle)
gboolean have_session_info = FALSE;
CK_SESSION_INFO session_info;
CK_RV rv;
-
- if ((pkcs11_lower->C_GetSessionInfo) (handle, &session_info) == CKR_OK)
+
+ if ((pkcs11_lower->C_GetSessionInfo) (handle, &session_info) == CKR_OK)
have_session_info = TRUE;
-
+
rv = (pkcs11_lower->C_CloseSession) (handle);
- if (rv == CKR_OK && have_session_info) {
- DAEMON_ENTER ();
-
- /* Track this session closure in our auth cache/store */
- gkr_pkcs11_auth_session_closed (handle, &session_info);
-
- DAEMON_LEAVE ();
- }
-
- return rv;
+
+ /* Track this session closure in our auth cache/store */
+ if (rv == CKR_OK && have_session_info)
+ gkd_pkcs11_data_session_closed (session_info.slotID, handle);
+
+ return rv;
}
static CK_RV
auth_C_CloseAllSessions (CK_SLOT_ID id)
{
CK_RV rv = (pkcs11_lower->C_CloseAllSessions) (id);
-
- if (rv == CKR_OK) {
- DAEMON_ENTER ();
-
- /* Track this session closure in our auth cache/store */
- gkr_pkcs11_auth_session_closed_all (id);
-
- DAEMON_LEAVE ();
- }
-
- return rv;
+
+ /* Track this session closure in our auth cache/store */
+ if (rv == CKR_OK)
+ gkd_pkcs11_data_session_closed_all (id);
+
+ return rv;
}
static CK_RV
@@ -399,66 +849,47 @@ auth_C_InitPIN (CK_SESSION_HANDLE handle, CK_UTF8CHAR_PTR pin, CK_ULONG n_pin)
CK_TOKEN_INFO token_info;
gboolean init_auth = FALSE;
CK_RV rv;
-
+
/* Dig up the information we'll need, and don't prompt if protected auth path */
if ((pkcs11_lower->C_GetSessionInfo) (handle, &session_info) == CKR_OK &&
- (pkcs11_lower->C_GetTokenInfo) (session_info.slotID, &token_info) == CKR_OK &&
- !(token_info.flags & CKF_PROTECTED_AUTHENTICATION_PATH)) {
-
- DAEMON_ENTER ();
-
- init_auth = gkr_pkcs11_auth_init_user_prompt (handle, &token_info, &pin, &n_pin);
-
- DAEMON_LEAVE ();
+ (pkcs11_lower->C_GetTokenInfo) (session_info.slotID, &token_info) == CKR_OK &&
+ !(token_info.flags & CKF_PROTECTED_AUTHENTICATION_PATH)) {
+ init_auth = init_user_prompt (handle, &token_info, &pin, &n_pin);
}
rv = (pkcs11_lower->C_InitPIN) (handle, pin, n_pin);
-
- if (init_auth) {
- DAEMON_ENTER ();
-
- gkr_pkcs11_auth_init_user_done (handle, &token_info, &pin, &n_pin, rv);
-
- DAEMON_LEAVE ();
- }
-
+
+ if (init_auth)
+ init_user_done (handle, &token_info, &pin, &n_pin, rv);
+
return rv;
}
static CK_RV
-auth_C_SetPIN (CK_SESSION_HANDLE handle, CK_UTF8CHAR_PTR old_pin, CK_ULONG n_old_pin,
+auth_C_SetPIN (CK_SESSION_HANDLE handle, CK_UTF8CHAR_PTR old_pin, CK_ULONG n_old_pin,
CK_UTF8CHAR_PTR new_pin, CK_ULONG n_new_pin)
{
CK_SESSION_INFO session_info;
CK_TOKEN_INFO token_info;
gboolean init_auth = FALSE;
CK_RV rv;
-
+
/* Dig up the information we'll need, and don't prompt if protected auth path */
if ((pkcs11_lower->C_GetSessionInfo) (handle, &session_info) == CKR_OK &&
- (pkcs11_lower->C_GetTokenInfo) (session_info.slotID, &token_info) == CKR_OK &&
- !(token_info.flags & CKF_PROTECTED_AUTHENTICATION_PATH)) {
-
- DAEMON_ENTER ();
-
- if (!(token_info.flags & CKF_USER_PIN_INITIALIZED))
- init_auth = gkr_pkcs11_auth_init_user_prompt (handle, &token_info, &new_pin, &n_new_pin);
- /* TODO: Prompt for other 'change password' case */
-
- DAEMON_LEAVE ();
+ (pkcs11_lower->C_GetTokenInfo) (session_info.slotID, &token_info) == CKR_OK &&
+ !(token_info.flags & CKF_PROTECTED_AUTHENTICATION_PATH)) {
+ if (!(token_info.flags & CKF_USER_PIN_INITIALIZED))
+ init_auth = init_user_prompt (handle, &token_info, &new_pin, &n_new_pin);
+ /* TODO: Prompt for other 'change password' case */
}
rv = (pkcs11_lower->C_SetPIN) (handle, old_pin, n_old_pin, new_pin, n_new_pin);
-
+
if (init_auth) {
- DAEMON_ENTER ();
-
- gkr_pkcs11_auth_init_user_done (handle, &token_info, &new_pin, &n_new_pin, rv);
- /* TODO: Done for other case */
-
- DAEMON_LEAVE ();
+ init_user_done (handle, &token_info, &new_pin, &n_new_pin, rv);
+ /* TODO: Done for other case */
}
-
+
return rv;
}
@@ -488,7 +919,7 @@ auth_C_Login (CK_SESSION_HANDLE handle, CK_USER_TYPE user_type,
/* Try the login first, this allows NULL logins to be tried */
rv = (pkcs11_lower->C_Login) (handle, user_type, pin, pin_len);
-
+
/* See if we can help the login to work */
if (rv != CKR_PIN_INCORRECT)
return rv;
@@ -500,51 +931,45 @@ auth_C_Login (CK_SESSION_HANDLE handle, CK_USER_TYPE user_type,
return rv;
/* If lower level is a protected authentication path, then don't bother */
- if (token_info.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
+ if (token_info.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
return rv;
-
+
/* Loop until logged in or user cancels */
while (rv == CKR_PIN_INCORRECT) {
-
- DAEMON_ENTER ();
- switch (user_type) {
- case CKU_CONTEXT_SPECIFIC:
- auth = gkr_pkcs11_auth_login_specific_prompt (handle, &session_info, &pin, &pin_len);
- object = gkr_pkcs11_auth_login_specific_object (handle, &session_info);
- break;
- case CKU_USER:
- auth = gkr_pkcs11_auth_login_user_prompt (handle, &token_info, &pin, &pin_len);
- break;
- default:
- break;
- };
- DAEMON_LEAVE ();
-
+ switch (user_type) {
+ case CKU_CONTEXT_SPECIFIC:
+ auth = login_specific_prompt (handle, &session_info, &pin, &pin_len, &object);
+ break;
+ case CKU_USER:
+ auth = login_user_prompt (handle, &token_info, &pin, &pin_len);
+ break;
+ default:
+ break;
+ };
+
if (!auth) {
rv = CKR_FUNCTION_CANCELED;
break;
}
-
+
/* Try the login again */
- rv = (pkcs11_lower->C_Login) (handle, user_type, pin, pin_len);
+ rv = (pkcs11_lower->C_Login) (handle, user_type, pin, pin_len);
/* If that was successful, then we can create an authenticator object */
if (user_type == CKU_CONTEXT_SPECIFIC && rv == CKR_OK && object != 0)
auth_create_credential (handle, object, pin, pin_len);
/* Wrap things up */
- DAEMON_ENTER ();
- switch (user_type) {
- case CKU_CONTEXT_SPECIFIC:
- gkr_pkcs11_auth_login_specific_done (handle, &session_info, &pin, &pin_len, rv);
- break;
- case CKU_USER:
- gkr_pkcs11_auth_login_user_done (handle, &token_info, &pin, &pin_len, rv);
- break;
- default:
- break;
- };
- DAEMON_LEAVE ();
+ switch (user_type) {
+ case CKU_CONTEXT_SPECIFIC:
+ login_specific_done (handle, &session_info, &pin, &pin_len, rv);
+ break;
+ case CKU_USER:
+ login_user_done (handle, &token_info, &pin, &pin_len, rv);
+ break;
+ default:
+ break;
+ };
}
return rv;
@@ -621,21 +1046,16 @@ static CK_RV
auth_C_EncryptInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism,
CK_OBJECT_HANDLE key)
{
- GkrPkcs11AuthObject *object = NULL;
+ AuthObject *object = NULL;
CK_RV rv;
-
+
rv = (pkcs11_lower->C_EncryptInit) (handle, mechanism, key);
if (rv == CKR_OK) {
object = auth_object_for_context_specific (handle, key);
- if (object != NULL) {
- DAEMON_ENTER ();
-
- gkr_pkcs11_auth_login_specific_prepare (handle, object);
-
- DAEMON_LEAVE ();
- }
+ if (object != NULL)
+ login_specific_prepare (handle, object);
}
-
+
return rv;
}
@@ -675,21 +1095,16 @@ static CK_RV
auth_C_DecryptInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism,
CK_OBJECT_HANDLE key)
{
- GkrPkcs11AuthObject *object = NULL;
+ AuthObject *object = NULL;
CK_RV rv;
rv = (pkcs11_lower->C_DecryptInit) (handle, mechanism, key);
if (rv == CKR_OK) {
object = auth_object_for_context_specific (handle, key);
- if (object != NULL) {
- DAEMON_ENTER ();
-
- gkr_pkcs11_auth_login_specific_prepare (handle, object);
-
- DAEMON_LEAVE ();
- }
+ if (object != NULL)
+ login_specific_prepare (handle, object);
}
-
+
return rv;
}
@@ -760,21 +1175,16 @@ static CK_RV
auth_C_SignInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism,
CK_OBJECT_HANDLE key)
{
- GkrPkcs11AuthObject *object = NULL;
+ AuthObject *object = NULL;
CK_RV rv;
rv = (pkcs11_lower->C_SignInit) (handle, mechanism, key);
if (rv == CKR_OK) {
object = auth_object_for_context_specific (handle, key);
- if (object != NULL) {
- DAEMON_ENTER ();
-
- gkr_pkcs11_auth_login_specific_prepare (handle, object);
-
- DAEMON_LEAVE ();
- }
+ if (object != NULL)
+ login_specific_prepare (handle, object);
}
-
+
return rv;
}
@@ -812,26 +1222,21 @@ static CK_RV
auth_C_SignRecoverInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism,
CK_OBJECT_HANDLE key)
{
- GkrPkcs11AuthObject *object = NULL;
+ AuthObject *object = NULL;
CK_RV rv;
rv = (pkcs11_lower->C_SignRecoverInit) (handle, mechanism, key);
if (rv == CKR_OK) {
object = auth_object_for_context_specific (handle, key);
- if (object != NULL) {
- DAEMON_ENTER ();
-
- gkr_pkcs11_auth_login_specific_prepare (handle, object);
-
- DAEMON_LEAVE ();
- }
+ if (object != NULL)
+ login_specific_prepare (handle, object);
}
-
+
return rv;
}
static CK_RV
-auth_C_SignRecover (CK_SESSION_HANDLE handle, CK_BYTE_PTR data, CK_ULONG data_len,
+auth_C_SignRecover (CK_SESSION_HANDLE handle, CK_BYTE_PTR data, CK_ULONG data_len,
CK_BYTE_PTR signature, CK_ULONG_PTR signature_len)
{
CK_RV rv = (pkcs11_lower->C_SignRecover) (handle, data, data_len, signature, signature_len);
@@ -846,21 +1251,16 @@ static CK_RV
auth_C_VerifyInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism,
CK_OBJECT_HANDLE key)
{
- GkrPkcs11AuthObject *object = NULL;
+ AuthObject *object = NULL;
CK_RV rv;
rv = (pkcs11_lower->C_VerifyInit) (handle, mechanism, key);
if (rv == CKR_OK) {
object = auth_object_for_context_specific (handle, key);
- if (object != NULL) {
- DAEMON_ENTER ();
-
- gkr_pkcs11_auth_login_specific_prepare (handle, object);
-
- DAEMON_LEAVE ();
- }
+ if (object != NULL)
+ login_specific_prepare (handle, object);
}
-
+
return rv;
}
@@ -898,19 +1298,14 @@ static CK_RV
auth_C_VerifyRecoverInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism,
CK_OBJECT_HANDLE key)
{
- GkrPkcs11AuthObject *object = NULL;
+ AuthObject *object = NULL;
CK_RV rv;
rv = (pkcs11_lower->C_VerifyRecoverInit) (handle, mechanism, key);
if (rv == CKR_OK) {
object = auth_object_for_context_specific (handle, key);
- if (object != NULL) {
- DAEMON_ENTER ();
-
- gkr_pkcs11_auth_login_specific_prepare (handle, object);
-
- DAEMON_LEAVE ();
- }
+ if (object != NULL)
+ login_specific_prepare (handle, object);
}
return rv;
@@ -943,7 +1338,7 @@ auth_C_DigestEncryptUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR part,
static CK_RV
auth_C_DecryptDigestUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR enc_part,
- CK_ULONG enc_part_len, CK_BYTE_PTR part,
+ CK_ULONG enc_part_len, CK_BYTE_PTR part,
CK_ULONG_PTR part_len)
{
CK_RV rv = (pkcs11_lower->C_DecryptDigestUpdate) (handle, enc_part, enc_part_len, part, part_len);
@@ -968,7 +1363,7 @@ auth_C_SignEncryptUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR part,
}
static CK_RV
-auth_C_DecryptVerifyUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR enc_part, CK_ULONG enc_part_len,
+auth_C_DecryptVerifyUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR enc_part, CK_ULONG enc_part_len,
CK_BYTE_PTR part, CK_ULONG_PTR part_len)
{
CK_RV rv = (pkcs11_lower->C_DecryptVerifyUpdate) (handle, enc_part, enc_part_len, part, part_len);
@@ -981,7 +1376,7 @@ auth_C_DecryptVerifyUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR enc_part, CK_U
static CK_RV
auth_C_GenerateKey (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism,
- CK_ATTRIBUTE_PTR template, CK_ULONG count,
+ CK_ATTRIBUTE_PTR template, CK_ULONG count,
CK_OBJECT_HANDLE_PTR key)
{
return (pkcs11_lower->C_GenerateKey) (handle, mechanism, template, count, key);
@@ -1038,10 +1433,10 @@ auth_C_GenerateRandom (CK_SESSION_HANDLE handle, CK_BYTE_PTR random_data,
* MODULE ENTRY POINT
*/
-/*
- * PKCS#11 is broken here. It states that Unix compilers automatically byte
- * pack structures. This is wrong. GCC on Linux aligns to 4 by default.
- *
+/*
+ * PKCS#11 is broken here. It states that Unix compilers automatically byte
+ * pack structures. This is wrong. GCC on Linux aligns to 4 by default.
+ *
* This results in incompatibilities. Where this structure's first version
* members take up too much or too little space depending on how this module
* is compiled.
@@ -1120,16 +1515,15 @@ static CK_FUNCTION_LIST auth_function_list = {
};
CK_FUNCTION_LIST_PTR
-gkr_pkcs11_auth_get_functions (void)
+gkd_pkcs11_auth_get_functions (void)
{
- return &auth_function_list;
+ return &auth_function_list;
}
void
-gkr_pkcs11_auth_chain_functions (CK_FUNCTION_LIST_PTR funcs)
+gkd_pkcs11_auth_chain_functions (CK_FUNCTION_LIST_PTR funcs)
{
g_assert (funcs);
g_assert (!pkcs11_lower);
pkcs11_lower = funcs;
}
-
diff --git a/daemon/pkcs11/gkr-pkcs11-daemon.h b/daemon/pkcs11/gkd-pkcs11-auth.h
similarity index 58%
copy from daemon/pkcs11/gkr-pkcs11-daemon.h
copy to daemon/pkcs11/gkd-pkcs11-auth.h
index 8f8f83e..d7edd3d 100644
--- a/daemon/pkcs11/gkr-pkcs11-daemon.h
+++ b/daemon/pkcs11/gkd-pkcs11-auth.h
@@ -1,39 +1,33 @@
-/*
+/*
* gnome-keyring
- *
+ *
* Copyright (C) 2008 Stefan Walter
- *
- * This program is free software; you can redistribute it and/or modify
+ *
+ * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General License as
* published by the Free Software Foundation; either version 2.1 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
* Lesser General License for more details.
- *
- * You should have received a copy of the GNU Lesser General
+ *
+ * You should have received a copy of the GNU Lesser General
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * 02111-1307, USA.
*/
-#ifndef GKRPKCS11DAEMON_H_
-#define GKRPKCS11DAEMON_H_
+#ifndef GKD_PKCS11_AUTH_H_
+#define GKD_PKCS11_AUTH_H_
#include <glib.h>
#include "pkcs11/pkcs11.h"
-gboolean gkr_pkcs11_daemon_initialize (void);
+void gkd_pkcs11_auth_chain_functions (CK_FUNCTION_LIST_PTR funcs);
-gboolean gkr_pkcs11_daemon_startup_pkcs11 (void);
+CK_FUNCTION_LIST_PTR gkd_pkcs11_auth_get_functions (void);
-gboolean gkr_pkcs11_daemon_startup_ssh (void);
-
-CK_FUNCTION_LIST_PTR gkr_pkcs11_daemon_get_functions (void);
-
-CK_FUNCTION_LIST_PTR gkr_pkcs11_daemon_get_base_functions (void);
-
-#endif /* GKRPKCS11DAEMON_H_ */
+#endif /* GKD_PKCS11_AUTH_H_ */
diff --git a/daemon/pkcs11/gkd-pkcs11-data.c b/daemon/pkcs11/gkd-pkcs11-data.c
new file mode 100644
index 0000000..17f3d55
--- /dev/null
+++ b/daemon/pkcs11/gkd-pkcs11-data.c
@@ -0,0 +1,263 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2008 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General License as
+ * published by the Free Software Foundation; either version 2.1 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
+ * Lesser General License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * 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 "config.h"
+
+#include "gkd-pkcs11-data.h"
+
+#include "egg/egg-cleanup.h"
+#include "egg/egg-secure-memory.h"
+
+#include "login/gkd-login.h"
+
+#include "pkcs11/pkcs11.h"
+
+#include "prompt/gkd-prompt.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+
+#include <unistd.h>
+
+/*
+ * THREADING INFO: These functions are called from multiple threads. All gkd_pkcs11_data_*()
+ * functions here with the exception of gkd_pkcs11_data_free_object() are locked. Again with
+ * the exception of gkd_pkcs11_data_free_object() they must not be called from one another.
+ */
+
+typedef struct _SlotData {
+ gint open_sessions;
+ GHashTable *session_to_data;
+} SlotData;
+
+typedef struct _SessionData {
+ gpointer user_data;
+ GDestroyNotify destroy_func;
+} SessionData;
+
+/* A hash table of CK_SLOT_ID_PTR to SlotData */
+static GHashTable *per_slot_data = NULL;
+G_LOCK_DEFINE_STATIC (pkcs11_data);
+
+static void
+free_slot_data (gpointer data)
+{
+ SlotData *sdata = data;
+ g_assert (sdata);
+ if (sdata->session_to_data)
+ g_hash_table_destroy (sdata->session_to_data);
+ g_slice_free (SlotData, sdata);
+}
+
+static void
+free_session_data (gpointer data)
+{
+ SessionData *sdata = data;
+ g_assert (sdata);
+ if (sdata->destroy_func && sdata->user_data)
+ (sdata->destroy_func) (sdata->user_data);
+ g_slice_free (SessionData, sdata);
+}
+
+static gulong*
+ulong_alloc (CK_ULONG value)
+{
+ return g_slice_dup (CK_ULONG, &value);
+}
+
+static void
+ulong_free (gpointer ptr_to_ulong)
+{
+ g_slice_free (CK_ULONG, ptr_to_ulong);
+}
+
+static guint
+ulong_hash (gconstpointer v)
+{
+ const signed char *p = v;
+ guint32 i, h = *p;
+ for(i = 0; i < sizeof (CK_ULONG); ++i)
+ h = (h << 5) - h + *(p++);
+ return h;
+}
+
+static gboolean
+ulong_equal (gconstpointer v1, gconstpointer v2)
+{
+ return *((const CK_ULONG*)v1) == *((const CK_ULONG*)v2);
+}
+
+static void
+store_data_unlocked (CK_SLOT_ID slot_id, CK_SESSION_HANDLE handle,
+ gpointer data, GDestroyNotify destroy_func)
+{
+ SessionData *sdata;
+ SlotData *slot;
+
+ /* Because we should have been notified when a session was opened */
+ g_return_if_fail (per_slot_data);
+
+ slot = g_hash_table_lookup (per_slot_data, &slot_id);
+ g_return_if_fail (slot);
+
+ /* Delayed allocation because we may never use this on a slot */
+ if (slot->session_to_data == NULL)
+ slot->session_to_data = g_hash_table_new_full (ulong_hash, ulong_equal, ulong_free, free_session_data);
+
+ sdata = g_slice_new0 (SessionData);
+ sdata->user_data = data;
+ sdata->destroy_func = destroy_func;
+ g_hash_table_replace (slot->session_to_data, ulong_alloc (handle), sdata);
+}
+
+void
+gkd_pkcs11_data_session_store (CK_SLOT_ID slot_id, CK_SESSION_HANDLE handle,
+ gpointer data, GDestroyNotify destroy_func)
+{
+ G_LOCK(pkcs11_data);
+ store_data_unlocked (slot_id, handle, data, destroy_func);
+ G_UNLOCK (pkcs11_data);
+}
+
+static gpointer
+lookup_data_unlocked (CK_SLOT_ID slot_id, CK_SESSION_HANDLE handle)
+{
+ SessionData *sdata;
+ SlotData *slot;
+
+ /* Because we should have been notified of open session */
+ g_return_val_if_fail (per_slot_data, FALSE);
+
+ /* Lookup the structure for this slot */
+ slot = g_hash_table_lookup (per_slot_data, &slot_id);
+ if (slot == NULL || slot->session_to_data == NULL)
+ return NULL;
+
+ sdata = g_hash_table_lookup (slot->session_to_data, &handle);
+ if (sdata == NULL)
+ return NULL;
+
+ return sdata->user_data;
+}
+
+gpointer
+gkd_pkcs11_data_session_lookup (CK_SLOT_ID slot_id, CK_SESSION_HANDLE handle)
+{
+ gpointer ret;
+ G_LOCK (pkcs11_data);
+ ret = lookup_data_unlocked (slot_id, handle);
+ G_UNLOCK (pkcs11_data);
+ return ret;
+}
+
+static void
+remove_data_unlocked (CK_SLOT_ID slot_id, CK_SESSION_HANDLE handle)
+{
+ SlotData *slot;
+
+ /* Because we should have been notified of open session */
+ g_return_if_fail (per_slot_data);
+
+ slot = g_hash_table_lookup (per_slot_data, &slot_id);
+ g_assert (slot != NULL && slot->session_to_data != NULL);
+
+ g_hash_table_remove (slot->session_to_data, &handle);
+}
+
+void
+gkd_pkcs11_data_session_remove (CK_SLOT_ID slot_id, CK_SESSION_HANDLE handle)
+{
+ G_LOCK (pkcs11_data);
+ remove_data_unlocked (slot_id, handle);
+ G_UNLOCK (pkcs11_data);
+}
+
+void
+gkd_pkcs11_data_initialized (void)
+{
+ G_LOCK (pkcs11_data);
+ g_warn_if_fail (!per_slot_data);
+ per_slot_data = g_hash_table_new_full (ulong_hash, ulong_equal, ulong_free,
+ (GDestroyNotify)free_slot_data);
+ G_UNLOCK (pkcs11_data);
+}
+
+void
+gkd_pkcs11_data_session_opened (CK_SLOT_ID slot_id, CK_SESSION_HANDLE handle)
+{
+ SlotData *slot;
+
+ G_LOCK (pkcs11_data);
+
+ slot = g_hash_table_lookup (per_slot_data, &slot_id);
+ if (slot == NULL) {
+ slot = g_slice_new0 (SlotData);
+ g_hash_table_replace (per_slot_data, ulong_alloc (slot_id), slot);
+ }
+
+ /* Track how many open sessions there are */
+ ++slot->open_sessions;
+
+ G_UNLOCK (pkcs11_data);
+}
+
+void
+gkd_pkcs11_data_session_closed (CK_SLOT_ID slot_id, CK_SESSION_HANDLE handle)
+{
+ SlotData *slot;
+
+ G_LOCK (pkcs11_data);
+
+ g_warn_if_fail (per_slot_data);
+
+ slot = g_hash_table_lookup (per_slot_data, &slot_id);
+ g_warn_if_fail (slot);
+ g_assert (slot->open_sessions > 0);
+
+ /* Track how many open sessions there are */
+ --(slot->open_sessions);
+ if (slot->open_sessions == 0)
+ g_hash_table_remove (per_slot_data, &slot_id);
+
+ G_UNLOCK (pkcs11_data);
+}
+
+void
+gkd_pkcs11_data_session_closed_all (CK_SLOT_ID id)
+{
+ G_LOCK (pkcs11_data);
+
+ /* Remove all information about this slot */
+ g_warn_if_fail (per_slot_data);
+ g_hash_table_remove (per_slot_data, &id);
+
+ G_UNLOCK (pkcs11_data);
+}
+
+void
+gkd_pkcs11_data_finalized (void)
+{
+ G_LOCK (pkcs11_data);
+ g_warn_if_fail (per_slot_data);
+ g_hash_table_destroy (per_slot_data);
+ per_slot_data = NULL;
+ G_UNLOCK (pkcs11_data);
+}
diff --git a/daemon/pkcs11/gkd-pkcs11-data.h b/daemon/pkcs11/gkd-pkcs11-data.h
new file mode 100644
index 0000000..0d22a7a
--- /dev/null
+++ b/daemon/pkcs11/gkd-pkcs11-data.h
@@ -0,0 +1,52 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2008 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General License as
+ * published by the Free Software Foundation; either version 2.1 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
+ * Lesser General License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * 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 GKD_PKCS11_DATA_H_
+#define GKD_PKCS11_DATA_H_
+
+#include <glib.h>
+
+#include "pkcs11/pkcs11.h"
+
+void gkd_pkcs11_data_initialized (void);
+
+void gkd_pkcs11_data_session_opened (CK_SLOT_ID slot_id,
+ CK_SESSION_HANDLE handle);
+
+void gkd_pkcs11_data_session_closed (CK_SLOT_ID slot_id,
+ CK_SESSION_HANDLE handle);
+
+void gkd_pkcs11_data_session_closed_all (CK_SLOT_ID slot);
+
+void gkd_pkcs11_data_finalized (void);
+
+void gkd_pkcs11_data_session_store (CK_SLOT_ID slot_id,
+ CK_SESSION_HANDLE handle,
+ gpointer data,
+ GDestroyNotify destroy_func);
+
+gpointer gkd_pkcs11_data_session_lookup (CK_SLOT_ID slot_id,
+ CK_SESSION_HANDLE handle);
+
+void gkd_pkcs11_data_session_remove (CK_SLOT_ID slot_id,
+ CK_SESSION_HANDLE handle);
+
+#endif /* GKD_PKCS11_DATA_H_ */
diff --git a/daemon/pkcs11/gkr-pkcs11-daemon.c b/daemon/pkcs11/gkd-pkcs11.c
similarity index 54%
rename from daemon/pkcs11/gkr-pkcs11-daemon.c
rename to daemon/pkcs11/gkd-pkcs11.c
index 4850fb7..8009e8f 100644
--- a/daemon/pkcs11/gkr-pkcs11-daemon.c
+++ b/daemon/pkcs11/gkd-pkcs11.c
@@ -1,29 +1,29 @@
-/*
+/*
* gnome-keyring
- *
+ *
* Copyright (C) 2008 Stefan Walter
- *
- * This program is free software; you can redistribute it and/or modify
+ *
+ * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General License as
* published by the Free Software Foundation; either version 2.1 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
* Lesser General License for more details.
- *
- * You should have received a copy of the GNU Lesser General
+ *
+ * You should have received a copy of the GNU Lesser General
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * 02111-1307, USA.
*/
#include "config.h"
#include "gkd-util.h"
-#include "gkr-pkcs11-auth.h"
-#include "gkr-pkcs11-daemon.h"
+#include "gkd-pkcs11-auth.h"
+#include "gkd-pkcs11.h"
#include "pkcs11/plex-layer/gck-plex-layer.h"
#include "pkcs11/roots-store/gck-roots-store.h"
@@ -33,22 +33,8 @@
#include "pkcs11/ssh-store/gck-ssh-store.h"
#include "pkcs11/user-store/gck-user-store.h"
-#include "daemon/util/gkr-daemon-async.h"
-
#include "egg/egg-cleanup.h"
-/*
- * ALL calls into PKCS#11 and anything starting with 'gck'
- * must be concurrent. That is must UNLOCK the demon lock,
- * perform the call and then relock.
- *
- * gkr_daemon_async_begin_concurrent ();
- *
- * gck_call_xxxx (xxx);
- *
- * gkr_daemon_async_end_concurrent ();
- */
-
/* The top level of our internal PKCS#11 module stack */
static CK_FUNCTION_LIST_PTR pkcs11_roof = NULL;
static CK_FUNCTION_LIST_PTR pkcs11_base = NULL;
@@ -57,17 +43,13 @@ static void
pkcs11_daemon_cleanup (gpointer unused)
{
CK_RV rv;
-
+
g_assert (pkcs11_roof);
- gkr_daemon_async_begin_concurrent ();
+ gck_ssh_agent_uninitialize ();
+ gck_rpc_layer_uninitialize ();
+ rv = (pkcs11_roof->C_Finalize) (NULL);
- gck_ssh_agent_uninitialize ();
- gck_rpc_layer_uninitialize ();
- rv = (pkcs11_roof->C_Finalize) (NULL);
-
- gkr_daemon_async_end_concurrent ();
-
if (rv != CKR_OK)
g_warning ("couldn't finalize internal PKCS#11 stack (code: %d)", (gint)rv);
@@ -75,7 +57,7 @@ pkcs11_daemon_cleanup (gpointer unused)
}
gboolean
-gkr_pkcs11_daemon_initialize (void)
+gkd_pkcs11_initialize (void)
{
CK_FUNCTION_LIST_PTR roots_store;
CK_FUNCTION_LIST_PTR secret_store;
@@ -84,53 +66,44 @@ gkr_pkcs11_daemon_initialize (void)
gboolean ret;
CK_RV rv;
- /* Now initialize them all */
- gkr_daemon_async_begin_concurrent ();
-
- /* Secrets */
- secret_store = gck_secret_store_get_functions ();
-
- /* SSH storage */
- ssh_store = gck_ssh_store_get_functions ();
-
- /* Root certificates */
- roots_store = gck_roots_store_get_functions ();
-
- /* User certificates */
- user_store = gck_user_store_get_functions ();
-
- /* Add all of those into the multiplexing layer */
- gck_plex_layer_add_module (ssh_store);
+ /* Secrets */
+ secret_store = gck_secret_store_get_functions ();
+
+ /* SSH storage */
+ ssh_store = gck_ssh_store_get_functions ();
+
+ /* Root certificates */
+ roots_store = gck_roots_store_get_functions ();
+
+ /* User certificates */
+ user_store = gck_user_store_get_functions ();
+
+ /* Add all of those into the multiplexing layer */
+ gck_plex_layer_add_module (ssh_store);
#ifdef ROOT_CERTIFICATES
- gck_plex_layer_add_module (roots_store);
+ gck_plex_layer_add_module (roots_store);
#endif
- gck_plex_layer_add_module (secret_store);
- gck_plex_layer_add_module (user_store);
+ gck_plex_layer_add_module (secret_store);
+ gck_plex_layer_add_module (user_store);
- pkcs11_base = gck_plex_layer_get_functions ();
+ pkcs11_base = gck_plex_layer_get_functions ();
- /* The auth component is the top component */
- gkr_pkcs11_auth_chain_functions (pkcs11_base);
- pkcs11_roof = gkr_pkcs11_auth_get_functions ();
-
- /* Initialize the whole caboodle */
- rv = (pkcs11_roof->C_Initialize) (NULL);
+ /* The auth component is the top component */
+ gkd_pkcs11_auth_chain_functions (pkcs11_base);
+ pkcs11_roof = gkd_pkcs11_auth_get_functions ();
- gkr_daemon_async_end_concurrent ();
+ /* Initialize the whole caboodle */
+ rv = (pkcs11_roof->C_Initialize) (NULL);
if (rv != CKR_OK) {
g_warning ("couldn't initialize internal PKCS#11 stack (code: %d)", (gint)rv);
return FALSE;
- }
-
- egg_cleanup_register (pkcs11_daemon_cleanup, NULL);
-
- gkr_daemon_async_begin_concurrent ();
+ }
- ret = gck_ssh_agent_initialize (pkcs11_roof) &&
- gck_rpc_layer_initialize (pkcs11_roof);
+ egg_cleanup_register (pkcs11_daemon_cleanup, NULL);
- gkr_daemon_async_end_concurrent ();
+ ret = gck_ssh_agent_initialize (pkcs11_roof) &&
+ gck_rpc_layer_initialize (pkcs11_roof);
return ret;
}
@@ -138,28 +111,20 @@ gkr_pkcs11_daemon_initialize (void)
static void
pkcs11_rpc_cleanup (gpointer unused)
{
- gkr_daemon_async_begin_concurrent ();
-
- gck_rpc_layer_shutdown ();
-
- gkr_daemon_async_end_concurrent ();
+ gck_rpc_layer_shutdown ();
}
static gboolean
accept_rpc_client (GIOChannel *channel, GIOCondition cond, gpointer unused)
{
- gkr_daemon_async_begin_concurrent ();
+ if (cond == G_IO_IN)
+ gck_rpc_layer_accept ();
- if (cond == G_IO_IN)
- gck_rpc_layer_accept ();
-
- gkr_daemon_async_end_concurrent ();
-
return TRUE;
}
gboolean
-gkr_pkcs11_daemon_startup_pkcs11 (void)
+gkd_pkcs11_startup_pkcs11 (void)
{
GIOChannel *channel;
const gchar *base_dir;
@@ -168,15 +133,10 @@ gkr_pkcs11_daemon_startup_pkcs11 (void)
base_dir = gkd_util_get_master_directory ();
g_return_val_if_fail (base_dir, FALSE);
- gkr_daemon_async_begin_concurrent ();
-
- sock = gck_rpc_layer_startup (base_dir);
-
- gkr_daemon_async_end_concurrent ();
-
+ sock = gck_rpc_layer_startup (base_dir);
if (sock == -1)
return FALSE;
-
+
channel = g_io_channel_unix_new (sock);
g_io_add_watch (channel, G_IO_IN | G_IO_HUP, accept_rpc_client, NULL);
g_io_channel_unref (channel);
@@ -189,28 +149,19 @@ gkr_pkcs11_daemon_startup_pkcs11 (void)
static void
pkcs11_ssh_cleanup (gpointer unused)
{
- gkr_daemon_async_begin_concurrent ();
-
- gck_ssh_agent_shutdown ();
-
- gkr_daemon_async_end_concurrent ();
+ gck_ssh_agent_shutdown ();
}
static gboolean
accept_ssh_client (GIOChannel *channel, GIOCondition cond, gpointer unused)
{
- gkr_daemon_async_begin_concurrent ();
-
- if (cond == G_IO_IN)
- gck_ssh_agent_accept ();
-
- gkr_daemon_async_end_concurrent ();
-
+ if (cond == G_IO_IN)
+ gck_ssh_agent_accept ();
return TRUE;
}
gboolean
-gkr_pkcs11_daemon_startup_ssh (void)
+gkd_pkcs11_startup_ssh (void)
{
GIOChannel *channel;
const gchar *base_dir;
@@ -219,19 +170,14 @@ gkr_pkcs11_daemon_startup_ssh (void)
base_dir = gkd_util_get_master_directory ();
g_return_val_if_fail (base_dir, FALSE);
- gkr_daemon_async_begin_concurrent ();
-
- sock = gck_ssh_agent_startup (base_dir);
-
- gkr_daemon_async_end_concurrent ();
-
+ sock = gck_ssh_agent_startup (base_dir);
if (sock == -1)
return FALSE;
-
+
channel = g_io_channel_unix_new (sock);
g_io_add_watch (channel, G_IO_IN | G_IO_HUP, accept_ssh_client, NULL);
g_io_channel_unref (channel);
-
+
/* gck-ssh-agent sets the environment variable */
gkd_util_push_environment ("SSH_AUTH_SOCK", g_getenv ("SSH_AUTH_SOCK"));
@@ -241,13 +187,13 @@ gkr_pkcs11_daemon_startup_ssh (void)
}
CK_FUNCTION_LIST_PTR
-gkr_pkcs11_daemon_get_functions (void)
+gkd_pkcs11_get_functions (void)
{
return pkcs11_roof;
}
CK_FUNCTION_LIST_PTR
-gkr_pkcs11_daemon_get_base_functions (void)
+gkd_pkcs11_get_base_functions (void)
{
return pkcs11_base;
}
diff --git a/daemon/pkcs11/gkr-pkcs11-daemon.h b/daemon/pkcs11/gkd-pkcs11.h
similarity index 59%
rename from daemon/pkcs11/gkr-pkcs11-daemon.h
rename to daemon/pkcs11/gkd-pkcs11.h
index 8f8f83e..e597b50 100644
--- a/daemon/pkcs11/gkr-pkcs11-daemon.h
+++ b/daemon/pkcs11/gkd-pkcs11.h
@@ -1,39 +1,39 @@
-/*
+/*
* gnome-keyring
- *
+ *
* Copyright (C) 2008 Stefan Walter
- *
- * This program is free software; you can redistribute it and/or modify
+ *
+ * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General License as
* published by the Free Software Foundation; either version 2.1 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
* Lesser General License for more details.
- *
- * You should have received a copy of the GNU Lesser General
+ *
+ * You should have received a copy of the GNU Lesser General
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * 02111-1307, USA.
*/
-#ifndef GKRPKCS11DAEMON_H_
-#define GKRPKCS11DAEMON_H_
+#ifndef GKD_PKCS11_H_
+#define GKD_PKCS11_H_
#include <glib.h>
#include "pkcs11/pkcs11.h"
-gboolean gkr_pkcs11_daemon_initialize (void);
+gboolean gkd_pkcs11_initialize (void);
-gboolean gkr_pkcs11_daemon_startup_pkcs11 (void);
+gboolean gkd_pkcs11_startup_pkcs11 (void);
-gboolean gkr_pkcs11_daemon_startup_ssh (void);
+gboolean gkd_pkcs11_startup_ssh (void);
-CK_FUNCTION_LIST_PTR gkr_pkcs11_daemon_get_functions (void);
+CK_FUNCTION_LIST_PTR gkd_pkcs11_get_functions (void);
-CK_FUNCTION_LIST_PTR gkr_pkcs11_daemon_get_base_functions (void);
+CK_FUNCTION_LIST_PTR gkd_pkcs11_get_base_functions (void);
-#endif /* GKRPKCS11DAEMON_H_ */
+#endif /* GKD_PKCS11_H_ */
diff --git a/daemon/prompt/Makefile.am b/daemon/prompt/Makefile.am
index c739fe2..ee4c398 100644
--- a/daemon/prompt/Makefile.am
+++ b/daemon/prompt/Makefile.am
@@ -61,11 +61,11 @@ libexec_PROGRAMS= \
gnome_keyring_prompt_SOURCES = \
gkd-prompt-tool.c \
- gkd-prompt-buffer.c gkd-prompt-buffer.h \
gkd-prompt-util.c gkd-prompt-util.h
gnome_keyring_prompt_LDADD = \
$(top_builddir)/egg/libegg-prompt.la \
+ $(top_builddir)/egg/libegg-entry-buffer.la \
$(LIBGCRYPT_LIBS) \
$(GTK_LIBS)
diff --git a/daemon/prompt/gkd-prompt-tool.c b/daemon/prompt/gkd-prompt-tool.c
index 7d034f4..8fec75c 100644
--- a/daemon/prompt/gkd-prompt-tool.c
+++ b/daemon/prompt/gkd-prompt-tool.c
@@ -22,10 +22,10 @@
#include "config.h"
-#include "gkd-prompt-buffer.h"
#include "gkd-prompt-util.h"
#include "egg/egg-dh.h"
+#include "egg/egg-entry-buffer.h"
#include "egg/egg-libgcrypt.h"
#include "egg/egg-secure-memory.h"
@@ -267,7 +267,7 @@ prepare_buttons (GtkBuilder *builder, GtkDialog *dialog)
static void
prepare_password_entry (GtkEntry *entry)
{
- GtkEntryBuffer *buffer = gkd_prompt_buffer_new ();
+ GtkEntryBuffer *buffer = egg_entry_buffer_new ();
g_return_if_fail (entry);
gtk_entry_set_buffer (entry, buffer);
g_object_unref (buffer);
diff --git a/daemon/prompt/gkd-prompt.c b/daemon/prompt/gkd-prompt.c
index c92aae8..999964e 100644
--- a/daemon/prompt/gkd-prompt.c
+++ b/daemon/prompt/gkd-prompt.c
@@ -577,6 +577,12 @@ gkd_prompt_class_init (GkdPromptClass *klass)
* PUBLIC
*/
+GkdPrompt*
+gkd_prompt_new (void)
+{
+ return g_object_new (GKD_TYPE_PROMPT, NULL);
+}
+
void
gkd_prompt_set_title (GkdPrompt *self, const gchar *title)
{
@@ -819,9 +825,11 @@ typedef struct _Attention {
gpointer user_data;
GkdPrompt *prompt;
gboolean active;
+ GCond *cond;
} AttentionReq;
static GHashTable *attention_reqs = NULL;
+static GStaticMutex attention_mutex = G_STATIC_MUTEX_INIT;
static void
done_attention_req (GkdPrompt *prompt, gpointer user_data)
@@ -835,6 +843,13 @@ done_attention_req (GkdPrompt *prompt, gpointer user_data)
att->active = FALSE;
next_attention_req (att->window_id);
}
+
+ if (att->cond) {
+ g_static_mutex_lock (&attention_mutex);
+ g_cond_broadcast (att->cond);
+ g_static_mutex_unlock (&attention_mutex);
+ att->cond = NULL;
+ }
}
static void
@@ -863,6 +878,7 @@ free_attention_req (gpointer data)
gchar *window_id = NULL;
if (att) {
+ att->cond = NULL;
if (att->destroy)
(att->destroy) (att->user_data);
if (att->prompt) {
@@ -904,7 +920,6 @@ alloc_attention_queue (void)
return g_queue_new ();
}
-
static void
next_attention_req (const gchar *window_id)
{
@@ -980,13 +995,13 @@ service_attention_req (gpointer user_data)
return FALSE;
}
-void
-gkd_prompt_request_attention_async (const gchar *window_id, GkdPromptAttentionFunc callback,
- gpointer user_data, GDestroyNotify destroy_notify)
+static AttentionReq*
+prepare_attention_req (const gchar *window_id, GkdPromptAttentionFunc callback,
+ gpointer user_data, GDestroyNotify destroy_notify)
{
AttentionReq *att;
- g_return_if_fail (callback);
+ g_return_val_if_fail (callback, NULL);
if (!window_id)
window_id = "";
@@ -995,5 +1010,35 @@ gkd_prompt_request_attention_async (const gchar *window_id, GkdPromptAttentionFu
att->user_data = user_data;
att->destroy = destroy_notify;
+ return att;
+}
+
+void
+gkd_prompt_request_attention_async (const gchar *window_id, GkdPromptAttentionFunc callback,
+ gpointer user_data, GDestroyNotify destroy_notify)
+{
+ AttentionReq *att = prepare_attention_req (window_id, callback, user_data, destroy_notify);
+ g_return_if_fail (att);
g_timeout_add (0, service_attention_req, att);
}
+
+void
+gkd_prompt_request_attention_sync (const gchar *window_id, GkdPromptAttentionFunc callback,
+ gpointer user_data, GDestroyNotify destroy_notify)
+{
+ AttentionReq *att = prepare_attention_req (window_id, callback, user_data, destroy_notify);
+ GCond *cond = g_cond_new ();
+
+ g_return_if_fail (att);
+ att->cond = cond;
+
+ g_static_mutex_lock (&attention_mutex);
+ g_timeout_add (0, service_attention_req, att);
+
+ /* WARNING: att may have been destroyed past this point */
+
+ g_cond_wait (cond, g_static_mutex_get_mutex (&attention_mutex));
+ g_static_mutex_unlock (&attention_mutex);
+
+ g_cond_free (cond);
+}
diff --git a/daemon/prompt/gkd-prompt.h b/daemon/prompt/gkd-prompt.h
index d3917c4..4cc8a91 100644
--- a/daemon/prompt/gkd-prompt.h
+++ b/daemon/prompt/gkd-prompt.h
@@ -58,6 +58,8 @@ struct _GkdPromptClass {
GType gkd_prompt_get_type (void);
+GkdPrompt* gkd_prompt_new (void);
+
void gkd_prompt_reset (GkdPrompt *prompt);
void gkd_prompt_set_title (GkdPrompt *prompt,
@@ -117,4 +119,9 @@ void gkd_prompt_request_attention_async (const gchar *window_i
gpointer user_data,
GDestroyNotify destroy_notify);
+void gkd_prompt_request_attention_sync (const gchar *window_id,
+ GkdPromptAttentionFunc callback,
+ gpointer user_data,
+ GDestroyNotify destroy_notify);
+
#endif /* __GKD_PROMPT_H__ */
diff --git a/daemon/prompt/gkd-prompt.ui b/daemon/prompt/gkd-prompt.ui
index 0125619..5b53b90 100644
--- a/daemon/prompt/gkd-prompt.ui
+++ b/daemon/prompt/gkd-prompt.ui
@@ -69,7 +69,6 @@ An application wants access to the keyring 'xxx', but it is locked.</property>
<property name="spacing">6</property>
<child>
<object class="GtkHBox" id="name_area">
- <property name="visible">True</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="name_label">
@@ -102,7 +101,6 @@ An application wants access to the keyring 'xxx', but it is locked.</property>
</child>
<child>
<object class="GtkHBox" id="original_area">
- <property name="visible">True</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="original_label">
@@ -135,7 +133,6 @@ An application wants access to the keyring 'xxx', but it is locked.</property>
</child>
<child>
<object class="GtkHBox" id="password_area">
- <property name="visible">True</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="password_label">
@@ -168,7 +165,6 @@ An application wants access to the keyring 'xxx', but it is locked.</property>
</child>
<child>
<object class="GtkVBox" id="confirm_area">
- <property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
@@ -255,7 +251,6 @@ An application wants access to the keyring 'xxx', but it is locked.</property>
</child>
<child>
<object class="GtkExpander" id="details_area">
- <property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkAlignment" id="alignment1">
@@ -478,11 +473,11 @@ An application wants access to the keyring 'xxx', but it is locked.</property>
</object>
<object class="GtkSizeGroup" id="prompt_label_sizegroup">
<widgets>
- <widget name="name_label"/>
- <widget name="original_label"/>
- <widget name="password_label"/>
- <widget name="confirm_label"/>
<widget name="strength_label"/>
+ <widget name="confirm_label"/>
+ <widget name="password_label"/>
+ <widget name="original_label"/>
+ <widget name="name_label"/>
</widgets>
</object>
</interface>
diff --git a/egg/Makefile.am b/egg/Makefile.am
index 6d5d3c8..94e8ea2 100644
--- a/egg/Makefile.am
+++ b/egg/Makefile.am
@@ -6,7 +6,7 @@ noinst_LTLIBRARIES = \
libegg-dbus.la \
libegg-secure.la \
libegg-prompt.la \
- libegg-secure-entry.la
+ libegg-entry-buffer.la
BUILT_SOURCES = \
asn1-def-pk.h asn1-def-pkix.h
@@ -53,19 +53,19 @@ DISTCLEANFILES = \
# COMMON STUFF COMPILED INTO SMALLER COMPONENTS
libegg_secure_la_SOURCES = \
- egg-secure-memory.c egg-secure-memory.h
+ egg-secure-memory.c egg-secure-memory.h
-libegg_secure_entry_la_SOURCES = \
- egg-secure-entry.c egg-secure-entry.h
+libegg_entry_buffer_la_SOURCES = \
+ egg-entry-buffer.c egg-entry-buffer.h
-libegg_secure_entry_la_CFLAGS = \
+libegg_entry_buffer_la_CFLAGS = \
$(GOBJECT_CFLAGS) \
$(GLIB_CFLAGS) \
$(GTK_CFLAGS)
-
+
libegg_buffer_la_SOURCES = \
egg-buffer.c egg-buffer.h
-
+
libegg_creds_la_SOURCES = \
egg-unix-credentials.c egg-unix-credentials.h
diff --git a/daemon/prompt/gkd-prompt-buffer.c b/egg/egg-entry-buffer.c
similarity index 70%
rename from daemon/prompt/gkd-prompt-buffer.c
rename to egg/egg-entry-buffer.c
index 3e07400..afb4093 100644
--- a/daemon/prompt/gkd-prompt-buffer.c
+++ b/egg/egg-entry-buffer.c
@@ -23,16 +23,15 @@
#include "config.h"
-#include "gkd-prompt-buffer.h"
-
-#include "egg/egg-secure-memory.h"
+#include "egg-entry-buffer.h"
+#include "egg-secure-memory.h"
#include <string.h>
/* Initial size of buffer, in bytes */
#define MIN_SIZE 16
-struct _GkdPromptBufferPrivate
+struct _EggEntryBufferPrivate
{
gchar *text;
gsize text_size;
@@ -40,16 +39,16 @@ struct _GkdPromptBufferPrivate
guint text_chars;
};
-G_DEFINE_TYPE (GkdPromptBuffer, gkd_prompt_buffer, GTK_TYPE_ENTRY_BUFFER);
+G_DEFINE_TYPE (EggEntryBuffer, egg_entry_buffer, GTK_TYPE_ENTRY_BUFFER);
/* --------------------------------------------------------------------------------
* SECURE IMPLEMENTATIONS OF TEXT BUFFER
*/
static const gchar*
-gkd_prompt_buffer_real_get_text (GtkEntryBuffer *buffer, gsize *n_bytes)
+egg_entry_buffer_real_get_text (GtkEntryBuffer *buffer, gsize *n_bytes)
{
- GkdPromptBuffer *self = GKD_PROMPT_BUFFER (buffer);
+ EggEntryBuffer *self = EGG_ENTRY_BUFFER (buffer);
if (n_bytes)
*n_bytes = self->priv->text_bytes;
if (!self->priv->text)
@@ -58,18 +57,18 @@ gkd_prompt_buffer_real_get_text (GtkEntryBuffer *buffer, gsize *n_bytes)
}
static guint
-gkd_prompt_buffer_real_get_length (GtkEntryBuffer *buffer)
+egg_entry_buffer_real_get_length (GtkEntryBuffer *buffer)
{
- GkdPromptBuffer *self = GKD_PROMPT_BUFFER (buffer);
+ EggEntryBuffer *self = EGG_ENTRY_BUFFER (buffer);
return self->priv->text_chars;
}
static guint
-gkd_prompt_buffer_real_insert_text (GtkEntryBuffer *buffer, guint position,
+egg_entry_buffer_real_insert_text (GtkEntryBuffer *buffer, guint position,
const gchar *chars, guint n_chars)
{
- GkdPromptBuffer *self = GKD_PROMPT_BUFFER (buffer);
- GkdPromptBufferPrivate *pv = self->priv;
+ EggEntryBuffer *self = EGG_ENTRY_BUFFER (buffer);
+ EggEntryBufferPrivate *pv = self->priv;
gsize n_bytes;
gsize at;
@@ -115,10 +114,10 @@ gkd_prompt_buffer_real_insert_text (GtkEntryBuffer *buffer, guint position,
}
static guint
-gkd_prompt_buffer_real_delete_text (GtkEntryBuffer *buffer, guint position, guint n_chars)
+egg_entry_buffer_real_delete_text (GtkEntryBuffer *buffer, guint position, guint n_chars)
{
- GkdPromptBuffer *self = GKD_PROMPT_BUFFER (buffer);
- GkdPromptBufferPrivate *pv = self->priv;
+ EggEntryBuffer *self = EGG_ENTRY_BUFFER (buffer);
+ EggEntryBufferPrivate *pv = self->priv;
gsize start, end;
if (position > pv->text_chars)
@@ -145,10 +144,10 @@ gkd_prompt_buffer_real_delete_text (GtkEntryBuffer *buffer, guint position, guin
*/
static void
-gkd_prompt_buffer_init (GkdPromptBuffer *self)
+egg_entry_buffer_init (EggEntryBuffer *self)
{
- GkdPromptBufferPrivate *pv;
- pv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GKD_TYPE_PROMPT_BUFFER, GkdPromptBufferPrivate);
+ EggEntryBufferPrivate *pv;
+ pv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, EGG_TYPE_ENTRY_BUFFER, EggEntryBufferPrivate);
pv->text = NULL;
pv->text_chars = 0;
@@ -157,10 +156,10 @@ gkd_prompt_buffer_init (GkdPromptBuffer *self)
}
static void
-gkd_prompt_buffer_finalize (GObject *obj)
+egg_entry_buffer_finalize (GObject *obj)
{
- GkdPromptBuffer *self = GKD_PROMPT_BUFFER (obj);
- GkdPromptBufferPrivate *pv = self->priv;
+ EggEntryBuffer *self = EGG_ENTRY_BUFFER (obj);
+ EggEntryBufferPrivate *pv = self->priv;
if (pv->text) {
egg_secure_strfree (pv->text);
@@ -169,23 +168,23 @@ gkd_prompt_buffer_finalize (GObject *obj)
pv->text_chars = 0;
}
- G_OBJECT_CLASS (gkd_prompt_buffer_parent_class)->finalize (obj);
+ G_OBJECT_CLASS (egg_entry_buffer_parent_class)->finalize (obj);
}
static void
-gkd_prompt_buffer_class_init (GkdPromptBufferClass *klass)
+egg_entry_buffer_class_init (EggEntryBufferClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GtkEntryBufferClass *buffer_class = GTK_ENTRY_BUFFER_CLASS (klass);
- gobject_class->finalize = gkd_prompt_buffer_finalize;
+ gobject_class->finalize = egg_entry_buffer_finalize;
- buffer_class->get_text = gkd_prompt_buffer_real_get_text;
- buffer_class->get_length = gkd_prompt_buffer_real_get_length;
- buffer_class->insert_text = gkd_prompt_buffer_real_insert_text;
- buffer_class->delete_text = gkd_prompt_buffer_real_delete_text;
+ buffer_class->get_text = egg_entry_buffer_real_get_text;
+ buffer_class->get_length = egg_entry_buffer_real_get_length;
+ buffer_class->insert_text = egg_entry_buffer_real_insert_text;
+ buffer_class->delete_text = egg_entry_buffer_real_delete_text;
- g_type_class_add_private (gobject_class, sizeof (GkdPromptBufferPrivate));
+ g_type_class_add_private (gobject_class, sizeof (EggEntryBufferPrivate));
}
/* --------------------------------------------------------------------------------
@@ -193,7 +192,7 @@ gkd_prompt_buffer_class_init (GkdPromptBufferClass *klass)
*/
GtkEntryBuffer*
-gkd_prompt_buffer_new (void)
+egg_entry_buffer_new (void)
{
- return g_object_new (GKD_TYPE_PROMPT_BUFFER, NULL);
+ return g_object_new (EGG_TYPE_ENTRY_BUFFER, NULL);
}
diff --git a/egg/egg-entry-buffer.h b/egg/egg-entry-buffer.h
new file mode 100644
index 0000000..1a7208d
--- /dev/null
+++ b/egg/egg-entry-buffer.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* egg-secure-buffer.h - secure memory gtkentry buffer
+
+ Copyright (C) 2009 Stefan Walter
+
+ The Gnome Keyring Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Keyring Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Stef Walter <stef memberwebs com>
+*/
+
+#ifndef __EGG_ENTRY_BUFFER_H__
+#define __EGG_ENTRY_BUFFER_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define EGG_TYPE_ENTRY_BUFFER (egg_entry_buffer_get_type ())
+#define EGG_ENTRY_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_ENTRY_BUFFER, EggEntryBuffer))
+#define EGG_ENTRY_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_ENTRY_BUFFER, EggEntryBufferClass))
+#define EGG_IS_ENTRY_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_ENTRY_BUFFER))
+#define EGG_IS_ENTRY_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_ENTRY_BUFFER))
+#define EGG_ENTRY_BUFFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_ENTRY_BUFFER, EggEntryBufferClass))
+
+typedef struct _EggEntryBuffer EggEntryBuffer;
+typedef struct _EggEntryBufferClass EggEntryBufferClass;
+typedef struct _EggEntryBufferPrivate EggEntryBufferPrivate;
+
+struct _EggEntryBuffer
+{
+ GtkEntryBuffer parent;
+ EggEntryBufferPrivate *priv;
+};
+
+struct _EggEntryBufferClass
+{
+ GtkEntryBufferClass parent_class;
+};
+
+GType egg_entry_buffer_get_type (void) G_GNUC_CONST;
+
+GtkEntryBuffer* egg_entry_buffer_new (void);
+
+G_END_DECLS
+
+#endif /* __EGG_ENTRY_BUFFER_H__ */
diff --git a/gcr/Makefile.am b/gcr/Makefile.am
index d8192e9..e46cf2b 100644
--- a/gcr/Makefile.am
+++ b/gcr/Makefile.am
@@ -63,7 +63,7 @@ libgcr_la_LDFLAGS = \
libgcr_la_LIBADD = \
$(top_builddir)/egg/libegg.la \
- $(top_builddir)/egg/libegg-secure-entry.la \
+ $(top_builddir)/egg/libegg-entry-buffer.la \
$(top_builddir)/gp11/libgp11.la \
$(GOBJECT_LIBS) \
$(GLIB_LIBS) \
diff --git a/gcr/gcr-certificate.c b/gcr/gcr-certificate.c
index d4a36bd..55abc68 100644
--- a/gcr/gcr-certificate.c
+++ b/gcr/gcr-certificate.c
@@ -262,7 +262,7 @@ gcr_certificate_get_type (void)
/**
* gcr_certificate_get_der_data:
* @self: a #GcrCertificate
- * @n_length: a pointer to a location to store the size of the resulting DER data.
+ * @n_data: a pointer to a location to store the size of the resulting DER data.
*
* Gets the raw DER data for an X509 certificate.
*
diff --git a/gcr/gcr-import-dialog.c b/gcr/gcr-import-dialog.c
index b017bd2..9fcb612 100644
--- a/gcr/gcr-import-dialog.c
+++ b/gcr/gcr-import-dialog.c
@@ -24,7 +24,7 @@
#include "gcr-import-dialog.h"
#include "gcr-internal.h"
-#include "egg/egg-secure-entry.h"
+#include "egg/egg-entry-buffer.h"
enum {
PROP_0,
@@ -43,7 +43,7 @@ enum {
struct _GcrImportDialogPrivate {
GtkBuilder *builder;
- EggSecureEntry *entry;
+ GtkEntry *entry;
GtkWidget *button;
GtkComboBox *combo;
GtkListStore *slots;
@@ -120,8 +120,9 @@ gcr_import_dialog_constructor (GType type, guint n_props, GObjectConstructParam
{
GcrImportDialog *self = GCR_IMPORT_DIALOG (G_OBJECT_CLASS (_gcr_import_dialog_parent_class)->constructor(type, n_props, props));
GtkCellRenderer *renderer;
+ GtkEntryBuffer *buffer;
GtkWidget *widget;
-
+
g_return_val_if_fail (self, NULL);
if (!gtk_builder_add_from_file (self->pv->builder, UIDIR "gcr-import-dialog.ui", NULL))
@@ -133,7 +134,9 @@ gcr_import_dialog_constructor (GType type, guint n_props, GObjectConstructParam
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (self)->vbox), widget);
/* Add a secure entry */
- self->pv->entry = EGG_SECURE_ENTRY (egg_secure_entry_new ());
+ buffer = egg_entry_buffer_new ();
+ self->pv->entry = GTK_ENTRY (gtk_entry_new_with_buffer (buffer));
+ g_object_unref (buffer);
widget = GTK_WIDGET (gtk_builder_get_object (self->pv->builder, "password-area"));
gtk_container_add (GTK_CONTAINER (widget), GTK_WIDGET (self->pv->entry));
gtk_widget_show (GTK_WIDGET (self->pv->entry));
@@ -384,7 +387,7 @@ const gchar*
_gcr_import_dialog_get_password (GcrImportDialog *self)
{
g_return_val_if_fail (GCR_IS_IMPORT_DIALOG (self), NULL);
- return egg_secure_entry_get_text (self->pv->entry);
+ return gtk_entry_get_text (self->pv->entry);
}
void
@@ -393,7 +396,7 @@ _gcr_import_dialog_set_password (GcrImportDialog *self, const gchar *password)
g_return_if_fail (GCR_IS_IMPORT_DIALOG (self));
if (password == NULL)
password = "";
- egg_secure_entry_set_text (self->pv->entry, password);
+ gtk_entry_set_text (self->pv->entry, password);
}
void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]