[seahorse/refactor: 21/33] pkcs11: Use new gck functionality to load certificates



commit e97b3fbaf8ed8a9d12ea498ae3cdacede7ef47c0
Author: Stef Walter <stefw collabora co uk>
Date:   Wed Oct 12 17:49:09 2011 +0200

    pkcs11: Use new gck functionality to load certificates
    
     * Use enumerator to load certificates, and have the enumerator
       get the attributes for each certificate.
     * No more SeahorsePkcs11Object
     * Simpler names for things`

 pkcs11/Makefile.am                         |    7 +-
 pkcs11/seahorse-certificate.c              |  194 ++++++++++++
 pkcs11/seahorse-certificate.h              |   59 ++++
 pkcs11/seahorse-pkcs11-backend.c           |    4 +-
 pkcs11/seahorse-pkcs11-certificate-props.c |    4 +-
 pkcs11/seahorse-pkcs11-certificate.c       |  333 ---------------------
 pkcs11/seahorse-pkcs11-certificate.h       |   65 ----
 pkcs11/seahorse-pkcs11-commands.c          |   10 +-
 pkcs11/seahorse-pkcs11-object.c            |  380 ------------------------
 pkcs11/seahorse-pkcs11-object.h            |   75 -----
 pkcs11/seahorse-pkcs11-operations.c        |  164 +----------
 pkcs11/seahorse-pkcs11-operations.h        |   12 -
 pkcs11/seahorse-pkcs11-token.c             |  303 -------------------
 pkcs11/seahorse-pkcs11-token.h             |   61 ----
 pkcs11/seahorse-token.c                    |  439 ++++++++++++++++++++++++++++
 pkcs11/seahorse-token.h                    |   66 +++++
 16 files changed, 779 insertions(+), 1397 deletions(-)
---
diff --git a/pkcs11/Makefile.am b/pkcs11/Makefile.am
index 142d5f1..4d4857a 100644
--- a/pkcs11/Makefile.am
+++ b/pkcs11/Makefile.am
@@ -15,15 +15,14 @@ INCLUDES = -I$(top_builddir) \
 noinst_LTLIBRARIES = libseahorse-pkcs11.la
 
 libseahorse_pkcs11_la_SOURCES = \
+	seahorse-certificate.c seahorse-certificate.h \
 	seahorse-pkcs11-backend.c seahorse-pkcs11-backend.h \
-	seahorse-pkcs11-certificate.c seahorse-pkcs11-certificate.h \
 	seahorse-pkcs11-certificate-props.c seahorse-pkcs11-certificate-props.h \
 	seahorse-pkcs11-commands.c seahorse-pkcs11-commands.h \
 	seahorse-pkcs11-helpers.c seahorse-pkcs11-helpers.h \
-	seahorse-pkcs11-object.c seahorse-pkcs11-object.h \
 	seahorse-pkcs11-operations.c seahorse-pkcs11-operations.h \
-	seahorse-pkcs11-token.c seahorse-pkcs11-token.h\
-	seahorse-pkcs11.c seahorse-pkcs11.h
+	seahorse-pkcs11.c seahorse-pkcs11.h \
+	seahorse-token.c seahorse-token.h
 
 libseahorse_pkcs11_la_LIBADD = \
 	$(top_builddir)/libseahorse/libseahorse.la \
diff --git a/pkcs11/seahorse-certificate.c b/pkcs11/seahorse-certificate.c
new file mode 100644
index 0000000..5715b54
--- /dev/null
+++ b/pkcs11/seahorse-certificate.c
@@ -0,0 +1,194 @@
+/*
+ * Seahorse
+ *
+ * Copyright (C) 2008 Stefan Walter
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * 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 "seahorse-certificate.h"
+#include "seahorse-pkcs11-helpers.h"
+#include "seahorse-pkcs11.h"
+#include "seahorse-token.h"
+
+#include "seahorse-util.h"
+#include "seahorse-validity.h"
+
+#include <gcr/gcr.h>
+#include <gck/pkcs11.h>
+
+#include <glib/gi18n-lib.h>
+
+static const gulong REQUIRED_ATTRS[] = {
+	CKA_VALUE,
+	CKA_ID,
+	CKA_LABEL,
+	CKA_CLASS
+};
+
+enum {
+	PROP_0,
+	PROP_SOURCE,
+	PROP_ATTRIBUTES,
+};
+
+struct _SeahorseCertificatePrivate {
+	SeahorseToken *token;
+	GckAttributes *attributes;
+	GckAttribute der_value;
+};
+
+static void seahorse_certificate_certificate_iface (GcrCertificateIface *iface);
+static void seahorse_certificate_object_attributes_iface (GckObjectAttributesIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (SeahorseCertificate, seahorse_certificate, GCK_TYPE_OBJECT,
+                         GCR_CERTIFICATE_MIXIN_IMPLEMENT_COMPARABLE ();
+                         G_IMPLEMENT_INTERFACE (GCR_TYPE_CERTIFICATE, seahorse_certificate_certificate_iface);
+                         G_IMPLEMENT_INTERFACE (GCK_TYPE_OBJECT_ATTRIBUTES, seahorse_certificate_object_attributes_iface)
+);
+
+static void
+seahorse_certificate_init (SeahorseCertificate *self)
+{
+	self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, SEAHORSE_TYPE_CERTIFICATE, SeahorseCertificatePrivate));
+	gck_attribute_init_invalid (&self->pv->der_value, CKA_VALUE);
+}
+
+static void
+seahorse_certificate_notify (GObject *obj,
+                             GParamSpec *pspec)
+{
+	/* When the base class attributes changes, it can affects lots */
+	if (g_str_equal (pspec->name, "attributes"))
+		gcr_certificate_mixin_emit_notify (GCR_CERTIFICATE (obj));
+
+	if (G_OBJECT_CLASS (seahorse_certificate_parent_class)->notify)
+		G_OBJECT_CLASS (seahorse_certificate_parent_class)->notify (obj, pspec);
+}
+
+
+static void
+seahorse_certificate_finalize (GObject *obj)
+{
+	SeahorseCertificate *self = SEAHORSE_CERTIFICATE (obj);
+
+	if (self->pv->attributes)
+		gck_attributes_unref (self->pv->attributes);
+	gck_attribute_clear (&self->pv->der_value);
+
+	G_OBJECT_CLASS (seahorse_certificate_parent_class)->finalize (obj);
+}
+
+static void
+seahorse_certificate_get_property (GObject *obj,
+                                   guint prop_id,
+                                   GValue *value,
+                                   GParamSpec *pspec)
+{
+	SeahorseCertificate *self = SEAHORSE_CERTIFICATE (obj);
+
+	switch (prop_id) {
+	case PROP_SOURCE:
+		g_value_set_object (value, self->pv->token);
+		break;
+	case PROP_ATTRIBUTES:
+		g_value_set_boxed (value, self->pv->attributes);
+		break;
+	default:
+		gcr_certificate_mixin_get_property (obj, prop_id, value, pspec);
+		break;
+	}
+}
+
+static void
+seahorse_certificate_set_property (GObject *obj,
+                                   guint prop_id,
+                                   const GValue *value,
+                                   GParamSpec *pspec)
+{
+	SeahorseCertificate *self = SEAHORSE_CERTIFICATE (obj);
+	GckAttribute *der_value = NULL;
+
+	switch (prop_id) {
+	case PROP_SOURCE:
+		g_return_if_fail (self->pv->token == NULL);
+		self->pv->token = g_value_dup_object (value);
+		break;
+	case PROP_ATTRIBUTES:
+		if (self->pv->attributes)
+			gck_attributes_unref (self->pv->attributes);
+		self->pv->attributes = g_value_dup_boxed (value);
+		if (self->pv->attributes)
+			der_value = gck_attributes_find (self->pv->attributes,
+			                                 CKA_VALUE);
+		if (der_value) {
+			gck_attribute_clear (&self->pv->der_value);
+			gck_attribute_init_copy (&self->pv->der_value, der_value);
+		}
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+seahorse_certificate_class_init (SeahorseCertificateClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (SeahorseCertificatePrivate));
+
+	gobject_class->finalize = seahorse_certificate_finalize;
+	gobject_class->set_property = seahorse_certificate_set_property;
+	gobject_class->get_property = seahorse_certificate_get_property;
+	gobject_class->notify = seahorse_certificate_notify;
+
+	g_object_class_install_property (gobject_class, PROP_SOURCE,
+	         g_param_spec_object ("source", "source", "source", SEAHORSE_TYPE_TOKEN,
+	                              G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+
+	g_object_class_override_property (gobject_class, PROP_ATTRIBUTES, "attributes");
+
+	gcr_certificate_mixin_class_init (gobject_class);
+}
+
+static const guchar *
+seahorse_certificate_get_der_data (GcrCertificate *cert,
+                                   gsize *n_length)
+{
+	SeahorseCertificate *self = SEAHORSE_CERTIFICATE (cert);
+
+	g_return_val_if_fail (!gck_attribute_is_invalid (&self->pv->der_value), NULL);
+	*n_length = self->pv->der_value.length;
+	return self->pv->der_value.value;
+}
+
+static void
+seahorse_certificate_certificate_iface (GcrCertificateIface *iface)
+{
+	iface->get_der_data = (gpointer)seahorse_certificate_get_der_data;
+}
+
+static void
+seahorse_certificate_object_attributes_iface (GckObjectAttributesIface *iface)
+{
+	iface->attribute_types = REQUIRED_ATTRS;
+	iface->n_attribute_types = G_N_ELEMENTS (REQUIRED_ATTRS);
+}
diff --git a/pkcs11/seahorse-certificate.h b/pkcs11/seahorse-certificate.h
new file mode 100644
index 0000000..589c1ab
--- /dev/null
+++ b/pkcs11/seahorse-certificate.h
@@ -0,0 +1,59 @@
+/*
+ * Seahorse
+ *
+ * Copyright (C) 2008 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef __SEAHORSE_CERTIFICATE_H__
+#define __SEAHORSE_CERTIFICATE_H__
+
+#include <gck/gck.h>
+
+#include <glib-object.h>
+
+#define SEAHORSE_TYPE_CERTIFICATE               (seahorse_certificate_get_type ())
+#define SEAHORSE_CERTIFICATE(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_TYPE_CERTIFICATE, SeahorseCertificate))
+#define SEAHORSE_CERTIFICATE_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_TYPE_CERTIFICATE, SeahorseCertificateClass))
+#define SEAHORSE_IS_CERTIFICATE(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_TYPE_CERTIFICATE))
+#define SEAHORSE_IS_CERTIFICATE_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_TYPE_CERTIFICATE))
+#define SEAHORSE_CERTIFICATE_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_TYPE_CERTIFICATE, SeahorseCertificateClass))
+
+typedef struct _SeahorseCertificate SeahorseCertificate;
+typedef struct _SeahorseCertificateClass SeahorseCertificateClass;
+typedef struct _SeahorseCertificatePrivate SeahorseCertificatePrivate;
+
+struct _SeahorseCertificate {
+	GckObject parent;
+	SeahorseCertificatePrivate *pv;
+};
+
+struct _SeahorseCertificateClass {
+	GckObjectClass parent_class;
+};
+
+GType                 seahorse_certificate_get_type               (void) G_GNUC_CONST;
+
+void                  seahorse_certificate_realize                (SeahorseCertificate *self);
+
+guint                 seahorse_certificate_get_validity           (SeahorseCertificate* self);
+
+guint                 seahorse_certificate_get_trust              (SeahorseCertificate* self);
+
+gulong                seahorse_certificate_get_expires            (SeahorseCertificate* self);
+
+#endif /* __SEAHORSE_CERTIFICATE_H__ */
diff --git a/pkcs11/seahorse-pkcs11-backend.c b/pkcs11/seahorse-pkcs11-backend.c
index 50ed744..1f87d9d 100644
--- a/pkcs11/seahorse-pkcs11-backend.c
+++ b/pkcs11/seahorse-pkcs11-backend.c
@@ -23,7 +23,7 @@
 
 #include "seahorse-pkcs11-backend.h"
 #include "seahorse-pkcs11-commands.h"
-#include "seahorse-pkcs11-token.h"
+#include "seahorse-token.h"
 
 #include "seahorse-backend.h"
 #include "seahorse-registry.h"
@@ -143,7 +143,7 @@ on_initialized_registered (GObject *unused,
 		for (s = slots; s; s = g_list_next (s)) {
 			token = gck_slot_get_token_info (s->data);
 			if (is_token_usable (self, s->data, token)) {
-				source = SEAHORSE_SOURCE (seahorse_pkcs11_token_new (s->data));
+				source = SEAHORSE_SOURCE (seahorse_token_new (s->data));
 				self->slots = g_list_append (self->slots, source);
 				gcr_collection_emit_added (GCR_COLLECTION (self), G_OBJECT (source));
 			}
diff --git a/pkcs11/seahorse-pkcs11-certificate-props.c b/pkcs11/seahorse-pkcs11-certificate-props.c
index 164743e..ad86f9c 100644
--- a/pkcs11/seahorse-pkcs11-certificate-props.c
+++ b/pkcs11/seahorse-pkcs11-certificate-props.c
@@ -21,7 +21,7 @@
 
 #include "config.h"
 
-#include "seahorse-pkcs11-certificate.h"
+#include "seahorse-certificate.h"
 #include "seahorse-pkcs11-certificate-props.h"
 
 #include <gcr/gcr.h>
@@ -143,7 +143,7 @@ seahorse_pkcs11_certificate_props_class_init (SeahorsePkcs11CertificatePropsClas
 
 	g_object_class_install_property (gobject_class, PROP_CERTIFICATE,
 	           g_param_spec_object ("certificate", "Certificate", "Certificate to display", 
-	                                SEAHORSE_PKCS11_TYPE_CERTIFICATE, G_PARAM_READWRITE));
+	                                SEAHORSE_TYPE_CERTIFICATE, G_PARAM_READWRITE));
 }
 
 /* -----------------------------------------------------------------------------
diff --git a/pkcs11/seahorse-pkcs11-commands.c b/pkcs11/seahorse-pkcs11-commands.c
index a7e1658..4202e8b 100644
--- a/pkcs11/seahorse-pkcs11-commands.c
+++ b/pkcs11/seahorse-pkcs11-commands.c
@@ -24,8 +24,8 @@
 
 #include "seahorse-pkcs11-commands.h"
 
+#include "seahorse-certificate.h"
 #include "seahorse-pkcs11.h"
-#include "seahorse-pkcs11-certificate.h"
 #include "seahorse-pkcs11-certificate-props.h"
 #include "seahorse-pkcs11-operations.h"
 
@@ -72,8 +72,8 @@ seahorse_pkcs11_commands_show_properties (SeahorseCommands *cmds,
 	gpointer previous;
 	
 	g_return_if_fail (SEAHORSE_PKCS11_IS_COMMANDS (cmds));
-	g_return_if_fail (SEAHORSE_PKCS11_IS_CERTIFICATE (object));
-	
+	g_return_if_fail (SEAHORSE_IS_CERTIFICATE (object));
+
 	/* Try to show an already present window */
 	previous = g_object_get_qdata (G_OBJECT (object), slot_certificate_window);
 	if (GTK_IS_WINDOW (previous)) {
@@ -245,8 +245,8 @@ seahorse_pkcs11_commands_class_init (SeahorsePkcs11CommandsClass *klass)
 
 	slot_certificate_window = g_quark_from_static_string ("seahorse-pkcs11-commands-window");
 
-	commands_predicate.type = SEAHORSE_PKCS11_TYPE_CERTIFICATE;
-		
+	commands_predicate.type = SEAHORSE_TYPE_CERTIFICATE;
+
 	/* Register this as a source of commands */
 	seahorse_registry_register_type (seahorse_registry_get (), SEAHORSE_PKCS11_TYPE_COMMANDS, 
 	                                 SEAHORSE_PKCS11_NAME, "commands", NULL);
diff --git a/pkcs11/seahorse-pkcs11-operations.c b/pkcs11/seahorse-pkcs11-operations.c
index c71b59d..f95039e 100644
--- a/pkcs11/seahorse-pkcs11-operations.c
+++ b/pkcs11/seahorse-pkcs11-operations.c
@@ -23,9 +23,8 @@
 #include "config.h"
 
 #include "seahorse-pkcs11-helpers.h"
-#include "seahorse-pkcs11-object.h"
 #include "seahorse-pkcs11-operations.h"
-#include "seahorse-pkcs11-token.h"
+#include "seahorse-token.h"
 
 #include "seahorse-progress.h"
 
@@ -37,152 +36,6 @@
 #include <gcr/gcr.h>
 
 typedef struct {
-	SeahorsePkcs11Token *token;
-	GCancellable *cancellable;
-	GHashTable *checks;
-	GckSession *session;
-} pkcs11_refresh_closure;
-
-static void
-pkcs11_refresh_free (gpointer data)
-{
-	pkcs11_refresh_closure *closure = data;
-	g_object_unref (closure->token);
-	g_clear_object (&closure->cancellable);
-	g_hash_table_destroy (closure->checks);
-	g_clear_object (&closure->session);
-	g_free (closure);
-}
-
-static gboolean
-remove_each_object (gpointer key,
-                    gpointer value,
-                    gpointer user_data)
-{
-	SeahorsePkcs11Token *token = SEAHORSE_PKCS11_TOKEN (user_data);
-	SeahorsePkcs11Object *object = SEAHORSE_PKCS11_OBJECT (value);
-	seahorse_pkcs11_token_remove_object (token, object);
-	return TRUE;
-}
-
-static void 
-on_refresh_find_objects (GckSession *session,
-                         GAsyncResult *result,
-                         gpointer user_data)
-{
-	GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
-	pkcs11_refresh_closure *closure = g_simple_async_result_get_op_res_gpointer (res);
-	GList *objects, *l;
-	GError *error = NULL;
-	gulong handle;
-
-	objects = gck_session_find_objects_finish (session, result, &error);
-	if (error != NULL) {
-		g_simple_async_result_take_error (res, error);
-	} else {
-
-		/* Remove all objects that were found, from the check table */
-		for (l = objects; l; l = g_list_next (l)) {
-			seahorse_pkcs11_token_receive_object (closure->token, l->data);
-			handle = gck_object_get_handle (l->data);
-			g_hash_table_remove (closure->checks, &handle);
-		}
-
-		/* Remove everything not found from the context */
-		g_hash_table_foreach_remove (closure->checks, remove_each_object, closure->token);
-	}
-
-	g_simple_async_result_complete (res);
-	g_object_unref (res);
-}
-
-static void
-on_refresh_open_session (GObject *source,
-                         GAsyncResult *result,
-                         gpointer user_data)
-{
-	GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
-	pkcs11_refresh_closure *closure = g_simple_async_result_get_op_res_gpointer (res);
-	GError *error = NULL;
-	GckAttributes *attrs;
-
-	closure->session = gck_slot_open_session_finish (GCK_SLOT (source), result, &error);
-	if (!closure->session) {
-		g_simple_async_result_take_error (res, error);
-		g_simple_async_result_complete (res);
-
-	/* Step 2. Load all the objects that we want */
-	} else {
-		attrs = gck_attributes_new ();
-		gck_attributes_add_boolean (attrs, CKA_TOKEN, TRUE);
-		gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_CERTIFICATE);
-		gck_session_find_objects_async (closure->session, attrs, closure->cancellable,
-		                                (GAsyncReadyCallback)on_refresh_find_objects,
-		                                g_object_ref (res));
-		gck_attributes_unref (attrs);
-	}
-
-	g_object_unref (res);
-}
-
-void
-seahorse_pkcs11_refresh_async (SeahorsePkcs11Token *token,
-                               GCancellable *cancellable,
-                               GAsyncReadyCallback callback,
-                               gpointer user_data)
-{
-	GSimpleAsyncResult *res;
-	pkcs11_refresh_closure *closure;
-	GckSlot *slot;
-	GList *objects, *l;
-	gulong handle;
-
-	res = g_simple_async_result_new (G_OBJECT (token), callback, user_data,
-	                                 seahorse_pkcs11_refresh_async);
-	closure = g_new0 (pkcs11_refresh_closure, 1);
-	closure->checks = g_hash_table_new_full (seahorse_pkcs11_ulong_hash,
-	                                         seahorse_pkcs11_ulong_equal,
-	                                         g_free, g_object_unref);
-	closure->token = g_object_ref (token);
-	closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
-	g_simple_async_result_set_op_res_gpointer (res, closure, pkcs11_refresh_free);
-
-	/* Make note of all the objects that were there */
-	objects = gcr_collection_get_objects (GCR_COLLECTION (token));
-	for (l = objects; l; l = g_list_next (l)) {
-		if (g_object_class_find_property (G_OBJECT_GET_CLASS (l->data), "pkcs11-handle")) {
-			g_object_get (l->data, "pkcs11-handle", &handle, NULL);
-			g_hash_table_insert (closure->checks,
-			                     g_memdup (&handle, sizeof (handle)),
-			                     g_object_ref (l->data));
-		}
-	}
-	g_list_free (objects);
-
-	/* Step 1. Load the session */
-	slot = seahorse_pkcs11_token_get_slot (closure->token);
-	gck_slot_open_session_async (slot, GCK_SESSION_READ_WRITE, closure->cancellable,
-	                             on_refresh_open_session, g_object_ref (res));
-
-	g_object_unref (res);
-}
-
-gboolean
-seahorse_pkcs11_refresh_finish (SeahorsePkcs11Token *token,
-                                GAsyncResult *result,
-                                GError **error)
-{
-	g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (token),
-	                      seahorse_pkcs11_refresh_async), FALSE);
-
-	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
-		return FALSE;
-
-	return TRUE;
-
-}
-
-typedef struct {
 	GQueue *objects;
 	GCancellable *cancellable;
 } pkcs11_delete_closure;
@@ -207,8 +60,8 @@ on_delete_object_completed (GObject *source,
 	GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
 	pkcs11_delete_closure *closure = g_simple_async_result_get_op_res_gpointer (res);
 	GError *error = NULL;
-	SeahorseObject *object;
-	SeahorsePkcs11Token *pkcs11_token;
+	GckObject *object;
+	SeahorseToken *pkcs11_token;
 
 	object = g_queue_pop_head (closure->objects);
 	seahorse_progress_end (closure->cancellable, object);
@@ -226,8 +79,9 @@ on_delete_object_completed (GObject *source,
 	}
 
 	if (error == NULL) {
-		pkcs11_token = SEAHORSE_PKCS11_TOKEN (seahorse_object_get_source (object));
-		seahorse_pkcs11_token_remove_object (pkcs11_token, SEAHORSE_PKCS11_OBJECT (object));
+		g_object_get (object, "source", &pkcs11_token, NULL);
+		g_return_if_fail (SEAHORSE_IS_TOKEN (pkcs11_token));
+		seahorse_token_remove_object (pkcs11_token, GCK_OBJECT (object));
 		pkcs11_delete_one_object (res);
 	}
 
@@ -239,7 +93,7 @@ static void
 pkcs11_delete_one_object (GSimpleAsyncResult *res)
 {
 	pkcs11_delete_closure *closure = g_simple_async_result_get_op_res_gpointer (res);
-	SeahorseObject *object;
+	GckObject *object;
 
 	if (g_queue_is_empty (closure->objects)) {
 		g_simple_async_result_complete_in_idle (res);
@@ -249,8 +103,8 @@ pkcs11_delete_one_object (GSimpleAsyncResult *res)
 	object = g_queue_peek_head (closure->objects);
 	seahorse_progress_begin (closure->cancellable, object);
 
-	gck_object_destroy_async (seahorse_pkcs11_object_get_pkcs11_object (SEAHORSE_PKCS11_OBJECT (object)),
-	                          closure->cancellable, on_delete_object_completed, g_object_ref (res));
+	gck_object_destroy_async (object, closure->cancellable,
+	                          on_delete_object_completed, g_object_ref (res));
 }
 
 void
diff --git a/pkcs11/seahorse-pkcs11-operations.h b/pkcs11/seahorse-pkcs11-operations.h
index d3a876f..a1b94e7 100644
--- a/pkcs11/seahorse-pkcs11-operations.h
+++ b/pkcs11/seahorse-pkcs11-operations.h
@@ -25,18 +25,6 @@
 
 #include <glib-object.h>
 
-#include "seahorse-pkcs11-object.h"
-#include "seahorse-pkcs11-token.h"
-
-void          seahorse_pkcs11_refresh_async    (SeahorsePkcs11Token *token,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-
-gboolean      seahorse_pkcs11_refresh_finish   (SeahorsePkcs11Token *token,
-                                                GAsyncResult *result,
-                                                GError **error);
-
 void          seahorse_pkcs11_delete_async     (GList *objects,
                                                 GCancellable *cancellable,
                                                 GAsyncReadyCallback callback,
diff --git a/pkcs11/seahorse-token.c b/pkcs11/seahorse-token.c
new file mode 100644
index 0000000..cb5fd12
--- /dev/null
+++ b/pkcs11/seahorse-token.c
@@ -0,0 +1,439 @@
+/*
+ * Seahorse
+ *
+ * Copyright (C) 2006 Stefan Walter
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ * You should have received a copy of the GNU 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 <stdlib.h>
+#include <string.h>
+#include <libintl.h>
+
+#include <glib/gi18n.h>
+
+#include "seahorse-certificate.h"
+#include "seahorse-pkcs11.h"
+#include "seahorse-pkcs11-helpers.h"
+#include "seahorse-pkcs11-operations.h"
+#include "seahorse-token.h"
+
+#include "seahorse-source.h"
+#include "seahorse-registry.h"
+#include "seahorse-util.h"
+
+enum {
+	PROP_0,
+	PROP_LABEL,
+	PROP_DESCRIPTION,
+	PROP_ICON,
+	PROP_SLOT,
+	PROP_FLAGS
+};
+
+struct _SeahorseTokenPrivate {
+	GckSlot *slot;
+	GHashTable *objects;
+};
+
+static void          receive_object                      (SeahorseToken *self,
+                                                          GckObject *obj);
+
+static void          seahorse_token_source_iface  (SeahorseSourceIface *iface);
+
+static void          seahorse_token_collection_iface    (GcrCollectionIface *iface);
+
+G_DEFINE_TYPE_EXTENDED (SeahorseToken, seahorse_token, G_TYPE_OBJECT, 0,
+                        G_IMPLEMENT_INTERFACE (GCR_TYPE_COLLECTION, seahorse_token_collection_iface);
+                        G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_SOURCE, seahorse_token_source_iface);
+);
+
+
+typedef struct {
+	SeahorseToken *token;
+	GCancellable *cancellable;
+	GHashTable *checks;
+	GckEnumerator *enumerator;
+} pkcs11_refresh_closure;
+
+static void
+pkcs11_refresh_free (gpointer data)
+{
+	pkcs11_refresh_closure *closure = data;
+	g_object_unref (closure->token);
+	g_clear_object (&closure->cancellable);
+	g_hash_table_destroy (closure->checks);
+	g_clear_object (&closure->enumerator);
+	g_free (closure);
+}
+
+static gboolean
+remove_each_object (gpointer key,
+                    gpointer value,
+                    gpointer user_data)
+{
+	SeahorseToken *token = SEAHORSE_TOKEN (user_data);
+	GckObject *object = GCK_OBJECT (value);
+	seahorse_token_remove_object (token, object);
+	return TRUE;
+}
+
+static void
+on_refresh_next_objects (GObject *source,
+                         GAsyncResult *result,
+                         gpointer user_data)
+{
+	GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+	pkcs11_refresh_closure *closure = g_simple_async_result_get_op_res_gpointer (res);
+	GError *error = NULL;
+	gulong handle;
+	GList *objects;
+	GList *l;
+
+	objects = gck_enumerator_next_finish (closure->enumerator, result, &error);
+
+	/* Remove all objects that were found, from the check table */
+	for (l = objects; l; l = g_list_next (l)) {
+		receive_object (closure->token, l->data);
+		handle = gck_object_get_handle (l->data);
+		g_hash_table_remove (closure->checks, &handle);
+	}
+
+	gck_list_unref_free (objects);
+
+	/* If there was an error, report it */
+	if (error != NULL) {
+		g_simple_async_result_take_error (res, error);
+		g_simple_async_result_complete (res);
+
+	/* Otherwise if there were objects go back and get more */
+	} else if (objects != NULL) {
+		gck_enumerator_next_async (closure->enumerator, 16, closure->cancellable,
+		                           on_refresh_next_objects, g_object_ref (res));
+
+	/* Otherwise we're done, remove everything not found */
+	} else {
+		g_hash_table_foreach_remove (closure->checks, remove_each_object, closure->token);
+		g_simple_async_result_complete (res);
+	}
+
+	g_object_unref (res);
+}
+
+void
+seahorse_token_refresh_async (SeahorseToken *token,
+                              GCancellable *cancellable,
+                              GAsyncReadyCallback callback,
+                              gpointer user_data)
+{
+	GSimpleAsyncResult *res;
+	pkcs11_refresh_closure *closure;
+	GckAttributes *attrs;
+	GckSlot *slot;
+	GList *objects, *l;
+	gulong handle;
+
+	res = g_simple_async_result_new (G_OBJECT (token), callback, user_data,
+	                                 seahorse_token_refresh_async);
+	closure = g_new0 (pkcs11_refresh_closure, 1);
+	closure->checks = g_hash_table_new_full (seahorse_pkcs11_ulong_hash,
+	                                         seahorse_pkcs11_ulong_equal,
+	                                         g_free, g_object_unref);
+	closure->token = g_object_ref (token);
+	closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
+	g_simple_async_result_set_op_res_gpointer (res, closure, pkcs11_refresh_free);
+
+	/* Make note of all the objects that were there */
+	objects = gcr_collection_get_objects (GCR_COLLECTION (token));
+	for (l = objects; l; l = g_list_next (l)) {
+		handle = gck_object_get_handle (l->data);
+		g_hash_table_insert (closure->checks,
+		                     g_memdup (&handle, sizeof (handle)),
+		                     g_object_ref (l->data));
+	}
+	g_list_free (objects);
+
+	attrs = gck_attributes_new ();
+	gck_attributes_add_boolean (attrs, CKA_TOKEN, TRUE);
+	gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_CERTIFICATE);
+
+	slot = seahorse_token_get_slot (closure->token);
+	closure->enumerator = gck_slot_enumerate_objects (slot, attrs, GCK_SESSION_READ_WRITE);
+	g_return_if_fail (closure->enumerator != NULL);
+
+	gck_attributes_unref (attrs);
+
+	/* This enumerator creates objects of type SeahorseCertificate */
+	gck_enumerator_set_object_type (closure->enumerator, SEAHORSE_TYPE_CERTIFICATE);
+
+	gck_enumerator_next_async (closure->enumerator, 16, closure->cancellable,
+	                           on_refresh_next_objects, g_object_ref (res));
+
+	g_object_unref (res);
+}
+
+gboolean
+seahorse_token_refresh_finish (SeahorseToken *token,
+                               GAsyncResult *result,
+                               GError **error)
+{
+	g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (token),
+	                      seahorse_token_refresh_async), FALSE);
+
+	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+		return FALSE;
+
+	return TRUE;
+
+}
+
+static void
+seahorse_token_init (SeahorseToken *self)
+{
+	self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, SEAHORSE_TYPE_TOKEN, SeahorseTokenPrivate));
+	self->pv->objects = g_hash_table_new_full (seahorse_pkcs11_ulong_hash,
+	                                           seahorse_pkcs11_ulong_equal,
+	                                           g_free, g_object_unref);
+}
+
+static void
+seahorse_token_constructed (GObject *obj)
+{
+	SeahorseToken *self = SEAHORSE_TOKEN (obj);
+
+	G_OBJECT_CLASS (seahorse_token_parent_class)->constructed (obj);
+
+	seahorse_token_refresh_async (self, NULL, NULL, NULL);
+}
+
+static void
+seahorse_token_get_property (GObject *object,
+                             guint prop_id,
+                             GValue *value,
+                             GParamSpec *pspec)
+{
+	SeahorseToken *self = SEAHORSE_TOKEN (object);
+	GckTokenInfo *token;
+
+	switch (prop_id) {
+	case PROP_LABEL:
+		token = gck_slot_get_token_info (self->pv->slot);
+		if (token == NULL)
+			g_value_set_string (value, _("Unknown"));
+		else
+			g_value_set_string (value, token->label);
+		gck_token_info_free (token);
+		break;
+	case PROP_DESCRIPTION:
+		token = gck_slot_get_token_info (self->pv->slot);
+		if (token == NULL)
+			g_value_set_string (value, NULL);
+		else
+			g_value_set_string (value, token->manufacturer_id);
+		gck_token_info_free (token);
+		break;
+	case PROP_ICON:
+		token = gck_slot_get_token_info (self->pv->slot);
+		if (token == NULL)
+			g_value_take_object (value, g_themed_icon_new (GTK_STOCK_DIALOG_QUESTION));
+		else
+			g_value_take_object (value, gcr_icon_for_token (token));
+		gck_token_info_free (token);
+		break;
+	case PROP_SLOT:
+		g_value_set_object (value, self->pv->slot);
+		break;
+	case PROP_FLAGS:
+		g_value_set_uint (value, 0);
+		break;
+	}
+}
+
+static void
+seahorse_token_set_property (GObject *object,
+                             guint prop_id,
+                             const GValue *value,
+                             GParamSpec *pspec)
+{
+	SeahorseToken *self = SEAHORSE_TOKEN (object);
+
+	switch (prop_id) {
+	case PROP_SLOT:
+		g_return_if_fail (!self->pv->slot);
+		self->pv->slot = g_value_get_object (value);
+		g_return_if_fail (self->pv->slot);
+		g_object_ref (self->pv->slot);
+		break;
+	};
+}
+
+static void
+seahorse_token_dispose (GObject *obj)
+{
+	SeahorseToken *self = SEAHORSE_TOKEN (obj);
+
+	/* The keyring object */
+	if (self->pv->slot)
+		g_object_unref (self->pv->slot);
+	self->pv->slot = NULL;
+
+	G_OBJECT_CLASS (seahorse_token_parent_class)->dispose (obj);
+}
+
+static void
+seahorse_token_finalize (GObject *obj)
+{
+	SeahorseToken *self = SEAHORSE_TOKEN (obj);
+
+	g_hash_table_destroy (self->pv->objects);
+	g_assert (self->pv->slot == NULL);
+
+	G_OBJECT_CLASS (seahorse_token_parent_class)->finalize (obj);
+}
+
+static void
+seahorse_token_class_init (SeahorseTokenClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (SeahorseTokenPrivate));
+
+	gobject_class->constructed = seahorse_token_constructed;
+	gobject_class->dispose = seahorse_token_dispose;
+	gobject_class->finalize = seahorse_token_finalize;
+	gobject_class->set_property = seahorse_token_set_property;
+	gobject_class->get_property = seahorse_token_get_property;
+
+	g_object_class_override_property (gobject_class, PROP_LABEL, "label");
+	g_object_class_override_property (gobject_class, PROP_DESCRIPTION, "description");
+	g_object_class_override_property (gobject_class, PROP_ICON, "icon");
+
+	g_object_class_install_property (gobject_class, PROP_SLOT,
+	         g_param_spec_object ("slot", "Slot", "Pkcs#11 SLOT",
+	                              GCK_TYPE_SLOT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+	g_object_class_install_property (gobject_class, PROP_FLAGS,
+	         g_param_spec_uint ("flags", "Flags", "Object Token flags.",
+	                            0, G_MAXUINT, 0, G_PARAM_READABLE));
+}
+
+static void
+seahorse_token_source_iface (SeahorseSourceIface *iface)
+{
+
+}
+
+static guint
+seahorse_token_get_length (GcrCollection *collection)
+{
+	SeahorseToken *self = SEAHORSE_TOKEN (collection);
+	return g_hash_table_size (self->pv->objects);
+}
+
+static GList *
+seahorse_token_get_objects (GcrCollection *collection)
+{
+	SeahorseToken *self = SEAHORSE_TOKEN (collection);
+	return g_hash_table_get_values (self->pv->objects);
+}
+
+static gboolean
+seahorse_token_contains (GcrCollection *collection,
+                         GObject *object)
+{
+	SeahorseToken *self = SEAHORSE_TOKEN (collection);
+	gulong handle;
+
+	if (!GCK_IS_OBJECT (object))
+		return FALSE;
+
+	handle = gck_object_get_handle (GCK_OBJECT (object));
+	return g_hash_table_lookup (self->pv->objects, &handle) == object;
+}
+
+static void
+seahorse_token_collection_iface (GcrCollectionIface *iface)
+{
+	iface->get_length = seahorse_token_get_length;
+	iface->get_objects = seahorse_token_get_objects;
+	iface->contains = seahorse_token_contains;
+}
+
+/* --------------------------------------------------------------------------
+ * PUBLIC
+ */
+
+SeahorseToken *
+seahorse_token_new (GckSlot *slot)
+{
+	return g_object_new (SEAHORSE_TYPE_TOKEN,
+	                     "slot", slot,
+	                     NULL);
+}
+
+GckSlot *
+seahorse_token_get_slot (SeahorseToken *self)
+{
+	g_return_val_if_fail (SEAHORSE_IS_TOKEN (self), NULL);
+	return self->pv->slot;
+}
+
+static void
+receive_object (SeahorseToken *self,
+                GckObject *obj)
+{
+	GckAttributes *attrs;
+	GckObject *prev;
+	gulong handle;
+
+	g_return_if_fail (SEAHORSE_IS_TOKEN (self));
+
+	handle = gck_object_get_handle (obj);
+	prev = g_hash_table_lookup (self->pv->objects, &handle);
+	if (prev != NULL) {
+		attrs = gck_object_attributes_get_attributes (GCK_OBJECT_ATTRIBUTES (obj));
+		gck_object_attributes_set_attributes (GCK_OBJECT_ATTRIBUTES (prev), attrs);
+		gck_attributes_unref (attrs);
+	} else {
+		g_hash_table_insert (self->pv->objects,
+		                     g_memdup (&handle, sizeof (handle)),
+		                     g_object_ref (obj));
+		gcr_collection_emit_added (GCR_COLLECTION (self), G_OBJECT (obj));
+	}
+}
+
+void
+seahorse_token_remove_object (SeahorseToken *self,
+                              GckObject *object)
+{
+	gulong handle;
+
+	g_return_if_fail (SEAHORSE_IS_TOKEN (self));
+	g_return_if_fail (GCK_IS_OBJECT (object));
+
+	g_object_ref (object);
+
+	handle = gck_object_get_handle (object);
+	g_return_if_fail (g_hash_table_lookup (self->pv->objects, &handle) == object);
+
+	g_hash_table_remove (self->pv->objects, &handle);
+	gcr_collection_emit_removed (GCR_COLLECTION (self), G_OBJECT (object));
+
+	g_object_unref (object);
+}
diff --git a/pkcs11/seahorse-token.h b/pkcs11/seahorse-token.h
new file mode 100644
index 0000000..cf2ff55
--- /dev/null
+++ b/pkcs11/seahorse-token.h
@@ -0,0 +1,66 @@
+/*
+ * Seahorse
+ *
+ * Copyright (C) 2008 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ * You should have received a copy of the GNU 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 __SEAHORSE_TOKEN_H__
+#define __SEAHORSE_TOKEN_H__
+
+#include <gck/gck.h>
+
+#define SEAHORSE_TYPE_TOKEN            (seahorse_token_get_type ())
+#define SEAHORSE_TOKEN(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_TYPE_TOKEN, SeahorseToken))
+#define SEAHORSE_TOKEN_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_TYPE_TOKEN, SeahorseTokenClass))
+#define SEAHORSE_IS_TOKEN(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_TYPE_TOKEN))
+#define SEAHORSE_IS_TOKEN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_TYPE_TOKEN))
+#define SEAHORSE_TOKEN_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_TYPE_TOKEN, SeahorseTokenClass))
+
+typedef struct _SeahorseToken SeahorseToken;
+typedef struct _SeahorseTokenClass SeahorseTokenClass;
+typedef struct _SeahorseTokenPrivate SeahorseTokenPrivate;
+
+struct _SeahorseToken {
+	GObject parent;
+	SeahorseTokenPrivate *pv;
+};
+
+struct _SeahorseTokenClass {
+	GObjectClass parent_class;
+};
+
+GType                  seahorse_token_get_type          (void);
+
+SeahorseToken *        seahorse_token_new               (GckSlot *slot);
+
+GckSlot *              seahorse_token_get_slot          (SeahorseToken *self);
+
+void                   seahorse_token_remove_object     (SeahorseToken *self,
+                                                         GckObject *object);
+
+void                   seahorse_token_refresh_async     (SeahorseToken *self,
+                                                         GCancellable *cancellable,
+                                                         GAsyncReadyCallback callback,
+                                                         gpointer user_data);
+
+gboolean               seahorse_token_refresh_finish    (SeahorseToken *self,
+                                                         GAsyncResult *result,
+                                                         GError **error);
+
+#endif /* __SEAHORSE_TOKEN_H__ */



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