[gnome-keyring/trust-store] [gck] Allow enumeration over slots as well as modules.



commit a8f145a910d1326724f87e872d06b560934a2878
Author: Stef Walter <stef memberwebs com>
Date:   Sat Dec 18 11:59:11 2010 -0600

    [gck] Allow enumeration over slots as well as modules.
    
    Can now enumerate object over a list of slots, as well as
    a list of modules.

 docs/reference/gck/gck-sections.txt |    1 +
 gck/gck-enumerator.c                |  116 ++++++++++++++++-------------------
 gck/gck-modules.c                   |    2 +-
 gck/gck-slot.c                      |   19 ++++++
 gck/gck.h                           |    4 +
 gck/tests/test-gck-enumerator.c     |   38 +++++++++++-
 6 files changed, 113 insertions(+), 67 deletions(-)
---
diff --git a/docs/reference/gck/gck-sections.txt b/docs/reference/gck/gck-sections.txt
index 1bad963..d567b8e 100644
--- a/docs/reference/gck/gck-sections.txt
+++ b/docs/reference/gck/gck-sections.txt
@@ -98,6 +98,7 @@ gck_slot_get_token_info
 gck_slot_get_mechanisms
 gck_slot_get_mechanism_info
 gck_slot_has_flags
+gck_slots_enumerate_objects
 gck_slot_open_session
 gck_slot_open_session_full
 gck_slot_open_session_async
diff --git a/gck/gck-enumerator.c b/gck/gck-enumerator.c
index 781dd90..2e39497 100644
--- a/gck/gck-enumerator.c
+++ b/gck/gck-enumerator.c
@@ -62,15 +62,13 @@ struct _GckEnumeratorState {
 	gboolean authenticate;
 	gchar *password;
 
-	/* state_module */
-	GckModule *module;
-
 	/* state_slots */
 	GList *slots;
 
 	/* state_slot */
 	GckSlot *slot;
 	GckTokenInfo *token_info;
+	CK_FUNCTION_LIST_PTR funcs;
 
 	/* state_session */
 	GckSession *session;
@@ -90,8 +88,7 @@ struct _GckEnumeratorPrivate {
 
 G_DEFINE_TYPE (GckEnumerator, gck_enumerator, G_TYPE_OBJECT);
 
-static gpointer state_start          (GckEnumeratorState *args, gboolean forward);
-static gpointer state_module         (GckEnumeratorState *args, gboolean forward);
+static gpointer state_modules        (GckEnumeratorState *args, gboolean forward);
 static gpointer state_slots          (GckEnumeratorState *args, gboolean forward);
 static gpointer state_slot           (GckEnumeratorState *args, gboolean forward);
 static gpointer state_session        (GckEnumeratorState *args, gboolean forward);
@@ -123,10 +120,7 @@ cleanup_state (GckEnumeratorState *args)
 	g_assert (args);
 
 	/* Have each state cleanup */
-	rewind_state (args, state_start);
-
-	/* state_module */
-	g_assert (!args->module);
+	rewind_state (args, state_modules);
 
 	/* state_slots */
 	g_assert (!args->slots);
@@ -134,6 +128,7 @@ cleanup_state (GckEnumeratorState *args)
 	/* state_slot */
 	g_assert (!args->slot);
 	g_assert (!args->token_info);
+	g_assert (!args->funcs);
 
 	/* state_session */
 	g_assert (!args->session);
@@ -166,9 +161,11 @@ cleanup_state (GckEnumeratorState *args)
 }
 
 static gpointer
-state_start (GckEnumeratorState *args, gboolean forward)
+state_modules (GckEnumeratorState *args, gboolean forward)
 {
-	g_assert (args->module == NULL);
+	GckModule *module;
+
+	g_assert (args->slots == NULL);
 
 	if (forward) {
 
@@ -177,40 +174,25 @@ state_start (GckEnumeratorState *args, gboolean forward)
 			return NULL;
 
 		/* Pop off the current module */
-		args->module = args->modules->data;
-		g_assert (GCK_IS_MODULE (args->module));
+		module = args->modules->data;
+		g_assert (GCK_IS_MODULE (module));
 		args->modules = g_list_delete_link (args->modules, args->modules);
-		return state_module;
-	}
 
-	/* Should never be asked to go backward from start state */
-	g_assert_not_reached ();
-}
-
-static gpointer
-state_module (GckEnumeratorState *args, gboolean forward)
-{
-	g_assert (args->module);
-	g_assert (!args->slots);
-
-	/* module to slots state */
-	if (forward) {
+		args->slots = gck_module_get_slots (module, TRUE);
+		g_object_unref (module);
 
-		args->slots = gck_module_get_slots (args->module, TRUE);
 		return state_slots;
-
-	/* module to start state */
-	} else {
-		g_object_unref (args->module);
-		args->module = NULL;
-		return state_start;
 	}
+
+	/* Should never be asked to go backward from start state */
+	g_assert_not_reached ();
 }
 
 static gpointer
 state_slots (GckEnumeratorState *args, gboolean forward)
 {
 	GckSlot *slot;
+	GckModule *module;
 	GckTokenInfo *token_info;
 
 	g_assert (args->slot == NULL);
@@ -220,7 +202,7 @@ state_slots (GckEnumeratorState *args, gboolean forward)
 
 		/* If there are no more slots go back to start state */
 		if (!args->slots)
-			return rewind_state (args, state_start);
+			return rewind_state (args, state_modules);
 
 		/* Pop the next slot off the stack */
 		slot = args->slots->data;
@@ -230,7 +212,7 @@ state_slots (GckEnumeratorState *args, gboolean forward)
 		if (!token_info) {
 			g_message ("couldn't get token info while enumerating");
 			g_object_unref (slot);
-			return rewind_state (args, state_start);
+			return rewind_state (args, state_modules);
 		}
 
 		/* Are we trying to match the slot? */
@@ -244,43 +226,44 @@ state_slots (GckEnumeratorState *args, gboolean forward)
 			}
 		}
 
+		module = gck_slot_get_module (slot);
+		args->funcs = gck_module_get_functions (module);
+		g_assert (args->funcs);
+		g_object_unref (module);
+
 		/* We have a slot */
 		args->slot = slot;
 		args->token_info = token_info;
 		return state_slot;
 
-	/* slots state to module state */
+	/* slots state to modules state */
 	} else {
 
 		gck_list_unref_free (args->slots);
 		args->slots = NULL;
-		return state_module;
+		return state_modules;
 	}
 }
 
 static gpointer
 state_slot (GckEnumeratorState *args, gboolean forward)
 {
-	CK_FUNCTION_LIST_PTR funcs;
 	CK_SESSION_HANDLE session;
 	CK_FLAGS flags;
 	CK_RV rv;
 
 	g_assert (args->slot);
-	g_assert (args->module);
+	g_assert (args->funcs);
 	g_assert (args->session == NULL);
 
 	/* slot to session state */
 	if (forward) {
-		funcs = gck_module_get_functions (args->module);
-		g_return_val_if_fail (funcs, NULL);
-
 		flags = CKF_SERIAL_SESSION;
 		if ((args->session_options & GCK_SESSION_READ_WRITE) == GCK_SESSION_READ_WRITE)
 			flags |= CKF_RW_SESSION;
 
-		rv = (funcs->C_OpenSession) (gck_slot_get_handle (args->slot),
-		                             flags, NULL, NULL, &session);
+		rv = (args->funcs->C_OpenSession) (gck_slot_get_handle (args->slot),
+		                                   flags, NULL, NULL, &session);
 
 		if (rv != CKR_OK) {
 			g_message ("couldn't open session on module while enumerating objects: %s",
@@ -295,6 +278,7 @@ state_slot (GckEnumeratorState *args, gboolean forward)
 	} else {
 		g_object_unref (args->slot);
 		args->slot = NULL;
+		args->funcs = NULL;
 
 		gck_token_info_free (args->token_info);
 		args->token_info = NULL;
@@ -306,13 +290,12 @@ state_slot (GckEnumeratorState *args, gboolean forward)
 static gpointer
 state_session (GckEnumeratorState *args, gboolean forward)
 {
-	CK_FUNCTION_LIST_PTR funcs;
 	GckSessionInfo *sinfo;
 	CK_ULONG n_pin;
 	CK_RV rv;
 
+	g_assert (args->funcs);
 	g_assert (args->session);
-	g_assert (args->module);
 	g_assert (!args->want_password);
 	g_assert (args->token_info);
 
@@ -344,13 +327,10 @@ state_session (GckEnumeratorState *args, gboolean forward)
 
 		gck_session_info_free (sinfo);
 
-		funcs = gck_module_get_functions (args->module);
-		g_return_val_if_fail (funcs, NULL);
-
 		/* Try to log in */
 		n_pin = args->password ? strlen (args->password) : 0;
-		rv = (funcs->C_Login) (gck_session_get_handle (args->session), CKU_USER,
-		                       (CK_BYTE_PTR)args->password, n_pin);
+		rv = (args->funcs->C_Login) (gck_session_get_handle (args->session), CKU_USER,
+		                             (CK_BYTE_PTR)args->password, n_pin);
 
 		/* Authentication failed, ask for a password */
 		if (rv == CKR_PIN_INCORRECT) {
@@ -375,7 +355,6 @@ state_session (GckEnumeratorState *args, gboolean forward)
 static gpointer
 state_authenticated (GckEnumeratorState *args, gboolean forward)
 {
-	CK_FUNCTION_LIST_PTR funcs;
 	CK_OBJECT_HANDLE objects[128];
 	CK_SESSION_HANDLE session;
 	CK_ATTRIBUTE_PTR attrs;
@@ -391,6 +370,7 @@ state_authenticated (GckEnumeratorState *args, gboolean forward)
 	g_assert (args->session);
 	g_assert (!args->want_password);
 	g_assert (args->want_objects);
+	g_assert (args->funcs);
 
 	if (args->match_attrs) {
 		attrs = _gck_attributes_commit_out (args->match_attrs, &n_attrs);
@@ -399,18 +379,15 @@ state_authenticated (GckEnumeratorState *args, gboolean forward)
 		n_attrs = 0;
 	}
 
-	funcs = gck_module_get_functions (args->module);
-	g_return_val_if_fail (funcs, NULL);
-
 	session = gck_session_get_handle (args->session);
 	g_return_val_if_fail (session, NULL);
 
 	/* Get all the objects */
-	rv = (funcs->C_FindObjectsInit) (session, attrs, n_attrs);
+	rv = (args->funcs->C_FindObjectsInit) (session, attrs, n_attrs);
 
 	if (rv == CKR_OK) {
 		for(;;) {
-			rv = (funcs->C_FindObjects) (session, objects, G_N_ELEMENTS (objects), &count);
+			rv = (args->funcs->C_FindObjects) (session, objects, G_N_ELEMENTS (objects), &count);
 			if (rv != CKR_OK || count == 0)
 				break;
 
@@ -419,7 +396,7 @@ state_authenticated (GckEnumeratorState *args, gboolean forward)
 			g_array_append_vals (args->objects, objects, count);
 		}
 
-		(funcs->C_FindObjectsFinal) (session);
+		(args->funcs->C_FindObjectsFinal) (session);
 	}
 
 	return state_results;
@@ -481,7 +458,6 @@ gck_enumerator_init (GckEnumerator *self)
 
 	self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCK_TYPE_ENUMERATOR, GckEnumeratorPrivate);
 	args = g_new0 (GckEnumeratorState, 1);
-	args->handler = state_start;
 	g_atomic_pointer_set (&self->pv->state, args);
 }
 
@@ -517,7 +493,8 @@ gck_enumerator_class_init (GckEnumeratorClass *klass)
  */
 
 GckEnumerator*
-_gck_enumerator_new (GList *modules, guint session_options, GckTokenInfo *match_token, GckAttributes *match_attrs)
+_gck_enumerator_new (GList *modules_or_slots, guint session_options,
+                     GckTokenInfo *match_token, GckAttributes *match_attrs)
 {
 	GckEnumerator *self;
 	GckEnumeratorState *state;
@@ -526,7 +503,16 @@ _gck_enumerator_new (GList *modules, guint session_options, GckTokenInfo *match_
 	state = g_atomic_pointer_get (&self->pv->state);
 
 	state->session_options = session_options;
-	state->modules = gck_list_ref_copy (modules);
+
+	if (modules_or_slots && GCK_IS_SLOT (modules_or_slots->data)) {
+		state->slots = gck_list_ref_copy (modules_or_slots);
+		state->modules = NULL;
+		state->handler = state_slots;
+	} else {
+		state->modules = gck_list_ref_copy (modules_or_slots);
+		state->slots = NULL;
+		state->handler = state_modules;
+	}
 
 	if (match_attrs) {
 		state->match_attrs = gck_attributes_ref (match_attrs);
@@ -569,20 +555,22 @@ static gboolean
 complete_enumerate_next (EnumerateNext *args, CK_RV result)
 {
 	GckEnumeratorState *state;
+	GckModule *module;
 	gboolean ret = TRUE;
 
 	g_assert (args->state);
 	state = args->state;
 
 	if (state->want_password) {
-		g_assert (state->module);
 		g_assert (state->slot);
 
 		/* TODO: Should we be using secure memory here? */
 		g_free (state->password);
 		state->password = NULL;
 
-		ret = _gck_module_fire_authenticate_slot (state->module, state->slot, NULL, &state->password);
+		module = gck_slot_get_module (state->slot);
+		ret = _gck_module_fire_authenticate_slot (module, state->slot, NULL, &state->password);
+		g_object_unref (module);
 
 		/* If authenticate returns TRUE then call is not complete */
 		ret = !ret;
diff --git a/gck/gck-modules.c b/gck/gck-modules.c
index a5b0b46..59ae1c8 100644
--- a/gck/gck-modules.c
+++ b/gck/gck-modules.c
@@ -135,7 +135,7 @@ gck_modules_get_slots (GList *modules, gboolean token_present)
 }
 
 /**
- * gck_module_enumerate_objects_full:
+ * gck_module_enumerate_objects:
  * @self: The module to enumerate objects.
  * @attrs: Attributes that the objects must have, or empty for all objects.
  * @session_flags: Flags for opening a session.
diff --git a/gck/gck-slot.c b/gck/gck-slot.c
index d8a4a4e..8698198 100644
--- a/gck/gck-slot.c
+++ b/gck/gck-slot.c
@@ -799,6 +799,25 @@ gck_slot_has_flags (GckSlot *self, gulong flags)
 	return (info.flags & flags) != 0;
 }
 
+/**
+ * gck_slots_enumerate_objects:
+ * @slots: a list of #GckSlot to enumerate objects on.
+ * @attrs: Attributes that the objects must have, or empty for all objects.
+ * @session_options: Options for opening a session.
+ *
+ * Setup an enumerator for listing matching objects on the slots.
+ *
+ * This call will not block but will return an enumerator immediately.
+ *
+ * Return value: a new enumerator
+ **/
+GckEnumerator*
+gck_slots_enumerate_objects (GList *slots, GckAttributes *attrs, guint session_options)
+{
+	return _gck_enumerator_new (slots, session_options, NULL, attrs);
+}
+
+
 #if UNIMPLEMENTED
 
 typedef struct InitToken {
diff --git a/gck/gck.h b/gck/gck.h
index c627e60..4a4a564 100644
--- a/gck/gck.h
+++ b/gck/gck.h
@@ -494,6 +494,10 @@ GckMechanismInfo*   gck_slot_get_mechanism_info             (GckSlot *self,
 gboolean            gck_slot_has_flags                      (GckSlot *self,
                                                              gulong flags);
 
+GckEnumerator*      gck_slots_enumerate_objects             (GList *slots,
+                                                             GckAttributes *attrs,
+                                                             guint session_options);
+
 #if UNIMPLEMENTED
 
 gboolean            gck_slot_init_token                     (GckSlot *self,
diff --git a/gck/tests/test-gck-enumerator.c b/gck/tests/test-gck-enumerator.c
index 699b061..2d86563 100644
--- a/gck/tests/test-gck-enumerator.c
+++ b/gck/tests/test-gck-enumerator.c
@@ -7,23 +7,26 @@
 #include "gck-private.h"
 
 static GList *modules = NULL;
+static GckModule *module = NULL;
 
 TESTING_SETUP(enumerator)
 {
-	GckModule *module;
 	GError *err = NULL;
 
 	/* Successful load */
 	module = gck_module_initialize (".libs/libmock-test-module.so", NULL, 0, &err);
 	SUCCESS_RES (module, err);
 
-	modules = g_list_append (NULL, module);
+	modules = g_list_append (NULL, g_object_ref (module));
 }
 
 TESTING_TEARDOWN(enumerator)
 {
 	gck_list_unref_free (modules);
 	modules = NULL;
+
+	g_object_unref (module);
+	module = NULL;
 }
 
 TESTING_TEST(enumerator_create)
@@ -35,6 +38,18 @@ TESTING_TEST(enumerator_create)
 	g_object_unref (en);
 }
 
+TESTING_TEST(enumerator_create_slots)
+{
+	GckEnumerator *en;
+	GList *slots;
+
+	slots = gck_module_get_slots (module, FALSE);
+	en = _gck_enumerator_new (slots, 0, NULL, NULL);
+	g_assert (GCK_IS_ENUMERATOR (en));
+	g_object_unref (en);
+	gck_list_unref_free (slots);
+}
+
 TESTING_TEST(enumerator_next)
 {
 	GError *error = NULL;
@@ -51,6 +66,25 @@ TESTING_TEST(enumerator_next)
 	g_object_unref (en);
 }
 
+TESTING_TEST(enumerator_next_slots)
+{
+	GError *error = NULL;
+	GList *slots = NULL;
+	GckEnumerator *en;
+	GckObject *obj;
+
+	slots = gck_module_get_slots (module, FALSE);
+	en = _gck_enumerator_new (slots, 0, NULL, NULL);
+	g_assert (GCK_IS_ENUMERATOR (en));
+
+	obj = gck_enumerator_next (en, NULL, &error);
+	g_assert (GCK_IS_OBJECT (obj));
+
+	g_object_unref (obj);
+	g_object_unref (en);
+	gck_list_unref_free (slots);
+}
+
 TESTING_TEST(enumerator_next_and_resume)
 {
 	GError *error = NULL;



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