[gnome-keyring] [secrets] Implement lookup collection passwords in login keyring.
- From: Stefan Walter <stefw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-keyring] [secrets] Implement lookup collection passwords in login keyring.
- Date: Sun, 3 Jan 2010 20:57:18 +0000 (UTC)
commit 9981a23971d924294055d9a142cc2a8d7b448306
Author: Stef Walter <stef memberwebs com>
Date: Sun Jan 3 20:27:29 2010 +0000
[secrets] Implement lookup collection passwords in login keyring.
Also add support for null passwords, and automatically unlocking
collections with null passwords.
daemon/dbus/gkd-secret-unlock.c | 100 ++++++++++++++++++++++++++++++++++++---
daemon/dbus/gkd-secret-unlock.h | 5 ++
2 files changed, 98 insertions(+), 7 deletions(-)
---
diff --git a/daemon/dbus/gkd-secret-unlock.c b/daemon/dbus/gkd-secret-unlock.c
index a9e8a56..6fad92a 100644
--- a/daemon/dbus/gkd-secret-unlock.c
+++ b/daemon/dbus/gkd-secret-unlock.c
@@ -32,6 +32,8 @@
#include "egg/egg-secure-memory.h"
+#include "login/gkd-login.h"
+
#include "pkcs11/pkcs11i.h"
#include <glib/gi18n.h>
@@ -53,6 +55,31 @@ G_DEFINE_TYPE (GkdSecretUnlock, gkd_secret_unlock, GKD_SECRET_TYPE_PROMPT);
* INTERNAL
*/
+static gchar*
+location_string_for_collection (GP11Object *collection)
+{
+ gpointer identifier;
+ gsize n_identifier;
+ gchar *location;
+
+ /* Figure out the identifier */
+ identifier = gp11_object_get_data (collection, CKA_ID, &n_identifier, NULL);
+ if (!identifier || !g_utf8_validate (identifier, n_identifier, NULL)) {
+ g_free (identifier);
+ return NULL;
+ }
+
+ /*
+ * COMPAT: Format it into a string. This is done this way for compatibility
+ * with old gnome-keyring releases. In the future this may change.
+ *
+ * FYI: gp11_object_get_data() null terminates
+ */
+ location = g_strdup_printf ("LOCAL:/keyrings/%s.keyring", (gchar*)identifier);
+ g_free (identifier);
+ return location;
+}
+
static void
prepare_unlock_prompt (GkdSecretUnlock *self, GP11Object *coll)
{
@@ -323,8 +350,10 @@ gkd_secret_unlock_new (GkdSecretService *service, const gchar *caller)
void
gkd_secret_unlock_queue (GkdSecretUnlock *self, const gchar *objpath)
{
+ gboolean locked = TRUE;
GP11Object *coll;
- gboolean locked;
+ gchar *password;
+ gchar *location;
gchar *path;
g_return_if_fail (GKD_SECRET_IS_UNLOCK (self));
@@ -334,14 +363,31 @@ gkd_secret_unlock_queue (GkdSecretUnlock *self, const gchar *objpath)
if (coll == NULL)
return;
- if (authenticate_collection (self, coll, &locked)) {
- path = g_strdup (objpath);
- if (locked)
- g_queue_push_tail (self->queued, path);
- else
- g_array_append_val (self->results, path);
+ /* Try to unlock with an empty password */
+ if (gkd_secret_unlock_with_password (coll, NULL, 0, NULL)) {
+ locked = FALSE;
+
+ /* Or try to use login keyring's passwords */
+ } else {
+ location = location_string_for_collection (coll);
+ if (location) {
+ password = gkd_login_lookup_secret ("keyring", location, NULL);
+ g_free (location);
+
+ if (password) {
+ if (gkd_secret_unlock_with_password (coll, (guchar*)password, strlen (password), NULL))
+ locked = FALSE;
+ egg_secure_strfree (password);
+ }
+ }
}
+ path = g_strdup (objpath);
+ if (locked)
+ g_queue_push_tail (self->queued, path);
+ else
+ g_array_append_val (self->results, path);
+
g_object_unref (coll);
}
@@ -402,3 +448,43 @@ gkd_secret_unlock_with_secret (GP11Object *collection, GkdSecretSecret *master,
g_object_unref (cred);
return (cred != NULL);
}
+
+gboolean
+gkd_secret_unlock_with_password (GP11Object *collection, const guchar *password,
+ gsize n_password, DBusError *derr)
+{
+ GError *error = NULL;
+ GP11Session *session;
+ GP11Object *cred;
+ gboolean locked;
+
+ g_return_val_if_fail (GP11_IS_OBJECT (collection), FALSE);
+
+ /* Shortcut if already unlocked */
+ if (check_locked_collection (collection, &locked) && !locked)
+ return TRUE;
+
+ session = gp11_object_get_session (collection);
+ g_return_val_if_fail (session, FALSE);
+
+ cred = gp11_session_create_object (session, &error, CKA_CLASS, GP11_ULONG, CKO_G_CREDENTIAL,
+ CKA_G_OBJECT, GP11_ULONG, gp11_object_get_handle (collection),
+ CKA_GNOME_TRANSIENT, GP11_BOOLEAN, TRUE,
+ CKA_TOKEN, GP11_BOOLEAN, TRUE,
+ CKA_VALUE, n_password, password,
+ GP11_INVALID);
+
+ if (cred == NULL) {
+ if (error->code == CKR_PIN_INCORRECT) {
+ dbus_set_error_const (derr, INTERNAL_ERROR_DENIED, "The password was incorrect.");
+ } else {
+ g_message ("couldn't create credential: %s", error->message);
+ dbus_set_error_const (derr, DBUS_ERROR_FAILED, "Couldn't use credentials");
+ }
+ g_clear_error (&error);
+ return FALSE;
+ }
+
+ g_object_unref (cred);
+ return TRUE;
+}
diff --git a/daemon/dbus/gkd-secret-unlock.h b/daemon/dbus/gkd-secret-unlock.h
index f0f351c..0f67731 100644
--- a/daemon/dbus/gkd-secret-unlock.h
+++ b/daemon/dbus/gkd-secret-unlock.h
@@ -58,4 +58,9 @@ gboolean gkd_secret_unlock_with_secret (GP11Object *colle
GkdSecretSecret *master,
DBusError *derr);
+gboolean gkd_secret_unlock_with_password (GP11Object *collection,
+ const guchar *password,
+ gsize n_password,
+ DBusError *derr);
+
#endif /* __GKD_SECRET_UNLOCK_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]