gnome-keyring/gnome-keyring-2.30.0-fix-st...

336 lines
11 KiB
Diff

From d864698a290c55d1ccda5cc20946894ade5e827d Mon Sep 17 00:00:00 2001
From: Stef Walter <stef@memberwebs.com>
Date: Sun, 21 Mar 2010 15:55:51 +0000
Subject: [login] Fix various issues storing and using auto unlock passwords.
* Unwrap secrets directly into login keyring for auto unlock.
* Fix various corner cases using auto unlock stuff in login keyring.
---
diff --git a/daemon/dbus/gkd-secret-session.c b/daemon/dbus/gkd-secret-session.c
index 80cd054..73551df 100644
--- a/daemon/dbus/gkd-secret-session.c
+++ b/daemon/dbus/gkd-secret-session.c
@@ -730,6 +730,8 @@ gkd_secret_session_create_credential (GkdSecretSession *self, GP11Session *sessi
}
g_clear_error (&error);
return NULL;
+ } else {
+ gp11_object_set_session (object, session);
}
return object;
diff --git a/daemon/dbus/gkd-secret-unlock.c b/daemon/dbus/gkd-secret-unlock.c
index 8a70ddc..f5df63b 100644
--- a/daemon/dbus/gkd-secret-unlock.c
+++ b/daemon/dbus/gkd-secret-unlock.c
@@ -247,43 +247,35 @@ check_locked_collection (GP11Object *collection, gboolean *locked)
}
static void
-attach_credential_to_login (GP11Object *collection, GP11Object *cred)
+attach_unlock_to_login (GP11Object *collection, GkdSecretSecret *master)
{
- GError *error = NULL;
+ DBusError derr = DBUS_ERROR_INIT;
GP11Attributes *attrs;
- gpointer value;
- gsize n_value;
+ GP11Object *cred;
gchar *location;
gchar *label;
g_assert (GP11_IS_OBJECT (collection));
- g_assert (GP11_IS_OBJECT (cred));
+ /* Relevant information for the unlock item */
attrs = attributes_for_collection (collection);
g_return_if_fail (attrs);
-
location = location_string_for_attributes (attrs);
label = label_string_for_attributes (attrs);
gp11_attributes_unref (attrs);
- value = gp11_object_get_data_full (cred, CKA_VALUE, egg_secure_realloc, NULL, &n_value, &error);
- if (value) {
- if (g_utf8_validate (value, n_value, NULL))
- gkd_login_attach_secret (label, value, "keyring", location, NULL);
- else
- g_warning ("couldn't save non utf-8 unlock credentials in login keyring");
- egg_secure_clear (value, n_value);
- egg_secure_free (value);
-
- } else {
- if (!g_error_matches (error, GP11_ERROR, CKR_USER_NOT_LOGGED_IN))
- g_warning ("couldn't read unlock credentials to save in login keyring: %s",
- egg_error_message (error));
- g_clear_error (&error);
- }
-
+ attrs = gkd_login_attach_make_attributes (label, "keyring", location, NULL);
g_free (location);
g_free (label);
+
+ cred = gkd_secret_session_create_credential (master->session, NULL, attrs, master, &derr);
+ gp11_attributes_unref (attrs);
+ g_object_unref (cred);
+
+ if (!cred) {
+ g_warning ("couldn't save unlock password in login collection: %s", derr.message);
+ dbus_error_free (&derr);
+ }
}
static void
@@ -304,6 +296,7 @@ authenticate_collection (GkdSecretUnlock *self, GP11Object *collection, gboolean
GP11Attribute *attr;
GP11Object *cred;
gboolean transient;
+ gboolean result;
g_assert (GKD_SECRET_IS_UNLOCK (self));
g_assert (GP11_IS_OBJECT (collection));
@@ -336,35 +329,37 @@ authenticate_collection (GkdSecretUnlock *self, GP11Object *collection, gboolean
}
cred = gkd_secret_session_create_credential (master->session, NULL, template, master, &derr);
- gkd_secret_secret_free (master);
+ g_object_unref (cred);
if (cred) {
/* Save it to the login keyring */
if (!transient)
- attach_credential_to_login (collection, cred);
- g_object_unref (cred);
+ attach_unlock_to_login (collection, master);
/* Save away the unlock options for next time */
gp11_object_set_template (collection, CKA_G_CREDENTIAL_TEMPLATE, template, NULL);
gp11_attributes_unref (template);
*locked = FALSE;
- return TRUE; /* Operation succeeded, and unlocked */
+ result = TRUE; /* Operation succeeded, and unlocked */
} else {
gp11_attributes_unref (template);
if (dbus_error_has_name (&derr, INTERNAL_ERROR_DENIED)) {
dbus_error_free (&derr);
*locked = TRUE;
- return TRUE; /* Operation succeded, although not unlocked*/
+ result = TRUE; /* Operation succeded, although not unlocked*/
} else {
g_warning ("couldn't create credential for collection: %s",
derr.message);
dbus_error_free (&derr);
- return FALSE; /* Operation failed */
+ result = FALSE; /* Operation failed */
}
}
+
+ gkd_secret_secret_free (master);
+ return result;
}
/* -----------------------------------------------------------------------------
diff --git a/daemon/login/gkd-login.c b/daemon/login/gkd-login.c
index bdef57d..373561c 100644
--- a/daemon/login/gkd-login.c
+++ b/daemon/login/gkd-login.c
@@ -77,7 +77,9 @@ open_and_login_session (GP11Slot *slot, CK_USER_TYPE user_type, GError **error)
session = gp11_slot_open_session (slot, CKF_RW_SESSION, error);
if (session != NULL) {
if (!gp11_session_login (session, user_type, NULL, 0, error)) {
- if ((*error)->code != CKR_USER_ALREADY_LOGGED_IN) {
+ if (g_error_matches (*error, GP11_ERROR, CKR_USER_ALREADY_LOGGED_IN)) {
+ g_clear_error (error);
+ } else {
g_object_unref (session);
session = NULL;
}
@@ -574,20 +576,88 @@ find_login_keyring_item (GP11Session *session, GP11Attribute *fields)
return item;
}
+static GP11Attributes*
+attach_make_attributes_va (GP11Session *session, const gchar *label,
+ const gchar *first, va_list va)
+{
+ GP11Attributes *attrs;
+ GP11Attribute fields;
+ gchar *display_name;
+ GP11Object* item;
+ GError *error = NULL;
+ gpointer value;
+ gsize n_value;
+
+ attrs = gp11_attributes_new ();
+
+ gp11_attribute_init_empty (&fields, CKA_G_FIELDS);
+ string_attribute_list_va (va, first, &fields);
+
+ /*
+ * If there already is such an item, then include its identifier.
+ * What this does is overwrite that item, rather than creating new.
+ */
+ item = find_login_keyring_item (session, &fields);
+ if (item) {
+ value = gp11_object_get_data (item, CKA_ID, &n_value, &error);
+ if (value != NULL) {
+ gp11_attributes_add_data (attrs, CKA_ID, value, n_value);
+ g_free (value);
+ } else {
+ g_warning ("couldn't retrieve id for previous login item: %s",
+ egg_error_message (error));
+ g_clear_error (&error);
+ }
+ g_object_unref (item);
+ }
+
+ if (label == NULL)
+ label = _("Unnamed");
+
+ display_name = g_strdup_printf (_("Unlock password for: %s"), label);
+ gp11_attributes_add_string (attrs, CKA_LABEL, display_name);
+
+ gp11_attributes_add_boolean (attrs, CKA_TOKEN, TRUE);
+ gp11_attributes_add_ulong (attrs, CKA_CLASS, CKO_SECRET_KEY);
+ gp11_attributes_add_data (attrs, CKA_G_COLLECTION, "login", (gsize)5);
+ gp11_attributes_add (attrs, &fields);
+
+ gp11_attribute_clear (&fields);
+ return attrs;
+}
+
+GP11Attributes*
+gkd_login_attach_make_attributes (const gchar *label, const gchar *first, ...)
+{
+ GP11Attributes *attrs;
+ GP11Session *session;
+ GP11Module *module;
+ va_list va;
+
+ module = module_instance ();
+ session = lookup_login_session (module);
+
+ va_start (va, first);
+ attrs = attach_make_attributes_va (session, label, first, va);
+ va_end (va);
+
+ g_object_unref (session);
+ g_object_unref (module);
+
+ return attrs;
+}
+
void
gkd_login_attach_secret (const gchar *label, const gchar *secret,
const gchar *first, ...)
{
GError *error = NULL;
- GP11Attribute fields;
GP11Session *session;
GP11Module *module;
- gchar *display_name;
- GP11Object* item;
+ GP11Attributes *attrs;
+ GP11Object *item;
va_list va;
- if (label == NULL)
- label = _("Unnamed");
if (secret == NULL)
secret = "";
@@ -595,29 +665,11 @@ gkd_login_attach_secret (const gchar *label, const gchar *secret,
session = lookup_login_session (module);
va_start(va, first);
- gp11_attribute_init_empty (&fields, CKA_G_FIELDS);
- string_attribute_list_va (va, first, &fields);
+ attrs = attach_make_attributes_va (session, label, first, va);
va_end(va);
- display_name = g_strdup_printf (_("Unlock password for: %s"), label);
-
- item = find_login_keyring_item (session, &fields);
- if (item) {
- gp11_object_set (item, &error,
- CKA_LABEL, strlen (display_name), display_name,
- CKA_VALUE, strlen (secret), secret,
- GP11_INVALID);
- } else {
- item = gp11_session_create_object (session, &error,
- CKA_TOKEN, GP11_BOOLEAN, TRUE,
- CKA_CLASS, GP11_ULONG, CKO_SECRET_KEY,
- CKA_LABEL, strlen (display_name), display_name,
- CKA_VALUE, strlen (secret), secret,
- CKA_G_COLLECTION, (gsize)5, "login",
- CKA_G_FIELDS, fields.length, fields.value,
- GP11_INVALID);
- }
-
+ gp11_attributes_add_string (attrs, CKA_VALUE, secret);
+ item = gp11_session_create_object_full (session, attrs, NULL, &error);
if (error != NULL) {
g_warning ("couldn't store secret in login keyring: %s", egg_error_message (error));
g_clear_error (&error);
@@ -625,8 +677,8 @@ gkd_login_attach_secret (const gchar *label, const gchar *secret,
if (item)
g_object_unref (item);
- g_free (display_name);
- gp11_attribute_clear (&fields);
+
+ gp11_attributes_unref (attrs);
g_object_unref (session);
g_object_unref (module);
}
@@ -701,22 +753,3 @@ gkd_login_remove_secret (const gchar *first, ...)
g_object_unref (session);
g_object_unref (module);
}
-
-GP11Attributes*
-gkd_login_attributes_for_secret (const gchar *first, ...)
-{
- GP11Attributes *attrs;
- GP11Attribute *fields;
- va_list va;
-
- attrs = gp11_attributes_newv (CKA_CLASS, GP11_ULONG, CKO_SECRET_KEY,
- CKA_G_COLLECTION, (gsize)5, "login",
- GP11_INVALID);
-
- va_start(va, first);
- fields = gp11_attributes_add_empty (attrs, CKA_G_FIELDS);
- string_attribute_list_va (va, first, fields);
- va_end(va);
-
- return attrs;
-}
diff --git a/daemon/login/gkd-login.h b/daemon/login/gkd-login.h
index 89157b1..849b9f4 100644
--- a/daemon/login/gkd-login.h
+++ b/daemon/login/gkd-login.h
@@ -40,13 +40,14 @@ void gkd_login_attach_secret (const gchar *label,
const gchar *first,
...);
-gchar* gkd_login_lookup_secret (const gchar *first,
+GP11Attributes* gkd_login_attach_make_attributes (const gchar *label,
+ const gchar *first,
...);
-void gkd_login_remove_secret (const gchar *first,
+gchar* gkd_login_lookup_secret (const gchar *first,
...);
-GP11Attributes* gkd_login_attributes_for_secret (const gchar *first,
+void gkd_login_remove_secret (const gchar *first,
...);
#endif /* __GKD_LOGIN_H__ */
--
cgit v0.8.3.1