[seahorse] pkcs11: Matching certificates and keys into a single item
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [seahorse] pkcs11: Matching certificates and keys into a single item
- Date: Thu, 3 Nov 2011 13:39:27 +0000 (UTC)
commit 57d1e9d0ff77cfb26654df69becaf53b617442ad
Author: Stef Walter <stefw collabora co uk>
Date: Thu Nov 3 13:29:08 2011 +0100
pkcs11: Matching certificates and keys into a single item
* Also fix regression of setting appropriate place on pkcs11 items
pkcs11/seahorse-certificate.c | 105 ++++++++++++-
pkcs11/seahorse-certificate.h | 10 +-
pkcs11/seahorse-private-key.c | 53 ++++++-
pkcs11/seahorse-private-key.h | 8 +-
pkcs11/seahorse-token.c | 363 +++++++++++++++++++++++++++++++----------
5 files changed, 441 insertions(+), 98 deletions(-)
---
diff --git a/pkcs11/seahorse-certificate.c b/pkcs11/seahorse-certificate.c
index 664daaa..9572189 100644
--- a/pkcs11/seahorse-certificate.c
+++ b/pkcs11/seahorse-certificate.c
@@ -26,6 +26,7 @@
#include "seahorse-pkcs11.h"
#include "seahorse-pkcs11-actions.h"
#include "seahorse-pkcs11-helpers.h"
+#include "seahorse-private-key.h"
#include "seahorse-token.h"
#include "seahorse-types.h"
@@ -49,7 +50,9 @@ enum {
PROP_PLACE,
PROP_ATTRIBUTES,
PROP_FLAGS,
- PROP_ACTIONS
+ PROP_ACTIONS,
+ PROP_ICON,
+ PROP_PRIVATE_KEY
};
struct _SeahorseCertificatePrivate {
@@ -57,6 +60,8 @@ struct _SeahorseCertificatePrivate {
GckAttributes *attributes;
GckAttribute der_value;
GtkActionGroup *actions;
+ SeahorsePrivateKey *private_key;
+ GIcon *icon;
};
static void seahorse_certificate_certificate_iface (GcrCertificateIface *iface);
@@ -69,6 +74,27 @@ G_DEFINE_TYPE_WITH_CODE (SeahorseCertificate, seahorse_certificate, GCK_TYPE_OBJ
);
static void
+update_icon (SeahorseCertificate *self)
+{
+ GEmblem *emblem;
+ GIcon *eicon;
+ GIcon *icon;
+
+ g_clear_object (&self->pv->icon);
+ icon = gcr_certificate_get_icon (GCR_CERTIFICATE (self));
+ if (self->pv->private_key) {
+ eicon = g_themed_icon_new (GCR_ICON_KEY);
+ emblem = g_emblem_new (eicon);
+ self->pv->icon = g_emblemed_icon_new (icon, emblem);
+ g_object_unref (icon);
+ g_object_unref (eicon);
+ g_object_unref (emblem);
+ } else {
+ self->pv->icon = icon;
+ }
+}
+
+static void
seahorse_certificate_init (SeahorseCertificate *self)
{
self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, SEAHORSE_TYPE_CERTIFICATE, SeahorseCertificatePrivate));
@@ -88,6 +114,15 @@ seahorse_certificate_notify (GObject *obj,
G_OBJECT_CLASS (seahorse_certificate_parent_class)->notify (obj, pspec);
}
+static void
+seahorse_certificate_dispose (GObject *obj)
+{
+ SeahorseCertificate *self = SEAHORSE_CERTIFICATE (obj);
+
+ g_clear_object (&self->pv->private_key);
+
+ G_OBJECT_CLASS (seahorse_certificate_parent_class)->dispose (obj);
+}
static void
seahorse_certificate_finalize (GObject *obj)
@@ -125,6 +160,12 @@ seahorse_certificate_get_property (GObject *obj,
case PROP_ACTIONS:
g_value_set_object (value, self->pv->actions);
break;
+ case PROP_ICON:
+ g_value_set_object (value, seahorse_certificate_get_icon (self));
+ break;
+ case PROP_PRIVATE_KEY:
+ g_value_set_object (value, seahorse_certificate_get_private_key (self));
+ break;
default:
gcr_certificate_mixin_get_property (obj, prop_id, value, pspec);
break;
@@ -142,8 +183,13 @@ seahorse_certificate_set_property (GObject *obj,
switch (prop_id) {
case PROP_PLACE:
- g_return_if_fail (self->pv->token == NULL);
- self->pv->token = g_value_dup_object (value);
+ if (self->pv->token)
+ g_object_remove_weak_pointer (G_OBJECT (self->pv->token),
+ (gpointer *)&self->pv->token);
+ self->pv->token = g_value_get_object (value);
+ if (self->pv->token)
+ g_object_add_weak_pointer (G_OBJECT (self->pv->token),
+ (gpointer *)&self->pv->token);
break;
case PROP_ATTRIBUTES:
if (self->pv->attributes)
@@ -157,6 +203,9 @@ seahorse_certificate_set_property (GObject *obj,
gck_attribute_init_copy (&self->pv->der_value, der_value);
}
break;
+ case PROP_PRIVATE_KEY:
+ seahorse_certificate_set_private_key (self, g_value_get_object (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
@@ -170,6 +219,7 @@ seahorse_certificate_class_init (SeahorseCertificateClass *klass)
g_type_class_add_private (klass, sizeof (SeahorseCertificatePrivate));
+ gobject_class->dispose = seahorse_certificate_dispose;
gobject_class->finalize = seahorse_certificate_finalize;
gobject_class->set_property = seahorse_certificate_set_property;
gobject_class->get_property = seahorse_certificate_get_property;
@@ -177,7 +227,7 @@ seahorse_certificate_class_init (SeahorseCertificateClass *klass)
g_object_class_install_property (gobject_class, PROP_PLACE,
g_param_spec_object ("place", "place", "place", SEAHORSE_TYPE_TOKEN,
- G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_FLAGS,
g_param_spec_flags ("flags", "flags", "flags", SEAHORSE_TYPE_FLAGS, SEAHORSE_FLAG_NONE,
@@ -187,6 +237,11 @@ seahorse_certificate_class_init (SeahorseCertificateClass *klass)
g_param_spec_object ("actions", "Actions", "Actions", GTK_TYPE_ACTION_GROUP,
G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ g_object_class_install_property (gobject_class, PROP_PRIVATE_KEY,
+ g_param_spec_object ("private-key", "Private key", "Private key associated with certificate",
+ SEAHORSE_TYPE_PRIVATE_KEY, G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+
+ g_object_class_override_property (gobject_class, PROP_ICON, "icon");
g_object_class_override_property (gobject_class, PROP_ATTRIBUTES, "attributes");
gcr_certificate_mixin_class_init (gobject_class);
@@ -215,3 +270,45 @@ seahorse_certificate_object_attributes_iface (GckObjectAttributesIface *iface)
iface->attribute_types = REQUIRED_ATTRS;
iface->n_attribute_types = G_N_ELEMENTS (REQUIRED_ATTRS);
}
+
+GIcon *
+seahorse_certificate_get_icon (SeahorseCertificate *self)
+{
+ g_return_val_if_fail (SEAHORSE_IS_CERTIFICATE (self), NULL);
+
+ if (!self->pv->icon)
+ update_icon (self);
+
+ return self->pv->icon;
+}
+
+SeahorsePrivateKey *
+seahorse_certificate_get_private_key (SeahorseCertificate *self)
+{
+ g_return_val_if_fail (SEAHORSE_IS_CERTIFICATE (self), NULL);
+ return self->pv->private_key;
+}
+
+void
+seahorse_certificate_set_private_key (SeahorseCertificate *self,
+ SeahorsePrivateKey *private_key)
+{
+ GObject *obj;
+
+ g_return_if_fail (SEAHORSE_IS_CERTIFICATE (self));
+ g_return_if_fail (private_key == NULL || SEAHORSE_IS_PRIVATE_KEY (private_key));
+
+ if (self->pv->private_key)
+ g_object_remove_weak_pointer (G_OBJECT (private_key),
+ (gpointer *)self->pv->private_key);
+ self->pv->private_key = private_key;
+ if (self->pv->private_key)
+ g_object_add_weak_pointer (G_OBJECT (private_key),
+ (gpointer *)self->pv->private_key);
+
+ obj = G_OBJECT (self);
+ g_object_notify (obj, "private-key");
+ g_clear_object (&self->pv->icon);
+ g_object_notify (obj, "icon");
+ g_object_notify (obj, "description");
+}
diff --git a/pkcs11/seahorse-certificate.h b/pkcs11/seahorse-certificate.h
index 589c1ab..f6f4d8e 100644
--- a/pkcs11/seahorse-certificate.h
+++ b/pkcs11/seahorse-certificate.h
@@ -36,6 +36,7 @@
typedef struct _SeahorseCertificate SeahorseCertificate;
typedef struct _SeahorseCertificateClass SeahorseCertificateClass;
typedef struct _SeahorseCertificatePrivate SeahorseCertificatePrivate;
+typedef struct _SeahorsePrivateKey SeahorsePrivateKey;
struct _SeahorseCertificate {
GckObject parent;
@@ -48,12 +49,11 @@ struct _SeahorseCertificateClass {
GType seahorse_certificate_get_type (void) G_GNUC_CONST;
-void seahorse_certificate_realize (SeahorseCertificate *self);
+GIcon * seahorse_certificate_get_icon (SeahorseCertificate *self);
-guint seahorse_certificate_get_validity (SeahorseCertificate* self);
+SeahorsePrivateKey * seahorse_certificate_get_private_key (SeahorseCertificate *self);
-guint seahorse_certificate_get_trust (SeahorseCertificate* self);
-
-gulong seahorse_certificate_get_expires (SeahorseCertificate* self);
+void seahorse_certificate_set_private_key (SeahorseCertificate *self,
+ SeahorsePrivateKey *private_key);
#endif /* __SEAHORSE_CERTIFICATE_H__ */
diff --git a/pkcs11/seahorse-private-key.c b/pkcs11/seahorse-private-key.c
index 58e0aeb..c869458 100644
--- a/pkcs11/seahorse-private-key.c
+++ b/pkcs11/seahorse-private-key.c
@@ -50,13 +50,15 @@ enum {
PROP_PLACE,
PROP_ATTRIBUTES,
PROP_FLAGS,
- PROP_ACTIONS
+ PROP_ACTIONS,
+ PROP_CERTIFICATE,
};
struct _SeahorsePrivateKeyPrivate {
SeahorseToken *token;
GckAttributes *attributes;
GtkActionGroup *actions;
+ SeahorseCertificate *certificate;
};
static void seahorse_private_key_object_attributes_iface (GckObjectAttributesIface *iface);
@@ -106,6 +108,9 @@ seahorse_private_key_get_property (GObject *obj,
case PROP_ACTIONS:
g_value_set_object (value, self->pv->actions);
break;
+ case PROP_CERTIFICATE:
+ g_value_set_object (value, seahorse_private_key_get_certificate (self));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
@@ -122,14 +127,22 @@ seahorse_private_key_set_property (GObject *obj,
switch (prop_id) {
case PROP_PLACE:
- g_return_if_fail (self->pv->token == NULL);
- self->pv->token = g_value_dup_object (value);
+ if (self->pv->token)
+ g_object_remove_weak_pointer (G_OBJECT (self->pv->token),
+ (gpointer *)&self->pv->token);
+ self->pv->token = g_value_get_object (value);
+ if (self->pv->token)
+ g_object_add_weak_pointer (G_OBJECT (self->pv->token),
+ (gpointer *)&self->pv->token);
break;
case PROP_ATTRIBUTES:
if (self->pv->attributes)
gck_attributes_unref (self->pv->attributes);
self->pv->attributes = g_value_dup_boxed (value);
break;
+ case PROP_CERTIFICATE:
+ seahorse_private_key_set_certificate (self, g_value_get_object (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
@@ -149,7 +162,7 @@ seahorse_private_key_class_init (SeahorsePrivateKeyClass *klass)
g_object_class_install_property (gobject_class, PROP_PLACE,
g_param_spec_object ("place", "place", "place", SEAHORSE_TYPE_TOKEN,
- G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_FLAGS,
g_param_spec_flags ("flags", "flags", "flags", SEAHORSE_TYPE_FLAGS, SEAHORSE_FLAG_NONE,
@@ -159,6 +172,10 @@ seahorse_private_key_class_init (SeahorsePrivateKeyClass *klass)
g_param_spec_object ("actions", "Actions", "Actions", GTK_TYPE_ACTION_GROUP,
G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ g_object_class_install_property (gobject_class, PROP_CERTIFICATE,
+ g_param_spec_object ("certificate", "Certificate", "Certificate associated with this private key",
+ SEAHORSE_TYPE_CERTIFICATE, G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+
g_object_class_override_property (gobject_class, PROP_ATTRIBUTES, "attributes");
}
@@ -168,3 +185,31 @@ seahorse_private_key_object_attributes_iface (GckObjectAttributesIface *iface)
iface->attribute_types = REQUIRED_ATTRS;
iface->n_attribute_types = G_N_ELEMENTS (REQUIRED_ATTRS);
}
+
+SeahorseCertificate *
+seahorse_private_key_get_certificate (SeahorsePrivateKey *self)
+{
+ g_return_val_if_fail (SEAHORSE_IS_PRIVATE_KEY (self), NULL);
+ return self->pv->certificate;
+}
+
+void
+seahorse_private_key_set_certificate (SeahorsePrivateKey *self,
+ SeahorseCertificate *certificate)
+{
+ GObject *obj;
+
+ g_return_if_fail (SEAHORSE_IS_PRIVATE_KEY (self));
+ g_return_if_fail (certificate == NULL || SEAHORSE_IS_CERTIFICATE (certificate));
+
+ if (self->pv->certificate)
+ g_object_remove_weak_pointer (G_OBJECT (certificate),
+ (gpointer *)self->pv->certificate);
+ self->pv->certificate = certificate;
+ if (self->pv->certificate)
+ g_object_add_weak_pointer (G_OBJECT (certificate),
+ (gpointer *)self->pv->certificate);
+
+ obj = G_OBJECT (self);
+ g_object_notify (obj, "certificate");
+}
diff --git a/pkcs11/seahorse-private-key.h b/pkcs11/seahorse-private-key.h
index b15d4c4..f80aba7 100644
--- a/pkcs11/seahorse-private-key.h
+++ b/pkcs11/seahorse-private-key.h
@@ -26,6 +26,8 @@
#include <glib-object.h>
+#include "seahorse-certificate.h"
+
#define SEAHORSE_TYPE_PRIVATE_KEY (seahorse_private_key_get_type ())
#define SEAHORSE_PRIVATE_KEY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_TYPE_PRIVATE_KEY, SeahorsePrivateKey))
#define SEAHORSE_PRIVATE_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_TYPE_PRIVATE_KEY, SeahorsePrivateKeyClass))
@@ -33,7 +35,6 @@
#define SEAHORSE_IS_PRIVATE_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_TYPE_PRIVATE_KEY))
#define SEAHORSE_PRIVATE_KEY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_TYPE_PRIVATE_KEY, SeahorsePrivateKeyClass))
-typedef struct _SeahorsePrivateKey SeahorsePrivateKey;
typedef struct _SeahorsePrivateKeyClass SeahorsePrivateKeyClass;
typedef struct _SeahorsePrivateKeyPrivate SeahorsePrivateKeyPrivate;
@@ -48,4 +49,9 @@ struct _SeahorsePrivateKeyClass {
GType seahorse_private_key_get_type (void) G_GNUC_CONST;
+SeahorseCertificate * seahorse_private_key_get_certificate (SeahorsePrivateKey *self);
+
+void seahorse_private_key_set_certificate (SeahorsePrivateKey *self,
+ SeahorseCertificate *certificate);
+
#endif /* __SEAHORSE_PRIVATE_KEY_H__ */
diff --git a/pkcs11/seahorse-token.c b/pkcs11/seahorse-token.c
index 1e98d49..ae79576 100644
--- a/pkcs11/seahorse-token.c
+++ b/pkcs11/seahorse-token.c
@@ -58,15 +58,15 @@ enum {
struct _SeahorseTokenPrivate {
GckSlot *slot;
gchar *uri;
- GHashTable *objects;
GckTokenInfo *info;
GckSession *session;
GtkActionGroup *actions;
+ GHashTable *object_for_handle;
+ GHashTable *objects_for_id;
+ GHashTable *id_for_object;
+ GHashTable *objects_visible;
};
-static void receive_object (SeahorseToken *self,
- GckObject *obj);
-
static void seahorse_token_place_iface (SeahorsePlaceIface *iface);
static void seahorse_token_collection_iface (GcrCollectionIface *iface);
@@ -76,6 +76,254 @@ G_DEFINE_TYPE_EXTENDED (SeahorseToken, seahorse_token, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_PLACE, seahorse_token_place_iface);
);
+static void
+update_token_info (SeahorseToken *self)
+{
+ GckTokenInfo *info;
+ GObject *obj;
+
+ info = gck_slot_get_token_info (self->pv->slot);
+ if (info != NULL) {
+ gck_token_info_free (self->pv->info);
+ self->pv->info = info;
+
+ obj = G_OBJECT (self);
+ g_object_notify (obj, "info");
+ g_object_notify (obj, "lockable");
+ g_object_notify (obj, "unlockable");
+ }
+}
+
+static void
+update_id_map (SeahorseToken *self,
+ gpointer object,
+ GckAttribute *id)
+{
+ GPtrArray *objects;
+ GckAttribute *pid;
+ gboolean remove = FALSE;
+ gboolean add = FALSE;
+
+ /* See if this object was here before */
+ pid = g_hash_table_lookup (self->pv->id_for_object, object);
+
+ /* Decide what we're going to do */
+ if (id == NULL) {
+ if (pid != NULL) {
+ id = pid;
+ remove = TRUE;
+ }
+ } else {
+ if (pid == NULL) {
+ add = TRUE;
+ } else if (!gck_attribute_equal (id, pid)) {
+ remove = TRUE;
+ add = TRUE;
+ }
+ }
+
+ if (add) {
+ if (!g_hash_table_lookup_extended (self->pv->objects_for_id, id,
+ (gpointer *)&id, (gpointer *)&objects)) {
+ objects = g_ptr_array_new ();
+ id = gck_attribute_dup (id);
+ g_hash_table_insert (self->pv->objects_for_id, id, objects);
+ }
+ g_ptr_array_add (objects, object);
+ g_hash_table_insert (self->pv->id_for_object, object, id);
+ }
+
+ /* Remove this object from the map */
+ if (remove) {
+ if (!g_hash_table_remove (self->pv->id_for_object, object))
+ g_assert_not_reached ();
+ objects = g_hash_table_lookup (self->pv->objects_for_id, id);
+ g_assert (objects != NULL);
+ g_assert (objects->len > 0);
+ if (objects->len == 1) {
+ if (!g_hash_table_remove (self->pv->objects_for_id, id))
+ g_assert_not_reached ();
+ } else {
+ if (!g_ptr_array_remove (objects, object))
+ g_assert_not_reached ();
+ }
+ }
+}
+
+static gpointer
+lookup_id_map (SeahorseToken *self,
+ GType object_type,
+ GckAttribute *id)
+{
+ GPtrArray *objects;
+ guint i;
+
+ objects = g_hash_table_lookup (self->pv->objects_for_id, id);
+ if (objects == NULL)
+ return NULL;
+
+ for (i = 0; i < objects->len; i++) {
+ if (G_TYPE_CHECK_INSTANCE_TYPE (objects->pdata[i], object_type))
+ return objects->pdata[i];
+ }
+
+ return NULL;
+}
+
+static void
+update_visibility (SeahorseToken *self,
+ GList *objects,
+ gboolean visible)
+{
+ gboolean have;
+ gpointer object;
+ GList *l;
+
+ for (l = objects; l != NULL; l = g_list_next (l)) {
+ object = l->data;
+ have = g_hash_table_lookup (self->pv->objects_visible, object) != NULL;
+ if (!have && visible) {
+ g_hash_table_insert (self->pv->objects_visible, object, object);
+ gcr_collection_emit_added (GCR_COLLECTION (self), object);
+ } else if (have && !visible) {
+ if (!g_hash_table_remove (self->pv->objects_visible, object))
+ g_assert_not_reached ();
+ gcr_collection_emit_removed (GCR_COLLECTION (self), object);
+ }
+ }
+}
+
+static gboolean
+make_certificate_key_pair (SeahorseCertificate *certificate,
+ SeahorsePrivateKey *private_key)
+{
+ if (seahorse_certificate_get_private_key (certificate) ||
+ seahorse_private_key_get_certificate (private_key))
+ return FALSE;
+
+ seahorse_certificate_set_private_key (certificate, private_key);
+ seahorse_private_key_set_certificate (private_key, certificate);
+ return TRUE;
+}
+
+static gpointer
+break_certificate_key_pair (gpointer object)
+{
+ SeahorseCertificate *certificate = NULL;
+ SeahorsePrivateKey *private_key = NULL;
+ gpointer pair;
+
+ if (SEAHORSE_IS_CERTIFICATE (object)) {
+ certificate = SEAHORSE_CERTIFICATE (object);
+ pair = seahorse_certificate_get_private_key (certificate);
+ seahorse_certificate_set_private_key (certificate, NULL);
+ } else if (SEAHORSE_IS_PRIVATE_KEY (object)) {
+ private_key = SEAHORSE_PRIVATE_KEY (object);
+ pair = seahorse_private_key_get_certificate (private_key);
+ seahorse_private_key_set_certificate (private_key, NULL);
+ } else {
+ pair = NULL;
+ }
+
+ return pair;
+}
+
+static void
+receive_objects (SeahorseToken *self,
+ GList *objects)
+{
+ GckAttributes *attrs;
+ GckAttribute *id;
+ gpointer object;
+ gpointer prev;
+ gpointer pair;
+ gulong handle;
+ GList *show = NULL;
+ GList *hide = NULL;
+ GList *l;
+
+ for (l = objects; l != NULL; l = g_list_next (l)) {
+ object = l->data;
+ handle = gck_object_get_handle (object);
+ attrs = gck_object_attributes_get_attributes (object);
+
+ prev = g_hash_table_lookup (self->pv->object_for_handle, &handle);
+ if (prev == NULL) {
+ g_hash_table_insert (self->pv->object_for_handle,
+ g_memdup (&handle, sizeof (handle)),
+ g_object_ref (object));
+ g_object_set (object, "place", self, NULL);
+ } else if (prev != object) {
+ gck_object_attributes_set_attributes (prev, attrs);
+ object = prev;
+ }
+
+ id = gck_attributes_find (attrs, CKA_ID);
+ update_id_map (self, object, id);
+
+ if (SEAHORSE_IS_CERTIFICATE (object)) {
+ pair = lookup_id_map (self, SEAHORSE_TYPE_PRIVATE_KEY, id);
+ if (pair && make_certificate_key_pair (object, pair))
+ hide = g_list_prepend (hide, pair);
+ show = g_list_prepend (show, object);
+
+ } else if (SEAHORSE_IS_PRIVATE_KEY (object)) {
+ pair = lookup_id_map (self, SEAHORSE_TYPE_CERTIFICATE, id);
+ if (pair && make_certificate_key_pair (pair, object))
+ hide = g_list_prepend (hide, object);
+ else
+ show = g_list_prepend (show, object);
+
+ } else {
+ show = g_list_prepend (show, object);
+ }
+
+ gck_attributes_unref (attrs);
+ }
+
+ update_visibility (self, hide, FALSE);
+ g_list_free (hide);
+
+ update_visibility (self, show, TRUE);
+ g_list_free (show);
+}
+
+static void
+remove_objects (SeahorseToken *self,
+ GList *objects)
+{
+ GList *depaired = NULL;
+ GList *hide = NULL;
+ gulong handle;
+ gpointer object;
+ gpointer pair;
+ GList *l;
+
+ for (l = objects; l != NULL; l = g_list_next (l)) {
+ object = l->data;
+ pair = break_certificate_key_pair (object);
+ if (pair != NULL)
+ depaired = g_list_prepend (depaired, pair);
+ update_id_map (self, object, NULL);
+ hide = g_list_prepend (hide, object);
+ }
+
+ /* Remove the ownership of these */
+ for (l = objects; l != NULL; l = g_list_next (l)) {
+ handle = gck_object_get_handle (l->data);
+ g_object_set (object, "place", NULL, NULL);
+ g_hash_table_remove (self->pv->object_for_handle, &handle);
+ }
+
+ update_visibility (self, hide, FALSE);
+ g_list_free (hide);
+
+ /* Add everything that was paired */
+ receive_objects (self, depaired);
+ g_list_free (depaired);
+}
+
+
typedef struct {
SeahorseToken *token;
GCancellable *cancellable;
@@ -94,17 +342,6 @@ pkcs11_refresh_free (gpointer data)
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,
@@ -119,9 +356,10 @@ on_refresh_next_objects (GObject *source,
objects = gck_enumerator_next_finish (closure->enumerator, result, &error);
- /* Remove all objects that were found, from the check table */
+ receive_objects (closure->token, objects);
+
+ /* 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);
}
@@ -140,7 +378,10 @@ on_refresh_next_objects (GObject *source,
/* Otherwise we're done, remove everything not found */
} else {
- g_hash_table_foreach_remove (closure->checks, remove_each_object, closure->token);
+ objects = g_hash_table_get_values (closure->checks);
+ remove_objects (closure->token, objects);
+ g_list_free (objects);
+
g_simple_async_result_complete (res);
}
@@ -148,24 +389,6 @@ on_refresh_next_objects (GObject *source,
}
static void
-update_token_info (SeahorseToken *self)
-{
- GckTokenInfo *info;
- GObject *obj;
-
- info = gck_slot_get_token_info (self->pv->slot);
- if (info != NULL) {
- gck_token_info_free (self->pv->info);
- self->pv->info = info;
-
- obj = G_OBJECT (self);
- g_object_notify (obj, "info");
- g_object_notify (obj, "lockable");
- g_object_notify (obj, "unlockable");
- }
-}
-
-static void
refresh_enumerate (GSimpleAsyncResult *res)
{
RefreshClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
@@ -296,10 +519,16 @@ 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);
self->pv->actions = seahorse_pkcs11_token_actions_instance ();
+ self->pv->object_for_handle = g_hash_table_new_full (seahorse_pkcs11_ulong_hash,
+ seahorse_pkcs11_ulong_equal,
+ g_free, g_object_unref);
+ self->pv->objects_for_id = g_hash_table_new_full (gck_attribute_hash,
+ gck_attribute_equal,
+ gck_attribute_free,
+ (GDestroyNotify)g_ptr_array_unref);
+ self->pv->id_for_object = g_hash_table_new (g_direct_hash, g_direct_equal);
+ self->pv->objects_visible = g_hash_table_new (g_direct_hash, g_direct_equal);
}
static void
@@ -429,7 +658,10 @@ seahorse_token_finalize (GObject *obj)
{
SeahorseToken *self = SEAHORSE_TOKEN (obj);
- g_hash_table_destroy (self->pv->objects);
+ g_hash_table_destroy (self->pv->objects_visible);
+ g_hash_table_destroy (self->pv->object_for_handle);
+ g_hash_table_destroy (self->pv->objects_for_id);
+ g_hash_table_destroy (self->pv->id_for_object);
g_assert (self->pv->slot == NULL);
g_clear_object (&self->pv->actions);
g_free (self->pv->uri);
@@ -491,14 +723,14 @@ static guint
seahorse_token_get_length (GcrCollection *collection)
{
SeahorseToken *self = SEAHORSE_TOKEN (collection);
- return g_hash_table_size (self->pv->objects);
+ return g_hash_table_size (self->pv->objects_visible);
}
static GList *
seahorse_token_get_objects (GcrCollection *collection)
{
SeahorseToken *self = SEAHORSE_TOKEN (collection);
- return g_hash_table_get_values (self->pv->objects);
+ return g_hash_table_get_values (self->pv->objects_visible);
}
static gboolean
@@ -506,13 +738,7 @@ 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;
+ return g_hash_table_lookup (self->pv->objects_visible, object) != NULL;
}
static void
@@ -636,51 +862,20 @@ seahorse_token_get_unlockable (SeahorseToken *self)
return FALSE;
return !is_session_logged_in (self->pv->session);
-
-}
-
-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;
+ GList *objects;
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);
+ objects = g_list_prepend (NULL, g_object_ref (object));
+ remove_objects (self, objects);
+ g_list_free_full (objects, g_object_unref);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]