diff options
author | Stef Walter <stefw@collabora.co.uk> | 2011-10-04 12:55:21 +0200 |
---|---|---|
committer | Stef Walter <stefw@collabora.co.uk> | 2011-10-04 12:55:21 +0200 |
commit | f4ac10720e2998583c60a084ecd6ac8a34300a40 (patch) | |
tree | 8384525f4bf74efce2d579f55fe908645fed84ec /gcr/gcr-pkcs11-importer.c | |
parent | 393ad5f15b2f7f6bfa000c0871161c81742806e7 (diff) | |
download | gcr-f4ac10720e2998583c60a084ecd6ac8a34300a40.tar.gz |
gcr: Complete the PKCS#11 import dialog
* Add GcrImportInteraction interface which importers
* Hookup between non-GUI importers and import interaction
isn't yet completely thought out.
Diffstat (limited to 'gcr/gcr-pkcs11-importer.c')
-rw-r--r-- | gcr/gcr-pkcs11-importer.c | 184 |
1 files changed, 136 insertions, 48 deletions
diff --git a/gcr/gcr-pkcs11-importer.c b/gcr/gcr-pkcs11-importer.c index feb012c..b22b4d7 100644 --- a/gcr/gcr-pkcs11-importer.c +++ b/gcr/gcr-pkcs11-importer.c @@ -27,6 +27,7 @@ #include "gcr-base.h" #include "gcr-internal.h" #include "gcr-library.h" +#include "gcr-import-interaction.h" #include "gcr-internal.h" #include "gcr-parser.h" #include "gcr-pkcs11-importer.h" @@ -39,18 +40,28 @@ enum { PROP_0, PROP_LABEL, PROP_ICON, + PROP_INTERACTION, PROP_SLOT, - PROP_IMPORTED + PROP_IMPORTED, + PROP_QUEUED }; -struct _GcrPkcs11ImporterPrivate { +typedef struct _GcrPkcs11ImporterClass GcrPkcs11ImporterClass; + +struct _GcrPkcs11Importer { + GObject parent; GckSlot *slot; GList *objects; GckSession *session; GQueue queue; + GTlsInteraction *interaction; gboolean any_private; }; +struct _GcrPkcs11ImporterClass { + GObjectClass parent_class; +}; + typedef struct { GcrPkcs11Importer *importer; GCancellable *cancellable; @@ -68,6 +79,9 @@ static void state_complete (GSimpleAsyncResult *res, static void state_create_object (GSimpleAsyncResult *res, gboolean async); +static void state_supplement (GSimpleAsyncResult *res, + gboolean async); + static void state_open_session (GSimpleAsyncResult *res, gboolean async); @@ -111,6 +125,13 @@ static void state_complete (GSimpleAsyncResult *res, gboolean async) { + GcrImporterData *data = g_simple_async_result_get_op_res_gpointer (res); + GcrPkcs11Importer *self = data->importer; + + /* Disconnect from the interaction */ + if (data->importer->interaction && GCR_IS_IMPORT_INTERACTION (self->interaction)) + gcr_import_interaction_set_importer (GCR_IMPORT_INTERACTION (self->interaction), NULL); + g_simple_async_result_complete (res); } @@ -146,7 +167,7 @@ complete_create_object (GSimpleAsyncResult *res, next_state (res, state_complete); } else { - self->pv->objects = g_list_append (self->pv->objects, object); + self->objects = g_list_append (self->objects, object); next_state (res, state_create_object); } } @@ -176,23 +197,23 @@ state_create_object (GSimpleAsyncResult *res, GError *error = NULL; /* No more objects */ - if (g_queue_is_empty (&self->pv->queue)) { + if (g_queue_is_empty (&self->queue)) { next_state (res, state_complete); } else { /* Pop first one off the list */ - attrs = g_queue_pop_head (&self->pv->queue); + attrs = g_queue_pop_head (&self->queue); g_assert (attrs != NULL); gck_attributes_add_boolean (attrs, CKA_TOKEN, CK_TRUE); if (async) { - gck_session_create_object_async (self->pv->session, attrs, + gck_session_create_object_async (self->session, attrs, data->cancellable, on_create_object, g_object_ref (res)); } else { - object = gck_session_create_object (self->pv->session, attrs, + object = gck_session_create_object (self->session, attrs, data->cancellable, &error); complete_create_object (res, object, error); } @@ -202,6 +223,61 @@ state_create_object (GSimpleAsyncResult *res, } /* --------------------------------------------------------------------------------- + * PROMPTING + */ + +static void +complete_supplement (GSimpleAsyncResult *res, + GError *error) +{ + if (error == NULL) { + next_state (res, state_create_object); + } else { + g_simple_async_result_take_error (res, error); + next_state (res, state_complete); + } +} + +static void +on_supplement_done (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data); + GcrImporterData *data = g_simple_async_result_get_op_res_gpointer (res); + GcrPkcs11Importer *self = data->importer; + GError *error = NULL; + + gcr_import_interaction_supplement_finish (GCR_IMPORT_INTERACTION (self->interaction), + result, &error); + complete_supplement (res, error); + g_object_unref (res); +} + +static void +state_supplement (GSimpleAsyncResult *res, + gboolean async) +{ + GcrImporterData *data = g_simple_async_result_get_op_res_gpointer (res); + GcrPkcs11Importer *self = data->importer; + GError *error = NULL; + + if (self->interaction == NULL || !GCR_IS_IMPORT_INTERACTION (self->interaction)) { + complete_supplement (res, NULL); + + } else if (async) { + gcr_import_interaction_supplement_async (GCR_IMPORT_INTERACTION (self->interaction), + data->cancellable, on_supplement_done, + g_object_ref (res)); + + } else { + gcr_import_interaction_supplement (GCR_IMPORT_INTERACTION (self->interaction), + data->cancellable, &error); + complete_supplement (res, error); + } +} + +/* --------------------------------------------------------------------------------- * OPEN SESSION */ @@ -218,9 +294,9 @@ complete_open_session (GSimpleAsyncResult *res, next_state (res, state_complete); } else { - g_clear_object (&self->pv->session); - self->pv->session = session; - next_state (res, state_create_object); + g_clear_object (&self->session); + self->session = session; + next_state (res, state_supplement); } } @@ -244,19 +320,16 @@ state_open_session (GSimpleAsyncResult *res, { GcrImporterData *data = g_simple_async_result_get_op_res_gpointer (res); GcrPkcs11Importer *self = data->importer; - guint options = GCK_SESSION_READ_WRITE; + guint options = GCK_SESSION_READ_WRITE | GCK_SESSION_LOGIN_USER; GckSession *session; GError *error = NULL; - if (self->pv->any_private) - options |= GCK_SESSION_LOGIN_USER; - if (async) { - gck_slot_open_session_async (self->pv->slot, options, + gck_slot_open_session_async (self->slot, options, data->cancellable, on_open_session, g_object_ref (res)); } else { - session = gck_slot_open_session_full (self->pv->slot, options, 0, + session = gck_slot_open_session_full (self->slot, options, 0, NULL, NULL, data->cancellable, &error); complete_open_session (res, session, error); } @@ -265,8 +338,7 @@ state_open_session (GSimpleAsyncResult *res, static void _gcr_pkcs11_importer_init (GcrPkcs11Importer *self) { - self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_PKCS11_IMPORTER, GcrPkcs11ImporterPrivate); - g_queue_init (&self->pv->queue); + g_queue_init (&self->queue); } static void @@ -274,12 +346,13 @@ _gcr_pkcs11_importer_dispose (GObject *obj) { GcrPkcs11Importer *self = GCR_PKCS11_IMPORTER (obj); - gck_list_unref_free (self->pv->objects); - self->pv->objects = NULL; - g_clear_object (&self->pv->session); + gck_list_unref_free (self->objects); + self->objects = NULL; + g_clear_object (&self->session); + g_clear_object (&self->interaction); - while (!g_queue_is_empty (&self->pv->queue)) - gck_attributes_unref (g_queue_pop_head (&self->pv->queue)); + while (!g_queue_is_empty (&self->queue)) + gck_attributes_unref (g_queue_pop_head (&self->queue)); G_OBJECT_CLASS (_gcr_pkcs11_importer_parent_class)->dispose (obj); } @@ -289,7 +362,7 @@ _gcr_pkcs11_importer_finalize (GObject *obj) { GcrPkcs11Importer *self = GCR_PKCS11_IMPORTER (obj); - g_clear_object (&self->pv->slot); + g_clear_object (&self->slot); G_OBJECT_CLASS (_gcr_pkcs11_importer_parent_class)->finalize (obj); } @@ -304,8 +377,13 @@ _gcr_pkcs11_importer_set_property (GObject *obj, switch (prop_id) { case PROP_SLOT: - self->pv->slot = g_value_dup_object (value); - g_return_if_fail (self->pv->slot); + self->slot = g_value_dup_object (value); + g_return_if_fail (self->slot); + break; + case PROP_INTERACTION: + g_clear_object (&self->interaction); + self->interaction = g_value_dup_object (value); + g_object_notify (G_OBJECT (self), "interaction"); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); @@ -319,7 +397,7 @@ calculate_label (GcrPkcs11Importer *self) GckTokenInfo *info; gchar *result; - info = gck_slot_get_token_info (self->pv->slot); + info = gck_slot_get_token_info (self->slot); result = g_strdup (info->label); gck_token_info_free (info); @@ -334,7 +412,7 @@ calculate_icon (GcrPkcs11Importer *self, GIcon *result; if (token_info == NULL) - info = token_info = gck_slot_get_token_info (self->pv->slot); + info = token_info = gck_slot_get_token_info (self->slot); result = gcr_icon_for_token (token_info); gck_token_info_free (info); @@ -360,7 +438,13 @@ _gcr_pkcs11_importer_get_property (GObject *obj, g_value_set_object (value, _gcr_pkcs11_importer_get_slot (self)); break; case PROP_IMPORTED: - g_value_set_boxed (value, _gcr_pkcs11_importer_get_imported (self)); + g_value_take_boxed (value, _gcr_pkcs11_importer_get_imported (self)); + break; + case PROP_QUEUED: + g_value_set_pointer (value, _gcr_pkcs11_importer_get_queued (self)); + break; + case PROP_INTERACTION: + g_value_set_object (value, self->interaction); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); @@ -379,12 +463,12 @@ _gcr_pkcs11_importer_class_init (GcrPkcs11ImporterClass *klass) gobject_class->set_property = _gcr_pkcs11_importer_set_property; gobject_class->get_property = _gcr_pkcs11_importer_get_property; - g_type_class_add_private (gobject_class, sizeof (GcrPkcs11ImporterPrivate)); - g_object_class_override_property (gobject_class, PROP_LABEL, "label"); g_object_class_override_property (gobject_class, PROP_ICON, "icon"); + g_object_class_override_property (gobject_class, PROP_INTERACTION, "interaction"); + g_object_class_install_property (gobject_class, PROP_SLOT, g_param_spec_object ("slot", "Slot", "PKCS#11 slot to import data into", GCK_TYPE_SLOT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); @@ -393,6 +477,10 @@ _gcr_pkcs11_importer_class_init (GcrPkcs11ImporterClass *klass) g_param_spec_boxed ("imported", "Imported", "Imported objects", GCK_TYPE_LIST, G_PARAM_READABLE)); + g_object_class_install_property (gobject_class, PROP_QUEUED, + g_param_spec_pointer ("queued", "Queued", "Queued attributes", + G_PARAM_READABLE)); + registered = gck_attributes_new (); gck_attributes_add_ulong (registered, CKA_CLASS, CKO_CERTIFICATE); gck_attributes_add_ulong (registered, CKA_CERTIFICATE_TYPE, CKC_X_509); @@ -493,16 +581,10 @@ _gcr_pkcs11_importer_queue_for_parsed (GcrImporter *importer, { GcrPkcs11Importer *self = GCR_PKCS11_IMPORTER (importer); GckAttributes *attrs; - gboolean is_private; attrs = gcr_parsed_get_attributes (parsed); + _gcr_pkcs11_importer_queue (self, attrs); - if (!gck_attributes_find_boolean (attrs, CKA_PRIVATE, &is_private)) - is_private = FALSE; - if (is_private) - self->pv->any_private = TRUE; - - g_queue_push_tail (&self->pv->queue, gck_attributes_ref (attrs)); return TRUE; } @@ -512,6 +594,7 @@ _gcr_pkcs11_importer_import_async (GcrImporter *importer, GAsyncReadyCallback callback, gpointer user_data) { + GcrPkcs11Importer *self = GCR_PKCS11_IMPORTER (importer); GSimpleAsyncResult *res; GcrImporterData *data; @@ -523,6 +606,11 @@ _gcr_pkcs11_importer_import_async (GcrImporter *importer, data->cancellable = cancellable ? g_object_ref (cancellable) : NULL; g_simple_async_result_set_op_res_gpointer (res, data, gcr_importer_data_free); + if (GCR_IS_IMPORT_INTERACTION (self->interaction)) + gcr_import_interaction_set_importer (GCR_IMPORT_INTERACTION (self->interaction), + GCR_IMPORTER (self)); + gck_slot_set_interaction (self->slot, self->interaction); + next_state (res, state_open_session); g_object_unref (res); } @@ -569,29 +657,29 @@ GckSlot * _gcr_pkcs11_importer_get_slot (GcrPkcs11Importer *self) { g_return_val_if_fail (GCR_IS_PKCS11_IMPORTER (self), NULL); - return self->pv->slot; + return self->slot; } GList * _gcr_pkcs11_importer_get_imported (GcrPkcs11Importer *self) { g_return_val_if_fail (GCR_IS_PKCS11_IMPORTER (self), NULL); - return self->pv->objects; + return g_list_copy (self->objects); +} + +GList * +_gcr_pkcs11_importer_get_queued (GcrPkcs11Importer *self) +{ + g_return_val_if_fail (GCR_IS_PKCS11_IMPORTER (self), NULL); + return g_list_copy (self->queue.head); } void _gcr_pkcs11_importer_queue (GcrPkcs11Importer *self, GckAttributes *attrs) { - gboolean is_private; - g_return_if_fail (GCR_IS_PKCS11_IMPORTER (self)); g_return_if_fail (attrs != NULL); - if (!gck_attributes_find_boolean (attrs, CKA_PRIVATE, &is_private)) - is_private = FALSE; - if (is_private) - self->pv->any_private = TRUE; - - g_queue_push_tail (&self->pv->queue, gck_attributes_ref (attrs)); + g_queue_push_tail (&self->queue, gck_attributes_ref (attrs)); } |