[gnome-keyring] Fix bugs preventing wrap layer propmting from working.



commit 27789d006f38f134a2a34482d9343034d7dfa5b8
Author: Stef Walter <stef memberwebs com>
Date:   Sun Jun 6 19:51:58 2010 +0000

    Fix bugs preventing wrap layer propmting from working.
    
     * Standard way to get object path from GkdSecretDispatch
     * Lots of minor little tweaks and bugs.

 daemon/Makefile.am                   |    2 +-
 daemon/dbus/gkd-secret-dispatch.c    |    9 +++
 daemon/dbus/gkd-secret-dispatch.h    |    3 +
 daemon/dbus/gkd-secret-prompt.c      |    9 +---
 daemon/dbus/gkd-secret-prompt.h      |    2 -
 daemon/dbus/gkd-secret-secret.c      |    3 +-
 daemon/dbus/gkd-secret-service.c     |   10 ++--
 daemon/dbus/gkd-secret-session.c     |   13 +----
 daemon/dbus/gkd-secret-session.h     |    2 -
 daemon/dbus/gkd-secret-unlock.c      |   10 ++--
 daemon/pkcs11/gkd-pkcs11.c           |   14 +++---
 gp11/gp11-attributes.c               |    4 +-
 pkcs11/user-store/gkm-user-storage.c |    2 +-
 pkcs11/wrap-layer/gkm-wrap-layer.c   |   94 +++++++++++++--------------------
 pkcs11/wrap-layer/gkm-wrap-prompt.c  |   10 +++-
 ui/gku-prompt.c                      |    1 +
 16 files changed, 85 insertions(+), 103 deletions(-)
---
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 70531cb..d182e55 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -34,7 +34,7 @@ gnome_keyring_daemon_LDADD = \
 	$(top_builddir)/daemon/control/libgkd-control.la \
 	$(top_builddir)/ui/libgku-prompt.la \
 	$(top_builddir)/daemon/ssh-agent/libgkd-ssh-agent.la \
-	$(top_builddir)/pkcs11/plex-layer/libgkm-plex-layer.la \
+	$(top_builddir)/pkcs11/wrap-layer/libgkm-wrap-layer.la \
 	$(top_builddir)/pkcs11/roots-store/libgkm-roots-store.la \
 	$(top_builddir)/pkcs11/rpc-layer/libgkm-rpc-layer.la \
 	$(top_builddir)/pkcs11/secret-store/libgkm-secret-store.la \
diff --git a/daemon/dbus/gkd-secret-dispatch.c b/daemon/dbus/gkd-secret-dispatch.c
index 1849a2e..dc86089 100644
--- a/daemon/dbus/gkd-secret-dispatch.c
+++ b/daemon/dbus/gkd-secret-dispatch.c
@@ -62,3 +62,12 @@ gkd_secret_dispatch_message (GkdSecretDispatch *self, DBusMessage *message)
 	g_return_val_if_fail (GKD_SECRET_DISPATCH_GET_INTERFACE (self)->dispatch_message, NULL);
 	return GKD_SECRET_DISPATCH_GET_INTERFACE (self)->dispatch_message (self, message);
 }
+
+const gchar*
+gkd_secret_dispatch_get_object_path (GkdSecretDispatch *self)
+{
+	const gchar *path = NULL;
+	/* object-path is boxed, no allocation */
+	g_object_get (self, "object-path", &path, NULL);
+	return path;
+}
diff --git a/daemon/dbus/gkd-secret-dispatch.h b/daemon/dbus/gkd-secret-dispatch.h
index b850bde..7869eff 100644
--- a/daemon/dbus/gkd-secret-dispatch.h
+++ b/daemon/dbus/gkd-secret-dispatch.h
@@ -40,11 +40,14 @@ typedef struct _GkdSecretDispatchIface GkdSecretDispatchIface;
 struct _GkdSecretDispatchIface {
 	GTypeInterface parent;
 
+	const gchar* (*get_path) (GkdSecretDispatch *self);
 	DBusMessage* (*dispatch_message) (GkdSecretDispatch *self, DBusMessage *message);
 };
 
 GType                  gkd_secret_dispatch_get_type                          (void) G_GNUC_CONST;
 
+const gchar*           gkd_secret_dispatch_get_object_path                   (GkdSecretDispatch *self);
+
 DBusMessage*           gkd_secret_dispatch_message                           (GkdSecretDispatch *self,
                                                                               DBusMessage *message);
 
diff --git a/daemon/dbus/gkd-secret-prompt.c b/daemon/dbus/gkd-secret-prompt.c
index 433e349..c65ccaa 100644
--- a/daemon/dbus/gkd-secret-prompt.c
+++ b/daemon/dbus/gkd-secret-prompt.c
@@ -382,7 +382,7 @@ gkd_secret_prompt_get_property (GObject *obj, guint prop_id, GValue *value,
 		g_value_set_string (value, gkd_secret_prompt_get_caller (self));
 		break;
 	case PROP_OBJECT_PATH:
-		g_value_set_boxed (value, gkd_secret_prompt_get_object_path (self));
+		g_value_set_boxed (value, self->pv->object_path);
 		break;
 	case PROP_SERVICE:
 		g_value_set_object (value, self->pv->service);
@@ -442,13 +442,6 @@ gkd_secret_prompt_get_caller (GkdSecretPrompt *self)
 	return self->pv->caller;
 }
 
-const gchar*
-gkd_secret_prompt_get_object_path (GkdSecretPrompt *self)
-{
-	g_return_val_if_fail (GKD_SECRET_IS_PROMPT (self), NULL);
-	return self->pv->object_path;
-}
-
 GP11Session*
 gkd_secret_prompt_get_pkcs11_session (GkdSecretPrompt *self)
 {
diff --git a/daemon/dbus/gkd-secret-prompt.h b/daemon/dbus/gkd-secret-prompt.h
index c0a6112..cc3b993 100644
--- a/daemon/dbus/gkd-secret-prompt.h
+++ b/daemon/dbus/gkd-secret-prompt.h
@@ -59,8 +59,6 @@ GType               gkd_secret_prompt_get_type                (void);
 
 const gchar*        gkd_secret_prompt_get_caller              (GkdSecretPrompt *self);
 
-const gchar*        gkd_secret_prompt_get_object_path         (GkdSecretPrompt *self);
-
 GP11Session*        gkd_secret_prompt_get_pkcs11_session      (GkdSecretPrompt *self);
 
 GkdSecretService*   gkd_secret_prompt_get_service             (GkdSecretPrompt *self);
diff --git a/daemon/dbus/gkd-secret-secret.c b/daemon/dbus/gkd-secret-secret.c
index 85bbbff..83afd19 100644
--- a/daemon/dbus/gkd-secret-secret.c
+++ b/daemon/dbus/gkd-secret-secret.c
@@ -21,6 +21,7 @@
 
 #include "config.h"
 
+#include "gkd-secret-dispatch.h"
 #include "gkd-secret-secret.h"
 #include "gkd-secret-service.h"
 #include "gkd-secret-session.h"
@@ -136,7 +137,7 @@ gkd_secret_secret_append (GkdSecretSecret *secret, DBusMessageIter *iter)
 	const gchar *path;
 	int length;
 
-	path = gkd_secret_session_get_object_path (secret->session);
+	path = gkd_secret_dispatch_get_object_path (GKD_SECRET_DISPATCH (secret->session));
 	g_return_if_fail (path);
 
 	dbus_message_iter_open_container (iter, DBUS_TYPE_STRUCT, NULL, &struc);
diff --git a/daemon/dbus/gkd-secret-service.c b/daemon/dbus/gkd-secret-service.c
index 1f27271..0003241 100644
--- a/daemon/dbus/gkd-secret-service.c
+++ b/daemon/dbus/gkd-secret-service.c
@@ -388,7 +388,7 @@ service_method_open_session (GkdSecretService *self, DBusMessage *message)
 		/* Take ownership of the session */
 		client = g_hash_table_lookup (self->clients, caller);
 		g_return_val_if_fail (client, NULL);
-		path = gkd_secret_session_get_object_path (session);
+		path = gkd_secret_dispatch_get_object_path (GKD_SECRET_DISPATCH (session));
 		g_return_val_if_fail (!g_hash_table_lookup (client->sessions, path), NULL);
 		g_hash_table_replace (client->sessions, (gpointer)path, session);
 
@@ -431,7 +431,7 @@ service_method_create_collection (GkdSecretService *self, DBusMessage *message)
 	create = gkd_secret_create_new (self, caller, attrs);
 	gp11_attributes_unref (attrs);
 
-	path = gkd_secret_prompt_get_object_path (GKD_SECRET_PROMPT (create));
+	path = gkd_secret_dispatch_get_object_path (GKD_SECRET_DISPATCH (create));
 	client = g_hash_table_lookup (self->clients, caller);
 	g_return_val_if_fail (client, NULL);
 	g_hash_table_replace (client->prompts, (gpointer)path, create);
@@ -482,7 +482,7 @@ service_method_unlock (GkdSecretService *self, DBusMessage *message)
 	if (gkd_secret_unlock_have_queued (unlock)) {
 		client = g_hash_table_lookup (self->clients, caller);
 		g_return_val_if_fail (client, NULL);
-		path = gkd_secret_prompt_get_object_path (GKD_SECRET_PROMPT (unlock));
+		path = gkd_secret_dispatch_get_object_path (GKD_SECRET_DISPATCH (unlock));
 		g_hash_table_replace (client->prompts, (gpointer)path, g_object_ref (unlock));
 
 	/* No need to prompt */
@@ -565,7 +565,7 @@ service_method_change_lock (GkdSecretService *self, DBusMessage *message)
 	change = gkd_secret_change_new (self, caller, path);
 	client = g_hash_table_lookup (self->clients, caller);
 	g_return_val_if_fail (client, NULL);
-	path = gkd_secret_prompt_get_object_path (GKD_SECRET_PROMPT (change));
+	path = gkd_secret_dispatch_get_object_path (GKD_SECRET_DISPATCH (change));
 	g_hash_table_replace (client->prompts, (gpointer)path, g_object_ref (change));
 
 	reply = dbus_message_new_method_return (message);
@@ -1276,6 +1276,6 @@ gkd_secret_service_close_session (GkdSecretService *self, GkdSecretSession *sess
 	client = g_hash_table_lookup (self->clients, caller);
 	g_return_if_fail (client);
 
-	path = gkd_secret_session_get_object_path (session);
+	path = gkd_secret_dispatch_get_object_path (GKD_SECRET_DISPATCH (session));
 	g_hash_table_remove (client->sessions, path);
 }
diff --git a/daemon/dbus/gkd-secret-session.c b/daemon/dbus/gkd-secret-session.c
index 32eed56..f75750b 100644
--- a/daemon/dbus/gkd-secret-session.c
+++ b/daemon/dbus/gkd-secret-session.c
@@ -395,7 +395,7 @@ gkd_secret_session_get_property (GObject *obj, guint prop_id, GValue *value,
 		g_value_set_string (value, gkd_secret_session_get_caller_executable (self));
 		break;
 	case PROP_OBJECT_PATH:
-		g_value_set_boxed (value, gkd_secret_session_get_object_path (self));
+		g_value_set_pointer (value, self->object_path);
 		break;
 	case PROP_SERVICE:
 		g_value_set_object (value, self->service);
@@ -426,8 +426,8 @@ gkd_secret_session_class_init (GkdSecretSessionClass *klass)
 		                     NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY ));
 
 	g_object_class_install_property (gobject_class, PROP_OBJECT_PATH,
-	        g_param_spec_string ("object-path", "Object Path", "DBus Object Path",
-		                     NULL, G_PARAM_READABLE));
+	        g_param_spec_pointer ("object-path", "Object Path", "DBus Object Path",
+		                      G_PARAM_READABLE));
 
 	g_object_class_install_property (gobject_class, PROP_SERVICE,
 		g_param_spec_object ("service", "Service", "Service which owns this session",
@@ -564,13 +564,6 @@ gkd_secret_session_get_caller_executable (GkdSecretSession *self)
 	return self->caller_exec;
 }
 
-const gchar*
-gkd_secret_session_get_object_path (GkdSecretSession *self)
-{
-	g_return_val_if_fail (GKD_SECRET_IS_SESSION (self), NULL);
-	return self->object_path;
-}
-
 GP11Session*
 gkd_secret_session_get_pkcs11_session (GkdSecretSession *self)
 {
diff --git a/daemon/dbus/gkd-secret-session.h b/daemon/dbus/gkd-secret-session.h
index c5e35a4..ce8853e 100644
--- a/daemon/dbus/gkd-secret-session.h
+++ b/daemon/dbus/gkd-secret-session.h
@@ -56,8 +56,6 @@ const gchar*        gkd_secret_session_get_caller              (GkdSecretSession
 
 const gchar*        gkd_secret_session_get_caller_executable   (GkdSecretSession *self);
 
-const gchar*        gkd_secret_session_get_object_path         (GkdSecretSession *self);
-
 GP11Session*        gkd_secret_session_get_pkcs11_session      (GkdSecretSession *self);
 
 GkdSecretSecret*    gkd_secret_session_get_item_secret         (GkdSecretSession *self,
diff --git a/daemon/dbus/gkd-secret-unlock.c b/daemon/dbus/gkd-secret-unlock.c
index 0c84964..bf1f5d0 100644
--- a/daemon/dbus/gkd-secret-unlock.c
+++ b/daemon/dbus/gkd-secret-unlock.c
@@ -173,7 +173,7 @@ on_unlock_complete (GObject *object, GAsyncResult *res, gpointer user_data)
 	} else if (g_error_matches (error, GP11_ERROR, CKR_PIN_INCORRECT)) {
 		g_free (self->current);
 		self->current = NULL;
-		perform_next_unlock (self);
+		mark_as_complete (self, TRUE);
 
 	/* The operation was cancelled via Dismiss call */
 	} else if (g_error_matches (error, GP11_ERROR, CKR_CANCEL)) {
@@ -203,7 +203,7 @@ perform_next_unlock (GkdSecretUnlock *self)
 
 		/* Nothing more to prompt for? */
 		if (!objpath) {
-			mark_as_complete (self, TRUE);
+			mark_as_complete (self, FALSE);
 			break;
 		}
 
@@ -438,7 +438,7 @@ gkd_secret_unlock_get_property (GObject *obj, guint prop_id, GValue *value,
 		g_value_set_string (value, self->caller);
 		break;
 	case PROP_OBJECT_PATH:
-		g_value_set_boxed (value, self->object_path);
+		g_value_set_pointer (value, self->object_path);
 		break;
 	case PROP_SERVICE:
 		g_value_set_object (value, self->service);
@@ -466,8 +466,8 @@ gkd_secret_unlock_class_init (GkdSecretUnlockClass *klass)
 		                     NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY ));
 
 	g_object_class_install_property (gobject_class, PROP_OBJECT_PATH,
-	        g_param_spec_string ("object-path", "Object Path", "DBus Object Path",
-		                     NULL, G_PARAM_READABLE));
+	        g_param_spec_pointer ("object-path", "Object Path", "DBus Object Path",
+		                      G_PARAM_READABLE));
 
 	g_object_class_install_property (gobject_class, PROP_SERVICE,
 		g_param_spec_object ("service", "Service", "Service which owns this prompt",
diff --git a/daemon/pkcs11/gkd-pkcs11.c b/daemon/pkcs11/gkd-pkcs11.c
index c5f569d..cc116be 100644
--- a/daemon/pkcs11/gkd-pkcs11.c
+++ b/daemon/pkcs11/gkd-pkcs11.c
@@ -27,7 +27,7 @@
 
 #include "egg/egg-cleanup.h"
 
-#include "pkcs11/plex-layer/gkm-plex-layer.h"
+#include "pkcs11/wrap-layer/gkm-wrap-layer.h"
 #include "pkcs11/roots-store/gkm-roots-store.h"
 #include "pkcs11/rpc-layer/gkm-rpc-layer.h"
 #include "pkcs11/secret-store/gkm-secret-store.h"
@@ -82,15 +82,15 @@ gkd_pkcs11_initialize (void)
 	/* User certificates */
 	user_store = gkm_user_store_get_functions ();
 
-	/* Add all of those into the multiplexing layer */
-	gkm_plex_layer_add_module (ssh_store);
+	/* Add all of those into the wrapper layer */
+	gkm_wrap_layer_add_module (ssh_store);
 #ifdef ROOT_CERTIFICATES
-	gkm_plex_layer_add_module (roots_store);
+	gkm_wrap_layer_add_module (roots_store);
 #endif
-	gkm_plex_layer_add_module (secret_store);
-	gkm_plex_layer_add_module (user_store);
+	gkm_wrap_layer_add_module (secret_store);
+	gkm_wrap_layer_add_module (user_store);
 
-	pkcs11_base = gkm_plex_layer_get_functions ();
+	pkcs11_base = gkm_wrap_layer_get_functions ();
 
 	/* The auth component is the top component */
 	gkd_pkcs11_auth_chain_functions (pkcs11_base);
diff --git a/gp11/gp11-attributes.c b/gp11/gp11-attributes.c
index 391a537..afbd08c 100644
--- a/gp11/gp11-attributes.c
+++ b/gp11/gp11-attributes.c
@@ -59,8 +59,8 @@ attribute_init (GP11Attribute *attr, gulong attr_type,
 	memset (attr, 0, sizeof (GP11Attribute));
 	attr->type = attr_type;
 	attr->length = length;
-	if (value && length) {
-		attr->value = (allocator) (NULL, length);
+	if (value) {
+		attr->value = (allocator) (NULL, length ? length : 1);
 		g_assert (attr->value);
 		memcpy (attr->value, value, length);
 	}
diff --git a/pkcs11/user-store/gkm-user-storage.c b/pkcs11/user-store/gkm-user-storage.c
index 148e883..46b8ed1 100644
--- a/pkcs11/user-store/gkm-user-storage.c
+++ b/pkcs11/user-store/gkm-user-storage.c
@@ -1221,7 +1221,7 @@ gkm_user_storage_relock (GkmUserStorage *self, GkmTransaction *transaction,
 		gkm_transaction_fail (transaction, CKR_FUNCTION_FAILED);
 		return;
 	case GKM_DATA_LOCKED:
-		gkm_transaction_fail (transaction, CKR_PIN_INVALID);
+		gkm_transaction_fail (transaction, CKR_PIN_INCORRECT);
 		return;
 	case GKM_DATA_SUCCESS:
 		break;
diff --git a/pkcs11/wrap-layer/gkm-wrap-layer.c b/pkcs11/wrap-layer/gkm-wrap-layer.c
index bee7832..15d4350 100644
--- a/pkcs11/wrap-layer/gkm-wrap-layer.c
+++ b/pkcs11/wrap-layer/gkm-wrap-layer.c
@@ -64,6 +64,9 @@ static gint last_handle = 16;
 static CK_RV
 map_slot_unlocked (CK_SLOT_ID slot, Mapping *mapping)
 {
+	if (!wrap_mappings)
+		return CKR_CRYPTOKI_NOT_INITIALIZED;
+
 	if (slot < PLEX_MAPPING_OFFSET)
 		return CKR_SLOT_ID_INVALID;
 	slot -= PLEX_MAPPING_OFFSET;
@@ -101,24 +104,27 @@ map_session_to_real (CK_SESSION_HANDLE_PTR handle, Mapping *mapping)
 {
 	CK_RV rv = CKR_OK;
 	Session *sess;
-	Mapping map;
 
 	g_assert (handle);
 	g_assert (mapping);
 
 	G_LOCK (wrap_layer);
 
-		sess = g_hash_table_lookup (wrap_sessions, GINT_TO_POINTER ((gint)*handle));
-		if (sess) {
-			if (!map_slot_unlocked (sess->wrap_slot, &map))
-				rv = CKR_SLOT_ID_INVALID;
+		if (!wrap_sessions) {
+			rv = CKR_CRYPTOKI_NOT_INITIALIZED;
 		} else {
-			rv = CKR_SESSION_HANDLE_INVALID;
+			sess = g_hash_table_lookup (wrap_sessions, GINT_TO_POINTER ((gint)*handle));
+			if (sess != NULL) {
+				*handle = sess->real_session;
+				rv = map_slot_unlocked (sess->wrap_slot, mapping);
+			} else {
+				rv = CKR_SESSION_HANDLE_INVALID;
+			}
 		}
 
 	G_UNLOCK (wrap_layer);
 
-	return CKR_OK;
+	return rv;
 }
 
 #define MAP_SLOT_UP(slot, map) G_STMT_START { \
@@ -204,6 +210,7 @@ wrap_C_Initialize (CK_VOID_PTR init_args)
 			n_wrap_mappings = mappings->len;
 			wrap_mappings = (Mapping*)g_array_free (mappings, FALSE);
 			mappings = NULL;
+			wrap_sessions = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
 		}
 
 	G_UNLOCK (wrap_layer);
@@ -227,6 +234,9 @@ wrap_C_Finalize (CK_VOID_PTR reserved)
 		g_free (wrap_mappings);
 		wrap_mappings = NULL;
 
+		g_hash_table_destroy (wrap_sessions);
+		wrap_sessions = NULL;
+
 	G_UNLOCK (wrap_layer);
 
 	return CKR_OK;
@@ -312,7 +322,7 @@ wrap_C_GetSlotInfo (CK_SLOT_ID id, CK_SLOT_INFO_PTR info)
 	CK_RV rv;
 
 	rv = map_slot_to_real (&id, &map);
-	if (rv == CKR_OK)
+	if (rv != CKR_OK)
 		return rv;
 	return (map.funcs->C_GetSlotInfo) (id, info);
 }
@@ -324,7 +334,7 @@ wrap_C_GetTokenInfo (CK_SLOT_ID id, CK_TOKEN_INFO_PTR info)
 	CK_RV rv;
 
 	rv = map_slot_to_real (&id, &map);
-	if (rv == CKR_OK)
+	if (rv != CKR_OK)
 		return rv;
 	return (map.funcs->C_GetTokenInfo) (id, info);
 }
@@ -336,7 +346,7 @@ wrap_C_GetMechanismList (CK_SLOT_ID id, CK_MECHANISM_TYPE_PTR mechanism_list, CK
 	CK_RV rv;
 
 	rv = map_slot_to_real (&id, &map);
-	if (rv == CKR_OK)
+	if (rv != CKR_OK)
 		return rv;
 	return (map.funcs->C_GetMechanismList) (id, mechanism_list, count);
 }
@@ -348,7 +358,7 @@ wrap_C_GetMechanismInfo (CK_SLOT_ID id, CK_MECHANISM_TYPE type, CK_MECHANISM_INF
 	CK_RV rv;
 
 	rv = map_slot_to_real (&id, &map);
-	if (rv == CKR_OK)
+	if (rv != CKR_OK)
 		return rv;
 	return (map.funcs->C_GetMechanismInfo) (id, type, info);
 }
@@ -360,7 +370,7 @@ wrap_C_InitToken (CK_SLOT_ID id, CK_UTF8CHAR_PTR pin, CK_ULONG pin_len, CK_UTF8C
 	CK_RV rv;
 
 	rv = map_slot_to_real (&id, &map);
-	if (rv == CKR_OK)
+	if (rv != CKR_OK)
 		return rv;
 	return (map.funcs->C_InitToken) (id, pin, pin_len, label);
 }
@@ -383,7 +393,7 @@ wrap_C_OpenSession (CK_SLOT_ID id, CK_FLAGS flags, CK_VOID_PTR user_data, CK_NOT
 		return CKR_ARGUMENTS_BAD;
 
 	rv = map_slot_to_real (&id, &map);
-	if (rv == CKR_OK)
+	if (rv != CKR_OK)
 		return rv;
 
 	rv = (map.funcs->C_OpenSession) (id, flags, user_data, callback, handle);
@@ -391,7 +401,7 @@ wrap_C_OpenSession (CK_SLOT_ID id, CK_FLAGS flags, CK_VOID_PTR user_data, CK_NOT
 	if (rv == CKR_OK) {
 		G_LOCK (wrap_layer);
 
-			sess = g_slice_new (Session);
+			sess = g_new (Session, 1);
 			if (flags & CKF_G_APPLICATION_SESSION)
 				sess->app_id = ((CK_G_APPLICATION_PTR)user_data)->applicationId;
 			sess->wrap_slot = map.wrap_slot;
@@ -410,13 +420,24 @@ wrap_C_OpenSession (CK_SLOT_ID id, CK_FLAGS flags, CK_VOID_PTR user_data, CK_NOT
 static CK_RV
 wrap_C_CloseSession (CK_SESSION_HANDLE handle)
 {
+	gint key = (gint)handle;
 	Mapping map;
 	CK_RV rv;
 
 	rv = map_session_to_real (&handle, &map);
 	if (rv != CKR_OK)
 		return rv;
-	return (map.funcs->C_CloseSession) (handle);
+	rv = (map.funcs->C_CloseSession) (handle);
+
+	if (rv == CKR_OK) {
+		G_LOCK (wrap_layer);
+
+			g_hash_table_remove (wrap_sessions, GINT_TO_POINTER (key));
+
+		G_UNLOCK (wrap_layer);
+	}
+
+	return rv;
 }
 
 static CK_RV
@@ -570,47 +591,6 @@ 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)
@@ -626,7 +606,7 @@ wrap_C_CreateObject (CK_SESSION_HANDLE handle, CK_ATTRIBUTE_PTR template,
 	for (;;) {
 		rv = (map.funcs->C_CreateObject) (handle, template, count, new_object);
 
-		if (rv != CKR_PIN_INVALID)
+		if (rv != CKR_PIN_INCORRECT)
 			break;
 
 		if (!prompt) {
diff --git a/pkcs11/wrap-layer/gkm-wrap-prompt.c b/pkcs11/wrap-layer/gkm-wrap-prompt.c
index 8e7746f..cfaa68b 100644
--- a/pkcs11/wrap-layer/gkm-wrap-prompt.c
+++ b/pkcs11/wrap-layer/gkm-wrap-prompt.c
@@ -47,6 +47,7 @@ struct _GkmWrapPrompt {
 	GArray *template;
 	CK_ULONG n_template;
 
+	guint iteration;
 	gchar *password;
 	GQueue pool;
 };
@@ -195,7 +196,7 @@ get_unlock_options_from_object (GkmWrapPrompt *self, CK_ULONG_PTR n_options)
 
 	/* Number of attributes, rounded down */
 	*n_options = (attr.ulValueLen / sizeof (CK_ATTRIBUTE));;
-	options = pool_alloc (self, attr.ulValueLen);
+	attr.pValue = options = pool_alloc (self, attr.ulValueLen);
 
 	/* Get the size of each value */
 	rv = (self->module->C_GetAttributeValue) (self->session, self->object, &attr, 1);
@@ -492,6 +493,9 @@ prepare_unlock_prompt (GkmWrapPrompt *self, gboolean first)
 	} else {
 		prepare_unlock_other_object (self, label);
 	}
+
+	if (!first)
+		gku_prompt_set_warning (GKU_PROMPT (self), _("The unlock password was incorrect"));
 }
 
 /* -----------------------------------------------------------------------------
@@ -599,7 +603,6 @@ gkm_wrap_prompt_for_credential (CK_FUNCTION_LIST_PTR module, CK_SESSION_HANDLE s
 	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));
@@ -631,6 +634,9 @@ gkm_wrap_prompt_do_credential (GkmWrapPrompt *self, CK_ATTRIBUTE_PTR *template,
 	g_return_val_if_fail (template, FALSE);
 	g_return_val_if_fail (n_template, FALSE);
 
+	prepare_unlock_prompt (self, self->iteration == 0);
+	++(self->iteration);
+
 	gku_prompt_request_attention_sync (NULL, on_prompt_attention,
 	                                   g_object_ref (self), g_object_unref);
 
diff --git a/ui/gku-prompt.c b/ui/gku-prompt.c
index d485885..f816142 100644
--- a/ui/gku-prompt.c
+++ b/ui/gku-prompt.c
@@ -458,6 +458,7 @@ clear_prompt_data (GkuPrompt *self)
 	self->pv->output = NULL;
 
 	self->pv->failure = FALSE;
+	self->pv->completed = FALSE;
 
 	g_free (self->pv->in_data);
 	self->pv->in_data = NULL;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]