summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Walter <stefw@src.gnome.org>2008-04-06 03:14:39 +0000
committerStefan Walter <stefw@src.gnome.org>2008-04-06 03:14:39 +0000
commitd4249897c0d1719fcd12be47b779c521fb6568e7 (patch)
tree24dbe24d0f6d750fb7fe7aa52679469753a983c4
parente1ec54ab836b3866548b357bdb5cb717e2914d97 (diff)
downloadgnome-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--ChangeLog11
-rw-r--r--pk/gkr-pk-object.c11
-rw-r--r--pk/gkr-pk-object.h8
-rw-r--r--pk/gkr-pk-privkey.c25
-rw-r--r--ssh/gkr-ssh-daemon-ops.c41
5 files changed, 82 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index 469441f6..913af23d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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;
}