diff options
author | Stefan Walter <stefw@src.gnome.org> | 2008-04-06 03:14:39 +0000 |
---|---|---|
committer | Stefan Walter <stefw@src.gnome.org> | 2008-04-06 03:14:39 +0000 |
commit | d4249897c0d1719fcd12be47b779c521fb6568e7 (patch) | |
tree | 24dbe24d0f6d750fb7fe7aa52679469753a983c4 | |
parent | e1ec54ab836b3866548b357bdb5cb717e2914d97 (diff) | |
download | gnome-keyring-d4249897c0d1719fcd12be47b779c521fb6568e7.tar.gz |
Make 'ssh-add -D' and 'ssh-add -d' lock any SSH private keys that
* pk/gkr-pk-object.c:
* pk/gkr-pk-object.h:
* pk/gkr-pk-privkey.c:
* ssh/gkr-ssh-daemon-ops.c: Make 'ssh-add -D' and 'ssh-add -d'
lock any SSH private keys that gnome-keyring natively handles.
Fixes bug #524823
svn path=/trunk/; revision=1130
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | pk/gkr-pk-object.c | 11 | ||||
-rw-r--r-- | pk/gkr-pk-object.h | 8 | ||||
-rw-r--r-- | pk/gkr-pk-privkey.c | 25 | ||||
-rw-r--r-- | ssh/gkr-ssh-daemon-ops.c | 41 |
5 files changed, 82 insertions, 14 deletions
@@ -1,4 +1,13 @@ -2008-04-05 Stef Walter <stef@memberwebs.com> +2008-04-05 Stef Walter <stef@memberwebs.com> + + * pk/gkr-pk-object.c: + * pk/gkr-pk-object.h: + * pk/gkr-pk-privkey.c: + * ssh/gkr-ssh-daemon-ops.c: Make 'ssh-add -D' and 'ssh-add -d' + lock any SSH private keys that gnome-keyring natively handles. + Fixes bug #524823 + +2008-04-05 Stef Walter <stef@memberwebs.com> * pkix/gkr-pkix-openssl.c: Fix compiler warnings about uninitialized variables. Patch by Alex Converse. Fixes diff --git a/pk/gkr-pk-object.c b/pk/gkr-pk-object.c index f1125f01..04474b95 100644 --- a/pk/gkr-pk-object.c +++ b/pk/gkr-pk-object.c @@ -407,6 +407,17 @@ gkr_pk_object_flush (GkrPkObject *object) g_hash_table_remove_all (pv->attr_cache); } +void +gkr_pk_object_lock (GkrPkObject *object) +{ + GkrPkObjectClass *klass; + + klass = GKR_PK_OBJECT_GET_CLASS (object); + + if (klass->lock) + (*klass->lock) (object); +} + gboolean gkr_pk_object_match_one (GkrPkObject *object, CK_ATTRIBUTE_PTR rattr) { diff --git a/pk/gkr-pk-object.h b/pk/gkr-pk-object.h index 3361bffe..91dfbd8b 100644 --- a/pk/gkr-pk-object.h +++ b/pk/gkr-pk-object.h @@ -79,6 +79,12 @@ struct _GkrPkObjectClass { * the data, as long as the representation is later decryptable. */ guchar* (*serialize) (GkrPkObject *obj, const gchar* password, gsize *n_data); + + /* + * Asks the object to lock itself, ie: remove any sensitive data from + * memory. + */ + void (*lock) (GkrPkObject *obj); }; GType gkr_pk_object_get_type (void) G_GNUC_CONST; @@ -90,6 +96,8 @@ void gkr_pk_object_refresh (GkrPkObject *object); void gkr_pk_object_flush (GkrPkObject *object); +void gkr_pk_object_lock (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 0ccfdbb0..6dbee5f1 100644 --- a/pk/gkr-pk-privkey.c +++ b/pk/gkr-pk-privkey.c @@ -519,6 +519,20 @@ gkr_pk_privkey_serialize (GkrPkObject *obj, const gchar *password, gsize *n_data } static void +gkr_pk_privkey_lock (GkrPkObject *obj) +{ + GkrPkPrivkey *key = GKR_PK_PRIVKEY (obj); + + if (!key->priv->s_key) + return; + + gcry_sexp_release (key->priv->s_key); + key->priv->s_key = NULL; + + initialize_from_key (key); +} + +static void gkr_pk_privkey_dispose (GObject *obj) { GkrPkPrivkey *key = GKR_PK_PRIVKEY (obj); @@ -536,13 +550,13 @@ gkr_pk_privkey_finalize (GObject *obj) { GkrPkPrivkey *key = GKR_PK_PRIVKEY (obj); + g_assert (!key->priv->pubkey); + gcry_sexp_release (key->priv->s_key); key->priv->s_key = NULL; - - initialize_from_key (key); - - g_assert (!key->priv->pubkey); - g_assert (!key->priv->numbers); + + gcry_sexp_release (key->priv->numbers); + key->priv->numbers = NULL; G_OBJECT_CLASS (gkr_pk_privkey_parent_class)->finalize (obj); } @@ -558,6 +572,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->serialize = gkr_pk_privkey_serialize; + parent_class->lock = gkr_pk_privkey_lock; gobject_class = (GObjectClass*)klass; gobject_class->get_property = gkr_pk_privkey_get_property; diff --git a/ssh/gkr-ssh-daemon-ops.c b/ssh/gkr-ssh-daemon-ops.c index 171628bd..4cefd242 100644 --- a/ssh/gkr-ssh-daemon-ops.c +++ b/ssh/gkr-ssh-daemon-ops.c @@ -570,8 +570,6 @@ op_v1_challenge (GkrBuffer *req, GkrBuffer *resp) if (!make_decrypt_sexp (challenge, &sdata)) return FALSE; -gkr_crypto_sexp_dump (sdata); - /* Do the magic */ gcry = gcry_pk_decrypt (&splain, sdata, skey); @@ -582,8 +580,6 @@ gkr_crypto_sexp_dump (sdata); goto cleanup; } -gkr_crypto_sexp_dump (splain); - /* Number of bits in the key */ bits = gcry_pk_get_nbits (skey); g_return_val_if_fail (bits, FALSE); @@ -625,6 +621,7 @@ static gboolean op_remove_identity (GkrBuffer *req, GkrBuffer *resp) { GkrPkPrivkey *key; + GkrPkObject *obj; gcry_sexp_t skey; gsize offset; @@ -632,11 +629,27 @@ op_remove_identity (GkrBuffer *req, GkrBuffer *resp) if (!gkr_ssh_proto_read_public (req, &offset, &skey, NULL)) return FALSE; - key = find_private_key (skey, FALSE, 2); + key = find_private_key (skey, TRUE, 2); gcry_sexp_release (skey); - if (key) - remove_session_key (key); + if (key) { + obj = GKR_PK_OBJECT (key); + + /* + * When the key is just a session key, then remove it + * completely. + */ + if (obj->manager == session_manager) + remove_session_key (key); + + /* + * Otherwise lock it so the user gets prompted for + * any passwords again. + */ + else + gkr_pk_object_lock (obj); + } + gkr_buffer_add_byte (resp, GKR_SSH_RES_SUCCESS); return TRUE; @@ -667,8 +680,9 @@ static gboolean op_remove_all_identities (GkrBuffer *req, GkrBuffer *resp) { GkrPkPrivkey *key; - GList *l, *removes = NULL; + GList *objects, *l, *removes = NULL; + /* Remove all session keys */ if (session_manager) { for (l = session_manager->objects; l; l = g_list_next (l)) { if (!GKR_IS_PK_PRIVKEY (l->data)) @@ -683,6 +697,17 @@ op_remove_all_identities (GkrBuffer *req, GkrBuffer *resp) g_list_free (removes); } + /* And now we lock all private keys with usage = SSH */ + objects = gkr_pk_object_manager_findv (gkr_pk_object_manager_for_token (), GKR_TYPE_PK_PRIVKEY, + CKA_GNOME_PURPOSE_SSH_AUTH, CK_TRUE, 0, NULL); + + for (l = objects; l; l = g_list_next (l)) { + g_return_val_if_fail (GKR_IS_PK_OBJECT (l->data), FALSE); + gkr_pk_object_lock (GKR_PK_OBJECT (l->data)); + } + + g_list_free (objects); + gkr_buffer_add_byte (resp, GKR_SSH_RES_SUCCESS); return TRUE; } |