[gnome-keyring/dbus-api] [dbus] Refactor error handling and session lookups.



commit d62b7cb7358b89c170850a052ba64066c6d280c7
Author: Stef Walter <stef memberwebs com>
Date:   Sun Dec 13 02:49:50 2009 +0000

    [dbus] Refactor error handling and session lookups.
    
    Cleaner dbus error handling and session lookups.
    Secrets are also redone, with less memory copies.

 daemon/dbus/Makefile.am          |    1 +
 daemon/dbus/gkd-secret-create.c  |   22 ++++++--------
 daemon/dbus/gkd-secret-error.c   |   48 ++++++++++++++++++++++++++++++
 daemon/dbus/gkd-secret-error.h   |   34 +++++++++++++++++++++
 daemon/dbus/gkd-secret-objects.c |   50 +++++++++++--------------------
 daemon/dbus/gkd-secret-secret.c  |   60 +++++++++++++++++++++++++++----------
 daemon/dbus/gkd-secret-secret.h  |   10 +++++-
 daemon/dbus/gkd-secret-service.c |   19 +++++++++--
 daemon/dbus/gkd-secret-session.c |   47 ++++++++++++++++++++++++++---
 daemon/dbus/gkd-secret-session.h |   10 ++++++
 daemon/dbus/gkd-secret-util.c    |    8 -----
 daemon/dbus/gkd-secret-util.h    |    2 -
 12 files changed, 229 insertions(+), 82 deletions(-)
---
diff --git a/daemon/dbus/Makefile.am b/daemon/dbus/Makefile.am
index fc81765..c4afb1f 100644
--- a/daemon/dbus/Makefile.am
+++ b/daemon/dbus/Makefile.am
@@ -19,6 +19,7 @@ libgkr_dbus_la_SOURCES = \
 	gkd-dbus-session.c \
 	gkd-dbus-util.c gkd-dbus-util.h \
 	gkd-secret-create.c gkd-secret-create.h \
+	gkd-secret-error.c gkd-secret-error.h \
 	gkd-secret-objects.c gkd-secret-objects.h \
 	gkd-secret-property.c gkd-secret-property.h \
 	gkd-secret-prompt.c gkd-secret-prompt.h \
diff --git a/daemon/dbus/gkd-secret-create.c b/daemon/dbus/gkd-secret-create.c
index 894e4a0..0ad964e 100644
--- a/daemon/dbus/gkd-secret-create.c
+++ b/daemon/dbus/gkd-secret-create.c
@@ -22,6 +22,7 @@
 #include "config.h"
 
 #include "gkd-secret-create.h"
+#include "gkd-secret-error.h"
 #include "gkd-secret-prompt.h"
 #include "gkd-secret-secret.h"
 #include "gkd-secret-service.h"
@@ -338,11 +339,9 @@ gkd_secret_create_without_prompting (GkdSecretService *service, DBusMessage *mes
 	gchar *path;
 
 	/* Figure out the session */
-	session = gkd_secret_service_lookup_session (service, master->path,
-	                                             dbus_message_get_sender (message));
+	session = gkd_secret_session_for_secret (service, master, &derr);
 	if (session == NULL)
-		return dbus_message_new_error (message, SECRET_ERROR_NO_SESSION,
-		                               "No such session exists");
+		return gkd_secret_error_to_reply (message, &derr);
 
 	if (!gp11_attributes_find_boolean (attrs, CKA_TOKEN, &token))
 		token = FALSE;
@@ -352,18 +351,15 @@ gkd_secret_create_without_prompting (GkdSecretService *service, DBusMessage *mes
 	                             CKA_TOKEN, GP11_BOOLEAN, token,
 	                             GP11_INVALID);
 
+	pkcs11_session = gkd_secret_service_get_pkcs11_session (service, dbus_message_get_sender (message));
+	g_return_val_if_fail (pkcs11_session, NULL);
+
 	/* Create ourselves some credentials */
-	cred = gkd_secret_session_create_credential (session, atts, master, &derr);
+	cred = gkd_secret_session_create_credential (session, pkcs11_session, atts, master, &derr);
 	gp11_attributes_unref (atts);
 
-	if (cred == NULL) {
-		reply = dbus_message_new_error (message, derr.name, derr.message);
-		dbus_error_free (&derr);
-		return reply;
-	}
-
-	pkcs11_session = gkd_secret_service_get_pkcs11_session (service, dbus_message_get_sender (message));
-	g_return_val_if_fail (pkcs11_session, NULL);
+	if (cred == NULL)
+		return gkd_secret_error_to_reply (message, &derr);
 
 	collection = gkd_secret_create_with_credential (pkcs11_session, attrs, cred, &error);
 
diff --git a/daemon/dbus/gkd-secret-error.c b/daemon/dbus/gkd-secret-error.c
new file mode 100644
index 0000000..3faa633
--- /dev/null
+++ b/daemon/dbus/gkd-secret-error.c
@@ -0,0 +1,48 @@
+/*
+ * 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 <glib.h>
+
+#include "gkd-secret-error.h"
+
+DBusMessage*
+gkd_secret_error_no_such_object (DBusMessage *message)
+{
+	g_return_val_if_fail (message, NULL);
+	return dbus_message_new_error_printf (message, SECRET_ERROR_NO_SUCH_OBJECT,
+	                                      "The '%s' object does not exist", dbus_message_get_path (message));
+}
+
+DBusMessage*
+gkd_secret_error_to_reply (DBusMessage *message, DBusError *derr)
+{
+	DBusMessage *reply;
+
+	g_return_val_if_fail (message, NULL);
+	g_return_val_if_fail (derr, NULL);
+	g_return_val_if_fail (dbus_error_is_set (derr), NULL);
+
+	reply = dbus_message_new_error (message, derr->name, derr->message);
+	dbus_error_free (derr);
+	return reply;
+}
diff --git a/daemon/dbus/gkd-secret-error.h b/daemon/dbus/gkd-secret-error.h
new file mode 100644
index 0000000..bc38e70
--- /dev/null
+++ b/daemon/dbus/gkd-secret-error.h
@@ -0,0 +1,34 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2009 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 __GKD_SECRET_ERROR_H__
+#define __GKD_SECRET_ERROR_H__
+
+#include "gkd-secret-types.h"
+
+#include <dbus/dbus.h>
+
+DBusMessage*      gkd_secret_error_no_such_object                       (DBusMessage *message);
+
+DBusMessage*      gkd_secret_error_to_reply                             (DBusMessage *message,
+                                                                         DBusError *derr);
+
+#endif /* __GKD_SECRET_ERROR_H__ */
diff --git a/daemon/dbus/gkd-secret-objects.c b/daemon/dbus/gkd-secret-objects.c
index 43be196..25bd4dd 100644
--- a/daemon/dbus/gkd-secret-objects.c
+++ b/daemon/dbus/gkd-secret-objects.c
@@ -23,6 +23,7 @@
 
 #include "gkd-dbus-util.h"
 
+#include "gkd-secret-error.h"
 #include "gkd-secret-objects.h"
 #include "gkd-secret-property.h"
 #include "gkd-secret-secret.h"
@@ -361,26 +362,18 @@ item_method_get_secret (GkdSecretObjects *self, GP11Object *item, DBusMessage *m
 	GkdSecretSecret *secret;
 	DBusMessage *reply;
 	DBusMessageIter iter;
-	const char *caller;
 	const char *path;
 
 	if (!dbus_message_get_args (message, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID))
 		return NULL;
 
-	caller = dbus_message_get_sender (message);
-	g_return_val_if_fail (caller, NULL);
-
-	session = gkd_secret_service_lookup_session (self->service, path, caller);
+	session = gkd_secret_session_for_path (self->service, path, dbus_message_get_sender (message), &derr);
 	if (session == NULL)
-		return dbus_message_new_error_printf (message, SECRET_ERROR_NO_SESSION,
-		                                      "No such session exists");
+		return gkd_secret_error_to_reply (message, &derr);
 
 	secret = gkd_secret_session_get_item_secret (session, item, &derr);
-	if (secret == NULL) {
-		reply = dbus_message_new_error (message, derr.name, derr.message);
-		dbus_error_free (&derr);
-		return reply;
-	}
+	if (secret == NULL)
+		return gkd_secret_error_to_reply (message, &derr);
 
 	reply = dbus_message_new_method_return (message);
 	dbus_message_iter_init_append (reply, &iter);
@@ -394,7 +387,6 @@ item_method_set_secret (GkdSecretObjects *self, GP11Object *item, DBusMessage *m
 {
 	DBusError derr = DBUS_ERROR_INIT;
 	DBusMessageIter iter;
-	DBusMessage *reply;
 	GkdSecretSecret *secret;
 	GkdSecretSession *session;
 	const char *caller;
@@ -402,7 +394,7 @@ item_method_set_secret (GkdSecretObjects *self, GP11Object *item, DBusMessage *m
 	if (!dbus_message_has_signature (message, "(oayay)"))
 		return NULL;
 	dbus_message_iter_init (message, &iter);
-	secret = gkd_secret_secret_parse (&iter);
+	secret = gkd_secret_secret_parse (message, &iter);
 	if (secret == NULL)
 		return dbus_message_new_error (message, DBUS_ERROR_INVALID_ARGS,
 		                               "The secret is invalid");
@@ -410,21 +402,17 @@ item_method_set_secret (GkdSecretObjects *self, GP11Object *item, DBusMessage *m
 	caller = dbus_message_get_sender (message);
 	g_return_val_if_fail (caller, NULL);
 
-	session = gkd_secret_service_lookup_session (self->service, secret->path, caller);
+	session = gkd_secret_session_for_secret (self->service, secret, &derr);
 	if (session == NULL) {
 		gkd_secret_secret_free (secret);
-		return dbus_message_new_error_printf (message, SECRET_ERROR_NO_SESSION,
-		                                      "No such session exists");
+		return gkd_secret_error_to_reply (message, &derr);
 	}
 
 	gkd_secret_session_set_item_secret (session, item, secret, &derr);
 	gkd_secret_secret_free (secret);
 
-	if (dbus_error_is_set (&derr)) {
-		reply = dbus_message_new_error (message, derr.name, derr.message);
-		dbus_error_free (&derr);
-		return reply;
-	}
+	if (dbus_error_is_set (&derr))
+		return gkd_secret_error_to_reply (message, &derr);
 
 	return dbus_message_new_method_return (message);
 }
@@ -682,7 +670,7 @@ collection_method_create_item (GkdSecretObjects *self, GP11Object *object, DBusM
 		goto cleanup;
 	}
 	dbus_message_iter_next (&iter);
-	secret = gkd_secret_secret_parse (&iter);
+	secret = gkd_secret_secret_parse (message, &iter);
 	if (secret == NULL) {
 		reply = dbus_message_new_error (message, DBUS_ERROR_INVALID_ARGS,
 		                                "Invalid secret argument");
@@ -692,11 +680,9 @@ collection_method_create_item (GkdSecretObjects *self, GP11Object *object, DBusM
 	dbus_message_iter_get_basic (&iter, &replace);
 
 	/* Figure out which session we're dealing with */
-	session = gkd_secret_service_lookup_session (self->service, secret->path,
-	                                             dbus_message_get_sender (message));
+	session = gkd_secret_session_for_secret (self->service, secret, &derr);
 	if (session == NULL) {
-		reply = dbus_message_new_error (message, SECRET_ERROR_NO_SESSION,
-		                                "No such secret session exists");
+		reply = gkd_secret_error_to_reply (message, &derr);
 		goto cleanup;
 	}
 
@@ -978,7 +964,7 @@ gkd_secret_objects_dispatch (GkdSecretObjects *self, DBusMessage *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);
+		return gkd_secret_error_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));
@@ -1008,7 +994,7 @@ gkd_secret_objects_dispatch (GkdSecretObjects *self, DBusMessage *message)
 	}
 
 	if (!objects)
-		return gkd_secret_util_no_such_object (message);
+		return gkd_secret_error_no_such_object (message);
 
 	gp11_object_set_session (objects->data, session);
 	if (is_item)
@@ -1296,10 +1282,10 @@ gkd_secret_objects_handle_get_secrets (GkdSecretObjects *self, DBusMessage *mess
 	caller = dbus_message_get_sender (message);
 	g_return_val_if_fail (caller, NULL);
 
-	session = gkd_secret_service_lookup_session (self->service, session_path, caller);
+	session = gkd_secret_session_for_path (self->service, session_path,
+	                                       dbus_message_get_sender (message), &derr);
 	if (session == NULL)
-		return dbus_message_new_error (message, SECRET_ERROR_NO_SESSION,
-		                               "No such session exists");
+		return gkd_secret_error_to_reply (message, &derr);
 
 	reply = dbus_message_new_method_return (message);
 	dbus_message_iter_init_append (reply, &iter);
diff --git a/daemon/dbus/gkd-secret-secret.c b/daemon/dbus/gkd-secret-secret.c
index 8434015..8473b0c 100644
--- a/daemon/dbus/gkd-secret-secret.c
+++ b/daemon/dbus/gkd-secret-secret.c
@@ -27,29 +27,48 @@
 
 #include <string.h>
 
+static void
+destroy_with_owned_memory (gpointer data)
+{
+	GkdSecretSecret *secret = data;
+	g_free (secret->path);
+	g_free (secret->caller);
+	g_free (secret->parameter);
+	g_free (secret->value);
+}
+
 GkdSecretSecret*
-gkd_secret_secret_create_and_take_memory (const gchar *path, gpointer parameter,
-                                          gsize n_parameter, gpointer value,
-                                          gsize n_value)
+gkd_secret_secret_new_take_memory (const gchar *path, const gchar *caller,
+                                   gpointer parameter, gsize n_parameter,
+                                   gpointer value, gsize n_value)
 {
 	GkdSecretSecret *secret;
 
+	g_return_val_if_fail (path, NULL);
+	g_return_val_if_fail (caller, NULL);
+
 	secret = g_slice_new0 (GkdSecretSecret);
 	secret->path = g_strdup (path);
+	secret->caller = g_strdup (caller);
 	secret->parameter = parameter;
 	secret->n_parameter = n_parameter;
 	secret->value = value;
 	secret->n_value = n_value;
+
+	secret->destroy_func = destroy_with_owned_memory;
+	secret->destroy_data = secret;
+
 	return secret;
 }
 
 GkdSecretSecret*
-gkd_secret_secret_parse (DBusMessageIter *iter)
+gkd_secret_secret_parse (DBusMessage *message, DBusMessageIter *iter)
 {
+	GkdSecretSecret *secret;
 	DBusMessageIter struc, array;
-	const void *parameter, *value;
+	void *parameter, *value;
 	int n_value, n_parameter;
-	const char *path;
+	char *path;
 
 	g_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_STRUCT, NULL);
 	dbus_message_iter_recurse (iter, &struc);
@@ -75,11 +94,18 @@ gkd_secret_secret_parse (DBusMessageIter *iter)
 	dbus_message_iter_recurse (&struc, &array);
 	dbus_message_iter_get_fixed_array (&array, &value, &n_value);
 
-	return gkd_secret_secret_create_and_take_memory (path,
-	                                                 n_parameter ? g_memdup (parameter, n_parameter) : NULL,
-	                                                 n_parameter,
-	                                                 n_value ? g_memdup (value, n_value) : NULL,
-	                                                 n_value);
+	secret = g_slice_new0 (GkdSecretSecret);
+	secret->path = path;
+	secret->caller = (char*)dbus_message_get_sender (message);
+	secret->parameter = parameter;
+	secret->n_parameter = n_parameter;
+	secret->value = value;
+	secret->n_value = n_value;
+
+	/* All the memory is owned by the message */
+	secret->destroy_data = dbus_message_ref (message);
+	secret->destroy_func = (GDestroyNotify)dbus_message_unref;
+	return secret;
 }
 
 void
@@ -109,6 +135,8 @@ gkd_secret_secret_free (gpointer data)
 	if (!data)
 		return;
 
+	secret = data;
+
 	/*
 	 * These are not usually actual plain text secrets. However in
 	 * the case that they are, we want to clear them from memory.
@@ -117,12 +145,12 @@ gkd_secret_secret_free (gpointer data)
 	 * have been sent over DBus, and through all sorts of processes.
 	 */
 
-	secret = data;
-	g_free (secret->path);
 	egg_secure_clear (secret->parameter, secret->n_parameter);
-	g_free (secret->parameter);
 	egg_secure_clear (secret->value, secret->n_value);
-	g_free (secret->value);
-	g_slice_free (GkdSecretSecret, secret);
 
+	/* Call the destructor of memory */
+	if (secret->destroy_func)
+		(secret->destroy_func) (secret->destroy_data);
+
+	g_slice_free (GkdSecretSecret, secret);
 }
diff --git a/daemon/dbus/gkd-secret-secret.h b/daemon/dbus/gkd-secret-secret.h
index f670db2..810cc3c 100644
--- a/daemon/dbus/gkd-secret-secret.h
+++ b/daemon/dbus/gkd-secret-secret.h
@@ -30,19 +30,25 @@
 
 struct _GkdSecretSecret {
 	gchar *path;
+	gchar *caller;
 	gpointer parameter;
 	gsize n_parameter;
 	gpointer value;
 	gsize n_value;
+
+	GDestroyNotify destroy_func;
+	gpointer destroy_data;
 };
 
-GkdSecretSecret*       gkd_secret_secret_create_and_take_memory   (const gchar *path,
+GkdSecretSecret*       gkd_secret_secret_new_take_memory          (const gchar *path,
+                                                                   const gchar *caller,
                                                                    gpointer parameter,
                                                                    gsize n_parameter,
                                                                    gpointer value,
                                                                    gsize n_value);
 
-GkdSecretSecret*       gkd_secret_secret_parse                    (DBusMessageIter *iter);
+GkdSecretSecret*       gkd_secret_secret_parse                    (DBusMessage *message,
+                                                                   DBusMessageIter *iter);
 
 void                   gkd_secret_secret_append                   (GkdSecretSecret *secret,
                                                                    DBusMessageIter *iter);
diff --git a/daemon/dbus/gkd-secret-service.c b/daemon/dbus/gkd-secret-service.c
index ace3e6e..0149183 100644
--- a/daemon/dbus/gkd-secret-service.c
+++ b/daemon/dbus/gkd-secret-service.c
@@ -23,6 +23,7 @@
 
 #include "gkd-dbus-util.h"
 #include "gkd-secret-create.h"
+#include "gkd-secret-error.h"
 #include "gkd-secret-objects.h"
 #include "gkd-secret-prompt.h"
 #include "gkd-secret-property.h"
@@ -469,7 +470,7 @@ service_method_create_with_master_password (GkdSecretService *self, DBusMessage
 		                               "Invalid properties argument");
 	}
 	dbus_message_iter_next (&iter);
-	secret = gkd_secret_secret_parse (&iter);
+	secret = gkd_secret_secret_parse (message, &iter);
 	if (secret == NULL) {
 		gp11_attributes_unref (attrs);
 		return dbus_message_new_error (message, DBUS_ERROR_INVALID_ARGS,
@@ -485,6 +486,16 @@ service_method_create_with_master_password (GkdSecretService *self, DBusMessage
 }
 
 static DBusMessage*
+service_method_lock_service (GkdSecretService *self, DBusMessage *message)
+{
+	if (!dbus_message_get_args (message, NULL, DBUS_TYPE_INVALID))
+		return NULL;
+
+	/* TODO: Need to implement */
+	return dbus_message_new_method_return (message);
+}
+
+static DBusMessage*
 service_method_unlock (GkdSecretService *self, DBusMessage *message)
 {
 	GkdSecretUnlock *unlock;
@@ -625,7 +636,7 @@ service_message_handler (GkdSecretService *self, DBusMessage *message)
 
 	/* org.freedesktop.Secret.Service.LockService() */
 	if (dbus_message_is_method_call (message, SECRET_SERVICE_INTERFACE, "LockService"))
-		g_return_val_if_reached (NULL); /* TODO: Need to implement */
+		return service_method_lock_service (self, message);
 
 	/* org.freedesktop.Secret.Service.SearchItems() */
 	if (dbus_message_is_method_call (message, SECRET_SERVICE_INTERFACE, "SearchItems"))
@@ -704,7 +715,7 @@ service_dispatch_message (GkdSecretService *self, DBusMessage *message)
 	if (object_path_has_prefix (path, SECRET_SESSION_PREFIX)) {
 		object = g_hash_table_lookup (client->sessions, path);
 		if (object == NULL)
-			reply = gkd_secret_util_no_such_object (message);
+			reply = gkd_secret_error_no_such_object (message);
 		else
 			reply = gkd_secret_session_dispatch (object, message);
 
@@ -712,7 +723,7 @@ service_dispatch_message (GkdSecretService *self, DBusMessage *message)
 	} else if (object_path_has_prefix (path, SECRET_PROMPT_PREFIX)) {
 		object = g_hash_table_lookup (client->prompts, path);
 		if (object == NULL)
-			reply = gkd_secret_util_no_such_object (message);
+			reply = gkd_secret_error_no_such_object (message);
 		else
 			reply = gkd_secret_prompt_dispatch (object, message);
 
diff --git a/daemon/dbus/gkd-secret-session.c b/daemon/dbus/gkd-secret-session.c
index 88f8a65..d996d94 100644
--- a/daemon/dbus/gkd-secret-session.c
+++ b/daemon/dbus/gkd-secret-session.c
@@ -534,7 +534,8 @@ gkd_secret_session_get_item_secret (GkdSecretSession *self, GP11Object *item,
 		return NULL;
 	}
 
-	return gkd_secret_secret_create_and_take_memory (self->object_path, iv, n_iv, value, n_value);
+	return gkd_secret_secret_new_take_memory (self->object_path, self->caller,
+	                                          iv, n_iv, value, n_value);
 }
 
 gboolean
@@ -607,21 +608,55 @@ gkd_secret_session_set_item_secret (GkdSecretSession *self, GP11Object *item,
 	return TRUE;
 }
 
+GkdSecretSession*
+gkd_secret_session_for_path (GkdSecretService *service, const gchar *path,
+                             const gchar *caller, DBusError *derr)
+{
+	GkdSecretSession *self;
+
+	self = gkd_secret_service_lookup_session (service, path, caller);
+	if (self == NULL)
+		dbus_set_error (derr, SECRET_ERROR_NO_SESSION, "The session does not exist");
+
+	return self;
+}
+
+GkdSecretSession*
+gkd_secret_session_for_secret (GkdSecretService *service, GkdSecretSecret *secret, DBusError *derr)
+{
+	GkdSecretSession *self;
+
+	self = gkd_secret_service_lookup_session (service, secret->path, secret->caller);
+	if (self == NULL)
+		dbus_set_error (derr, SECRET_ERROR_NO_SESSION,
+		                "The session wrapping the secret does not exist");
+
+	return self;
+}
+
 GP11Object*
-gkd_secret_session_create_credential (GkdSecretSession *self, GP11Attributes *attrs,
-                                      GkdSecretSecret *secret, DBusError *derr)
+gkd_secret_session_create_credential (GkdSecretSession *self, GP11Session *session,
+                                      GP11Attributes *attrs, GkdSecretSecret *secret,
+                                      DBusError *derr)
 {
+	GP11Attributes *alloc = NULL;
 	GP11Mechanism *mech;
 	GP11Object *object;
-	GP11Session *session;
 	GError *error = NULL;
 
 	g_assert (GP11_IS_OBJECT (self->key));
+	g_assert (GP11_IS_SESSION (session));
 	g_assert (attrs);
 
-	session = gkd_secret_service_get_pkcs11_session (self->service, self->caller);
+	if (session == NULL)
+		session = gkd_secret_service_get_pkcs11_session (self->service, self->caller);
 	g_return_val_if_fail (session, NULL);
 
+	if (attrs == NULL)
+		alloc = attrs = gp11_attributes_newv (CKA_CLASS, GP11_ULONG, CKO_G_CREDENTIAL,
+		                                      CKA_TOKEN, GP11_BOOLEAN, FALSE,
+		                                      GP11_INVALID);
+
 	mech = gp11_mechanism_new_with_param (self->mech_type, secret->parameter,
 	                                      secret->n_parameter);
 
@@ -629,6 +664,8 @@ gkd_secret_session_create_credential (GkdSecretSession *self, GP11Attributes *at
 	                                       secret->n_value, attrs, NULL, &error);
 
 	gp11_mechanism_unref (mech);
+	if (alloc != NULL)
+		gp11_attributes_unref (alloc);
 
 	if (object == NULL) {
 		if (error->code == CKR_WRAPPED_KEY_INVALID ||
diff --git a/daemon/dbus/gkd-secret-session.h b/daemon/dbus/gkd-secret-session.h
index b8e9031..ae329a1 100644
--- a/daemon/dbus/gkd-secret-session.h
+++ b/daemon/dbus/gkd-secret-session.h
@@ -41,6 +41,15 @@ struct _GkdSecretSessionClass {
 
 GType               gkd_secret_session_get_type                (void);
 
+GkdSecretSession*   gkd_secret_session_for_path                (GkdSecretService *service,
+                                                                const gchar *path,
+                                                                const gchar *caller,
+                                                                DBusError *derr);
+
+GkdSecretSession*   gkd_secret_session_for_secret              (GkdSecretService *service,
+                                                                GkdSecretSecret *secret,
+                                                                DBusError *derr);
+
 DBusMessage*        gkd_secret_session_dispatch                (GkdSecretSession *self,
                                                                 DBusMessage *message);
 
@@ -60,6 +69,7 @@ gboolean            gkd_secret_session_set_item_secret         (GkdSecretSession
                                                                 DBusError *derr);
 
 GP11Object*         gkd_secret_session_create_credential       (GkdSecretSession *self,
+                                                                GP11Session *session,
                                                                 GP11Attributes *attrs,
                                                                 GkdSecretSecret *secret,
                                                                 DBusError *derr);
diff --git a/daemon/dbus/gkd-secret-util.c b/daemon/dbus/gkd-secret-util.c
index 8a8e57d..b72f5b6 100644
--- a/daemon/dbus/gkd-secret-util.c
+++ b/daemon/dbus/gkd-secret-util.c
@@ -147,11 +147,3 @@ gkd_secret_util_build_path (const gchar *base, gconstpointer identifier, gssize
 
 	return g_string_free (result, FALSE);
 }
-
-DBusMessage*
-gkd_secret_util_no_such_object (DBusMessage *message)
-{
-	g_return_val_if_fail (message, NULL);
-	return dbus_message_new_error_printf (message, SECRET_ERROR_NO_SUCH_OBJECT,
-	                                      "The '%s' object does not exist", dbus_message_get_path (message));
-}
diff --git a/daemon/dbus/gkd-secret-util.h b/daemon/dbus/gkd-secret-util.h
index 500c945..b29153b 100644
--- a/daemon/dbus/gkd-secret-util.h
+++ b/daemon/dbus/gkd-secret-util.h
@@ -36,6 +36,4 @@ gchar*            gkd_secret_util_build_path                            (const g
                                                                          gconstpointer identifier,
                                                                          gssize n_identifier);
 
-DBusMessage*      gkd_secret_util_no_such_object                        (DBusMessage *message);
-
 #endif /* __GKD_SECRET_UTIL_H__ */



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