evolution-data-server r8812 - trunk/libedataserverui



Author: mbarnes
Date: Mon May 19 14:14:43 2008
New Revision: 8812
URL: http://svn.gnome.org/viewvc/evolution-data-server?rev=8812&view=rev

Log:
2008-05-19  Matthew Barnes  <mbarnes redhat com>

	** Fixes bug #354923

	* libedataserverui/e-passwords.c:
	Store passwords in the keyring by server, username and protocol.
	Storing the protocol allows us to handle situations where, for
	example, you use the same server and username for IMAP and
	authenticated SMTP but the passwords are different.

	Also add sufficient backward-compatibility cruft that we can still
	find existing passwords that are stored in the keyring by server
	and username only.



Modified:
   trunk/libedataserverui/ChangeLog
   trunk/libedataserverui/e-passwords.c

Modified: trunk/libedataserverui/e-passwords.c
==============================================================================
--- trunk/libedataserverui/e-passwords.c	(original)
+++ trunk/libedataserverui/e-passwords.c	Mon May 19 14:14:43 2008
@@ -212,19 +212,21 @@
 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)
+	if (user == NULL && server == NULL && protocol == NULL)
 		return TRUE;
 
-	/* Look for "user" and "server" attributes. */
+	/* Look for "user", "server", and "protocol" attributes. */
 	for (ii = 0; ii < attributes->len; ii++) {
 		GnomeKeyringAttribute *attr;
 
@@ -235,6 +237,8 @@
 			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? */
@@ -253,12 +257,21 @@
 	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)
 {
@@ -267,9 +280,14 @@
 		GnomeKeyringResult result;
 
 		/* Validate the item before deleting it. */
-		if (!ep_keyring_validate (user, server, found->attributes)) {
-			passwords = g_list_next (passwords);
-			continue;
+		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);
@@ -291,6 +309,7 @@
 static gboolean
 ep_keyring_insert_password (const gchar *user,
                             const gchar *server,
+                            const gchar *protocol,
                             const gchar *display_name,
                             const gchar *password,
                             GError **error)
@@ -301,6 +320,7 @@
 
 	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);
 
@@ -311,6 +331,8 @@
 		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! */
@@ -333,6 +355,7 @@
 static GList *
 ep_keyring_lookup_passwords (const gchar *user,
                              const gchar *server,
+                             const gchar *protocol,
                              GError **error)
 {
 	GnomeKeyringAttributeList *attributes;
@@ -348,6 +371,9 @@
 	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);
@@ -479,9 +505,9 @@
 	GError *error = NULL;
 
 	/* Find all Evolution passwords and delete them. */
-	passwords = ep_keyring_lookup_passwords (NULL, NULL, &error);
+	passwords = ep_keyring_lookup_passwords (NULL, NULL, NULL, &error);
 	if (passwords != NULL) {
-		ep_keyring_delete_passwords (NULL, NULL, passwords, &error);
+		ep_keyring_delete_passwords (NULL, NULL, NULL, passwords, &error);
 		gnome_keyring_found_list_free (passwords);
 	}
 
@@ -509,9 +535,9 @@
 
 	/* Not finding the requested group is acceptable, but we still
 	 * want to leave an informational message on the terminal. */
-        else if (g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) {
-                g_message ("%s", error->message);
-                g_error_free (error);
+	else if (g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) {
+		g_message ("%s", error->message);
+		g_error_free (error);
 
 	} else if (error != NULL)
 		g_propagate_error (&msg->error, error);
@@ -543,9 +569,9 @@
 	GError *error = NULL;
 
 	/* Find all Evolution passwords and delete them. */
-	passwords = ep_keyring_lookup_passwords (NULL, NULL, &error);
+	passwords = ep_keyring_lookup_passwords (NULL, NULL, NULL, &error);
 	if (passwords != NULL) {
-		ep_keyring_delete_passwords (NULL, NULL, passwords, &error);
+		ep_keyring_delete_passwords (NULL, NULL, NULL, passwords, &error);
 		gnome_keyring_found_list_free (passwords);
 
 	}
@@ -623,7 +649,7 @@
 
 	/* Only remove the password from the session hash
 	 * if the keyring insertion was successful. */
-	if (ep_keyring_insert_password (uri->user, uri->host, msg->key, password, &error))
+	if (ep_keyring_insert_password (uri->user, uri->host, uri->protocol, msg->key, password, &error))
 		g_hash_table_remove (password_cache, msg->key);
 
 	if (error != NULL)
@@ -684,10 +710,17 @@
 	uri = ep_keyring_uri_new (msg->key);
 	g_return_if_fail (uri != NULL);
 
-	/* Find all Evolution passwords matching the URI and delete them. */
-	passwords = ep_keyring_lookup_passwords (uri->user, uri->host, &error);
+	/* Find all Evolution passwords matching the URI and delete them.
+	 *
+	 * XXX We didn't always store protocols in the keyring, so for
+	 *     backward-compatibility we need to lookup passwords by user
+	 *     and host only (no protocol).  But we do send the protocol
+	 *     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, passwords, &error);
+		ep_keyring_delete_passwords (uri->user, uri->host, uri->protocol, passwords, &error);
 		gnome_keyring_found_list_free (passwords);
 	}
 
@@ -716,10 +749,10 @@
 		g_message ("%s", error->message);
 		g_error_free (error);
 
-        /* Not finding the requested group is also acceptable. */
-        } else if (g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) {
-                g_message ("%s", error->message);
-                g_error_free (error);
+	/* Not finding the requested group is also acceptable. */
+	} else if (g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) {
+		g_message ("%s", error->message);
+		g_error_free (error);
 
 	} else if (error != NULL)
 		g_propagate_error (&msg->error, error);
@@ -758,14 +791,43 @@
 	g_return_if_fail (uri != NULL);
 
 	/* Find the first Evolution password that matches the URI. */
-	passwords = ep_keyring_lookup_passwords (uri->user, uri->host, &error);
+	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 (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);
+	}
+
+	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. */
+	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 (ep_keyring_validate (uri->user, uri->host, found->attributes)) {
+			if (ep_keyring_validate (uri->user, uri->host, NULL, found->attributes)) {
 				msg->password = g_strdup (found->secret);
 				break;
 			}
@@ -776,6 +838,7 @@
 		gnome_keyring_found_list_free (passwords);
 	}
 
+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)) {
@@ -809,10 +872,10 @@
 		g_message ("%s", error->message);
 		g_error_free (error);
 
-        /* Not finding the requested group is also acceptable. */
-        } else if (g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) {
-                g_message ("%s", error->message);
-                g_error_free (error);
+	/* Not finding the requested group is also acceptable. */
+	} else if (g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) {
+		g_message ("%s", error->message);
+		g_error_free (error);
 
 	} else if (error != NULL)
 		g_propagate_error (&msg->error, error);
@@ -992,13 +1055,13 @@
 	gtk_dialog_set_has_separator (GTK_DIALOG (widget), FALSE);
 	gtk_dialog_set_default_response (
 		GTK_DIALOG (widget), GTK_RESPONSE_OK);
-        gtk_window_set_resizable (GTK_WINDOW (widget), FALSE);
+	gtk_window_set_resizable (GTK_WINDOW (widget), FALSE);
 	gtk_window_set_transient_for (GTK_WINDOW (widget), msg->parent);
 	gtk_window_set_position (GTK_WINDOW (widget), GTK_WIN_POS_CENTER_ON_PARENT);
 	gtk_container_set_border_width (GTK_CONTAINER (widget), 12);
 	password_dialog = GTK_DIALOG (widget);
 
-        /* Override GtkDialog defaults */
+	/* Override GtkDialog defaults */
 	widget = password_dialog->vbox;
 	gtk_box_set_spacing (GTK_BOX (widget), 12);
 	gtk_container_set_border_width (GTK_CONTAINER (widget), 0);
@@ -1031,7 +1094,7 @@
 	/* Password Label */
 	widget = gtk_label_new (NULL);
 	gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
-        gtk_label_set_markup (GTK_LABEL (widget), msg->prompt);
+	gtk_label_set_markup (GTK_LABEL (widget), msg->prompt);
 	gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
 	gtk_widget_show (widget);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]