summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Walter <stefw@src.gnome.org>2008-04-18 21:05:22 +0000
committerStefan Walter <stefw@src.gnome.org>2008-04-18 21:05:22 +0000
commitef3cfa77a1cdb4a8961dbb38d0f60db766720dd6 (patch)
tree8068e0d5156fc7f4ff60b31e03a57b0236383378
parent5a6dd3919356b80dd6a712438c52d611a12343c3 (diff)
downloadgnome-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--ChangeLog13
-rw-r--r--pk/gkr-pk-index.c16
-rw-r--r--pk/gkr-pk-index.h3
-rw-r--r--pk/gkr-pk-object-storage.c78
-rw-r--r--pk/gkr-pk-object.c17
-rw-r--r--pk/gkr-pk-object.h9
-rw-r--r--pk/gkr-pk-privkey.c13
-rw-r--r--ui/gkr-ask-request.h2
8 files changed, 138 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index 7e5cf01e..441e6dc5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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 \