336 lines
11 KiB
Diff
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
|