[evolution-data-server] [CalDAV/CardDAV] Check for TLS/authentication errors on refresh
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] [CalDAV/CardDAV] Check for TLS/authentication errors on refresh
- Date: Mon, 28 Aug 2017 17:31:56 +0000 (UTC)
commit c823d109bc9b0364464e031011a42ec3e6bdc274
Author: Milan Crha <mcrha redhat com>
Date: Mon Aug 28 19:30:29 2017 +0200
[CalDAV/CardDAV] Check for TLS/authentication errors on refresh
By checking for the TLS/authentication errors in refresh function
the connected backend can recover when a password expires or
when the server changes its connection certificate.
.../backends/webdav/e-book-backend-webdav.c | 59 ++++++++++++++++----
.../backends/caldav/e-cal-backend-caldav.c | 59 ++++++++++++++++----
2 files changed, 94 insertions(+), 24 deletions(-)
---
diff --git a/src/addressbook/backends/webdav/e-book-backend-webdav.c
b/src/addressbook/backends/webdav/e-book-backend-webdav.c
index 79593f2..b4a16fa 100644
--- a/src/addressbook/backends/webdav/e-book-backend-webdav.c
+++ b/src/addressbook/backends/webdav/e-book-backend-webdav.c
@@ -554,6 +554,7 @@ ebb_webdav_get_changes_sync (EBookMetaBackend *meta_backend,
GHashTableIter iter;
gpointer key = NULL, value = NULL;
gboolean success;
+ GError *local_error = NULL;
g_return_val_if_fail (E_IS_BOOK_BACKEND_WEBDAV (meta_backend), FALSE);
g_return_val_if_fail (out_new_sync_tag, FALSE);
@@ -594,7 +595,7 @@ ebb_webdav_get_changes_sync (EBookMetaBackend *meta_backend,
known_items = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, e_book_meta_backend_info_free);
success = e_webdav_session_propfind_sync (bbdav->priv->webdav, NULL,
E_WEBDAV_DEPTH_THIS_AND_CHILDREN, xml,
- ebb_webdav_get_contact_items_cb, known_items, cancellable, error);
+ ebb_webdav_get_contact_items_cb, known_items, cancellable, &local_error);
g_object_unref (xml);
@@ -608,24 +609,21 @@ ebb_webdav_get_changes_sync (EBookMetaBackend *meta_backend,
book_cache = e_book_meta_backend_ref_cache (meta_backend);
- success = e_book_cache_search_with_callback (book_cache, NULL, ebb_webdav_search_changes_cb,
&ccd, cancellable, error);
+ success = e_book_cache_search_with_callback (book_cache, NULL, ebb_webdav_search_changes_cb,
&ccd, cancellable, &local_error);
g_clear_object (&book_cache);
}
- if (!success) {
- g_hash_table_destroy (known_items);
- return FALSE;
- }
-
- g_hash_table_iter_init (&iter, known_items);
- while (g_hash_table_iter_next (&iter, &key, &value)) {
- *out_created_objects = g_slist_prepend (*out_created_objects, e_book_meta_backend_info_copy
(value));
+ if (success) {
+ g_hash_table_iter_init (&iter, known_items);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ *out_created_objects = g_slist_prepend (*out_created_objects,
e_book_meta_backend_info_copy (value));
+ }
}
g_hash_table_destroy (known_items);
- if (*out_created_objects || *out_modified_objects) {
+ if (success && (*out_created_objects || *out_modified_objects)) {
GSList *link, *set2 = *out_modified_objects;
if (*out_created_objects) {
@@ -636,10 +634,47 @@ ebb_webdav_get_changes_sync (EBookMetaBackend *meta_backend,
}
do {
- success = ebb_webdav_multiget_from_sets_sync (bbdav, &link, &set2, cancellable,
error);
+ success = ebb_webdav_multiget_from_sets_sync (bbdav, &link, &set2, cancellable,
&local_error);
} while (success && link);
}
+ if (local_error && !g_cancellable_is_cancelled (cancellable)) {
+ ESourceCredentialsReason reason = E_SOURCE_CREDENTIALS_REASON_UNKNOWN;
+
+ if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED)) {
+ reason = E_SOURCE_CREDENTIALS_REASON_SSL_FAILED;
+ } else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED) ||
+ g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_FORBIDDEN)) {
+ reason = E_SOURCE_CREDENTIALS_REASON_REQUIRED;
+ }
+
+ if (reason != E_SOURCE_CREDENTIALS_REASON_UNKNOWN) {
+ GTlsCertificateFlags certificate_errors = 0;
+ gchar *certificate_pem = NULL;
+ GError *local_error2 = NULL;
+
+ if (!e_soup_session_get_ssl_error_details (E_SOUP_SESSION (bbdav->priv->webdav),
&certificate_pem, &certificate_errors)) {
+ certificate_pem = NULL;
+ certificate_errors = 0;
+ }
+
+ if (!e_backend_credentials_required_sync (E_BACKEND (bbdav), reason, certificate_pem,
certificate_errors,
+ local_error, cancellable, &local_error2)) {
+ g_warning ("%s: Failed to call credentials required: %s", G_STRFUNC,
local_error2 ? local_error2->message : "Unknown error");
+ } else {
+ /* Ignore the error when the caller had been notified through the
credentials-required */
+ g_clear_error (&local_error);
+ success = TRUE;
+ }
+
+ g_clear_error (&local_error2);
+ g_free (certificate_pem);
+ }
+ }
+
+ if (local_error)
+ g_propagate_error (error, local_error);
+
return success;
}
diff --git a/src/calendar/backends/caldav/e-cal-backend-caldav.c
b/src/calendar/backends/caldav/e-cal-backend-caldav.c
index 0421143..94a0984 100644
--- a/src/calendar/backends/caldav/e-cal-backend-caldav.c
+++ b/src/calendar/backends/caldav/e-cal-backend-caldav.c
@@ -589,6 +589,7 @@ ecb_caldav_get_changes_sync (ECalMetaBackend *meta_backend,
GHashTableIter iter;
gpointer key = NULL, value = NULL;
gboolean success;
+ GError *local_error = NULL;
g_return_val_if_fail (E_IS_CAL_BACKEND_CALDAV (meta_backend), FALSE);
g_return_val_if_fail (out_repeat, FALSE);
@@ -683,7 +684,7 @@ ecb_caldav_get_changes_sync (ECalMetaBackend *meta_backend,
known_items = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, e_cal_meta_backend_info_free);
success = e_webdav_session_report_sync (cbdav->priv->webdav, NULL, E_WEBDAV_DEPTH_THIS_AND_CHILDREN,
xml,
- ecb_caldav_get_calendar_items_cb, known_items, NULL, NULL, cancellable, error);
+ ecb_caldav_get_calendar_items_cb, known_items, NULL, NULL, cancellable, &local_error);
g_object_unref (xml);
@@ -698,24 +699,21 @@ ecb_caldav_get_changes_sync (ECalMetaBackend *meta_backend,
cal_cache = e_cal_meta_backend_ref_cache (meta_backend);
- success = e_cal_cache_search_with_callback (cal_cache, NULL, ecb_caldav_search_changes_cb,
&ccd, cancellable, error);
+ success = e_cal_cache_search_with_callback (cal_cache, NULL, ecb_caldav_search_changes_cb,
&ccd, cancellable, &local_error);
g_clear_object (&cal_cache);
}
- if (!success) {
- g_hash_table_destroy (known_items);
- return FALSE;
- }
-
- g_hash_table_iter_init (&iter, known_items);
- while (g_hash_table_iter_next (&iter, &key, &value)) {
- *out_created_objects = g_slist_prepend (*out_created_objects, e_cal_meta_backend_info_copy
(value));
+ if (success) {
+ g_hash_table_iter_init (&iter, known_items);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ *out_created_objects = g_slist_prepend (*out_created_objects,
e_cal_meta_backend_info_copy (value));
+ }
}
g_hash_table_destroy (known_items);
- if (*out_created_objects || *out_modified_objects) {
+ if (success && (*out_created_objects || *out_modified_objects)) {
GSList *link, *set2 = *out_modified_objects;
if (*out_created_objects) {
@@ -726,10 +724,47 @@ ecb_caldav_get_changes_sync (ECalMetaBackend *meta_backend,
}
do {
- success = ecb_caldav_multiget_from_sets_sync (cbdav, &link, &set2, cancellable,
error);
+ success = ecb_caldav_multiget_from_sets_sync (cbdav, &link, &set2, cancellable,
&local_error);
} while (success && link);
}
+ if (local_error && !g_cancellable_is_cancelled (cancellable)) {
+ ESourceCredentialsReason reason = E_SOURCE_CREDENTIALS_REASON_UNKNOWN;
+
+ if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED)) {
+ reason = E_SOURCE_CREDENTIALS_REASON_SSL_FAILED;
+ } else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED) ||
+ g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_FORBIDDEN)) {
+ reason = E_SOURCE_CREDENTIALS_REASON_REQUIRED;
+ }
+
+ if (reason != E_SOURCE_CREDENTIALS_REASON_UNKNOWN) {
+ GTlsCertificateFlags certificate_errors = 0;
+ gchar *certificate_pem = NULL;
+ GError *local_error2 = NULL;
+
+ if (!e_soup_session_get_ssl_error_details (E_SOUP_SESSION (cbdav->priv->webdav),
&certificate_pem, &certificate_errors)) {
+ certificate_pem = NULL;
+ certificate_errors = 0;
+ }
+
+ if (!e_backend_credentials_required_sync (E_BACKEND (cbdav), reason, certificate_pem,
certificate_errors,
+ local_error, cancellable, &local_error2)) {
+ g_warning ("%s: Failed to call credentials required: %s", G_STRFUNC,
local_error2 ? local_error2->message : "Unknown error");
+ } else {
+ /* Ignore the error when the caller had been notified through the
credentials-required */
+ g_clear_error (&local_error);
+ success = TRUE;
+ }
+
+ g_clear_error (&local_error2);
+ g_free (certificate_pem);
+ }
+ }
+
+ if (local_error)
+ g_propagate_error (error, local_error);
+
return success;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]