[gnome-keyring] Prompting for creation of credentials in wrap layer.
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-keyring] Prompting for creation of credentials in wrap layer.
- Date: Tue, 8 Jun 2010 16:01:12 +0000 (UTC)
commit bf0d4ea4f4ef51d95238bf30d3a434203319987c
Author: Stef Walter <stef memberwebs com>
Date: Sat Jun 5 22:44:35 2010 +0000
Prompting for creation of credentials in wrap layer.
* Not yet tested.
* Not yet used by Secret Service API.
Makefile.am | 2 +-
daemon/dbus/gkd-secret-iface.c | 59 +++
daemon/dbus/gkd-secret-iface.h | 45 +++
daemon/dbus/gkd-secret-unlock.c | 4 +
daemon/pkcs11/gkd-pkcs11-auth.c | 10 +-
pkcs11/gkm/gkm-util.c | 100 +++++
pkcs11/gkm/gkm-util.h | 2 +
pkcs11/wrap-layer/Makefile.am | 7 +-
pkcs11/wrap-layer/gkm-wrap-layer.c | 70 ++++-
pkcs11/wrap-layer/gkm-wrap-prompt.c | 688 +++++++++++++++++++++++++++++++++++
pkcs11/wrap-layer/gkm-wrap-prompt.h | 63 ++++
ui/gku-prompt.c | 53 +--
ui/gku-prompt.h | 16 +-
13 files changed, 1068 insertions(+), 51 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index ef22bc7..7805792 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -15,8 +15,8 @@ SUBDIRS = \
gp11 \
egg \
gcr \
- pkcs11 \
ui \
+ pkcs11 \
daemon \
tool \
$(TESTS_DIR) \
diff --git a/daemon/dbus/gkd-secret-iface.c b/daemon/dbus/gkd-secret-iface.c
new file mode 100644
index 0000000..de52c49
--- /dev/null
+++ b/daemon/dbus/gkd-secret-iface.c
@@ -0,0 +1,59 @@
+/*
+ * 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 Public 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 Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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 "config.h"
+
+#include "gkm-zzz.h"
+
+static void
+gkm_zzz_base_init (gpointer gobject_class)
+{
+ static gboolean initialized = FALSE;
+ if (!initialized) {
+ /* Add properties and signals to the interface */
+
+
+ initialized = TRUE;
+ }
+}
+
+GType
+gkm_zzz_get_type (void)
+{
+ static GType type = 0;
+ if (!type) {
+ static const GTypeInfo info = {
+ sizeof (GkmZzzIFace),
+ gkm_zzz_base_init, /* base init */
+ NULL, /* base finalize */
+ NULL, /* class_init */
+ NULL, /* class finalize */
+ NULL, /* class data */
+ 0,
+ 0, /* n_preallocs */
+ NULL, /* instance init */
+ };
+ type = g_type_register_static (G_TYPE_INTERFACE, "GkmZzzIFace", &info, 0);
+ g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
+ }
+
+ return type;
+}
diff --git a/daemon/dbus/gkd-secret-iface.h b/daemon/dbus/gkd-secret-iface.h
new file mode 100644
index 0000000..60dd29f
--- /dev/null
+++ b/daemon/dbus/gkd-secret-iface.h
@@ -0,0 +1,45 @@
+/*
+ * 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 Public 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 Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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 __GKR_ZZZ_H__
+#define __GKR_ZZZ_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GKR_TYPE_ZZZ (gkr_zzz_get_type())
+#define GKR_ZZZ(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GKR_TYPE_ZZZ, GkrZzz))
+#define GKR_IS_ZZZ(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GKR_TYPE_ZZZ))
+#define GKR_ZZZ_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GKR_TYPE_ZZZ, GkrZzzIface))
+
+typedef struct _GkrZzz GkrZzz;
+typedef struct _GkrZzzIface GkrZzzIface;
+
+struct _GkrZzzIface {
+ GTypeInterface parent;
+};
+
+GType gkr_zzz_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __GKR_ZZZ_H__ */
diff --git a/daemon/dbus/gkd-secret-unlock.c b/daemon/dbus/gkd-secret-unlock.c
index d7e5bcb..d86578b 100644
--- a/daemon/dbus/gkd-secret-unlock.c
+++ b/daemon/dbus/gkd-secret-unlock.c
@@ -209,7 +209,9 @@ prepare_unlock_prompt (GkdSecretUnlock *self, GP11Object *coll, gboolean first)
if (first) {
template = gp11_object_get_template (coll, CKA_G_CREDENTIAL_TEMPLATE, &error);
if (template) {
+#if 0
gku_prompt_set_unlock_options (prompt, template);
+#endif
gp11_attributes_unref (template);
} else {
g_warning ("couldn't get credential template for collection: %s",
@@ -318,7 +320,9 @@ authenticate_collection (GkdSecretUnlock *self, GP11Object *collection, gboolean
/* The various unlock options */
template = gp11_attributes_new ();
common_unlock_attributes (template, collection);
+#if 0
gku_prompt_get_unlock_options (GKU_PROMPT (self), template);
+#endif
/* If it's supposed to save non-transient, then we override that */
attr = gp11_attributes_find (template, CKA_GNOME_TRANSIENT);
diff --git a/daemon/pkcs11/gkd-pkcs11-auth.c b/daemon/pkcs11/gkd-pkcs11-auth.c
index 8809c72..912c6f5 100644
--- a/daemon/pkcs11/gkd-pkcs11-auth.c
+++ b/daemon/pkcs11/gkd-pkcs11-auth.c
@@ -268,6 +268,7 @@ init_user_prompt (CK_SESSION_HANDLE handle, CK_TOKEN_INFO *info,
gchar *manufacturer;
gchar *serial;
gboolean ret = TRUE;
+ gint value = 0;
g_assert (info);
g_assert (pin);
@@ -317,7 +318,7 @@ init_user_prompt (CK_SESSION_HANDLE handle, CK_TOKEN_INFO *info,
} else {
password = gku_prompt_get_password (prompt, "password");
- if (gku_prompt_get_unlock_auto (prompt)) {
+ if (gku_prompt_get_unlock_option (prompt, GKU_UNLOCK_AUTO, &value) && value) {
gkd_login_attach_secret (label, password,
"manufacturer", manufacturer,
"serial-number", serial,
@@ -417,6 +418,7 @@ login_specific_prompt (CK_SESSION_HANDLE handle, CK_SESSION_INFO *info,
GkuPrompt *prompt;
gchar *secondary;
gboolean ret;
+ gint value = 0;
g_assert (info);
g_assert (pin);
@@ -481,7 +483,8 @@ login_specific_prompt (CK_SESSION_HANDLE handle, CK_SESSION_INFO *info,
password = gku_prompt_get_password (prompt, "password");
/* Store forever */
- if (gku_prompt_get_unlock_auto (prompt) && object->unique && object->token) {
+ if (gku_prompt_get_unlock_option (prompt, GKU_UNLOCK_AUTO, &value) &&
+ value && object->unique && object->token) {
gkd_login_attach_secret (object->label, password,
"unique", object->unique, NULL);
}
@@ -554,6 +557,7 @@ login_user_prompt (CK_SESSION_HANDLE handle, CK_TOKEN_INFO *info,
gchar *serial;
const gchar *password;
gboolean ret = TRUE;
+ gint value = 0;
g_assert (info);
g_assert (pin);
@@ -621,7 +625,7 @@ login_user_prompt (CK_SESSION_HANDLE handle, CK_TOKEN_INFO *info,
password = gku_prompt_get_password (prompt, "password");
/* Store forever */
- if (gku_prompt_get_unlock_auto (prompt)) {
+ if (gku_prompt_get_unlock_option (prompt, GKU_UNLOCK_AUTO, &value) && value) {
gkd_login_attach_secret (label, password,
"manufacturer", manufacturer,
"serial-number", serial,
diff --git a/pkcs11/gkm/gkm-util.c b/pkcs11/gkm/gkm-util.c
index a1c6253..984c5ce 100644
--- a/pkcs11/gkm/gkm-util.c
+++ b/pkcs11/gkm/gkm-util.c
@@ -98,3 +98,103 @@ gkm_util_dispose_unref (gpointer object)
g_object_run_dispose (G_OBJECT (object));
g_object_unref (object);
}
+
+const gchar*
+gkm_util_rv_to_string (CK_RV rv)
+{
+ #define GKM_X(rv) case rv: return #rv;
+ switch (rv) {
+
+ /* These are not really errors, or not current */
+ GKM_X (CKR_OK)
+ GKM_X (CKR_NO_EVENT)
+ GKM_X (CKR_FUNCTION_NOT_PARALLEL)
+ GKM_X (CKR_SESSION_PARALLEL_NOT_SUPPORTED)
+ GKM_X (CKR_CANCEL)
+ GKM_X (CKR_FUNCTION_CANCELED)
+ GKM_X (CKR_HOST_MEMORY)
+ GKM_X (CKR_SLOT_ID_INVALID)
+ GKM_X (CKR_GENERAL_ERROR)
+ GKM_X (CKR_FUNCTION_FAILED)
+ GKM_X (CKR_ARGUMENTS_BAD)
+ GKM_X (CKR_NEED_TO_CREATE_THREADS)
+ GKM_X (CKR_CANT_LOCK)
+ GKM_X (CKR_ATTRIBUTE_READ_ONLY)
+ GKM_X (CKR_ATTRIBUTE_SENSITIVE)
+ GKM_X (CKR_ATTRIBUTE_TYPE_INVALID)
+ GKM_X (CKR_ATTRIBUTE_VALUE_INVALID)
+ GKM_X (CKR_DATA_INVALID)
+ GKM_X (CKR_DATA_LEN_RANGE)
+ GKM_X (CKR_DEVICE_ERROR)
+ GKM_X (CKR_DEVICE_MEMORY)
+ GKM_X (CKR_DEVICE_REMOVED)
+ GKM_X (CKR_ENCRYPTED_DATA_INVALID)
+ GKM_X (CKR_ENCRYPTED_DATA_LEN_RANGE)
+ GKM_X (CKR_FUNCTION_NOT_SUPPORTED)
+ GKM_X (CKR_KEY_HANDLE_INVALID)
+ GKM_X (CKR_KEY_SIZE_RANGE)
+ GKM_X (CKR_KEY_TYPE_INCONSISTENT)
+ GKM_X (CKR_KEY_NOT_NEEDED)
+ GKM_X (CKR_KEY_CHANGED)
+ GKM_X (CKR_KEY_NEEDED)
+ GKM_X (CKR_KEY_INDIGESTIBLE)
+ GKM_X (CKR_KEY_FUNCTION_NOT_PERMITTED)
+ GKM_X (CKR_KEY_NOT_WRAPPABLE)
+ GKM_X (CKR_KEY_UNEXTRACTABLE)
+ GKM_X (CKR_MECHANISM_INVALID)
+ GKM_X (CKR_MECHANISM_PARAM_INVALID)
+ GKM_X (CKR_OBJECT_HANDLE_INVALID)
+ GKM_X (CKR_OPERATION_ACTIVE)
+ GKM_X (CKR_OPERATION_NOT_INITIALIZED)
+ GKM_X (CKR_PIN_INCORRECT)
+ GKM_X (CKR_PIN_INVALID)
+ GKM_X (CKR_PIN_LEN_RANGE)
+ GKM_X (CKR_PIN_EXPIRED)
+ GKM_X (CKR_PIN_LOCKED)
+ GKM_X (CKR_SESSION_CLOSED)
+ GKM_X (CKR_SESSION_COUNT)
+ GKM_X (CKR_SESSION_HANDLE_INVALID)
+ GKM_X (CKR_SESSION_READ_ONLY)
+ GKM_X (CKR_SESSION_EXISTS)
+ GKM_X (CKR_SESSION_READ_ONLY_EXISTS)
+ GKM_X (CKR_SESSION_READ_WRITE_SO_EXISTS)
+ GKM_X (CKR_SIGNATURE_INVALID)
+ GKM_X (CKR_SIGNATURE_LEN_RANGE)
+ GKM_X (CKR_TEMPLATE_INCOMPLETE)
+ GKM_X (CKR_TEMPLATE_INCONSISTENT)
+ GKM_X (CKR_TOKEN_NOT_PRESENT)
+ GKM_X (CKR_TOKEN_NOT_RECOGNIZED)
+ GKM_X (CKR_TOKEN_WRITE_PROTECTED)
+ GKM_X (CKR_UNWRAPPING_KEY_HANDLE_INVALID)
+ GKM_X (CKR_UNWRAPPING_KEY_SIZE_RANGE)
+ GKM_X (CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT)
+ GKM_X (CKR_USER_ALREADY_LOGGED_IN)
+ GKM_X (CKR_USER_NOT_LOGGED_IN)
+ GKM_X (CKR_USER_PIN_NOT_INITIALIZED)
+ GKM_X (CKR_USER_TYPE_INVALID)
+ GKM_X (CKR_USER_ANOTHER_ALREADY_LOGGED_IN)
+ GKM_X (CKR_USER_TOO_MANY_TYPES)
+ GKM_X (CKR_WRAPPED_KEY_INVALID)
+ GKM_X (CKR_WRAPPED_KEY_LEN_RANGE)
+ GKM_X (CKR_WRAPPING_KEY_HANDLE_INVALID)
+ GKM_X (CKR_WRAPPING_KEY_SIZE_RANGE)
+ GKM_X (CKR_WRAPPING_KEY_TYPE_INCONSISTENT)
+ GKM_X (CKR_RANDOM_SEED_NOT_SUPPORTED)
+ GKM_X (CKR_RANDOM_NO_RNG)
+ GKM_X (CKR_DOMAIN_PARAMS_INVALID)
+ GKM_X (CKR_BUFFER_TOO_SMALL)
+ GKM_X (CKR_SAVED_STATE_INVALID)
+ GKM_X (CKR_INFORMATION_SENSITIVE)
+ GKM_X (CKR_STATE_UNSAVEABLE)
+ GKM_X (CKR_CRYPTOKI_NOT_INITIALIZED)
+ GKM_X (CKR_CRYPTOKI_ALREADY_INITIALIZED)
+ GKM_X (CKR_MUTEX_BAD)
+ GKM_X (CKR_MUTEX_NOT_LOCKED)
+ GKM_X (CKR_FUNCTION_REJECTED)
+ default:
+ g_message ("unknown error: %lu", (gulong)rv);
+ return "CKR_?UNKNOWN?";
+ }
+
+ #undef GKM_X
+}
diff --git a/pkcs11/gkm/gkm-util.h b/pkcs11/gkm/gkm-util.h
index 1152bc8..d6ac807 100644
--- a/pkcs11/gkm/gkm-util.h
+++ b/pkcs11/gkm/gkm-util.h
@@ -49,4 +49,6 @@ CK_ULONG gkm_util_next_handle (void);
void gkm_util_dispose_unref (gpointer object);
+const gchar* gkm_util_rv_to_string (CK_RV rv);
+
#endif /* GKM_UTIL_H_ */
diff --git a/pkcs11/wrap-layer/Makefile.am b/pkcs11/wrap-layer/Makefile.am
index 436f81f..f4d3a28 100644
--- a/pkcs11/wrap-layer/Makefile.am
+++ b/pkcs11/wrap-layer/Makefile.am
@@ -4,15 +4,18 @@ noinst_LTLIBRARIES = \
INCLUDES = -I. \
-I$(top_srcdir) \
- -I$(top_builddir)
+ -I$(top_builddir) \
+ -I$(top_srcdir)/pkcs11
# ------------------------------------------------------------------------------
# The code
libgkm_wrap_layer_la_SOURCES = \
- gkm-wrap-layer.c gkm-wrap-layer.h
+ gkm-wrap-layer.c gkm-wrap-layer.h \
+ gkm-wrap-prompt.c gkm-wrap-prompt.h
libgkm_wrap_layer_la_LIBADD = \
+ $(top_builddir)/pkcs11/gkm/libgkm.la \
$(GTHREAD_LIBS) \
$(GLIB_LIBS)
diff --git a/pkcs11/wrap-layer/gkm-wrap-layer.c b/pkcs11/wrap-layer/gkm-wrap-layer.c
index 558567a..bee7832 100644
--- a/pkcs11/wrap-layer/gkm-wrap-layer.c
+++ b/pkcs11/wrap-layer/gkm-wrap-layer.c
@@ -1,7 +1,7 @@
/*
* gnome-keyring
*
- * Copyright (C) 2008 Stefan Walter
+ * Copyright (C) 2010 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
@@ -22,6 +22,7 @@
#include "config.h"
#include "gkm-wrap-layer.h"
+#include "gkm-wrap-prompt.h"
#include "pkcs11/pkcs11.h"
#include "pkcs11/pkcs11g.h"
@@ -569,17 +570,82 @@ wrap_C_Logout (CK_SESSION_HANDLE handle)
return (map.funcs->C_Logout) (handle);
}
+#if 0
+static CK_RV
+wrap_C_CreateObject (CK_SESSION_HANDLE handle, CK_ATTRIBUTE_PTR template,
+ CK_ULONG n_template, CK_OBJECT_HANDLE_PTR new_object)
+{
+ CK_ATTRIBUTE_PTR attrs = NULL;
+ CK_ULONG n_attrs;
+ Mapping map;
+ CK_RV rv;
+
+ rv = map_session_to_real (&handle, &map);
+ if (rv != CKR_OK)
+ return rv;
+
+ while (rv == CKR_OK) {
+ rv = (map.funcs->C_CreateObject) (handle,
+ attrs ? attrs : template,
+ attrs ? n_attrs : n_template,
+ new_object);
+
+ if (attrs != NULL) {
+ if (rv == CKR_OK)
+ gkm_wrap_prompt_done_create_object (map.funcs, handle,
+ attrs, n_attrs);
+ g_free (attrs);
+ attrs = NULL;
+ }
+
+ if (rv != CKR_PIN_INVALID)
+ break;
+
+ /* Only prompting for creating credentials, under certain circumstances */
+ rv = gkm_wrap_prompt_for_create_object (map.funcs, handle, template,
+ n_template, &attrs, &n_attrs);
+ }
+
+ g_assert (attrs == NULL);
+ return rv;
+}
+#endif
+
static CK_RV
wrap_C_CreateObject (CK_SESSION_HANDLE handle, CK_ATTRIBUTE_PTR template,
CK_ULONG count, CK_OBJECT_HANDLE_PTR new_object)
{
+ GkmWrapPrompt *prompt = NULL;
Mapping map;
CK_RV rv;
rv = map_session_to_real (&handle, &map);
if (rv != CKR_OK)
return rv;
- return (map.funcs->C_CreateObject) (handle, template, count, new_object);
+
+ for (;;) {
+ rv = (map.funcs->C_CreateObject) (handle, template, count, new_object);
+
+ if (rv != CKR_PIN_INVALID)
+ break;
+
+ if (!prompt) {
+ prompt = gkm_wrap_prompt_for_credential (map.funcs, handle, template, count);
+ if (prompt == NULL)
+ break;
+ }
+
+ if (!gkm_wrap_prompt_do_credential (prompt, &template, &count))
+ break;
+ }
+
+
+ if (prompt) {
+ gkm_wrap_prompt_done_credential (prompt, rv);
+ g_object_unref (prompt);
+ }
+
+ return rv;
}
static CK_RV
diff --git a/pkcs11/wrap-layer/gkm-wrap-prompt.c b/pkcs11/wrap-layer/gkm-wrap-prompt.c
new file mode 100644
index 0000000..8e7746f
--- /dev/null
+++ b/pkcs11/wrap-layer/gkm-wrap-prompt.c
@@ -0,0 +1,688 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2010 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public 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 Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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 "config.h"
+
+#include "gkm-wrap-prompt.h"
+
+#include "egg/egg-secure-memory.h"
+
+#include "gkm/gkm-attributes.h"
+#include "gkm/gkm-util.h"
+
+#include "pkcs11/pkcs11.h"
+#include "pkcs11/pkcs11i.h"
+
+#include "ui/gku-prompt.h"
+
+#include <glib/gi18n.h>
+
+#include <string.h>
+
+struct _GkmWrapPrompt {
+ GkuPrompt parent;
+
+ CK_FUNCTION_LIST_PTR module;
+ CK_SESSION_HANDLE session;
+ CK_OBJECT_HANDLE object;
+
+ GArray *template;
+ CK_ULONG n_template;
+
+ gchar *password;
+ GQueue pool;
+};
+
+G_DEFINE_TYPE (GkmWrapPrompt, gkm_wrap_prompt, GKU_TYPE_PROMPT);
+
+/* -----------------------------------------------------------------------------
+ * INTERNAL
+ */
+
+#if 0
+static gchar*
+location_string_for_attributes (GP11Attributes *attrs)
+{
+ gchar *identifier;
+ gchar *location;
+
+ identifier = identifier_string_for_attributes (attrs);
+ if (identifier == NULL)
+ return NULL;
+
+ /*
+ * COMPAT: Format it into a string. This is done this way for compatibility
+ * with old gnome-keyring releases. In the future this may change.
+ *
+ * FYI: gp11_object_get_data() null terminates
+ */
+ location = g_strdup_printf ("LOCAL:/keyrings/%s.keyring", (gchar*)identifier);
+ g_free (identifier);
+ return location;
+}
+
+static void
+set_warning_wrong (GkdSecretUnlock *self)
+{
+ g_assert (GKD_SECRET_IS_UNLOCK (self));
+ gku_prompt_set_warning (GKU_PROMPT (self), _("The unlock password was incorrect"));
+}
+
+static void
+attach_unlock_to_login (GP11Object *collection, GkdSecretSecret *master)
+{
+ DBusError derr = DBUS_ERROR_INIT;
+ GP11Attributes *attrs;
+ GP11Object *cred;
+ gchar *location;
+ gchar *label;
+
+ g_assert (GP11_IS_OBJECT (collection));
+
+ /* Relevant information for the unlock item */
+ attrs = attributes_for_collection (collection);
+ g_return_if_fail (attrs);
+ location = location_string_for_attributes (attrs);
+ label = label_string_for_attributes (attrs);
+ gp11_attributes_unref (attrs);
+
+ attrs = gkd_login_attach_make_attributes (label, "keyring", location, NULL);
+ g_free (location);
+ g_free (label);
+
+ cred = gkd_secret_session_create_credential (master->session, NULL, attrs, master, &derr);
+ gp11_attributes_unref (attrs);
+ g_object_unref (cred);
+
+ if (!cred) {
+ g_warning ("couldn't save unlock password in login collection: %s", derr.message);
+ dbus_error_free (&derr);
+ }
+}
+
+/* Save it to the login keyring */
+if (!transient)
+ attach_unlock_to_login (collection, master);
+
+/* Or try to use login keyring's passwords */
+} else {
+ attrs = attributes_for_collection (coll);
+ location = location_string_for_attributes (attrs);
+ gp11_attributes_unref (attrs);
+
+ if (location) {
+ password = gkd_login_lookup_secret ("keyring", location, NULL);
+ g_free (location);
+
+ if (password) {
+ if (gkd_secret_unlock_with_password (coll, NULL, 0, NULL))
+ locked = FALSE;
+ egg_secure_strfree (password);
+ }
+ }
+
+#endif
+
+static GkuPrompt*
+on_prompt_attention (gpointer user_data)
+{
+ /* We passed the prompt as the argument */
+ return g_object_ref (user_data);
+}
+
+static gpointer
+pool_alloc (GkmWrapPrompt *self, gsize length)
+{
+ gpointer memory = g_malloc0 (length);
+
+ g_assert (GKM_WRAP_IS_PROMPT (self));
+ g_queue_push_tail (&self->pool, memory);
+ return memory;
+}
+
+static gpointer
+pool_dup (GkmWrapPrompt *self, gconstpointer original, gsize length)
+{
+ gpointer memory = pool_alloc (self, length);
+ memcpy (memory, original, length);
+ return memory;
+}
+
+static CK_ATTRIBUTE_PTR
+get_unlock_options_from_object (GkmWrapPrompt *self, CK_ULONG_PTR n_options)
+{
+ CK_ATTRIBUTE_PTR options;
+ CK_ATTRIBUTE attr;
+ CK_ULONG i;
+ CK_RV rv;
+
+ g_assert (GKM_WRAP_IS_PROMPT (self));
+ g_assert (self->module);
+ g_assert (n_options);
+
+ *n_options = 0;
+
+ attr.type = CKA_G_CREDENTIAL_TEMPLATE;
+ attr.ulValueLen = 0;
+ attr.pValue = NULL;
+
+ /* Get the length of the entire template */
+ rv = (self->module->C_GetAttributeValue) (self->session, self->object, &attr, 1);
+ if (rv != CKR_OK) {
+ if (rv != CKR_ATTRIBUTE_TYPE_INVALID)
+ g_warning ("couldn't get credential template for prompt: %s",
+ gkm_util_rv_to_string (rv));
+ return NULL;
+ }
+
+ /* Number of attributes, rounded down */
+ *n_options = (attr.ulValueLen / sizeof (CK_ATTRIBUTE));;
+ options = pool_alloc (self, attr.ulValueLen);
+
+ /* Get the size of each value */
+ rv = (self->module->C_GetAttributeValue) (self->session, self->object, &attr, 1);
+ if (rv != CKR_OK) {
+ g_warning ("couldn't read credential template for prompt: %s",
+ gkm_util_rv_to_string (rv));
+ return NULL;
+ }
+
+ /* Allocate memory for each value */
+ for (i = 0; i < *n_options; ++i) {
+ if (options[i].ulValueLen != (CK_ULONG)-1)
+ options[i].pValue = pool_alloc (self, options[i].ulValueLen);
+ }
+
+ /* Now get the actual values */
+ rv = (self->module->C_GetAttributeValue) (self->session, self->object, &attr, 1);
+ if (rv != CKR_OK) {
+ g_warning ("couldn't retrieve credential template for prompt: %s",
+ gkm_util_rv_to_string (rv));
+ return NULL;
+ }
+
+ return options;
+}
+
+static void
+set_unlock_options_on_object (GkmWrapPrompt *self, CK_ATTRIBUTE_PTR options, CK_ULONG n_options)
+{
+ CK_ATTRIBUTE attr;
+ CK_RV rv;
+
+ g_assert (GKM_WRAP_IS_PROMPT (self));
+ g_assert (self->module);
+ g_assert (options);
+
+ attr.type = CKA_G_CREDENTIAL_TEMPLATE;
+ attr.pValue = options;
+ attr.ulValueLen = sizeof (CK_ATTRIBUTE) * n_options;
+
+ rv = (self->module->C_SetAttributeValue) (self->session, self->object, &attr, 1);
+ if (rv != CKR_OK && rv != CKR_ATTRIBUTE_TYPE_INVALID) {
+ g_warning ("Couldn't set credential template for prompt: %s",
+ gkm_util_rv_to_string (rv));
+ }
+}
+
+static CK_ATTRIBUTE_PTR
+get_unlock_options_from_prompt (GkmWrapPrompt *self, CK_ULONG_PTR n_options)
+{
+ CK_ATTRIBUTE_PTR options;
+ CK_BBOOL bval;
+ CK_ULONG uval;
+ gint value;
+
+ g_assert (GKM_WRAP_IS_PROMPT (self));
+ g_assert (n_options);
+
+ *n_options = 4;
+ options = pool_alloc (self, sizeof (CK_ATTRIBUTE) * (*n_options));
+
+ /* CKA_TOKEN */
+ bval = TRUE;
+ options[0].type = CKA_TOKEN;
+ options[0].pValue = pool_dup (self, &bval, sizeof (bval));
+ options[0].ulValueLen = sizeof (bval);
+
+ /* CKA_GNOME_TRANSIENT */
+ bval = TRUE;
+ options[1].type = CKA_GNOME_TRANSIENT;
+ options[1].pValue = pool_dup (self, &bval, sizeof (bval));
+ options[1].ulValueLen = sizeof (bval);
+
+ /* CKA_G_DESTRUCT_IDLE */
+ value = 0;
+ gku_prompt_get_unlock_option (GKU_PROMPT (self), GKU_UNLOCK_IDLE, &value);
+ uval = value < 0 ? 0 : value;
+ options[2].type = CKA_G_DESTRUCT_IDLE;
+ options[2].pValue = pool_dup (self, &uval, sizeof (uval));
+ options[2].ulValueLen = sizeof (uval);
+
+ /* CKA_G_DESTRUCT_AFTER */
+ value = 0;
+ gku_prompt_get_unlock_option (GKU_PROMPT (self), GKU_UNLOCK_TIMEOUT, &value);
+ uval = value < 0 ? 0 : value;
+ options[3].type = CKA_G_DESTRUCT_AFTER;
+ options[3].pValue = pool_dup (self, &uval, sizeof (uval));
+ options[3].ulValueLen = sizeof (uval);
+
+ return options;
+}
+
+static void
+set_unlock_options_on_prompt (GkmWrapPrompt *self, CK_ATTRIBUTE_PTR options, CK_ULONG n_options)
+{
+ gboolean bval;
+ gulong uval;
+
+ g_assert (GKM_WRAP_IS_PROMPT (self));
+ g_assert (options || !n_options);
+
+ if (gkm_attributes_find_boolean (options, n_options, CKA_GNOME_TRANSIENT, &bval))
+ gku_prompt_set_unlock_option (GKU_PROMPT (self), GKU_UNLOCK_AUTO, bval ? 0 : 1);
+
+ if (gkm_attributes_find_ulong (options, n_options, CKA_G_DESTRUCT_IDLE, &uval))
+ gku_prompt_set_unlock_option (GKU_PROMPT (self), GKU_UNLOCK_IDLE, (int)uval);
+
+ if (gkm_attributes_find_ulong (options, n_options, CKA_G_DESTRUCT_AFTER, &uval))
+ gku_prompt_set_unlock_option (GKU_PROMPT (self), GKU_UNLOCK_TIMEOUT, (int)uval);
+}
+
+static CK_ATTRIBUTE_PTR
+get_attributes_from_object (GkmWrapPrompt *self, CK_ULONG *n_attrs)
+{
+ CK_ATTRIBUTE attrs[3];
+ CK_ULONG i, count = 3;
+ CK_RV rv;
+
+ g_assert (GKM_WRAP_IS_PROMPT (self));
+ g_assert (n_attrs);
+ g_assert (self->module);
+
+ memset (attrs, 0, sizeof (attrs));
+ attrs[0].type = CKA_LABEL;
+ attrs[1].type = CKA_ID;
+ attrs[2].type = CKA_CLASS;
+
+ rv = (self->module->C_GetAttributeValue) (self->session, self->object, attrs, count);
+ if (rv != CKR_OK && rv != CKR_ATTRIBUTE_TYPE_INVALID) {
+ g_warning ("Couldn't retrieve information about object to unlock: %s",
+ gkm_util_rv_to_string (rv));
+ return NULL;
+ }
+
+ /* Allocate for each value, note we're null terminating values */
+ for (i = 0; i < count; ++i) {
+ if (attrs[i].ulValueLen != (CK_ULONG)-1)
+ attrs[i].pValue = pool_alloc (self, attrs[i].ulValueLen + 1);
+ }
+
+ /* Now get the actual values */
+ rv = (self->module->C_GetAttributeValue) (self->session, self->object, attrs, count);
+ if (rv != CKR_OK && rv != CKR_ATTRIBUTE_TYPE_INVALID) {
+ g_warning ("couldn't retrieve credential template for prompt: %s",
+ gkm_util_rv_to_string (rv));
+ return NULL;
+ }
+
+ *n_attrs = count;
+ return pool_dup (self, attrs, sizeof (attrs));
+
+}
+
+static void
+prepare_unlock_login_keyring (GkmWrapPrompt *self)
+{
+ GkuPrompt *prompt;
+ const gchar *text;
+
+ g_assert (GKM_WRAP_IS_PROMPT (self));
+
+ prompt = GKU_PROMPT (self);
+
+ gku_prompt_set_title (prompt, _("Unlock Login Keyring"));
+
+ text = _("Enter password for to unlock your login keyring");
+ gku_prompt_set_primary_text (prompt, text);
+
+#if 0
+ /* TODO: Reimplement this */
+ if (gkd_login_did_unlock_fail ())
+ text = _("The password you use to log in to your computer no longer matches that of your login keyring.");
+ else
+#endif
+ text = _("The login keyring did not get unlocked when you logged into your computer.");
+ gku_prompt_set_secondary_text (prompt, text);
+
+ gku_prompt_hide_widget (prompt, "name_area");
+ gku_prompt_hide_widget (prompt, "confirm_area");
+ gku_prompt_show_widget (prompt, "password_area");
+}
+
+
+
+static void
+prepare_unlock_other_keyring (GkmWrapPrompt *self, const gchar *label)
+{
+ GkuPrompt *prompt;
+ gchar *text;
+
+ g_assert (GKM_WRAP_IS_PROMPT (self));
+
+ prompt = GKU_PROMPT (self);
+
+ gku_prompt_set_title (prompt, _("Unlock Keyring"));
+
+ text = g_markup_printf_escaped (_("Enter password for keyring '%s' to unlock"), label);
+ gku_prompt_set_primary_text (prompt, text);
+ g_free (text);
+
+ text = g_markup_printf_escaped (_("An application wants access to the keyring '%s', but it is locked"), label);
+ gku_prompt_set_secondary_text (prompt, text);
+ g_free (text);
+
+ gku_prompt_hide_widget (prompt, "name_area");
+ gku_prompt_hide_widget (prompt, "confirm_area");
+ gku_prompt_show_widget (prompt, "details_area");
+ gku_prompt_show_widget (prompt, "password_area");
+ gku_prompt_show_widget (prompt, "lock_area");
+ gku_prompt_show_widget (prompt, "options_area");
+
+#if 0 /* TODO: Implement */
+ if (gkd_login_is_usable ())
+ gku_prompt_show_widget (prompt, "auto_unlock_check");
+ else
+#endif
+ gku_prompt_hide_widget (prompt, "auto_unlock_check");
+}
+
+static void
+prepare_unlock_other_object (GkmWrapPrompt *self, const gchar *label)
+{
+ GkuPrompt *prompt;
+ gchar *text;
+
+ g_assert (GKM_WRAP_IS_PROMPT (self));
+
+ prompt = GKU_PROMPT (self);
+
+ gku_prompt_set_title (prompt, _("Unlock"));
+
+ text = g_markup_printf_escaped (_("Enter password for '%s' to unlock"), label);
+ gku_prompt_set_primary_text (prompt, text);
+ g_free (text);
+
+ text = g_markup_printf_escaped (_("An application wants access to '%s', but it is locked"), label);
+ gku_prompt_set_secondary_text (prompt, text);
+ g_free (text);
+
+ gku_prompt_hide_widget (prompt, "name_area");
+ gku_prompt_hide_widget (prompt, "confirm_area");
+ gku_prompt_show_widget (prompt, "details_area");
+ gku_prompt_show_widget (prompt, "password_area");
+ gku_prompt_show_widget (prompt, "lock_area");
+ gku_prompt_show_widget (prompt, "options_area");
+ gku_prompt_hide_widget (prompt, "auto_unlock_check");
+}
+
+static void
+prepare_unlock_prompt (GkmWrapPrompt *self, gboolean first)
+{
+ CK_ATTRIBUTE_PTR attrs;
+ CK_ATTRIBUTE_PTR attr;
+ CK_ULONG n_attrs;
+ GkuPrompt *prompt;
+ const gchar *label = NULL;
+ CK_OBJECT_CLASS klass;
+
+ g_assert (GKM_WRAP_IS_PROMPT (self));
+
+ prompt = GKU_PROMPT (self);
+
+ /* Hard reset on first prompt, soft on later */
+ gku_prompt_reset (GKU_PROMPT (prompt), first);
+
+ /* Load up all the values, note they're null terminated */
+ attrs = get_attributes_from_object (self, &n_attrs);
+ g_return_if_fail (attrs);
+
+ /* Load up the object class */
+ if (!gkm_attributes_find_ulong (attrs, n_attrs, CKA_CLASS, &klass))
+ klass = (CK_ULONG)-1;
+
+ /* Load up its label */
+ attr = gkm_attributes_find (attrs, n_attrs, CKA_LABEL);
+ if (attr != NULL)
+ label = attr->pValue;
+
+ /* Load up the identifier */
+ attr = gkm_attributes_find (attrs, n_attrs, CKA_ID);
+ if (attr != NULL && !label)
+ label = attr->pValue;
+
+ if (!label)
+ label = _("Unnamed");
+
+ if (klass == CKO_G_COLLECTION) {
+ if (attr && attr->pValue && attr->ulValueLen == 5 &&
+ memcmp (attr->pValue, "login", 5)) {
+ prepare_unlock_login_keyring (self);
+ } else {
+ prepare_unlock_other_keyring (self, label);
+ }
+ } else {
+ prepare_unlock_other_object (self, label);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * OBJECT
+ */
+
+static void
+gkm_wrap_prompt_init (GkmWrapPrompt *self)
+{
+ g_queue_init (&self->pool);
+}
+
+#if 0
+static void
+gkm_wrap_prompt_dispose (GObject *obj)
+{
+ GkmWrapPrompt *self = GKM_WRAP_PROMPT (obj);
+
+ G_OBJECT_CLASS (gkm_wrap_prompt_parent_class)->dispose (obj);
+}
+#endif
+
+static void
+gkm_wrap_prompt_finalize (GObject *obj)
+{
+ GkmWrapPrompt *self = GKM_WRAP_PROMPT (obj);
+
+ egg_secure_strfree (self->password);
+
+ while (!g_queue_is_empty(&self->pool))
+ g_free (g_queue_pop_head (&self->pool));
+
+ g_array_free (self->template, TRUE);
+
+ G_OBJECT_CLASS (gkm_wrap_prompt_parent_class)->finalize (obj);
+}
+
+static void
+gkm_wrap_prompt_set_property (GObject *obj, guint prop_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gkm_wrap_prompt_get_property (GObject *obj, guint prop_id, GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gkm_wrap_prompt_class_init (GkmWrapPromptClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+#if 0
+ gobject_class->dispose = gkm_wrap_prompt_dispose;
+#endif
+ gobject_class->finalize = gkm_wrap_prompt_finalize;
+ gobject_class->set_property = gkm_wrap_prompt_set_property;
+ gobject_class->get_property = gkm_wrap_prompt_get_property;
+}
+
+/* -----------------------------------------------------------------------------
+ * PUBLIC
+ */
+
+GkmWrapPrompt*
+gkm_wrap_prompt_for_credential (CK_FUNCTION_LIST_PTR module, CK_SESSION_HANDLE session,
+ CK_ATTRIBUTE_PTR template, CK_ULONG n_template)
+{
+ CK_ATTRIBUTE_PTR attr;
+ CK_ATTRIBUTE_PTR options;
+ CK_ULONG n_options, i;
+ CK_OBJECT_CLASS klass;
+ CK_OBJECT_HANDLE object;
+ GkmWrapPrompt *self;
+
+ g_return_val_if_fail (module, NULL);
+ g_return_val_if_fail (session, NULL);
+ g_return_val_if_fail (n_template || !template, NULL);
+
+ /* Must be credential and have object for protected outh path */
+ if (!gkm_attributes_find_ulong (template, n_template, CKA_CLASS, &klass) ||
+ !gkm_attributes_find_ulong (template, n_template, CKA_G_OBJECT, &object) ||
+ klass != CKO_G_CREDENTIAL || object == 0)
+ return NULL;
+
+ /* Must have CKA_VALUE with pValue set to null for protected auth path */
+ attr = gkm_attributes_find (template, n_template, CKA_VALUE);
+ if (attr == NULL || attr->pValue != NULL)
+ return NULL;
+
+ /* Build up the prompt */
+ self = g_object_new (GKM_WRAP_TYPE_PROMPT, NULL);
+ self->object = object;
+ self->module = module;
+ self->session = session;
+ prepare_unlock_prompt (self, TRUE);
+
+ /* Build up a copy of the template with CKA_VALUE first */
+ self->template = g_array_new (FALSE, FALSE, sizeof (CK_ATTRIBUTE));
+ g_array_append_val (self->template, *attr);
+ for (i = 0; i < n_template; ++i) {
+ if (template[i].type != CKA_VALUE)
+ g_array_append_val (self->template, template[i]);
+ }
+
+ self->n_template = n_template;
+
+ /* Now load up the unlock options into the prompt*/
+ options = get_unlock_options_from_object (self, &n_options);
+ if (options != NULL)
+ set_unlock_options_on_prompt (self, options, n_options);
+
+ return self;
+}
+
+gboolean
+gkm_wrap_prompt_do_credential (GkmWrapPrompt *self, CK_ATTRIBUTE_PTR *template,
+ CK_ULONG *n_template)
+{
+ CK_ATTRIBUTE_PTR options;
+ CK_ATTRIBUTE_PTR attr;
+ CK_ULONG n_options, i;
+
+ g_return_val_if_fail (GKM_WRAP_IS_PROMPT (self), FALSE);
+ g_return_val_if_fail (template, FALSE);
+ g_return_val_if_fail (n_template, FALSE);
+
+ gku_prompt_request_attention_sync (NULL, on_prompt_attention,
+ g_object_ref (self), g_object_unref);
+
+ if (gku_prompt_get_response (GKU_PROMPT (self)) != GKU_RESPONSE_OK)
+ return FALSE;
+
+ egg_secure_strfree (self->password);
+ self->password = gku_prompt_get_password (GKU_PROMPT (self), "password");
+ g_return_val_if_fail (self->password, FALSE);
+
+ /* Truncate any extra options off the end of template */
+ g_assert (self->n_template > 0);
+ g_assert (self->template->len >= self->n_template);
+ g_array_set_size (self->template, self->n_template);
+
+ /* Put the password into the template, always first */
+ attr = &g_array_index (self->template, CK_ATTRIBUTE, 0);
+ g_assert (attr->type == CKA_VALUE);
+ attr->pValue = self->password;
+ attr->ulValueLen = strlen (self->password);
+
+ /* Tag any options onto the end of template */
+ options = get_unlock_options_from_prompt (self, &n_options);
+ for (i = 0; options && i < n_options; ++i)
+ g_array_append_val (self->template, options[i]);
+
+ *template = (CK_ATTRIBUTE_PTR)self->template->data;
+ *n_template = self->template->len;
+ return TRUE;
+}
+
+void
+gkm_wrap_prompt_done_credential (GkmWrapPrompt *self, CK_RV call_result)
+{
+ CK_ATTRIBUTE_PTR options;
+ CK_ULONG n_options;
+ gint value = 0;
+
+ g_return_if_fail (GKM_WRAP_IS_PROMPT (self));
+
+ /* Save the options, and possibly auto unlock */
+ if (call_result == CKR_OK) {
+ options = get_unlock_options_from_prompt (self, &n_options);
+ if (options != NULL)
+ set_unlock_options_on_object (self, options, n_options);
+
+ if (gku_prompt_get_unlock_option (GKU_PROMPT (self), GKU_UNLOCK_AUTO, &value) && value) {
+ g_assert_not_reached (); /* TODO: Need to implement */
+ }
+
+ /* Make sure to remove any auto-unlock when we fail */
+ } else if (call_result == CKR_PIN_INCORRECT) {
+ /* TODO: Implement removal from login keyring */
+ }
+}
diff --git a/pkcs11/wrap-layer/gkm-wrap-prompt.h b/pkcs11/wrap-layer/gkm-wrap-prompt.h
new file mode 100644
index 0000000..855ce89
--- /dev/null
+++ b/pkcs11/wrap-layer/gkm-wrap-prompt.h
@@ -0,0 +1,63 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2010 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public 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 Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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 __GKM_WRAP_PROMPT_H__
+#define __GKM_WRAP_PROMPT_H__
+
+#include <glib-object.h>
+
+#include "ui/gku-prompt.h"
+
+#define GKM_WRAP_TYPE_PROMPT (gkm_wrap_prompt_get_type ())
+#define GKM_WRAP_PROMPT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GKM_WRAP_TYPE_PROMPT, GkmWrapPrompt))
+#define GKM_WRAP_PROMPT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GKM_WRAP_TYPE_PROMPT, GkmWrapPromptClass))
+#define GKM_WRAP_IS_PROMPT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GKM_WRAP_TYPE_PROMPT))
+#define GKM_WRAP_IS_PROMPT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GKM_WRAP_TYPE_PROMPT))
+#define GKM_WRAP_PROMPT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GKM_WRAP_TYPE_PROMPT, GkmWrapPromptClass))
+
+typedef struct _GkmWrapPrompt GkmWrapPrompt;
+typedef struct _GkmWrapPromptClass GkmWrapPromptClass;
+
+struct _GkmWrapPromptClass {
+ GkuPromptClass parent_class;
+};
+
+GType gkm_wrap_prompt_get_type (void);
+
+GkmWrapPrompt* gkm_wrap_prompt_for_credential (CK_FUNCTION_LIST_PTR module,
+ CK_SESSION_HANDLE session,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG n_template);
+
+gboolean gkm_wrap_prompt_do_credential (GkmWrapPrompt *self,
+ CK_ATTRIBUTE_PTR *template,
+ CK_ULONG *n_template);
+
+void gkm_wrap_prompt_done_credential (GkmWrapPrompt *self,
+ CK_RV call_result);
+
+#if 0
+void gkm_wrap_prompt_complete (GkmWrapPrompt *self);
+
+void gkm_wrap_prompt_dismiss (GkmWrapPrompt *self);
+#endif
+
+#endif /* __GKM_WRAP_PROMPT_H__ */
diff --git a/ui/gku-prompt.c b/ui/gku-prompt.c
index 01c7c77..d485885 100644
--- a/ui/gku-prompt.c
+++ b/ui/gku-prompt.c
@@ -839,54 +839,33 @@ gku_prompt_get_transport_password (GkuPrompt *self, const gchar *password_type,
return TRUE;
}
-void
-gku_prompt_get_unlock_options (GkuPrompt *self, GP11Attributes *attrs)
+gboolean
+gku_prompt_get_unlock_option (GkuPrompt *self, const gchar *option, gint *value)
{
- gboolean bval;
- gint ival;
-
- g_return_if_fail (GKU_IS_PROMPT (self));
- g_return_if_fail (attrs);
- g_return_if_fail (self->pv->output);
-
- gp11_attributes_add_boolean (attrs, CKA_TOKEN, TRUE);
+ GError *error = NULL;
- bval = g_key_file_get_boolean (self->pv->output, "unlock-options", "unlock-auto", NULL);
- gp11_attributes_add_boolean (attrs, CKA_GNOME_TRANSIENT, !bval);
+ g_return_val_if_fail (GKU_IS_PROMPT (self), FALSE);
+ g_return_val_if_fail (option, FALSE);
+ g_return_val_if_fail (value, FALSE);
+ g_return_val_if_fail (self->pv->output, FALSE);
- ival = g_key_file_get_integer (self->pv->output, "unlock-options", "unlock-idle", NULL);
- gp11_attributes_add_ulong (attrs, CKA_G_DESTRUCT_IDLE, ival <= 0 ? 0 : ival);
+ *value = g_key_file_get_integer (self->pv->output, "unlock-options", option, &error);
+ if (error != NULL) {
+ g_clear_error (&error);
+ return FALSE;
+ }
- ival = g_key_file_get_integer (self->pv->output, "unlock-options", "unlock-timeout", NULL);
- gp11_attributes_add_ulong (attrs, CKA_G_DESTRUCT_AFTER, ival <= 0 ? 0 : ival);
+ return TRUE;
}
void
-gku_prompt_set_unlock_options (GkuPrompt *self, GP11Attributes *attrs)
+gku_prompt_set_unlock_option (GkuPrompt *self, const gchar *option, gint value)
{
- gboolean bval;
- gulong uval;
-
g_return_if_fail (GKU_IS_PROMPT (self));
- g_return_if_fail (attrs);
+ g_return_if_fail (option);
g_return_if_fail (self->pv->input);
- if (gp11_attributes_find_boolean (attrs, CKA_GNOME_TRANSIENT, &bval))
- g_key_file_set_boolean (self->pv->input, "unlock-options", "unlock-auto", !bval);
-
- if (gp11_attributes_find_ulong (attrs, CKA_G_DESTRUCT_IDLE, &uval))
- g_key_file_set_integer (self->pv->input, "unlock-options", "unlock-idle", (int)uval);
-
- if (gp11_attributes_find_ulong (attrs, CKA_G_DESTRUCT_AFTER, &uval))
- g_key_file_set_integer (self->pv->input, "unlock-options", "unlock-timeout", (int)uval);
-}
-
-gboolean
-gku_prompt_get_unlock_auto (GkuPrompt *self)
-{
- g_return_val_if_fail (GKU_IS_PROMPT (self), FALSE);
- g_return_val_if_fail (self->pv->output, FALSE);
- return g_key_file_get_boolean (self->pv->output, "unlock-options", "unlock-auto", NULL);
+ g_key_file_set_integer (self->pv->input, "unlock-options", option, value);
}
/* ----------------------------------------------------------------------------------
diff --git a/ui/gku-prompt.h b/ui/gku-prompt.h
index 1520f89..a1c6fcb 100644
--- a/ui/gku-prompt.h
+++ b/ui/gku-prompt.h
@@ -34,6 +34,10 @@ typedef enum {
GKU_RESPONSE_OTHER = 3,
} GkuResponse;
+#define GKU_UNLOCK_AUTO "unlock-auto"
+#define GKU_UNLOCK_IDLE "unlock-idle"
+#define GKU_UNLOCK_TIMEOUT "unlock-timeout"
+
#define GKU_TYPE_PROMPT (gku_prompt_get_type ())
#define GKU_PROMPT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GKU_TYPE_PROMPT, GkuPrompt))
#define GKU_PROMPT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GKU_TYPE_PROMPT, GkuPromptClass))
@@ -112,13 +116,13 @@ gboolean gku_prompt_get_transport_password (GkuPrompt *self,
gpointer *value,
gsize *n_value);
-void gku_prompt_get_unlock_options (GkuPrompt *self,
- GP11Attributes *attrs);
-
-void gku_prompt_set_unlock_options (GkuPrompt *self,
- GP11Attributes *attrs);
+gboolean gku_prompt_get_unlock_option (GkuPrompt *self,
+ const gchar *option,
+ gint *value);
-gboolean gku_prompt_get_unlock_auto (GkuPrompt *self);
+void gku_prompt_set_unlock_option (GkuPrompt *self,
+ const gchar *option,
+ gint value);
gboolean gku_prompt_is_widget_selected (GkuPrompt *prompt,
const gchar *widget);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]