[evolution-ews] Bug #679303 - Doesn't detect when password has changed



commit e200e1a58b526d26961b2adff800bff8eba22092
Author: Milan Crha <mcrha redhat com>
Date:   Tue Jul 3 19:09:08 2012 +0200

    Bug #679303 - Doesn't detect when password has changed

 src/camel/camel-ews-folder.c  |  146 ++++++++++++++++++++++++++++++-----------
 src/camel/camel-ews-store.c   |   78 ++++++++++++++++------
 src/camel/camel-ews-store.h   |    3 +
 src/server/e-ews-connection.c |   23 +++++--
 src/server/e-ews-connection.h |    3 +
 5 files changed, 186 insertions(+), 67 deletions(-)
---
diff --git a/src/camel/camel-ews-folder.c b/src/camel/camel-ews-folder.c
index c8be750..f367228 100644
--- a/src/camel/camel-ews-folder.c
+++ b/src/camel/camel-ews-folder.c
@@ -391,6 +391,7 @@ camel_ews_folder_get_message (CamelFolder *folder,
 	const gchar *temp;
 	gboolean res;
 	gchar *mime_fname_new = NULL;
+	GError *local_error = NULL;
 
 	ews_store = (CamelEwsStore *) camel_folder_get_parent_store (folder);
 	ews_folder = (CamelEwsFolder *) folder;
@@ -445,11 +446,14 @@ camel_ews_folder_get_message (CamelFolder *folder,
 		&items,
 		(ESoapProgressFn) camel_operation_progress,
 		(gpointer) cancellable,
-		cancellable, error);
+		cancellable, &local_error);
 	g_free (mime_dir);
 
-	if (!res)
+	if (!res) {
+		camel_ews_store_maybe_disconnect (ews_store, local_error);
+		g_propagate_error (error, local_error);
 		goto exit;
+	}
 
 	/* The mime_content actually contains the *filename*, due to the
 	 * streaming hack in ESoapMessage */
@@ -475,12 +479,16 @@ camel_ews_folder_get_message (CamelFolder *folder,
 			&items_req,
 			(ESoapProgressFn) camel_operation_progress,
 			(gpointer) cancellable,
-			cancellable, error);
+			cancellable, &local_error);
 		if (!res || (items_req && e_ews_item_get_item_type (items_req->data) == E_EWS_ITEM_TYPE_ERROR)) {
 			if (items_req) {
 				g_object_unref (items_req->data);
 				g_slist_free (items_req);
 			}
+			if (local_error) {
+				camel_ews_store_maybe_disconnect (ews_store, local_error);
+				g_propagate_error (error, local_error);
+			}
 			goto exit;
 		}
 		calendar_item_accept_id = e_ews_item_get_calendar_item_accept_id (items_req->data);
@@ -781,16 +789,30 @@ ews_sync_mi_flags (CamelFolder *folder,
 {
 	CamelEwsStore *ews_store;
 	EEwsConnection *cnc;
+	GError *local_error = NULL;
+	gboolean res;
 
 	ews_store = (CamelEwsStore *) camel_folder_get_parent_store (folder);
+
+	if (!camel_ews_store_connected (ews_store, error)) {
+		return FALSE;
+	}
+
 	cnc = camel_ews_store_get_connection (ews_store);
 
-	return e_ews_connection_update_items_sync (
+	res = e_ews_connection_update_items_sync (
 		cnc, EWS_PRIORITY_LOW,
 		"AlwaysOverwrite", "SaveOnly",
 		NULL, NULL,
 		msg_update_flags, mi_list, NULL,
-		cancellable, error);
+		cancellable, &local_error);
+
+	if (local_error) {
+		camel_ews_store_maybe_disconnect (ews_store, local_error);
+		g_propagate_error (error, local_error);
+	}
+
+	return res;
 }
 
 static gboolean
@@ -843,6 +865,9 @@ ews_move_to_junk_folder (CamelFolder *folder,
 	ews_folder = CAMEL_EWS_FOLDER (folder);
 	ews_store = CAMEL_EWS_STORE (parent_store);
 
+	if (!camel_ews_store_connected (ews_store, error))
+		return FALSE;
+
 	cnc = camel_ews_store_get_connection (ews_store);
 
 	if (junk_uids) {
@@ -890,8 +915,10 @@ ews_move_to_junk_folder (CamelFolder *folder,
 			camel_folder_change_info_free (changes);
 		}
 
-		if (local_error)
+		if (local_error) {
+			camel_ews_store_maybe_disconnect (ews_store, local_error);
 			g_propagate_error (error, local_error);
+		}
 
 		g_slist_free_full (junk_uids, (GDestroyNotify) camel_pstring_free);
 	}
@@ -1095,9 +1122,13 @@ sync_updated_items (CamelEwsFolder *ews_folder,
                     GCancellable *cancellable,
                     GError **error)
 {
+	CamelEwsStore *ews_store;
 	CamelFolder *folder = (CamelFolder *) ews_folder;
 	GSList *items = NULL, *l;
 	GSList *generic_item_ids = NULL, *msg_ids = NULL;
+	GError *local_error = NULL;
+
+	ews_store = CAMEL_EWS_STORE (camel_folder_get_parent_store (folder));
 
 	for (l = updated_items; l != NULL; l = g_slist_next (l)) {
 		EEwsItem *item = (EEwsItem *) l->data;
@@ -1134,21 +1165,29 @@ sync_updated_items (CamelEwsFolder *ews_folder,
 			g_object_ref (cnc), EWS_PRIORITY_MEDIUM,
 			 msg_ids, "IdOnly", SUMMARY_MESSAGE_FLAGS,
 			 FALSE, NULL, &items, NULL, NULL,
-			 cancellable, error);
+			 cancellable, &local_error);
 
 	camel_ews_utils_sync_updated_items (ews_folder, items);
 	items = NULL;
-	if (*error)
+	if (local_error) {
+		camel_ews_store_maybe_disconnect (ews_store, local_error);
+		g_propagate_error (error, local_error);
 		goto exit;
+	}
 
 	if (generic_item_ids)
 		e_ews_connection_get_items_sync (
 			g_object_ref (cnc), EWS_PRIORITY_MEDIUM,
 			generic_item_ids, "IdOnly", SUMMARY_ITEM_FLAGS,
 			FALSE, NULL, &items, NULL, NULL,
-			cancellable, error);
+			cancellable, &local_error);
 	camel_ews_utils_sync_updated_items (ews_folder, items);
 
+	if (local_error) {
+		camel_ews_store_maybe_disconnect (ews_store, local_error);
+		g_propagate_error (error, local_error);
+	}
+
 exit:
 	if (msg_ids) {
 		g_slist_foreach (msg_ids, (GFunc) g_free, NULL);
@@ -1168,8 +1207,12 @@ sync_created_items (CamelEwsFolder *ews_folder,
                     GCancellable *cancellable,
                     GError **error)
 {
+	CamelEwsStore *ews_store;
 	GSList *items = NULL, *l;
 	GSList *generic_item_ids = NULL, *msg_ids = NULL, *post_item_ids = NULL;
+	GError *local_error = NULL;
+
+	ews_store = CAMEL_EWS_STORE (camel_folder_get_parent_store (CAMEL_FOLDER (ews_folder)));
 
 	for (l = created_items; l != NULL; l = g_slist_next (l)) {
 		EEwsItem *item = (EEwsItem *) l->data;
@@ -1205,10 +1248,13 @@ sync_created_items (CamelEwsFolder *ews_folder,
 			g_object_ref (cnc), EWS_PRIORITY_MEDIUM,
 			msg_ids, "IdOnly", SUMMARY_MESSAGE_PROPS,
 			FALSE, NULL, &items, NULL, NULL,
-			cancellable, error);
+			cancellable, &local_error);
 
-	if (*error)
+	if (local_error) {
+		camel_ews_store_maybe_disconnect (ews_store, local_error);
+		g_propagate_error (error, local_error);
 		goto exit;
+	}
 
 	camel_ews_utils_sync_created_items (ews_folder, cnc, items);
 	items = NULL;
@@ -1218,10 +1264,13 @@ sync_created_items (CamelEwsFolder *ews_folder,
 			g_object_ref (cnc), EWS_PRIORITY_MEDIUM,
 			post_item_ids, "IdOnly", SUMMARY_POSTITEM_PROPS,
 			FALSE, NULL, &items, NULL, NULL,
-			cancellable, error);
+			cancellable, &local_error);
 
-	if (*error)
+	if (local_error) {
+		camel_ews_store_maybe_disconnect (ews_store, local_error);
+		g_propagate_error (error, local_error);
 		goto exit;
+	}
 
 	camel_ews_utils_sync_created_items (ews_folder, cnc, items);
 	items = NULL;
@@ -1231,10 +1280,14 @@ sync_created_items (CamelEwsFolder *ews_folder,
 			g_object_ref (cnc), EWS_PRIORITY_MEDIUM,
 			generic_item_ids, "IdOnly", SUMMARY_ITEM_PROPS,
 			FALSE, NULL, &items, NULL, NULL,
-			cancellable, error);
+			cancellable, &local_error);
 
 	camel_ews_utils_sync_created_items (ews_folder, cnc, items);
 
+	if (local_error) {
+		camel_ews_store_maybe_disconnect (ews_store, local_error);
+		g_propagate_error (error, local_error);
+	}
 exit:
 	if (msg_ids) {
 		g_slist_foreach (msg_ids, (GFunc) g_free, NULL);
@@ -1265,7 +1318,7 @@ ews_refresh_info_sync (CamelFolder *folder,
 	gchar *id;
 	gchar *sync_state;
 	gboolean includes_last_item = FALSE;
-	GError *rerror = NULL;
+	GError *local_error = NULL;
 
 	full_name = camel_folder_get_full_name (folder);
 	ews_store = (CamelEwsStore *) camel_folder_get_parent_store (folder);
@@ -1310,18 +1363,20 @@ ews_refresh_info_sync (CamelFolder *folder,
 			"IdOnly", NULL,
 			EWS_MAX_FETCH_COUNT, &includes_last_item,
 			&items_created, &items_updated,
-			&items_deleted, cancellable, &rerror);
+			&items_deleted, cancellable, &local_error);
 
-		if (rerror)
+		if (local_error) {
+			camel_ews_store_maybe_disconnect (ews_store, local_error);
 			break;
+		}
 
 		if (items_deleted)
 			camel_ews_utils_sync_deleted_items (ews_folder, items_deleted);
 
 		if (items_created)
-			sync_created_items (ews_folder, cnc, items_created, cancellable, &rerror);
+			sync_created_items (ews_folder, cnc, items_created, cancellable, &local_error);
 
-		if (rerror) {
+		if (local_error) {
 			if (items_updated) {
 				g_slist_foreach (items_updated, (GFunc) g_object_unref, NULL);
 				g_slist_free (items_updated);
@@ -1331,9 +1386,9 @@ ews_refresh_info_sync (CamelFolder *folder,
 		}
 
 		if (items_updated)
-			sync_updated_items (ews_folder, cnc, items_updated, cancellable, &rerror);
+			sync_updated_items (ews_folder, cnc, items_updated, cancellable, &local_error);
 
-		if (rerror)
+		if (local_error)
 			break;
 
 		total = camel_folder_summary_count (folder->summary);
@@ -1349,10 +1404,10 @@ ews_refresh_info_sync (CamelFolder *folder,
 		camel_folder_summary_touch (folder->summary);
 		camel_folder_summary_save_to_db (folder->summary, NULL);
 
-	} while (!rerror && !includes_last_item);
+	} while (!local_error && !includes_last_item);
 
-	if (rerror)
-		g_propagate_error (error, rerror);
+	if (local_error)
+		g_propagate_error (error, local_error);
 
 	g_mutex_lock (priv->state_lock);
 	priv->refreshing = FALSE;
@@ -1362,7 +1417,7 @@ ews_refresh_info_sync (CamelFolder *folder,
 	g_object_unref (cnc);
 	g_free (id);
 
-	return !rerror;
+	return !local_error;
 }
 
 static gboolean
@@ -1379,6 +1434,7 @@ ews_append_message_sync (CamelFolder *folder,
 	CamelAddress *from;
 	CamelEwsStore *ews_store;
 	EEwsConnection *cnc;
+	GError *local_error = NULL;
 
 	ews_store = (CamelEwsStore *) camel_folder_get_parent_store (folder);
 
@@ -1390,6 +1446,10 @@ ews_append_message_sync (CamelFolder *folder,
 
 	from = CAMEL_ADDRESS (camel_mime_message_get_from (message));
 
+	if (!camel_ews_store_connected (ews_store, error)) {
+		return FALSE;
+	}
+
 	cnc = camel_ews_store_get_connection (ews_store);
 
 	if (!cnc) {
@@ -1402,7 +1462,9 @@ ews_append_message_sync (CamelFolder *folder,
 						  message,
 						  camel_message_info_flags (info),
 						  from, &itemid, &changekey,
-						  cancellable, error)) {
+						  cancellable, &local_error)) {
+		camel_ews_store_maybe_disconnect (ews_store, local_error);
+		g_propagate_error (error, local_error);
 		g_free (folder_id);
 		g_object_unref (cnc);
 		return FALSE;
@@ -1437,7 +1499,7 @@ ews_transfer_messages_to_sync (CamelFolder *source,
 	CamelFolderChangeInfo *changes = NULL;
 	const gchar *dst_full_name;
 	gchar *dst_id;
-	GError *rerror = NULL;
+	GError *local_error = NULL;
 	GSList *ids = NULL, *ret_items = NULL;
 	gint i = 0;
 
@@ -1460,7 +1522,7 @@ ews_transfer_messages_to_sync (CamelFolder *source,
 			cnc, EWS_PRIORITY_MEDIUM,
 			dst_id, !delete_originals,
 			ids, &ret_items,
-			cancellable, &rerror)) {
+			cancellable, &local_error)) {
 
 		if (delete_originals) {
 			changes = camel_folder_change_info_new ();
@@ -1478,14 +1540,16 @@ ews_transfer_messages_to_sync (CamelFolder *source,
 	}
 	g_free (dst_id);
 
-	if (rerror)
-		g_propagate_error (error, rerror);
+	if (local_error) {
+		camel_ews_store_maybe_disconnect (dst_ews_store, local_error);
+		g_propagate_error (error, local_error);
+	}
 
 	g_object_unref (cnc);
 	g_slist_free (ids);
 	g_slist_free_full (ret_items, g_object_unref);
 
-	return !rerror;
+	return !local_error;
 }
 
 static gboolean
@@ -1508,25 +1572,29 @@ ews_delete_messages (CamelFolder *folder,
 	ews_store = CAMEL_EWS_STORE (parent_store);
 	deleted_head = deleted_items;
 
+	if (!camel_ews_store_connected (ews_store, error)) {
+		return FALSE;
+	}
+
 	cnc = camel_ews_store_get_connection (ews_store);
 	changes = camel_folder_change_info_new ();
 
 	if (deleted_items) {
-		GError *rerror = NULL;
+		GError *local_error = NULL;
 		EwsDeleteType delete_type;
 
 		delete_type = expunge ? EWS_HARD_DELETE : EWS_MOVE_TO_DELETED_ITEMS;
 
 		status = e_ews_connection_delete_items_sync (
 			cnc, EWS_PRIORITY_MEDIUM, deleted_items, delete_type,
-			EWS_SEND_TO_NONE, FALSE, cancellable, &rerror);
+			EWS_SEND_TO_NONE, FALSE, cancellable, &local_error);
 
-		if (!status && rerror->code == EWS_CONNECTION_ERROR_ITEMNOTFOUND) {
+		if (!status && local_error->code == EWS_CONNECTION_ERROR_ITEMNOTFOUND) {
 			/* If delete failed due to the item not found, ignore the error,
 			 * trigger folder info refresh and then go on to clear the
 			 * cache of the deleted items anyway. */
-			g_clear_error (&rerror);
-			status = ews_refresh_info_sync (folder, cancellable, &rerror);
+			g_clear_error (&local_error);
+			status = ews_refresh_info_sync (folder, cancellable, &local_error);
 		}
 
 		if (status) {
@@ -1541,8 +1609,10 @@ ews_delete_messages (CamelFolder *folder,
 			}
 		}
 
-		if (rerror)
-			g_propagate_error (error, rerror);
+		if (local_error) {
+			camel_ews_store_maybe_disconnect (ews_store, local_error);
+			g_propagate_error (error, local_error);
+		}
 
 		camel_folder_changed (folder, changes);
 
diff --git a/src/camel/camel-ews-store.c b/src/camel/camel-ews-store.c
index 45b6102..71065b1 100644
--- a/src/camel/camel-ews-store.c
+++ b/src/camel/camel-ews-store.c
@@ -322,17 +322,15 @@ ews_disconnect_sync (CamelService *service,
 	CamelEwsStore *ews_store = (CamelEwsStore *) service;
 	CamelServiceClass *service_class;
 
-	service_class = CAMEL_SERVICE_CLASS (camel_ews_store_parent_class);
-	if (!service_class->disconnect_sync (service, clean, cancellable, error))
-		return FALSE;
-
 	/* TODO cancel all operations in the connection */
 	if (ews_store->priv->cnc) {
+		e_ews_connection_forget_password (ews_store->priv->cnc);
 		g_object_unref (ews_store->priv->cnc);
 		ews_store->priv->cnc = NULL;
 	}
 
-	return TRUE;
+	service_class = CAMEL_SERVICE_CLASS (camel_ews_store_parent_class);
+	return service_class->disconnect_sync (service, clean, cancellable, error);
 }
 
 typedef struct {
@@ -424,8 +422,9 @@ ews_authenticate_sync (CamelService *service,
 			ews_store, sync_state, includes_last_folder,
 			folders_created, folders_deleted, folders_updated);
 	} else {
+		g_free (sync_state);
+
 		/* Make sure we're not leaking anything. */
-		g_warn_if_fail (sync_state == NULL);
 		g_warn_if_fail (folders_created == NULL);
 		g_warn_if_fail (folders_updated == NULL);
 		g_warn_if_fail (folders_deleted == NULL);
@@ -470,9 +469,11 @@ ews_authenticate_sync (CamelService *service,
 		result = CAMEL_AUTHENTICATION_ACCEPTED;
 	} else if (g_error_matches (local_error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_AUTHENTICATION_FAILED)) {
 		g_clear_error (&local_error);
+		e_ews_connection_forget_password (priv->cnc);
 		result = CAMEL_AUTHENTICATION_REJECTED;
 	} else {
 		g_propagate_error (error, local_error);
+		e_ews_connection_forget_password (priv->cnc);
 		result = CAMEL_AUTHENTICATION_ERROR;
 	}
 
@@ -613,6 +614,8 @@ ews_folder_hierarchy_ready_cb (GObject *obj,
 	if (error != NULL) {
 		g_warning ("Unable to fetch the folder hierarchy: %s :%d \n", error->message, error->code);
 
+		camel_ews_store_maybe_disconnect (ews_store, error);
+
 		g_mutex_lock (priv->get_finfo_lock);
 		ews_store->priv->last_refresh_time -= FINFO_REFRESH_INTERVAL;
 		g_mutex_unlock (priv->get_finfo_lock);
@@ -666,6 +669,7 @@ ews_get_folder_info_sync (CamelStore *store,
 	GSList *folders_created = NULL, *folders_updated = NULL;
 	GSList *folders_deleted = NULL;
 	gboolean includes_last_folder;
+	GError *local_error = NULL;
 
 	ews_store = (CamelEwsStore *) store;
 	priv = ews_store->priv;
@@ -696,13 +700,16 @@ ews_get_folder_info_sync (CamelStore *store,
 			ews_store->priv->cnc, EWS_PRIORITY_MEDIUM,
 			&sync_state, &includes_last_folder,
 			&folders_created, &folders_updated,
-			&folders_deleted, cancellable, error)) {
-		if (error)
+			&folders_deleted, cancellable, &local_error)) {
+		if (local_error)
 			g_warning ("Unable to fetch the folder hierarchy: %s :%d \n",
-				   (*error)->message, (*error)->code);
+				   local_error->message, local_error->code);
 		else
 			g_warning ("Unable to fetch the folder hierarchy.\n");
 
+		camel_ews_store_maybe_disconnect (ews_store, local_error);
+		g_propagate_error (error, local_error);
+
 		g_mutex_unlock (priv->get_finfo_lock);
 		return NULL;
 	}
@@ -728,6 +735,7 @@ ews_create_folder_sync (CamelStore *store,
 	gchar *full_name;
 	EwsFolderId *folder_id;
 	CamelFolderInfo *fi = NULL;
+	GError *local_error = NULL;
 
 	/* Get Parent folder ID */
 	if (parent_name && parent_name[0]) {
@@ -740,9 +748,7 @@ ews_create_folder_sync (CamelStore *store,
 		}
 	}
 
-	if (!ews_store->priv->cnc) {
-		g_set_error (error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
-			     _("Cant perform actions on the folder while in offline mode"));
+	if (!camel_ews_store_connected (ews_store, error)) {
 		if (fid) g_free (fid);
 		return NULL;
 	}
@@ -752,7 +758,9 @@ ews_create_folder_sync (CamelStore *store,
 			ews_store->priv->cnc,
 			EWS_PRIORITY_MEDIUM, fid,
 			FALSE, folder_name, &folder_id,
-			cancellable, error)) {
+			cancellable, &local_error)) {
+		camel_ews_store_maybe_disconnect (ews_store, local_error);
+		g_propagate_error (error, local_error);
 		g_free (fid);
 		return NULL;
 	}
@@ -788,6 +796,7 @@ ews_delete_folder_sync (CamelStore *store,
 	CamelEwsStoreSummary *ews_summary = ews_store->summary;
 	gchar *fid;
 	CamelFolderInfo *fi = NULL;
+	GError *local_error = NULL;
 
 	fid = camel_ews_store_summary_get_folder_id_from_name (ews_summary,
 							       folder_name);
@@ -797,9 +806,7 @@ ews_delete_folder_sync (CamelStore *store,
 		return FALSE;
 	}
 
-	if (!ews_store->priv->cnc) {
-		g_set_error (error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
-			     _("Cant perform actions on the folder while in offline mode"));
+	if (!camel_ews_store_connected (ews_store, error)) {
 		g_free (fid);
 		return FALSE;
 	}
@@ -808,7 +815,9 @@ ews_delete_folder_sync (CamelStore *store,
 			ews_store->priv->cnc,
 			EWS_PRIORITY_MEDIUM,
 			fid, FALSE, "HardDelete",
-			cancellable, error)) {
+			cancellable, &local_error)) {
+		camel_ews_store_maybe_disconnect (ews_store, local_error);
+		g_propagate_error (error, local_error);
 		g_free (fid);
 		return FALSE;
 	}
@@ -864,13 +873,12 @@ ews_rename_folder_sync (CamelStore *store,
 	gchar *fid;
 	gchar *changekey;
 	gboolean res = FALSE;
+	GError *local_error = NULL;
 
 	if (!strcmp (old_name, new_name))
 		return TRUE;
 
-	if (!ews_store->priv->cnc) {
-		g_set_error (error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
-			     _("Cant perform actions on the folder while in offline mode"));
+	if (!camel_ews_store_connected (ews_store, error)) {
 		return FALSE;
 	}
 
@@ -938,7 +946,7 @@ ews_rename_folder_sync (CamelStore *store,
 
 		if (!e_ews_connection_update_folder_sync (
 				ews_store->priv->cnc, EWS_PRIORITY_MEDIUM,
-				rename_folder_cb, rename_data, cancellable, error)) {
+				rename_folder_cb, rename_data, cancellable, &local_error)) {
 			g_free (rename_data);
 			goto out;
 		}
@@ -965,7 +973,7 @@ ews_rename_folder_sync (CamelStore *store,
 		}
 		if (!e_ews_connection_move_folder_sync (
 				ews_store->priv->cnc, EWS_PRIORITY_MEDIUM,
-				pfid, fid, cancellable, error)) {
+				pfid, fid, cancellable, &local_error)) {
 			g_free (pfid);
 			goto out;
 		}
@@ -975,6 +983,11 @@ ews_rename_folder_sync (CamelStore *store,
 
 	res = TRUE;
  out:
+	if (local_error) {
+		camel_ews_store_maybe_disconnect (ews_store, local_error);
+		g_propagate_error (error, local_error);
+	}
+
 	g_free (changekey);
 	g_free (fid);
 	return res;
@@ -1084,6 +1097,27 @@ camel_ews_store_connected (CamelEwsStore *ews_store,
 	return TRUE;
 }
 
+void
+camel_ews_store_maybe_disconnect (CamelEwsStore *store,
+				  const GError *error)
+{
+	CamelService *service;
+
+	g_return_if_fail (store != NULL);
+
+	if (!error)
+		return;
+
+	service = CAMEL_SERVICE (store);
+
+	if (camel_service_get_connection_status (service) != CAMEL_SERVICE_CONNECTED)
+		return;
+
+	if (g_error_matches (error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_NORESPONSE) ||
+	    g_error_matches (error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_AUTHENTICATION_FAILED))
+		camel_service_disconnect_sync (service, FALSE, NULL, NULL);
+}
+
 static void
 ews_store_dispose (GObject *object)
 {
diff --git a/src/camel/camel-ews-store.h b/src/camel/camel-ews-store.h
index f7e1b31..5ac981d 100644
--- a/src/camel/camel-ews-store.h
+++ b/src/camel/camel-ews-store.h
@@ -76,6 +76,9 @@ EEwsConnection *
 
 gboolean	camel_ews_store_connected	(CamelEwsStore *store,
 						 GError **error);
+void		camel_ews_store_maybe_disconnect
+						(CamelEwsStore *store,
+						 const GError *error);
 
 G_END_DECLS
 
diff --git a/src/server/e-ews-connection.c b/src/server/e-ews-connection.c
index 0ababda..48e77e2 100644
--- a/src/server/e-ews-connection.c
+++ b/src/server/e-ews-connection.c
@@ -988,10 +988,7 @@ e_ews_connection_dispose (GObject *object)
 		priv->username = NULL;
 	}
 
-	if (priv->password) {
-		g_free (priv->password);
-		priv->password = NULL;
-	}
+	e_ews_connection_forget_password (cnc);
 
 	if (priv->email) {
 		g_free (priv->email);
@@ -1111,8 +1108,7 @@ ews_connection_authenticate (SoupSession *sess,
 	g_return_if_fail (cnc != NULL);
 
 	if (retrying) {
-		g_free (cnc->priv->password);
-		cnc->priv->password = NULL;
+		e_ews_connection_forget_password (cnc);
 	}
 
 	if (cnc->priv->password) {
@@ -1179,7 +1175,7 @@ e_ews_connection_authenticate (EEwsConnection *cnc,
 		cnc->priv->username = g_strdup (user);
 	}
 
-	g_free (cnc->priv->password);
+	e_ews_connection_forget_password (cnc);
 	cnc->priv->password = g_strdup (passwd);
 
 	soup_auth_authenticate (auth, cnc->priv->username,
@@ -1297,6 +1293,19 @@ e_ews_connection_new (const gchar *uri,
 
 }
 
+void
+e_ews_connection_forget_password (EEwsConnection *cnc)
+{
+	g_return_if_fail (cnc != NULL);
+
+	if (cnc->priv->password && *cnc->priv->password) {
+		memset (cnc->priv->password, 0, strlen (cnc->priv->password));
+	}
+
+	g_free (cnc->priv->password);
+	cnc->priv->password = NULL;
+}
+
 static xmlDoc *
 e_ews_autodiscover_ws_xml (const gchar *email_address)
 {
diff --git a/src/server/e-ews-connection.h b/src/server/e-ews-connection.h
index 9c06fe4..a7e7038 100644
--- a/src/server/e-ews-connection.h
+++ b/src/server/e-ews-connection.h
@@ -190,6 +190,9 @@ EEwsConnection *e_ews_connection_new		(const gchar *uri,
 						 GCallback authenticate_cb,
 						 gpointer authenticate_ctx,
 						 GError **error);
+void		e_ews_connection_forget_password
+						(EEwsConnection *cnc);
+
 EEwsConnection *e_ews_connection_find		(const gchar *uri,
 						 const gchar *username);
 void		e_ews_connection_authenticate	(EEwsConnection *cnc,



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