summaryrefslogtreecommitdiff
path: root/libedataserverui/e-passwords.c
diff options
context:
space:
mode:
Diffstat (limited to 'libedataserverui/e-passwords.c')
-rw-r--r--libedataserverui/e-passwords.c357
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);