[gnome-keyring/dbus-api] [dbus] Reorganize path <-> object mapping.



commit 8142993ebabdc620ac1dcce00d60684cb76b08ab
Author: Stef Walter <stef memberwebs com>
Date:   Sat Dec 12 22:07:14 2009 +0000

    [dbus] Reorganize path <-> object mapping.
    
    Needed to remove abstractions in order to properly support
    aliases. We use paths as much as possible, and try as little
    as possible to convert an object to a path. This gives us
    predictable behavior from the client side when accessed
    through an alias.

 daemon/dbus/gkd-secret-create.c  |   31 +++-
 daemon/dbus/gkd-secret-objects.c |  282 +++++++++++++++++++++++--------
 daemon/dbus/gkd-secret-objects.h |   23 ++-
 daemon/dbus/gkd-secret-prompt.c  |    9 +-
 daemon/dbus/gkd-secret-prompt.h  |    2 +
 daemon/dbus/gkd-secret-service.c |  129 ++++----------
 daemon/dbus/gkd-secret-service.h |   11 +-
 daemon/dbus/gkd-secret-session.c |   16 ++-
 daemon/dbus/gkd-secret-types.h   |    1 +
 daemon/dbus/gkd-secret-unlock.c  |   11 +-
 daemon/dbus/gkd-secret-util.c    |  351 ++++----------------------------------
 daemon/dbus/gkd-secret-util.h    |   27 +---
 12 files changed, 362 insertions(+), 531 deletions(-)
---
diff --git a/daemon/dbus/gkd-secret-create.c b/daemon/dbus/gkd-secret-create.c
index 807fca6..1757307 100644
--- a/daemon/dbus/gkd-secret-create.c
+++ b/daemon/dbus/gkd-secret-create.c
@@ -22,9 +22,9 @@
 #include "config.h"
 
 #include "gkd-secret-create.h"
-#include "gkd-secret-service.h"
 #include "gkd-secret-prompt.h"
 #include "gkd-secret-secret.h"
+#include "gkd-secret-service.h"
 #include "gkd-secret-session.h"
 #include "gkd-secret-types.h"
 #include "gkd-secret-util.h"
@@ -94,6 +94,8 @@ create_collection_with_credential (GkdSecretCreate *self, GP11Object *cred)
 	GError *error = NULL;
 	GP11Object *collection;
 	GP11Session *session;
+	gpointer identifier;
+	gsize n_identifier;
 
 	g_assert (GKD_SECRET_IS_CREATE (self));
 	g_return_val_if_fail (self->pkcs11_attrs, FALSE);
@@ -115,9 +117,18 @@ create_collection_with_credential (GkdSecretCreate *self, GP11Object *cred)
 	}
 
 	gp11_object_set_session (collection, session);
-	self->result_path = gkd_secret_util_path_for_collection (collection);
+	identifier = gp11_object_get_data (collection, CKA_ID, &n_identifier, &error);
 	g_object_unref (collection);
 
+	if (!identifier) {
+		g_warning ("couldn't lookup new collection identifier: %s", error->message);
+		g_clear_error (&error);
+		return FALSE;
+	}
+
+	self->result_path = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX, identifier, n_identifier);
+	g_free (identifier);
+
 	return TRUE;
 }
 
@@ -299,6 +310,8 @@ gkd_secret_create_without_prompting (GkdSecretService *service, DBusMessage *mes
 	GP11Object *collection;
 	GP11Session *pkcs11_session;
 	GError *error = NULL;
+	gpointer identifier;
+	gsize n_identifier;
 	gchar *path;
 
 	/* Figure out the session */
@@ -348,13 +361,25 @@ gkd_secret_create_without_prompting (GkdSecretService *service, DBusMessage *mes
 		                               "Couldn't create new collection");
 	}
 
-	path = gkd_secret_util_path_for_collection (collection);
+	gp11_object_set_session (collection, pkcs11_session);
+	identifier = gp11_object_get_data (collection, CKA_ID, &n_identifier, &error);
 	g_object_unref (collection);
 
+	if (!identifier) {
+		g_warning ("couldn't lookup new collection identifier: %s", error->message);
+		g_clear_error (&error);
+		return dbus_message_new_error (message, DBUS_ERROR_FAILED,
+		                               "Couldn't find new collection just created");
+	}
+
+	path = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX, identifier, n_identifier);
+	g_free (identifier);
+
 	reply = dbus_message_new_method_return (message);
 	dbus_message_append_args (reply,
 	                          DBUS_TYPE_OBJECT_PATH, &path,
 	                          DBUS_TYPE_INVALID);
+	g_free (path);
 
 	return reply;
 }
diff --git a/daemon/dbus/gkd-secret-objects.c b/daemon/dbus/gkd-secret-objects.c
index 1cf6dca..7124908 100644
--- a/daemon/dbus/gkd-secret-objects.c
+++ b/daemon/dbus/gkd-secret-objects.c
@@ -45,6 +45,7 @@ struct _GkdSecretObjects {
 	GObject parent;
 	GkdSecretService *service;
 	GP11Slot *pkcs11_slot;
+	GHashTable *aliases;
 };
 
 G_DEFINE_TYPE (GkdSecretObjects, gkd_secret_objects, G_TYPE_OBJECT);
@@ -53,41 +54,110 @@ G_DEFINE_TYPE (GkdSecretObjects, gkd_secret_objects, G_TYPE_OBJECT);
  * INTERNAL
  */
 
+static gboolean
+parse_object_path (GkdSecretObjects *self, const gchar *path, gchar **collection, gchar **item)
+{
+	const gchar *replace;
+
+	g_assert (self);
+	g_assert (path);
+	g_assert (collection);
+
+	if (!gkd_secret_util_parse_path (path, collection, item))
+		return FALSE;
+
+	if (g_str_has_prefix (path, SECRET_ALIAS_PREFIX)) {
+		replace = g_hash_table_lookup (self->aliases, *collection);
+		g_free (*collection);
+		if (!replace) {
+			*collection = NULL;
+			if (item) {
+				g_free (*item);
+				*item = NULL;
+			}
+			return FALSE;
+		}
+		*collection = g_strdup (replace);
+	}
+
+	return TRUE;
+}
+
 static void
-iter_append_item_paths (DBusMessageIter *iter, GList *items)
+iter_append_item_path (const gchar *base, GP11Object *object, DBusMessageIter *iter)
 {
-	DBusMessageIter array;
+	GError *error = NULL;
+	gpointer identifier;
+	gsize n_identifier;
 	gchar *path;
+	gchar *alloc = NULL;
+
+	if (base == NULL) {
+		identifier = gp11_object_get_data (object, CKA_G_COLLECTION, &n_identifier, &error);
+		if (!identifier) {
+			g_warning ("couldn't get item collection identifier: %s", error->message);
+			g_clear_error (&error);
+			return;
+		}
+
+		base = alloc = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX, identifier, n_identifier);
+		g_free (identifier);
+	}
+
+	identifier = gp11_object_get_data (object, CKA_ID, &n_identifier, &error);
+	if (identifier == NULL) {
+		g_warning ("couldn't get item identifier: %s", error->message);
+		g_clear_error (&error);
+	} else {
+		path = gkd_secret_util_build_path (base, identifier, n_identifier);
+		g_free (identifier);
+		dbus_message_iter_append_basic (iter, DBUS_TYPE_OBJECT_PATH, &path);
+		g_free (path);
+	}
+
+	g_free (alloc);
+}
+
+static void
+iter_append_item_paths (const gchar *base, GList *items, DBusMessageIter *iter)
+{
+	DBusMessageIter array;
 	GList *l;
 
 	dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "o", &array);
 
-	for (l = items; l; l = g_list_next (l)) {
-		path = gkd_secret_util_path_for_item (l->data);
-		if (path != NULL) {
-			dbus_message_iter_append_basic (&array, DBUS_TYPE_OBJECT_PATH, &path);
-			g_free (path);
-		}
-	}
+	for (l = items; l; l = g_list_next (l))
+		iter_append_item_path (base, l->data, &array);
 
 	dbus_message_iter_close_container (iter, &array);
 }
 
 static void
-iter_append_collection_paths (DBusMessageIter *iter, GList *collections)
+iter_append_collection_paths (GList *collections, DBusMessageIter *iter)
 {
 	DBusMessageIter array;
+	gpointer identifier;
+	gsize n_identifier;
+	GError *error = NULL;
 	gchar *path;
 	GList *l;
 
 	dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "o", &array);
 
 	for (l = collections; l; l = g_list_next (l)) {
-		path = gkd_secret_util_path_for_collection (l->data);
-		if (path != NULL) {
-			dbus_message_iter_append_basic (&array, DBUS_TYPE_OBJECT_PATH, &path);
-			g_free (path);
+
+		identifier = gp11_object_get_data (l->data, CKA_ID, &n_identifier, &error);
+		if (identifier == NULL) {
+			g_warning ("couldn't get collection identifier: %s", error->message);
+			g_clear_error (&error);
+			continue;
 		}
+
+		path = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX, identifier, n_identifier);
+		g_free (identifier);
+
+		dbus_message_iter_append_basic (&array, DBUS_TYPE_OBJECT_PATH, &path);
+		g_free (path);
 	}
 
 	dbus_message_iter_close_container (iter, &array);
@@ -413,7 +483,7 @@ collection_property_get (GkdSecretObjects *self, GP11Object *object, DBusMessage
 	if (g_str_equal (name, "Items")) {
 		reply = dbus_message_new_method_return (message);
 		dbus_message_iter_init_append (reply, &iter);
-		gkd_secret_objects_append_item_paths (self, &iter, message, object);
+		gkd_secret_objects_append_item_paths (self, dbus_message_get_path (message), &iter, message);
 		return reply;
 	}
 
@@ -488,7 +558,7 @@ collection_property_getall (GkdSecretObjects *self, GP11Object *object, DBusMess
 	dbus_message_iter_open_container (&array, DBUS_TYPE_DICT_ENTRY, NULL, &dict);
 	name = "Items";
 	dbus_message_iter_append_basic (&dict, DBUS_TYPE_STRING, &name);
-	gkd_secret_objects_append_item_paths (self, &dict, message, object);
+	gkd_secret_objects_append_item_paths (self, dbus_message_get_path (message), &dict, message);
 	dbus_message_iter_close_container (&array, &dict);
 
 	dbus_message_iter_close_container (&iter, &array);
@@ -498,24 +568,20 @@ collection_property_getall (GkdSecretObjects *self, GP11Object *object, DBusMess
 static DBusMessage*
 collection_method_search_items (GkdSecretObjects *self, GP11Object *object, DBusMessage *message)
 {
-	return gkd_secret_objects_handle_search_items (self, message, object);
+	return gkd_secret_objects_handle_search_items (self, message, dbus_message_get_path (message));
 }
 
 static GP11Object*
-collection_find_matching_item (GkdSecretObjects *self, GP11Object *coll, GP11Attribute *fields)
+collection_find_matching_item (GkdSecretObjects *self, GP11Session *session,
+                               const gchar *identifier, GP11Attribute *fields)
 {
 	GP11Attributes *attrs;
-	const gchar *identifier;
 	GP11Object *result = NULL;
 	GError *error = NULL;
-	GP11Session *session;
 	GP11Object *search;
 	gpointer data;
 	gsize n_data;
 
-	identifier = gkd_secret_util_identifier_for_collection (coll);
-	g_return_val_if_fail (identifier, NULL);
-
 	/* Find items matching the collection and fields */
 	attrs = gp11_attributes_new ();
 	gp11_attributes_add (attrs, fields);
@@ -523,10 +589,6 @@ collection_find_matching_item (GkdSecretObjects *self, GP11Object *coll, GP11Att
 	gp11_attributes_add_ulong (attrs, CKA_CLASS, CKO_G_SEARCH);
 	gp11_attributes_add_boolean (attrs, CKA_TOKEN, FALSE);
 
-	/* The session we're using to find the object */
-	session = gp11_object_get_session (coll);
-	g_return_val_if_fail (session, NULL);
-
 	/* Create the search object */
 	search = gp11_session_create_object_full (session, attrs, NULL, &error);
 	gp11_attributes_unref (attrs);
@@ -566,6 +628,7 @@ collection_method_create_item (GkdSecretObjects *self, GP11Object *object, DBusM
 	DBusMessageIter iter, array;
 	GP11Object *item = NULL;
 	const gchar *prompt;
+	const gchar *base;
 	GError *error = NULL;
 	DBusMessage *reply = NULL;
 	gchar *path = NULL;
@@ -603,10 +666,18 @@ collection_method_create_item (GkdSecretObjects *self, GP11Object *object, DBusM
 		goto cleanup;
 	}
 
+	base = dbus_message_get_path (message);
+	if (!parse_object_path (self, base, &identifier, NULL))
+		g_return_val_if_reached (NULL);
+	g_return_val_if_fail (identifier, NULL);
+
+	pkcs11_session = gp11_object_get_session (object);
+	g_return_val_if_fail (pkcs11_session, NULL);
+
 	if (replace) {
 		fields = gp11_attributes_find (attrs, CKA_G_FIELDS);
 		if (fields)
-			item = collection_find_matching_item (self, object, fields);
+			item = collection_find_matching_item (self, pkcs11_session, identifier, fields);
 	}
 
 	/* Replace the item */
@@ -616,12 +687,7 @@ collection_method_create_item (GkdSecretObjects *self, GP11Object *object, DBusM
 
 	/* Create a new item */
 	} else {
-		pkcs11_session = gp11_object_get_session (object);
-		g_return_val_if_fail (pkcs11_session, NULL);
-		identifier = gkd_secret_util_identifier_for_collection (object);
-		g_return_val_if_fail (identifier, NULL);
 		gp11_attributes_add_string (attrs, CKA_G_COLLECTION, identifier);
-		g_free (identifier);
 		gp11_attributes_add_ulong (attrs, CKA_CLASS, CKO_SECRET_KEY);
 		item = gp11_session_create_object_full (pkcs11_session, attrs, NULL, &error);
 		if (item == NULL)
@@ -638,13 +704,11 @@ collection_method_create_item (GkdSecretObjects *self, GP11Object *object, DBusM
 	}
 
 	/* Build up the item identifier */
-	path = gkd_secret_util_path_for_item (item);
-	g_return_val_if_fail (path, NULL);
-	prompt = "/";
 	reply = dbus_message_new_method_return (message);
-	dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &path,
-	                          DBUS_TYPE_OBJECT_PATH, &prompt,
-	                          DBUS_TYPE_INVALID);
+	dbus_message_iter_init_append (reply, &iter);
+	iter_append_item_path (base, item, &iter);
+	prompt = "/";
+	dbus_message_iter_append_basic (&iter, DBUS_TYPE_OBJECT_PATH, &prompt);
 
 cleanup:
 	if (error) {
@@ -752,7 +816,7 @@ gkd_secret_objects_constructor (GType type, guint n_props, GObjectConstructParam
 static void
 gkd_secret_objects_init (GkdSecretObjects *self)
 {
-
+	self->aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
 }
 
 static void
@@ -779,6 +843,7 @@ gkd_secret_objects_finalize (GObject *obj)
 {
 	GkdSecretObjects *self = GKD_SECRET_OBJECTS (obj);
 
+	g_hash_table_destroy (self->aliases);
 	g_assert (!self->pkcs11_slot);
 	g_assert (!self->service);
 
@@ -864,47 +929,108 @@ DBusMessage*
 gkd_secret_objects_dispatch (GkdSecretObjects *self, DBusMessage *message)
 {
 	DBusMessage *reply = NULL;
-	GP11Object *object;
+	GError *error = NULL;
+	GList *objects;
 	GP11Session *session;
+	gchar *c_ident;
+	gchar *i_ident;
 	gboolean is_item;
 	const char *path;
 
 	g_return_val_if_fail (GKD_SECRET_IS_OBJECTS (self), NULL);
 	g_return_val_if_fail (message, NULL);
 
+	path = dbus_message_get_path (message);
+	g_return_val_if_fail (path, NULL);
+
+	if (!parse_object_path (self, path, &c_ident, &i_ident) || !c_ident)
+		return gkd_secret_util_no_such_object (message);
+
 	/* The session we're using to access the object */
 	session = gkd_secret_service_get_pkcs11_session (self->service, dbus_message_get_sender (message));
-	if (session == NULL)
-		return NULL;
+	g_return_val_if_fail (session, NULL);
 
-	path = dbus_message_get_path (message);
-	g_return_val_if_fail (path, NULL);
+	if (i_ident) {
+		is_item = TRUE;
+		objects = gp11_session_find_objects (session, &error,
+		                                     CKA_CLASS, GP11_ULONG, CKO_SECRET_KEY,
+		                                     CKA_G_COLLECTION, strlen (c_ident), c_ident,
+		                                     CKA_ID, strlen (i_ident), i_ident,
+		                                     GP11_INVALID);
+	} else {
+		is_item = FALSE;
+		objects = gp11_session_find_objects (session, &error,
+		                                     CKA_CLASS, GP11_ULONG, CKO_G_COLLECTION,
+		                                     CKA_ID, strlen (c_ident), c_ident,
+		                                     GP11_INVALID);
+	}
+
+	g_free (c_ident);
+	g_free (i_ident);
+
+	if (error != NULL) {
+		g_warning ("couldn't lookup object: %s: %s", path, error->message);
+		g_clear_error (&error);
+	}
 
-	object = gkd_secret_util_path_to_object (session, path, &is_item);
-	if (!object)
+	if (!objects)
 		return gkd_secret_util_no_such_object (message);
 
+	gp11_object_set_session (objects->data, session);
 	if (is_item)
-		reply = item_message_handler (self, object, message);
+		reply = item_message_handler (self, objects->data, message);
 	else
-		reply = collection_message_handler (self, object, message);
+		reply = collection_message_handler (self, objects->data, message);
 
-	g_object_unref (object);
+	gp11_list_unref_free (objects);
 	return reply;
 }
 
-DBusMessage*
-gkd_secret_objects_handle_collection (GkdSecretObjects *self, GP11Object *collection, DBusMessage *message)
+GP11Object*
+gkd_secret_objects_lookup_collection (GkdSecretObjects *self, const gchar *caller,
+                                      const gchar *path)
 {
+	GP11Object *object = NULL;
+	GError *error = NULL;
+	GList *objects;
+	GP11Session *session;
+	gchar *identifier;
+
 	g_return_val_if_fail (GKD_SECRET_IS_OBJECTS (self), NULL);
-	g_return_val_if_fail (GP11_IS_OBJECT (collection), NULL);
-	g_return_val_if_fail (message, NULL);
-	return collection_message_handler (self, collection, message);
+	g_return_val_if_fail (caller, NULL);
+	g_return_val_if_fail (path, NULL);
+
+	if (!parse_object_path (self, path, &identifier, NULL))
+		return NULL;
+
+	/* The session we're using to access the object */
+	session = gkd_secret_service_get_pkcs11_session (self->service, caller);
+	g_return_val_if_fail (session, NULL);
+
+	objects = gp11_session_find_objects (session, &error,
+	                                     CKA_CLASS, GP11_ULONG, CKO_G_COLLECTION,
+	                                     CKA_ID, strlen (identifier), identifier,
+	                                     GP11_INVALID);
+
+	g_free (identifier);
+
+	if (error != NULL) {
+		g_warning ("couldn't lookup collection: %s: %s", path, error->message);
+		g_clear_error (&error);
+	}
+
+	if (objects) {
+		object = g_object_ref (objects->data);
+		gp11_object_set_session (object, session);
+	}
+
+	gp11_list_unref_free (objects);
+	return object;
 }
 
 void
-gkd_secret_objects_append_item_paths (GkdSecretObjects *self, DBusMessageIter *iter,
-                                      DBusMessage *message, GP11Object *collection)
+gkd_secret_objects_append_item_paths (GkdSecretObjects *self, const gchar *base,
+                                      DBusMessageIter *iter, DBusMessage *message)
 {
 	DBusMessageIter variant;
 	GP11Session *session;
@@ -913,15 +1039,16 @@ gkd_secret_objects_append_item_paths (GkdSecretObjects *self, DBusMessageIter *i
 	GList *items;
 
 	g_return_if_fail (GKD_SECRET_IS_OBJECTS (self));
-	g_return_if_fail (GP11_IS_OBJECT (collection));
-	g_return_if_fail (iter && message);
+	g_return_if_fail (base);
+	g_return_if_fail (iter);
+	g_return_if_fail (message);
 
 	/* The session we're using to access the object */
 	session = gkd_secret_service_get_pkcs11_session (self->service, dbus_message_get_sender (message));
 	g_return_if_fail (session);
 
-	identifier = gkd_secret_util_identifier_for_collection (collection);
-	g_return_if_fail (identifier);
+	if (!parse_object_path (self, base, &identifier, NULL))
+		g_return_if_reached ();
 
 	items = gp11_session_find_objects (session, &error,
 	                                   CKA_CLASS, GP11_ULONG, CKO_SECRET_KEY,
@@ -930,7 +1057,7 @@ gkd_secret_objects_append_item_paths (GkdSecretObjects *self, DBusMessageIter *i
 
 	if (error == NULL) {
 		dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "ao", &variant);
-		iter_append_item_paths (&variant, items);
+		iter_append_item_paths (base, items, &variant);
 		dbus_message_iter_close_container (iter, &variant);
 	} else {
 		g_warning ("couldn't lookup items in '%s' collection: %s", identifier, error->message);
@@ -968,14 +1095,14 @@ gkd_secret_objects_append_collection_paths (GkdSecretObjects *self, DBusMessageI
 	}
 
 	dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "ao", &variant);
-	iter_append_collection_paths (&variant, colls);
+	iter_append_collection_paths (colls, &variant);
 	dbus_message_iter_close_container (iter, &variant);
 	gp11_list_unref_free (colls);
 }
 
 DBusMessage*
 gkd_secret_objects_handle_search_items (GkdSecretObjects *self, DBusMessage *message,
-                                        GP11Object *collection)
+                                        const gchar *base)
 {
 	GP11Attributes *attrs;
 	GP11Attribute *attr;
@@ -1005,9 +1132,9 @@ gkd_secret_objects_handle_search_items (GkdSecretObjects *self, DBusMessage *mes
 		                               "Invalid data in attributes argument");
 	}
 
-	if (collection != NULL) {
-		identifier = gkd_secret_util_identifier_for_collection (collection);
-		g_return_val_if_fail (identifier, NULL);
+	if (base != NULL) {
+		if (!parse_object_path (self, base, &identifier, NULL))
+			g_return_val_if_reached (NULL);
 		gp11_attributes_add_string (attrs, CKA_G_COLLECTION, identifier);
 		g_free (identifier);
 	}
@@ -1053,8 +1180,27 @@ gkd_secret_objects_handle_search_items (GkdSecretObjects *self, DBusMessage *mes
 	/* Prepare the reply message */
 	reply = dbus_message_new_method_return (message);
 	dbus_message_iter_init_append (reply, &iter);
-	iter_append_item_paths (&iter, items);
+	iter_append_item_paths (NULL, items, &iter);
 	gp11_list_unref_free (items);
 
 	return reply;
 }
+
+
+const gchar*
+gkd_secret_objects_get_alias (GkdSecretObjects *self, const gchar *alias)
+{
+	g_return_val_if_fail (GKD_SECRET_IS_OBJECTS (self), NULL);
+	g_return_val_if_fail (alias, NULL);
+	return g_hash_table_lookup (self->aliases, alias);
+}
+
+void
+gkd_secret_objects_set_alias (GkdSecretObjects *self, const gchar *alias,
+                              const gchar *identifier)
+{
+	g_return_if_fail (GKD_SECRET_IS_OBJECTS (self));
+	g_return_if_fail (alias);
+	g_return_if_fail (identifier);
+	return g_hash_table_replace (self->aliases, g_strdup (alias), g_strdup (identifier));
+}
diff --git a/daemon/dbus/gkd-secret-objects.h b/daemon/dbus/gkd-secret-objects.h
index c450186..8b4dcda 100644
--- a/daemon/dbus/gkd-secret-objects.h
+++ b/daemon/dbus/gkd-secret-objects.h
@@ -28,6 +28,8 @@
 
 #include <glib-object.h>
 
+#include <dbus/dbus.h>
+
 #define GKD_SECRET_TYPE_OBJECTS               (gkd_secret_objects_get_type ())
 #define GKD_SECRET_OBJECTS(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GKD_SECRET_TYPE_OBJECTS, GkdSecretObjects))
 #define GKD_SECRET_OBJECTS_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GKD_SECRET_TYPE_OBJECTS, GkdSecretObjectsClass))
@@ -48,21 +50,28 @@ DBusMessage*        gkd_secret_objects_dispatch                  (GkdSecretObjec
 
 DBusMessage*        gkd_secret_objects_handle_search_items       (GkdSecretObjects *self,
                                                                   DBusMessage *message,
-                                                                  GP11Object *object);
-
-DBusMessage*        gkd_secret_objects_handle_collection         (GkdSecretObjects *self,
-                                                                  GP11Object *collection,
-                                                                  DBusMessage *message);
+                                                                  const gchar *base);
 
 void                gkd_secret_objects_append_collection_paths   (GkdSecretObjects *self,
                                                                   DBusMessageIter *iter,
                                                                   DBusMessage *message);
 
 void                gkd_secret_objects_append_item_paths         (GkdSecretObjects *self,
+                                                                  const gchar *base,
                                                                   DBusMessageIter *iter,
-                                                                  DBusMessage *message,
-                                                                  GP11Object *collection);
+                                                                  DBusMessage *message);
 
 GP11Slot*           gkd_secret_objects_get_pkcs11_slot           (GkdSecretObjects *self);
 
+GP11Object*         gkd_secret_objects_lookup_collection         (GkdSecretObjects *self,
+                                                                  const gchar *caller,
+                                                                  const gchar *path);
+
+const gchar*        gkd_secret_objects_get_alias                 (GkdSecretObjects *self,
+                                                                  const gchar *alias);
+
+void                gkd_secret_objects_set_alias                 (GkdSecretObjects *self,
+                                                                  const gchar *alias,
+                                                                  const gchar *identifier);
+
 #endif /* __GKD_SECRET_OBJECTS_H__ */
diff --git a/daemon/dbus/gkd-secret-prompt.c b/daemon/dbus/gkd-secret-prompt.c
index 69d58b5..79a45d6 100644
--- a/daemon/dbus/gkd-secret-prompt.c
+++ b/daemon/dbus/gkd-secret-prompt.c
@@ -363,10 +363,17 @@ gkd_secret_prompt_get_pkcs11_session (GkdSecretPrompt *self)
 {
 	g_return_val_if_fail (GKD_SECRET_IS_PROMPT (self), NULL);
 	g_return_val_if_fail (self->pv->service, NULL);
-
 	return gkd_secret_service_get_pkcs11_session (self->pv->service, self->pv->caller);
 }
 
+GkdSecretObjects*
+gkd_secret_prompt_get_objects (GkdSecretPrompt *self)
+{
+	g_return_val_if_fail (GKD_SECRET_IS_PROMPT (self), NULL);
+	g_return_val_if_fail (self->pv->service, NULL);
+	return gkd_secret_service_get_objects (self->pv->service);
+}
+
 void
 gkd_secret_prompt_complete (GkdSecretPrompt *self)
 {
diff --git a/daemon/dbus/gkd-secret-prompt.h b/daemon/dbus/gkd-secret-prompt.h
index ded1ae4..2a4f0a7 100644
--- a/daemon/dbus/gkd-secret-prompt.h
+++ b/daemon/dbus/gkd-secret-prompt.h
@@ -66,6 +66,8 @@ const gchar*        gkd_secret_prompt_get_object_path         (GkdSecretPrompt *
 
 GP11Session*        gkd_secret_prompt_get_pkcs11_session      (GkdSecretPrompt *self);
 
+GkdSecretObjects*   gkd_secret_prompt_get_objects             (GkdSecretPrompt *self);
+
 void                gkd_secret_prompt_complete                (GkdSecretPrompt *self);
 
 void                gkd_secret_prompt_dismiss                 (GkdSecretPrompt *self);
diff --git a/daemon/dbus/gkd-secret-service.c b/daemon/dbus/gkd-secret-service.c
index 6a14cdd..a75dda7 100644
--- a/daemon/dbus/gkd-secret-service.c
+++ b/daemon/dbus/gkd-secret-service.c
@@ -540,29 +540,32 @@ service_method_unlock (GkdSecretService *self, DBusMessage *message)
 static DBusMessage*
 service_method_read_alias (GkdSecretService *self, DBusMessage *message)
 {
-	GP11Object *collection;
-	GP11Session *session;
 	DBusMessage *reply;
 	const char *alias;
 	gchar *path = NULL;
+	const gchar *identifier;
+	GP11Object  *collection;
 
 	if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &alias, DBUS_TYPE_INVALID))
 		return NULL;
 
-	if (alias && g_str_equal (alias, "default")) {
-		update_default (self, FALSE);
-		if (self->default_collection) {
-			session = gkd_secret_service_get_pkcs11_session (self, dbus_message_get_sender (message));
-			collection = gkd_secret_util_identifier_to_collection (session, self->default_collection);
-		}
-	}
+	update_default (self, FALSE);
 
-	reply = dbus_message_new_method_return (message);
-	if (collection) {
-		path = gkd_secret_util_path_for_collection (collection);
+	identifier = gkd_secret_objects_get_alias (self->objects, alias);
+	if (identifier)
+		path = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX, identifier, -1);
+
+	/* Make sure it actually exists */
+	collection = gkd_secret_objects_lookup_collection (self->objects,
+	                                                   dbus_message_get_sender (message), path);
+	if (collection == NULL) {
+		g_free (path);
+		path = NULL;
+	} else {
 		g_object_unref (collection);
 	}
 
+	reply = dbus_message_new_method_return (message);
 	if (path == NULL)
 		path = g_strdup ("/");
 	dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID);
@@ -575,30 +578,38 @@ static DBusMessage*
 service_method_set_alias (GkdSecretService *self, DBusMessage *message)
 {
 	GP11Object *collection;
-	GP11Session *session;
+	gchar *identifier;
 	const char *alias;
 	const char *path;
 
 	if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &alias,
 	                            DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID))
 		return NULL;
+	g_return_val_if_fail (alias, NULL);
 
-	if (!alias || !g_str_equal (alias, "default"))
+	if (!g_str_equal (alias, "default"))
 		return dbus_message_new_error (message, DBUS_ERROR_NOT_SUPPORTED,
 		                               "Only the 'default' alias is supported");
 
 	/* Find a collection with that path */
-	session = gkd_secret_service_get_pkcs11_session (self, dbus_message_get_sender (message));
-	collection = gkd_secret_util_path_to_collection (session, path);
-	if (collection == NULL)
-		return dbus_message_new_error_printf (message, SECRET_ERROR_NO_SUCH_OBJECT,
-		                                      "No such collection: %s", path);
+	if (!object_path_has_prefix (path, SECRET_COLLECTION_PREFIX) ||
+	    !gkd_secret_util_parse_path (path, &identifier, NULL))
+		return dbus_message_new_error (message, DBUS_ERROR_INVALID_ARGS,
+		                               "Invalid collection object path");
+
+	collection = gkd_secret_objects_lookup_collection (self->objects,
+	                                                   dbus_message_get_sender (message), path);
+	if (collection == NULL) {
+		g_free (identifier);
+		return dbus_message_new_error (message, SECRET_ERROR_NO_SUCH_OBJECT,
+		                               "No such collection exists");
+	}
 
-	/* Convert into an identifier */
-	g_free (self->default_collection);
-	self->default_collection = gkd_secret_util_identifier_for_collection (collection);
 	g_object_unref (collection);
 
+	gkd_secret_objects_set_alias (self->objects, alias, identifier);
+	g_free (identifier);
+
 	store_default (self);
 
 	return dbus_message_new_method_return (message);
@@ -660,33 +671,6 @@ service_message_handler (GkdSecretService *self, DBusMessage *message)
 	return NULL;
 }
 
-static DBusMessage*
-service_alias_handler (GkdSecretService *self, const gchar *alias, DBusMessage *message)
-{
-	GP11Object *collection;
-	GP11Session *session;
-	DBusMessage *reply;
-
-	g_return_val_if_fail (alias, NULL);
-	g_return_val_if_fail (message, NULL);
-
-	if (!g_str_equal (alias, "default"))
-		return gkd_secret_util_no_such_object (message);
-
-	update_default (self, FALSE);
-	if (!self->default_collection)
-		return gkd_secret_util_no_such_object (message);
-
-	session = gkd_secret_service_get_pkcs11_session (self, dbus_message_get_sender (message));
-	collection = gkd_secret_util_identifier_to_collection (session, self->default_collection);
-	if (!collection)
-		return gkd_secret_util_no_such_object (message);
-
-	reply = gkd_secret_objects_handle_collection (self->objects, collection, message);
-	g_object_unref (collection);
-	return reply;
-}
-
 static void
 service_dispatch_message (GkdSecretService *self, DBusMessage *message)
 {
@@ -735,14 +719,10 @@ service_dispatch_message (GkdSecretService *self, DBusMessage *message)
 			reply = gkd_secret_prompt_dispatch (object, message);
 
 	/* Dispatched to a collection, off it goes */
-	} else if (object_path_has_prefix (path, SECRET_COLLECTION_PREFIX)) {
+	} else if (object_path_has_prefix (path, SECRET_COLLECTION_PREFIX) ||
+	           object_path_has_prefix (path, SECRET_ALIAS_PREFIX)) {
 		reply = gkd_secret_objects_dispatch (self->objects, message);
 
-	/* Dispatched to an alias, send it off */
-	} else if (object_path_has_prefix (path, SECRET_ALIAS_PREFIX)) {
-		path += strlen (SECRET_ALIAS_PREFIX);
-		reply = service_alias_handler (self, path, message);
-
 	/* Addressed to the service */
 	} else if (g_str_equal (path, SECRET_SERVICE_PATH)) {
 		reply = service_message_handler (self, message);
@@ -921,11 +901,6 @@ gkd_secret_service_finalize (GObject *obj)
 	g_hash_table_destroy (self->clients);
 	self->clients = NULL;
 
-#if 0
-	g_free (self->pv->default_collection);
-	self->pv->default_collection = NULL;
-#endif
-
 	G_OBJECT_CLASS (gkd_secret_service_parent_class)->finalize (obj);
 }
 
@@ -1100,37 +1075,3 @@ gkd_secret_service_close_session (GkdSecretService *self, GkdSecretSession *sess
 	path = gkd_secret_session_get_object_path (session);
 	g_hash_table_remove (client->sessions, path);
 }
-
-#if 0
-GkdSecretCollection*
-gkd_secret_service_get_default_collection (GkdSecretService *self)
-{
-	GkdSecretCollection *collection = NULL;
-
-	g_return_val_if_fail (GKD_SECRET_IS_SERVICE (self), NULL);
-
-	if (!self->pv->default_collection)
-		update_default (self);
-
-	if (self->pv->default_collection != NULL)
-		collection = gkd_secret_service_get_collection (self, self->pv->default_collection);
-
-	/*
-	 * We prefer to make the 'login' keyring the default
-	 * keyring when nothing else is setup.
-	 */
-	if (collection == NULL)
-		collection = gkd_secret_service_get_collection (self, "login");
-
-	/*
-	 * Otherwise fall back to the 'default' keyring setup
-	 * if PAM integration is borked, and the user had to
-	 * create a new keyring.
-	 */
-	if (collection == NULL)
-		collection = gkd_secret_service_get_collection (self, "default");
-
-	return collection;
-}
-
-#endif
diff --git a/daemon/dbus/gkd-secret-service.h b/daemon/dbus/gkd-secret-service.h
index 8652b02..e644caa 100644
--- a/daemon/dbus/gkd-secret-service.h
+++ b/daemon/dbus/gkd-secret-service.h
@@ -41,11 +41,6 @@ typedef struct _GkdSecretServiceClass GkdSecretServiceClass;
 
 struct _GkdSecretServiceClass {
 	GObjectClass parent_class;
-#if 0
-	/* signals --------------------------------------------------------- */
-
-	void (*signal) (GkdSecretService *self);
-#endif
 };
 
 GType                   gkd_secret_service_get_type                (void);
@@ -59,6 +54,8 @@ GP11Session*            gkd_secret_service_get_pkcs11_session      (GkdSecretSer
 
 GkdSecretObjects*       gkd_secret_service_get_objects             (GkdSecretService *self);
 
+GkdSecretIndex*         gkd_secret_service_get_index               (GkdSecretService *self);
+
 GkdSecretSession*       gkd_secret_service_lookup_session          (GkdSecretService *self,
                                                                     const gchar *path,
                                                                     const gchar *caller);
@@ -69,8 +66,4 @@ void                    gkd_secret_service_close_session           (GkdSecretSer
 void                    gkd_secret_service_send                    (GkdSecretService *self,
                                                                     DBusMessage *message);
 
-#if 0
-GkdSecretCollection*    gkd_secret_service_get_default_collection  (GkdSecretService *self);
-#endif
-
 #endif /* ___SECRET_SERVICE_H__ */
diff --git a/daemon/dbus/gkd-secret-session.c b/daemon/dbus/gkd-secret-session.c
index b237e74..83a4c50 100644
--- a/daemon/dbus/gkd-secret-session.c
+++ b/daemon/dbus/gkd-secret-session.c
@@ -554,16 +554,22 @@ gkd_secret_session_set_item_secret (GkdSecretSession *self, GP11Object *item,
 
 	g_assert (GP11_IS_OBJECT (self->key));
 
-	session = gkd_secret_service_get_pkcs11_session (self->service, self->caller);
-	g_return_val_if_fail (session, FALSE);
-
 	/*
 	 * By getting these attributes, and then using them in the unwrap,
 	 * the unwrap won't generate a new object, but merely set the secret.
 	 */
 
-	attrs = gkd_secret_util_attributes_for_item (item);
-	g_return_val_if_fail (attrs, FALSE);
+	attrs = gp11_object_get (item, &error, CKA_ID, CKA_G_COLLECTION, GP11_INVALID);
+	if (attrs == NULL) {
+		g_message ("couldn't get item attributes: %s", error->message);
+		dbus_set_error_const (derr, DBUS_ERROR_FAILED, "Couldn't set item secret");
+		g_clear_error (&error);
+		return FALSE;
+	}
+	gp11_attributes_add_ulong (attrs, CKA_CLASS, CKO_SECRET_KEY);
+
+	session = gkd_secret_service_get_pkcs11_session (self->service, self->caller);
+	g_return_val_if_fail (session, FALSE);
 
 	mech = gp11_mechanism_new_with_param (self->mech_type, secret->parameter,
 	                                      secret->n_parameter);
diff --git a/daemon/dbus/gkd-secret-types.h b/daemon/dbus/gkd-secret-types.h
index 4ebd0d3..596a196 100644
--- a/daemon/dbus/gkd-secret-types.h
+++ b/daemon/dbus/gkd-secret-types.h
@@ -50,6 +50,7 @@
 
 typedef struct _GkdSecretCollection GkdSecretCollection;
 typedef struct _GkdSecretCreate GkdSecretCreate;
+typedef struct _GkdSecretIndex GkdSecretIndex;
 typedef struct _GkdSecretItem GkdSecretItem;
 typedef struct _GkdSecretObjects GkdSecretObjects;
 typedef struct _GkdSecretPrompt GkdSecretPrompt;
diff --git a/daemon/dbus/gkd-secret-unlock.c b/daemon/dbus/gkd-secret-unlock.c
index b62285a..e4c84b9 100644
--- a/daemon/dbus/gkd-secret-unlock.c
+++ b/daemon/dbus/gkd-secret-unlock.c
@@ -21,6 +21,7 @@
 
 #include "config.h"
 
+#include "gkd-secret-objects.h"
 #include "gkd-secret-service.h"
 #include "gkd-secret-prompt.h"
 #include "gkd-secret-types.h"
@@ -172,12 +173,12 @@ authenticate_collection (GkdSecretUnlock *self, GP11Object *coll, gboolean *lock
 static GP11Object*
 lookup_collection (GkdSecretUnlock *self, const gchar *path)
 {
-	GP11Session *session;
-
-	session = gkd_secret_prompt_get_pkcs11_session (GKD_SECRET_PROMPT (self));
-	g_return_val_if_fail (session, NULL);
+	GkdSecretObjects *objects;
+	const gchar *caller;
 
-	return gkd_secret_util_path_to_collection (session, path);
+	objects = gkd_secret_prompt_get_objects (GKD_SECRET_PROMPT (self));
+	caller = gkd_secret_prompt_get_caller (GKD_SECRET_PROMPT (self));
+	return gkd_secret_objects_lookup_collection (objects, caller, path);
 }
 
 /* -----------------------------------------------------------------------------
diff --git a/daemon/dbus/gkd-secret-util.c b/daemon/dbus/gkd-secret-util.c
index 0b4a266..8a8e57d 100644
--- a/daemon/dbus/gkd-secret-util.c
+++ b/daemon/dbus/gkd-secret-util.c
@@ -31,32 +31,6 @@
  * INTERNAL
  */
 
-static void
-encode_object_identifier (GString *result, const gchar* name, gssize length)
-{
-	g_assert (result);
-	g_assert (name);
-
-	if (length < 0)
-		length = strlen (name);
-
-	while (length > 0) {
-		char ch = *(name++);
-		--length;
-
-		/* Normal characters can go right through */
-		if (G_LIKELY ((ch >= 'A' && ch <= 'Z') ||
-		              (ch >= 'a' && ch <= 'z') ||
-		              (ch >= '0' && ch <= '9'))) {
-			g_string_append_c_inline (result, ch);
-
-		/* Special characters are encoded with a _ */
-		} else {
-			g_string_append_printf (result, "_%02x", (unsigned int)ch);
-		}
-	}
-}
-
 static gchar*
 decode_object_identifier (const gchar* enc, gssize length)
 {
@@ -88,17 +62,20 @@ decode_object_identifier (const gchar* enc, gssize length)
 	return g_string_free (result, FALSE);
 }
 
-static gboolean
-parse_collection_and_item_from_path (const gchar *path, gchar **collection, gchar **item)
+gboolean
+gkd_secret_util_parse_path (const gchar *path, gchar **collection, gchar **item)
 {
 	const gchar *pos;
 
 	g_return_val_if_fail (path, FALSE);
 
 	/* Make sure it starts with our prefix */
-	if (!g_str_has_prefix (path, SECRET_COLLECTION_PREFIX))
+	if (g_str_has_prefix (path, SECRET_COLLECTION_PREFIX))
+		path += strlen (SECRET_COLLECTION_PREFIX);
+	else if (g_str_has_prefix (path, SECRET_ALIAS_PREFIX))
+		path += strlen (SECRET_ALIAS_PREFIX);
+	else
 		return FALSE;
-	path += strlen (SECRET_COLLECTION_PREFIX);
 
 	/* Skip the path separator */
 	if (path[0] != '/')
@@ -131,310 +108,46 @@ parse_collection_and_item_from_path (const gchar *path, gchar **collection, gcha
 	return TRUE;
 }
 
-static gchar*
-get_cached_path (GP11Object *object)
-{
-	gchar *path = g_object_get_data (G_OBJECT (object), "gkd-util-cached-identifier");
-	return g_strdup (path);
-}
-
-static void
-set_cached_path (GP11Object *object, const gchar *path)
-{
-	g_object_set_data_full (G_OBJECT (object), "gkd-util-cached-identifier",
-	                        g_strdup (path), g_free);
-}
-
-static GP11Object*
-item_for_identifier (GP11Session *session, const gchar *coll_id, const gchar *item_id)
-{
-	GP11Object *object = NULL;
-	GError *error = NULL;
-	GList *objects;
-
-	g_assert (coll_id);
-	g_assert (item_id);
-
-	/*
-	 * TODO: I think this could benefit from some sort of
-	 * caching?
-	 */
-
-	objects = gp11_session_find_objects (session, &error,
-	                                     CKA_CLASS, GP11_ULONG, CKO_SECRET_KEY,
-	                                     CKA_G_COLLECTION, strlen (coll_id), coll_id,
-	                                     CKA_ID, strlen (item_id), item_id,
-	                                     GP11_INVALID);
-
-	if (error != NULL) {
-		g_warning ("couldn't lookup '%s/%s' item: %s", coll_id, item_id, error->message);
-		g_clear_error (&error);
-		return NULL;
-	}
-
-	if (objects) {
-		object = g_object_ref (objects->data);
-		gp11_object_set_session (object, session);
-	}
-
-	gp11_list_unref_free (objects);
-	return object;
-}
-
-GP11Object*
-gkd_secret_util_identifier_to_collection (GP11Session *session, const gchar *coll_id)
-{
-	GP11Object *object = NULL;
-	GError *error = NULL;
-	GList *objects;
-
-	g_assert (GP11_IS_SESSION (session));
-	g_assert (coll_id);
-
-	objects = gp11_session_find_objects (session, &error,
-	                                     CKA_CLASS, GP11_ULONG, CKO_G_COLLECTION,
-	                                     CKA_ID, strlen (coll_id), coll_id,
-	                                     GP11_INVALID);
-
-	if (error != NULL) {
-		g_warning ("couldn't lookup '%s' collection: %s", coll_id, error->message);
-		g_clear_error (&error);
-		return NULL;
-	}
-
-	if (objects) {
-		object = objects->data;
-		gp11_object_set_session (object, session);
-		g_object_ref (object);
-	}
-
-	gp11_list_unref_free (objects);
-	return object;
-}
-
-GP11Object*
-gkd_secret_util_path_to_collection (GP11Session *session, const gchar *path)
-{
-	GP11Object *collection = NULL;
-	gchar *coll_id;
-	gchar *item_id;
-
-	g_return_val_if_fail (GP11_IS_SESSION (session), NULL);
-	g_return_val_if_fail (path, NULL);
-
-	/* Figure out which collection or item we're talking about */
-	if (!parse_collection_and_item_from_path (path, &coll_id, &item_id))
-		return NULL;
-
-	g_return_val_if_fail (coll_id, NULL);
-	collection = gkd_secret_util_identifier_to_collection (session, coll_id);
-
-	g_free (coll_id);
-	g_free (item_id);
-
-	if (collection) {
-		set_cached_path (collection, path);
-		gp11_object_set_session (collection, session);
-	}
-
-	return collection;
-}
-
 gchar*
-gkd_secret_util_path_for_collection (GP11Object *object)
+gkd_secret_util_build_path (const gchar *base, gconstpointer identifier, gssize n_identifier)
 {
-	GError *error = NULL;
 	GString *result;
-	gpointer data;
-	gsize n_data;
-	gchar *path;
-
-	g_return_val_if_fail (GP11_IS_OBJECT (object), NULL);
+	const gchar *name;
+	gsize length;
 
-	path = get_cached_path (object);
-	if (path != NULL)
-		return path;
+	g_assert (base);
+	g_assert (base[0] == '/');
+	g_assert (identifier);
 
-	data = gp11_object_get_data (object, CKA_ID, &n_data, &error);
-	if (data == NULL) {
-		g_warning ("couldn't lookup identifier for collection: %s",
-		           error->message);
-		g_clear_error (&error);
-		g_return_val_if_reached (NULL);
-	}
-
-	result = g_string_new (SECRET_COLLECTION_PREFIX);
-	g_string_append_c (result, '/');
-	encode_object_identifier (result, data, n_data);
-	g_free (data);
-
-	path = g_string_free (result, FALSE);
-	set_cached_path (object, path);
-	return path;
-}
-
-GP11Object*
-gkd_secret_util_path_to_item (GP11Session *session, const gchar *path)
-{
-	GP11Object *item = NULL;
-	gchar *coll_id;
-	gchar *item_id;
-
-	g_return_val_if_fail (GP11_IS_SESSION (session), NULL);
-	g_return_val_if_fail (path, NULL);
-
-	/* Figure out which collection or item we're talking about */
-	if (!parse_collection_and_item_from_path (path, &coll_id, &item_id))
-		return NULL;
-
-	if (coll_id && item_id)
-		item = item_for_identifier (session, coll_id, item_id);
-	g_free (coll_id);
-	g_free (item_id);
-
-	if (item) {
-		set_cached_path (item, path);
-		gp11_object_set_session (item, session);
-	}
-
-	return item;
-}
-
-gchar*
-gkd_secret_util_path_for_item (GP11Object *object)
-{
-	GError *error = NULL;
-	GP11Attributes *attrs;
-	GP11Attribute *attr;
-	GString *result;
-	gchar *path;
-
-	g_return_val_if_fail (GP11_IS_OBJECT (object), NULL);
-
-	path = get_cached_path (object);
-	if (path != NULL)
-		return path;
-
-	attrs = gp11_object_get (object, &error, CKA_ID, CKA_G_COLLECTION, GP11_INVALID);
-	if (attrs == NULL) {
-		g_warning ("couldn't lookup identifier for item: %s", error->message);
-		g_clear_error (&error);
-		g_return_val_if_reached (NULL);
-	}
-
-	result = g_string_new (SECRET_COLLECTION_PREFIX);
-
-	g_string_append_c (result, '/');
-	attr = gp11_attributes_find (attrs, CKA_G_COLLECTION);
-	g_return_val_if_fail (attr && !gp11_attribute_is_invalid (attr), NULL);
-	encode_object_identifier (result, (const gchar*)attr->value, attr->length);
-
-	g_string_append_c (result, '/');
-	attr = gp11_attributes_find (attrs, CKA_ID);
-	g_return_val_if_fail (attr && !gp11_attribute_is_invalid (attr), NULL);
-	encode_object_identifier (result, (const gchar*)attr->value, attr->length);
-
-	gp11_attributes_unref (attrs);
-
-	path = g_string_free (result, FALSE);
-	set_cached_path (object, path);
-	return path;
-}
-
-GP11Object*
-gkd_secret_util_path_to_object (GP11Session *session, const gchar *path,
-                                gboolean *is_item)
-{
-	GP11Object *object = NULL;
-	gchar *coll_id;
-	gchar *item_id;
-
-	g_return_val_if_fail (GP11_IS_SESSION (session), NULL);
-	g_return_val_if_fail (path, NULL);
-
-	/* Figure out which collection or item we're talking about */
-	if (!parse_collection_and_item_from_path (path, &coll_id, &item_id))
-		return NULL;
-
-	if (item_id) {
-		object = item_for_identifier (session, coll_id, item_id);
-		if (is_item)
-			*is_item = TRUE;
-	} else {
-		object = gkd_secret_util_identifier_to_collection (session, coll_id);
-	}
-
-	g_free (coll_id);
-	g_free (item_id);
-
-	if (object) {
-		set_cached_path (object, path);
-		gp11_object_set_session (object, session);
-	}
-
-	return object;
-}
+	name = identifier;
+	if (n_identifier < 0)
+		length = strlen (name);
+	else
+		length = n_identifier;
 
+	result = g_string_new (base);
+	if (!g_str_has_suffix (base, "/"))
+		g_string_append_c (result, '/');
 
-gchar*
-gkd_secret_util_identifier_for_collection (GP11Object *collection)
-{
-	GError *error = NULL;
-	gchar *identifier = NULL;
-	gpointer data;
-	gsize n_data;
-	gchar *path;
-
-	g_return_val_if_fail (GP11_IS_OBJECT (collection), NULL);
+	while (length > 0) {
+		char ch = *(name++);
+		--length;
 
-	/* Try to parse it out of the path */
-	path = get_cached_path (collection);
-	if (path != NULL) {
-		parse_collection_and_item_from_path (path, &identifier, NULL);
-		g_free (path);
-	}
+		/* Normal characters can go right through */
+		if (G_LIKELY ((ch >= 'A' && ch <= 'Z') ||
+		              (ch >= 'a' && ch <= 'z') ||
+		              (ch >= '0' && ch <= '9'))) {
+			g_string_append_c_inline (result, ch);
 
-	/* Must do a lookup */
-	if (identifier == NULL) {
-		data = gp11_object_get_data (collection, CKA_ID, &n_data, &error);
-		if (data == NULL) {
-			g_warning ("couldn't get identifier for collection: %s", error->message);
-			g_clear_error (&error);
+		/* Special characters are encoded with a _ */
 		} else {
-			identifier = g_strndup (data, n_data);
-			g_free (data);
+			g_string_append_printf (result, "_%02x", (unsigned int)ch);
 		}
 	}
 
-	return identifier;
-}
-
-GP11Attributes*
-gkd_secret_util_attributes_for_item (GP11Object *item)
-{
-	gchar *coll, *identifier;
-	GP11Attributes *attrs;
-	gchar *path;
-
-	path = gkd_secret_util_path_for_item (item);
-	if (path == NULL)
-		return NULL;
-
-	if (!parse_collection_and_item_from_path (path, &coll, &identifier))
-		g_return_val_if_reached (NULL);
-
-	attrs = gp11_attributes_new ();
-	gp11_attributes_add_ulong (attrs, CKA_CLASS, CKO_SECRET_KEY);
-	gp11_attributes_add_string (attrs, CKA_G_COLLECTION, coll);
-	gp11_attributes_add_string (attrs, CKA_ID, identifier);
-
-	g_free (identifier);
-	g_free (coll);
-	g_free (path);
-	return attrs;
+	return g_string_free (result, FALSE);
 }
 
-
 DBusMessage*
 gkd_secret_util_no_such_object (DBusMessage *message)
 {
diff --git a/daemon/dbus/gkd-secret-util.h b/daemon/dbus/gkd-secret-util.h
index 576057a..500c945 100644
--- a/daemon/dbus/gkd-secret-util.h
+++ b/daemon/dbus/gkd-secret-util.h
@@ -24,30 +24,17 @@
 
 #include "gkd-secret-types.h"
 
-#include "gp11/gp11.h"
+#include <glib.h>
 
 #include <dbus/dbus.h>
 
-GP11Object*       gkd_secret_util_path_to_collection                    (GP11Session *session,
-                                                                         const gchar *path);
+gboolean          gkd_secret_util_parse_path                            (const gchar *path,
+                                                                         gchar **collection,
+                                                                         gchar **item);
 
-GP11Object*       gkd_secret_util_path_to_item                          (GP11Session *session,
-                                                                         const gchar *path);
-
-GP11Object*       gkd_secret_util_path_to_object                        (GP11Session *session,
-                                                                         const gchar *path,
-                                                                         gboolean *is_item);
-
-gchar*            gkd_secret_util_path_for_collection                   (GP11Object *object);
-
-gchar*            gkd_secret_util_path_for_item                         (GP11Object *object);
-
-gchar*            gkd_secret_util_identifier_for_collection             (GP11Object *collection);
-
-GP11Object*       gkd_secret_util_identifier_to_collection              (GP11Session *session,
-                                                                         const gchar *identifier);
-
-GP11Attributes*   gkd_secret_util_attributes_for_item                   (GP11Object *item);
+gchar*            gkd_secret_util_build_path                            (const gchar *base,
+                                                                         gconstpointer identifier,
+                                                                         gssize n_identifier);
 
 DBusMessage*      gkd_secret_util_no_such_object                        (DBusMessage *message);
 



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