diff options
author | Stefan Walter <stefw@src.gnome.org> | 2008-04-18 21:05:22 +0000 |
---|---|---|
committer | Stefan Walter <stefw@src.gnome.org> | 2008-04-18 21:05:22 +0000 |
commit | ef3cfa77a1cdb4a8961dbb38d0f60db766720dd6 (patch) | |
tree | 8068e0d5156fc7f4ff60b31e03a57b0236383378 | |
parent | 5a6dd3919356b80dd6a712438c52d611a12343c3 (diff) | |
download | gnome-keyring-ef3cfa77a1cdb4a8961dbb38d0f60db766720dd6.tar.gz |
Streamline the importing of keys, and make the proper 'import' prompt come
* pk/gkr-pk-index.c:
* pk/gkr-pk-index.h:
* pk/gkr-pk-object.c:
* pk/gkr-pk-object.h:
* pk/gkr-pk-object-storage.c:
* pk/gkr-pk-privkey.c:
* ui/gkr-ask-request.h: Streamline the importing of keys, and make
the proper 'import' prompt come up when importing. Don't repeatedly
try to import a key that a user has 'denied'. Use the 'cancel'
label instead of 'deny' for the import prompt. See bug #528122
svn path=/trunk/; revision=1137
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | pk/gkr-pk-index.c | 16 | ||||
-rw-r--r-- | pk/gkr-pk-index.h | 3 | ||||
-rw-r--r-- | pk/gkr-pk-object-storage.c | 78 | ||||
-rw-r--r-- | pk/gkr-pk-object.c | 17 | ||||
-rw-r--r-- | pk/gkr-pk-object.h | 9 | ||||
-rw-r--r-- | pk/gkr-pk-privkey.c | 13 | ||||
-rw-r--r-- | ui/gkr-ask-request.h | 2 |
8 files changed, 138 insertions, 13 deletions
@@ -1,3 +1,16 @@ +2008-04-18 Stef Walter <stef@memberwebs.com> + + * pk/gkr-pk-index.c: + * pk/gkr-pk-index.h: + * pk/gkr-pk-object.c: + * pk/gkr-pk-object.h: + * pk/gkr-pk-object-storage.c: + * pk/gkr-pk-privkey.c: + * ui/gkr-ask-request.h: Streamline the importing of keys, and make + the proper 'import' prompt come up when importing. Don't repeatedly + try to import a key that a user has 'denied'. Use the 'cancel' + label instead of 'deny' for the import prompt. See bug #528122 + 2008-04-16 Stef Walter <stef@memberwebs.com> * common/gkr-location.h: diff --git a/pk/gkr-pk-index.c b/pk/gkr-pk-index.c index 18530b56..44f17ce1 100644 --- a/pk/gkr-pk-index.c +++ b/pk/gkr-pk-index.c @@ -939,6 +939,22 @@ gkr_pk_index_get_boolean (GkrPkObject *obj, const gchar *field, gboolean defvalu return ret; } +gboolean +gkr_pk_index_get_boolean_full (GQuark location, gkrconstid digest, + const gchar *field, gboolean defvalue) +{ + gboolean ret = defvalue; + + g_return_val_if_fail (digest, ret); + g_return_val_if_fail (field != NULL, ret); + + if (!read_pk_index_value (get_index_singleton (), location, digest, field, + NULL, (ReadValueFunc)read_boolean_value, &ret)) + ret = defvalue; + + return ret; +} + gint gkr_pk_index_get_int (GkrPkObject *obj, const gchar *field, gint defvalue) { diff --git a/pk/gkr-pk-index.h b/pk/gkr-pk-index.h index 750daa31..6b371501 100644 --- a/pk/gkr-pk-index.h +++ b/pk/gkr-pk-index.h @@ -32,6 +32,9 @@ gboolean gkr_pk_index_get_boolean (GkrPkObject *object, const gchar *field, gboolean defvalue); +gboolean gkr_pk_index_get_boolean_full (GQuark location, gkrconstid digest, + const gchar *field, gboolean defvalue); + gint gkr_pk_index_get_int (GkrPkObject *object, const gchar *field, gint defvalue); diff --git a/pk/gkr-pk-object-storage.c b/pk/gkr-pk-object-storage.c index 442829de..138963d6 100644 --- a/pk/gkr-pk-object-storage.c +++ b/pk/gkr-pk-object-storage.c @@ -56,6 +56,7 @@ struct _GkrPkObjectStoragePrivate { GHashTable *objects; GHashTable *objects_by_location; GHashTable *specific_load_requests; + GHashTable *denied_import_requests; GSList *watches; }; @@ -182,7 +183,9 @@ parser_ask_password (GkrPkixParser *parser, GQuark loc, gkrid digest, GkrAskRequest *ask; gchar *custom_label, *ret, *display_name, *stype, *secondary; const gchar *password; - gboolean have_indexed = FALSE; + gboolean imported = FALSE; + gboolean importing = FALSE; + guint flags; g_return_val_if_fail (loc == ctx->location, NULL); @@ -216,27 +219,43 @@ parser_ask_password (GkrPkixParser *parser, GQuark loc, gkrid digest, if (stype) { if (!type && stype[0]) type = g_quark_from_string (stype); - have_indexed = TRUE; g_free (stype); } + + /* This is how we know if we've imported this object before */ + imported = gkr_pk_index_get_boolean_full (loc, digest, "imported", FALSE); - /* - * If we've indexed this before, and the user isn't specifically requesting it - * to be loaded then we don't need to prompt for the password + /* + * If the user isn't specifically requeting this object, then we don't + * necessarily prompt for a password. */ - if (have_indexed && !g_hash_table_lookup (pv->specific_load_requests, digest)) - return NULL; - + if (!g_hash_table_lookup (pv->specific_load_requests, digest)) { + + /* If the user specifically denied this earlier, then don't prompt */ + if (g_hash_table_lookup (pv->denied_import_requests, digest)) + return NULL; + + /* If this has been imported already, then don't prompt */ + if (imported) + return NULL; + + importing = TRUE; + } + /* TODO: Load a better label if we have one */ custom_label = NULL; if (custom_label != NULL) label = custom_label; - ask = gkr_ask_request_new (prepare_ask_title (type), prepare_ask_primary (type), - GKR_ASK_REQUEST_PROMPT_PASSWORD); + /* Build up the prompt */ + if (importing) + flags = GKR_ASK_REQUEST_PASSWORD | GKR_ASK_REQUEST_OK_CANCEL_BUTTONS; + else + flags = GKR_ASK_REQUEST_PASSWORD | GKR_ASK_REQUEST_OK_DENY_BUTTONS; + ask = gkr_ask_request_new (prepare_ask_title (type), prepare_ask_primary (type), flags); - secondary = prepare_ask_secondary (type, have_indexed, label); + secondary = prepare_ask_secondary (type, !importing, label); gkr_ask_request_set_secondary (ask, secondary); g_free (secondary); @@ -245,10 +264,22 @@ parser_ask_password (GkrPkixParser *parser, GQuark loc, gkrid digest, if (gkr_keyring_login_is_usable ()) gkr_ask_request_set_check_option (ask, prepare_ask_check (type)); + /* Prompt the user */ gkr_ask_daemon_process (ask); + + /* If the user denied ... */ + if (ask->response == GKR_ASK_RESPONSE_DENY) { + + /* If we were importing then don't try again */ + if (importing) + g_hash_table_insert (pv->denied_import_requests, + gkr_id_dup (digest), NO_VALUE); + + ret = NULL; - /* User denied or cancelled */ - if (ask->response < GKR_ASK_RESPONSE_ALLOW) { + /* User cancelled or failure */ + } else if (ask->response < GKR_ASK_RESPONSE_ALLOW) { + ret = NULL; /* Successful response */ @@ -453,6 +484,15 @@ parser_parsed_sexp (GkrPkixParser *parser, GQuark location, gkrid digest, /* Setup the sexp, probably a key on this object */ g_object_set (object, "gcrypt-sexp", sexp, NULL); + + /* + * Now we have the object loaded and everything, and since it's a fully + * loaded (if encrypted a password has been provided), take the + * opportunity to 'import' it and make sure we have all necessary data + * on it. + */ + if (!gkr_pk_index_get_boolean (object, "imported", FALSE)) + gkr_pk_object_import (object); } static void @@ -479,6 +519,15 @@ parser_parsed_asn1 (GkrPkixParser *parser, GQuark location, gkrconstid digest, /* Setup the asn1, probably a certificate on this object */ g_object_set (object, "asn1-tree", asn1, NULL); + + /* + * Now we have the object loaded and everything, and since it's a fully + * loaded (if encrypted a password has been provided), take the + * opportunity to 'import' it and make sure we have all necessary data + * on it. + */ + if (gkr_pk_index_get_boolean (object, "imported", FALSE)) + gkr_pk_object_import (object); } static void @@ -618,6 +667,7 @@ gkr_pk_object_storage_init (GkrPkObjectStorage *storage) pv->objects = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL); pv->objects_by_location = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, free_array); pv->specific_load_requests = g_hash_table_new_full (gkr_id_hash, gkr_id_equals, gkr_id_free, NULL); + pv->denied_import_requests = g_hash_table_new_full (gkr_id_hash, gkr_id_equals, gkr_id_free, NULL); for (i = 0; i < G_N_ELEMENTS (gkr_pk_places); ++i) { place = &gkr_pk_places[i]; @@ -649,6 +699,7 @@ gkr_pk_object_storage_dispose (GObject *obj) g_hash_table_remove_all (pv->objects_by_location); g_hash_table_remove_all (pv->specific_load_requests); + g_hash_table_remove_all (pv->denied_import_requests); g_hash_table_remove_all (pv->objects); for (l = pv->watches; l; l = g_slist_next (l)) { @@ -670,6 +721,7 @@ gkr_pk_object_storage_finalize (GObject *obj) g_hash_table_destroy (pv->objects); g_hash_table_destroy (pv->objects_by_location); g_hash_table_destroy (pv->specific_load_requests); + g_hash_table_destroy (pv->denied_import_requests); for (l = pv->watches; l; l = g_slist_next (l)) { watch = GKR_LOCATION_WATCH (l->data); diff --git a/pk/gkr-pk-object.c b/pk/gkr-pk-object.c index 04474b95..f7289676 100644 --- a/pk/gkr-pk-object.c +++ b/pk/gkr-pk-object.c @@ -419,6 +419,23 @@ gkr_pk_object_lock (GkrPkObject *object) } gboolean +gkr_pk_object_import (GkrPkObject *object) +{ + GkrPkObjectClass *klass; + gboolean ret = TRUE; + + klass = GKR_PK_OBJECT_GET_CLASS (object); + + if (klass->import) + ret = (*klass->import) (object); + + if (ret) + gkr_pk_index_set_boolean (object, "imported", TRUE); + + return ret; +} + +gboolean gkr_pk_object_match_one (GkrPkObject *object, CK_ATTRIBUTE_PTR rattr) { CK_ATTRIBUTE_PTR attr; diff --git a/pk/gkr-pk-object.h b/pk/gkr-pk-object.h index 91dfbd8b..dccc1c8e 100644 --- a/pk/gkr-pk-object.h +++ b/pk/gkr-pk-object.h @@ -70,6 +70,13 @@ struct _GkrPkObjectClass { CK_RV (*get_attribute) (GkrPkObject *obj, CK_ATTRIBUTE_PTR attr); CK_RV (*set_attribute) (GkrPkObject *obj, CK_ATTRIBUTE_PTR attr); + /* + * Overridden by derived classes to prepare an object for + * use by gnome-keyring. This might include extracting public + * key and storing it in indexes or other stuff like that. + */ + gboolean (*import) (GkrPkObject *obj); + /* * Overridden by derived classes to provide the serialized * representation of the object, minus modifiable attributes, and @@ -98,6 +105,8 @@ void gkr_pk_object_flush (GkrPkObject *object); void gkr_pk_object_lock (GkrPkObject *object); +gboolean gkr_pk_object_import (GkrPkObject *object); + gboolean gkr_pk_object_match (GkrPkObject *object, GArray *attrs); diff --git a/pk/gkr-pk-privkey.c b/pk/gkr-pk-privkey.c index 6dbee5f1..59fbb73b 100644 --- a/pk/gkr-pk-privkey.c +++ b/pk/gkr-pk-privkey.c @@ -504,6 +504,18 @@ gkr_pk_privkey_get_attribute (GkrPkObject* obj, CK_ATTRIBUTE_PTR attr) return GKR_PK_OBJECT_CLASS (gkr_pk_privkey_parent_class)->get_attribute (obj, attr); } +static gboolean +gkr_pk_privkey_import (GkrPkObject *obj) +{ + GkrPkPrivkey *key = GKR_PK_PRIVKEY (obj); + GkrPkPubkey *pub; + + /* This stores all necessary information in the indexes */ + pub = get_public_key (key, TRUE); + + return GKR_IS_PK_PUBKEY (pub); +} + static guchar* gkr_pk_privkey_serialize (GkrPkObject *obj, const gchar *password, gsize *n_data) { @@ -571,6 +583,7 @@ gkr_pk_privkey_class_init (GkrPkPrivkeyClass *klass) parent_class = GKR_PK_OBJECT_CLASS (klass); parent_class->get_attribute = gkr_pk_privkey_get_attribute; + parent_class->import = gkr_pk_privkey_import; parent_class->serialize = gkr_pk_privkey_serialize; parent_class->lock = gkr_pk_privkey_lock; diff --git a/ui/gkr-ask-request.h b/ui/gkr-ask-request.h index 1f466bcb..973d8ab0 100644 --- a/ui/gkr-ask-request.h +++ b/ui/gkr-ask-request.h @@ -59,6 +59,8 @@ typedef enum { #define GKR_ASK_REQUEST_OK_DENY_BUTTONS \ (GKR_ASK_REQUEST_OK_BUTTON | GKR_ASK_REQUEST_DENY_BUTTON) +#define GKR_ASK_REQUEST_OK_CANCEL_BUTTONS \ + (GKR_ASK_REQUEST_OK_BUTTON | GKR_ASK_REQUEST_CANCEL_BUTTON) #define GKR_ASK_REQUEST_NEW_PASSWORD \ (GKR_ASK_REQUEST_PASSWORD | GKR_ASK_REQUEST_CONFIRM_PASSWORD | GKR_ASK_REQUEST_OK_DENY_BUTTONS) #define GKR_ASK_REQUEST_PROMPT_PASSWORD \ |