diff options
Diffstat (limited to 'libedataserverui/e-passwords.c')
| -rw-r--r-- | libedataserverui/e-passwords.c | 357 |
1 files changed, 54 insertions, 303 deletions
diff --git a/libedataserverui/e-passwords.c b/libedataserverui/e-passwords.c index 96ce70e0b..f54bcf35d 100644 --- a/libedataserverui/e-passwords.c +++ b/libedataserverui/e-passwords.c @@ -46,7 +46,7 @@ #include <string.h> #include <gtk/gtk.h> #include <glib/gi18n-lib.h> -#include <gnome-keyring.h> +#include <libsecret/secret.h> #include <libedataserver/libedataserver.h> @@ -81,6 +81,18 @@ struct _EPassMsg { * dispatch functions from others */ }; +/* XXX probably want to share this with evalution-source-registry-migrate-sources.c */ +static const SecretSchema e_passwords_schema = { + "org.gnome.Evolution.Password", + SECRET_SCHEMA_DONT_MATCH_NAME, + { + { "application", SECRET_SCHEMA_ATTRIBUTE_STRING, }, + { "user", SECRET_SCHEMA_ATTRIBUTE_STRING, }, + { "server", SECRET_SCHEMA_ATTRIBUTE_STRING, }, + { "protocol", SECRET_SCHEMA_ATTRIBUTE_STRING, }, + } +}; + G_LOCK_DEFINE_STATIC (passwords); static GThread *main_thread = NULL; static GHashTable *password_cache = NULL; @@ -88,21 +100,6 @@ static GtkDialog *password_dialog = NULL; static GQueue message_queue = G_QUEUE_INIT; static gint idle_id; static gint ep_online_state = TRUE; -static gchar *default_keyring = NULL; - -/* XXX Unfortunately, gnome-keyring doesn't use GErrors. */ -#define EP_KEYRING_ERROR (ep_keyring_error_domain ()) - -static GQuark -ep_keyring_error_domain (void) -{ - static GQuark quark = 0; - - if (G_UNLIKELY (quark == 0)) - quark = g_quark_from_static_string ("ep-keyring-error-quark"); - - return quark; -} static EUri * ep_keyring_uri_new (const gchar *string, @@ -121,8 +118,8 @@ ep_keyring_uri_new (const gchar *string, /* Make sure the URI has the required components. */ if (uri->user == NULL && uri->host == NULL) { g_set_error_literal ( - error, EP_KEYRING_ERROR, - GNOME_KEYRING_RESULT_BAD_ARGUMENTS, + error, G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, _("Keyring key is unusable: no user or host name")); e_uri_free (uri); uri = NULL; @@ -132,187 +129,6 @@ ep_keyring_uri_new (const gchar *string, } static gboolean -ep_keyring_validate (const gchar *user, - const gchar *server, - const gchar *protocol, - GnomeKeyringAttributeList *attributes) -{ - const gchar *user_value = NULL; - const gchar *server_value = NULL; - const gchar *protocol_value = NULL; - gint ii; - - g_return_val_if_fail (attributes != NULL, FALSE); - - /* Is there anything to validate? */ - if (user == NULL && server == NULL && protocol == NULL) - return TRUE; - - /* Look for "user", "server", and "protocol" attributes. */ - for (ii = 0; ii < attributes->len; ii++) { - GnomeKeyringAttribute *attr; - - attr = &g_array_index (attributes, GnomeKeyringAttribute, ii); - - /* Just assume the attribute values are strings. */ - if (strcmp (attr->name, "user") == 0) - user_value = attr->value.string; - else if (strcmp (attr->name, "server") == 0) - server_value = attr->value.string; - else if (strcmp (attr->name, "protocol") == 0) - protocol_value = attr->value.string; - } - - /* Is there a "user" attribute? */ - if (user != NULL && user_value == NULL) - return FALSE; - - /* Does it match what we're looking for? */ - if (user != NULL && strcmp (user, user_value) != 0) - return FALSE; - - /* Is there a "server" attribute? */ - if (server != NULL && server_value == NULL) - return FALSE; - - /* Does it match what we're looking for? */ - if (server != NULL && strcmp (server, server_value) != 0) - return FALSE; - - /* Is there a "protocol" attribute? */ - if (protocol != NULL && protocol_value == NULL) - return FALSE; - - /* Does it match what we're looking for? */ - if (protocol != NULL && strcmp (protocol, protocol_value) != 0) - return FALSE; - - return TRUE; -} - -static gboolean -ep_keyring_delete_passwords (const gchar *user, - const gchar *server, - const gchar *protocol, - GList *passwords, - GError **error) -{ - while (passwords != NULL) { - GnomeKeyringFound *found = passwords->data; - GnomeKeyringResult result; - - /* Validate the item before deleting it. */ - if (!ep_keyring_validate (user, server, protocol, found->attributes)) { - /* XXX We didn't always store protocols in the - * keyring, so for backward-compatibility - * try validating by user and server only. */ - if (!ep_keyring_validate (user, server, NULL, found->attributes)) { - passwords = g_list_next (passwords); - continue; - } - } - - result = gnome_keyring_item_delete_sync (NULL, found->item_id); - if (result != GNOME_KEYRING_RESULT_OK) { - g_set_error ( - error, EP_KEYRING_ERROR, result, - "Unable to delete password in " - "keyring (Keyring reports: %s)", - gnome_keyring_result_to_message (result)); - return FALSE; - } - - passwords = g_list_next (passwords); - } - - return TRUE; -} - -static gboolean -ep_keyring_insert_password (const gchar *user, - const gchar *server, - const gchar *protocol, - const gchar *display_name, - const gchar *password, - GError **error) -{ - GnomeKeyringAttributeList *attributes; - GnomeKeyringResult result; - guint32 item_id; - - g_return_val_if_fail (user != NULL, FALSE); - g_return_val_if_fail (server != NULL, FALSE); - g_return_val_if_fail (protocol != NULL, FALSE); - g_return_val_if_fail (display_name != NULL, FALSE); - g_return_val_if_fail (password != NULL, FALSE); - - attributes = gnome_keyring_attribute_list_new (); - gnome_keyring_attribute_list_append_string ( - attributes, "application", "Evolution"); - gnome_keyring_attribute_list_append_string ( - attributes, "user", user); - gnome_keyring_attribute_list_append_string ( - attributes, "server", server); - gnome_keyring_attribute_list_append_string ( - attributes, "protocol", protocol); - - /* XXX We don't use item_id but gnome-keyring doesn't allow - * for a NULL pointer. In fact it doesn't even check! */ - result = gnome_keyring_item_create_sync ( - NULL, GNOME_KEYRING_ITEM_NETWORK_PASSWORD, - display_name, attributes, password, TRUE, &item_id); - if (result != GNOME_KEYRING_RESULT_OK) { - g_set_error ( - error, EP_KEYRING_ERROR, result, - "Unable to create password in " - "keyring (Keyring reports: %s)", - gnome_keyring_result_to_message (result)); - } - - gnome_keyring_attribute_list_free (attributes); - - return (result == GNOME_KEYRING_RESULT_OK); -} - -static GList * -ep_keyring_lookup_passwords (const gchar *user, - const gchar *server, - const gchar *protocol, - GError **error) -{ - GnomeKeyringAttributeList *attributes; - GnomeKeyringResult result; - GList *passwords = NULL; - - attributes = gnome_keyring_attribute_list_new (); - gnome_keyring_attribute_list_append_string ( - attributes, "application", "Evolution"); - if (user != NULL) - gnome_keyring_attribute_list_append_string ( - attributes, "user", user); - if (server != NULL) - gnome_keyring_attribute_list_append_string ( - attributes, "server", server); - if (protocol != NULL) - gnome_keyring_attribute_list_append_string ( - attributes, "protocol", protocol); - - result = gnome_keyring_find_items_sync ( - GNOME_KEYRING_ITEM_NETWORK_PASSWORD, attributes, &passwords); - if (result != GNOME_KEYRING_RESULT_OK) { - g_set_error ( - error, EP_KEYRING_ERROR, result, - "Unable to find password(s) in " - "keyring (Keyring reports: %s)", - gnome_keyring_result_to_message (result)); - } - - gnome_keyring_attribute_list_free (attributes); - - return passwords; -} - -static gboolean ep_idle_dispatch (gpointer data) { EPassMsg *msg; @@ -393,43 +209,12 @@ ep_msg_send (EPassMsg *msg) static void ep_clear_passwords (EPassMsg *msg) { - GList *passwords; GError *error = NULL; /* Find all Evolution passwords and delete them. */ - passwords = ep_keyring_lookup_passwords (NULL, NULL, NULL, &error); - if (passwords != NULL) { - ep_keyring_delete_passwords (NULL, NULL, NULL, passwords, &error); - gnome_keyring_found_list_free (passwords); - } - - /* Not finding the requested key is acceptable, but we still - * want to leave an informational message on the terminal. */ - if (g_error_matches (error, EP_KEYRING_ERROR, GNOME_KEYRING_RESULT_NO_MATCH)) { - g_message ("%s", error->message); - g_error_free (error); - - } else if (error != NULL) - g_propagate_error (&msg->error, error); - - if (!msg->noreply) - e_flag_set (msg->done); -} - -static void -ep_forget_passwords (EPassMsg *msg) -{ - GList *passwords; - GError *error = NULL; - - g_hash_table_remove_all (password_cache); - - /* Find all Evolution passwords and delete them. */ - passwords = ep_keyring_lookup_passwords (NULL, NULL, NULL, &error); - if (passwords != NULL) { - ep_keyring_delete_passwords (NULL, NULL, NULL, passwords, &error); - gnome_keyring_found_list_free (passwords); - } + secret_password_clear_sync ( + &e_passwords_schema, NULL, &error, + "application", "Evolution", NULL); if (error != NULL) g_propagate_error (&msg->error, error); @@ -455,12 +240,22 @@ ep_remember_password (EPassMsg *msg) if (uri == NULL) goto exit; + secret_password_store_sync ( + &e_passwords_schema, + SECRET_COLLECTION_DEFAULT, + msg->key, password, + NULL, &error, + "application", "Evolution", + "user", uri->user, + "server", uri->host, + "protocol", uri->protocol, + NULL); + /* Only remove the password from the session hash * if the keyring insertion was successful. */ - if (ep_keyring_insert_password (uri->user, uri->host, uri->protocol, msg->key, password, &error)) + if (error == NULL) g_hash_table_remove (password_cache, msg->key); - - if (error != NULL) + else g_propagate_error (&msg->error, error); e_uri_free (uri); @@ -473,7 +268,6 @@ exit: static void ep_forget_password (EPassMsg *msg) { - GList *passwords; EUri *uri; GError *error = NULL; @@ -491,11 +285,12 @@ ep_forget_password (EPassMsg *msg) * to ep_keyring_delete_passwords(), which also knows about * the backward-compatibility issue and will filter the list * appropriately. */ - passwords = ep_keyring_lookup_passwords (uri->user, uri->host, NULL, &error); - if (passwords != NULL) { - ep_keyring_delete_passwords (uri->user, uri->host, uri->protocol, passwords, &error); - gnome_keyring_found_list_free (passwords); - } + secret_password_clear_sync ( + &e_passwords_schema, NULL, &error, + "application", "Evolution", + "user", uri->user, + "server", uri->host, + NULL); if (error != NULL) g_propagate_error (&msg->error, error); @@ -511,7 +306,6 @@ static void ep_get_password (EPassMsg *msg) { EUri *uri; - GList *passwords; gchar *password; GError *error = NULL; @@ -526,73 +320,34 @@ ep_get_password (EPassMsg *msg) if (uri == NULL) goto exit; - /* Find the first Evolution password that matches the URI. */ - passwords = ep_keyring_lookup_passwords (uri->user, uri->host, uri->protocol, &error); - if (passwords != NULL) { - GList *iter = passwords; - - while (iter != NULL) { - GnomeKeyringFound *found = iter->data; - - if (default_keyring && strcmp (default_keyring, found->keyring) != 0) { - g_message ("Received a password from keyring '%s'. But looking for the password from '%s' keyring\n", found->keyring, default_keyring); - iter = g_list_next (iter); - continue; - } - - if (ep_keyring_validate (uri->user, uri->host, uri->protocol, found->attributes)) { - msg->password = g_strdup (found->secret); - break; - } - - iter = g_list_next (iter); - } - - gnome_keyring_found_list_free (passwords); - } + msg->password = secret_password_lookup_sync ( + &e_passwords_schema, NULL, &error, + "application", "Evolution", + "user", uri->user, + "server", uri->host, + "protocol", uri->protocol, + NULL); if (msg->password != NULL) goto done; - /* Clear the previous error, if there was one. If the error was - * something other than NO_MATCH then it's likely to occur again. */ + /* Clear the previous error, if there was one. + * It's likely to occur again. */ if (error != NULL) g_clear_error (&error); /* XXX We didn't always store protocols in the keyring, so for * backward-compatibility we also need to lookup passwords * by user and host only (no protocol). */ - passwords = ep_keyring_lookup_passwords (uri->user, uri->host, NULL, &error); - if (passwords != NULL) { - GList *iter = passwords; - - while (iter != NULL) { - GnomeKeyringFound *found = iter->data; - - if (default_keyring && strcmp (default_keyring, found->keyring) != 0) { - g_message ("Received a password from keyring '%s'. But looking for the password from '%s' keyring\n", found->keyring, default_keyring); - iter = g_list_next (iter); - continue; - } - if (ep_keyring_validate (uri->user, uri->host, NULL, found->attributes)) { - msg->password = g_strdup (found->secret); - break; - } - - iter = g_list_next (iter); - } - - gnome_keyring_found_list_free (passwords); - } + msg->password = secret_password_lookup_sync ( + &e_passwords_schema, NULL, &error, + "application", "Evolution", + "user", uri->user, + "server", uri->host, + NULL); done: - /* Not finding the requested key is acceptable, but we still - * want to leave an informational message on the terminal. */ - if (g_error_matches (error, EP_KEYRING_ERROR, GNOME_KEYRING_RESULT_NO_MATCH)) { - g_message ("%s", error->message); - g_error_free (error); - - } else if (error != NULL) + if (error != NULL) g_propagate_error (&msg->error, error); e_uri_free (uri); @@ -873,8 +628,6 @@ e_passwords_init (void) (GDestroyNotify) g_free, (GDestroyNotify) g_free); main_thread = g_thread_self (); - - gnome_keyring_get_default_keyring_sync (&default_keyring); } G_UNLOCK (passwords); @@ -920,8 +673,6 @@ e_passwords_shutdown (void) password_cache = NULL; } - g_free (default_keyring); - G_UNLOCK (passwords); if (password_dialog != NULL) @@ -953,7 +704,7 @@ e_passwords_set_online (gint state) void e_passwords_forget_passwords (void) { - EPassMsg *msg = ep_msg_new (ep_forget_passwords); + EPassMsg *msg = ep_msg_new (ep_clear_passwords); ep_msg_send (msg); ep_msg_free (msg); |
