[evolution-data-server] Bug #699797 - Verify SSL trust after redirection



commit 64875ea215804fcec8c3db55200eae84f8d603ea
Author: Matt McCutchen <matt mattmccutchen net>
Date:   Fri Apr 18 17:44:10 2014 +0200

    Bug #699797 - Verify SSL trust after redirection

 .../backends/webdav/e-book-backend-webdav.c        |   35 +---
 calendar/backends/caldav/e-cal-backend-caldav.c    |   39 +----
 calendar/backends/http/e-cal-backend-http.c        |   36 +----
 docs/reference/eds/eds-sections.txt                |    6 +
 libebackend/Makefile.am                            |    2 +
 libebackend/e-soup-ssl-trust.c                     |  187 ++++++++++++++++++++
 libebackend/e-soup-ssl-trust.h                     |   38 ++++
 libebackend/libebackend.h                          |    1 +
 libedataserver/e-source-webdav.c                   |   87 +++++-----
 libedataserver/e-source-webdav.h                   |    6 +
 modules/owncloud-backend/owncloud-utils.c          |   63 +------
 modules/trust-prompt/trust-prompt-gtk.c            |    1 -
 12 files changed, 303 insertions(+), 198 deletions(-)
---
diff --git a/addressbook/backends/webdav/e-book-backend-webdav.c 
b/addressbook/backends/webdav/e-book-backend-webdav.c
index 891cad1..cc9c6a9 100644
--- a/addressbook/backends/webdav/e-book-backend-webdav.c
+++ b/addressbook/backends/webdav/e-book-backend-webdav.c
@@ -228,37 +228,12 @@ send_and_handle_ssl (EBookBackendWebdav *webdav,
 {
        guint status_code;
 
-       status_code = soup_session_send_message (webdav->priv->session, message);
-       if (status_code == SOUP_STATUS_SSL_FAILED) {
-               ESource *source;
-               ESourceWebdav *extension;
-               ESourceRegistry *registry;
-               EBackend *backend;
-               ETrustPromptResponse response;
-               ENamedParameters *parameters;
-
-               backend = E_BACKEND (webdav);
-               source = e_backend_get_source (backend);
-               registry = e_book_backend_get_registry (E_BOOK_BACKEND (backend));
-               extension = e_source_get_extension (source, E_SOURCE_EXTENSION_WEBDAV_BACKEND);
-
-               parameters = e_named_parameters_new ();
-
-               response = e_source_webdav_prepare_ssl_trust_prompt (extension, message, registry, 
parameters);
-               if (response == E_TRUST_PROMPT_RESPONSE_UNKNOWN) {
-                       response = e_backend_trust_prompt_sync (backend, parameters, cancellable, NULL);
-                       if (response != E_TRUST_PROMPT_RESPONSE_UNKNOWN)
-                               e_source_webdav_store_ssl_trust_prompt (extension, message, response);
-               }
-
-               e_named_parameters_free (parameters);
+       e_soup_ssl_trust_connect (
+               message, e_backend_get_source (E_BACKEND (webdav)),
+               e_book_backend_get_registry (E_BOOK_BACKEND (webdav)),
+               cancellable);
 
-               if (response == E_TRUST_PROMPT_RESPONSE_ACCEPT ||
-                   response == E_TRUST_PROMPT_RESPONSE_ACCEPT_TEMPORARILY) {
-                       g_object_set (webdav->priv->session, SOUP_SESSION_SSL_STRICT, FALSE, NULL);
-                       status_code = soup_session_send_message (webdav->priv->session, message);
-               }
-       }
+       status_code = soup_session_send_message (webdav->priv->session, message);
 
        return status_code;
 }
diff --git a/calendar/backends/caldav/e-cal-backend-caldav.c b/calendar/backends/caldav/e-cal-backend-caldav.c
index b95993e..962f359 100644
--- a/calendar/backends/caldav/e-cal-backend-caldav.c
+++ b/calendar/backends/caldav/e-cal-backend-caldav.c
@@ -1103,42 +1103,16 @@ send_and_handle_redirection (ECalBackendCalDAV *cbdav,
        if (new_location)
                old_uri = soup_uri_to_string (soup_message_get_uri (msg), FALSE);
 
+       e_soup_ssl_trust_connect (
+               msg, e_backend_get_source (E_BACKEND (cbdav)),
+               e_cal_backend_get_registry (E_CAL_BACKEND (cbdav)),
+               cancellable);
+
        soup_message_set_flags (msg, SOUP_MESSAGE_NO_REDIRECT);
        soup_message_add_header_handler (msg, "got_body", "Location", G_CALLBACK (redirect_handler), 
cbdav->priv->session);
        soup_message_headers_append (msg->request_headers, "Connection", "close");
        soup_session_send_message (cbdav->priv->session, msg);
 
-       if (msg->status_code == SOUP_STATUS_SSL_FAILED) {
-               ESource *source;
-               ESourceWebdav *extension;
-               ESourceRegistry *registry;
-               EBackend *backend;
-               ETrustPromptResponse response;
-               ENamedParameters *parameters;
-
-               backend = E_BACKEND (cbdav);
-               source = e_backend_get_source (backend);
-               registry = e_cal_backend_get_registry (E_CAL_BACKEND (backend));
-               extension = e_source_get_extension (source, E_SOURCE_EXTENSION_WEBDAV_BACKEND);
-
-               parameters = e_named_parameters_new ();
-
-               response = e_source_webdav_prepare_ssl_trust_prompt (extension, msg, registry, parameters);
-               if (response == E_TRUST_PROMPT_RESPONSE_UNKNOWN) {
-                       response = e_backend_trust_prompt_sync (backend, parameters, cancellable, error);
-                       if (response != E_TRUST_PROMPT_RESPONSE_UNKNOWN)
-                               e_source_webdav_store_ssl_trust_prompt (extension, msg, response);
-               }
-
-               e_named_parameters_free (parameters);
-
-               if (response == E_TRUST_PROMPT_RESPONSE_ACCEPT ||
-                   response == E_TRUST_PROMPT_RESPONSE_ACCEPT_TEMPORARILY) {
-                       g_object_set (cbdav->priv->session, SOUP_SESSION_SSL_STRICT, FALSE, NULL);
-                       soup_session_send_message (cbdav->priv->session, msg);
-               }
-       }
-
        if (new_location) {
                gchar *new_loc = soup_uri_to_string (soup_message_get_uri (msg), FALSE);
 
@@ -1194,9 +1168,6 @@ caldav_server_open_calendar (ECalBackendCalDAV *cbdav,
                message->request_headers,
                "User-Agent", "Evolution/" VERSION);
 
-       /* re-check server's certificate trust, if needed */
-       g_object_set (cbdav->priv->session, SOUP_SESSION_SSL_STRICT, TRUE, NULL);
-
        source = e_backend_get_source (E_BACKEND (cbdav));
        webdav_extension = e_source_get_extension (source, E_SOURCE_EXTENSION_WEBDAV_BACKEND);
        e_source_webdav_unset_temporary_ssl_trust (webdav_extension);
diff --git a/calendar/backends/http/e-cal-backend-http.c b/calendar/backends/http/e-cal-backend-http.c
index 6212780..c13fe19 100644
--- a/calendar/backends/http/e-cal-backend-http.c
+++ b/calendar/backends/http/e-cal-backend-http.c
@@ -500,37 +500,12 @@ cal_backend_http_load (ECalBackendHttp *backend,
                        &cancel_data, (GDestroyNotify) NULL);
        }
 
-       status_code = soup_session_send_message (soup_session, soup_message);
-       if (status_code == SOUP_STATUS_SSL_FAILED) {
-               ESource *source;
-               ESourceWebdav *extension;
-               ESourceRegistry *registry;
-               EBackend *ebackend;
-               ETrustPromptResponse response;
-               ENamedParameters *parameters;
-
-               ebackend = E_BACKEND (backend);
-               source = e_backend_get_source (ebackend);
-               registry = e_cal_backend_get_registry (E_CAL_BACKEND (backend));
-               extension = e_source_get_extension (source, E_SOURCE_EXTENSION_WEBDAV_BACKEND);
-
-               parameters = e_named_parameters_new ();
-
-               response = e_source_webdav_prepare_ssl_trust_prompt (extension, soup_message, registry, 
parameters);
-               if (response == E_TRUST_PROMPT_RESPONSE_UNKNOWN) {
-                       response = e_backend_trust_prompt_sync (ebackend, parameters, cancellable, NULL);
-                       if (response != E_TRUST_PROMPT_RESPONSE_UNKNOWN)
-                               e_source_webdav_store_ssl_trust_prompt (extension, soup_message, response);
-               }
-
-               e_named_parameters_free (parameters);
+       e_soup_ssl_trust_connect (
+               soup_message, e_backend_get_source (E_BACKEND (backend)),
+               e_cal_backend_get_registry (E_CAL_BACKEND (backend)),
+               cancellable);
 
-               if (response == E_TRUST_PROMPT_RESPONSE_ACCEPT ||
-                   response == E_TRUST_PROMPT_RESPONSE_ACCEPT_TEMPORARILY) {
-                       g_object_set (soup_session, SOUP_SESSION_SSL_STRICT, FALSE, NULL);
-                       status_code = soup_session_send_message (soup_session, soup_message);
-               }
-       }
+       status_code = soup_session_send_message (soup_session, soup_message);
 
        if (G_IS_CANCELLABLE (cancellable))
                g_cancellable_disconnect (cancellable, cancel_id);
@@ -896,7 +871,6 @@ e_cal_backend_http_open (ECalBackendSync *backend,
        extension_name = E_SOURCE_EXTENSION_WEBDAV_BACKEND;
        webdav_extension = e_source_get_extension (source, extension_name);
 
-       g_object_set (cbhttp->priv->soup_session, SOUP_SESSION_SSL_STRICT, TRUE, NULL);
        e_source_webdav_unset_temporary_ssl_trust (webdav_extension);
 
        if (priv->source_changed_id == 0) {
diff --git a/docs/reference/eds/eds-sections.txt b/docs/reference/eds/eds-sections.txt
index cd8bd29..80282ac 100644
--- a/docs/reference/eds/eds-sections.txt
+++ b/docs/reference/eds/eds-sections.txt
@@ -2840,6 +2840,12 @@ e_soup_auth_bearer_get_type
 </SECTION>
 
 <SECTION>
+<FILE>e-soup-ssl-trust</FILE>
+<TITLE>SSL certificate trust handling for WebDAV sources</TITLE>
+e_soup_ssl_trust_connect
+</SECTION>
+
+<SECTION>
 <FILE>e-source</FILE>
 <TITLE>ESource</TITLE>
 E_SOURCE_PARAM_SETTING
diff --git a/libebackend/Makefile.am b/libebackend/Makefile.am
index f057181..3f6db8f 100644
--- a/libebackend/Makefile.am
+++ b/libebackend/Makefile.am
@@ -63,6 +63,7 @@ libebackend_1_2_la_SOURCES = \
        e-module.c \
        e-server-side-source.c \
        e-soup-auth-bearer.c \
+       e-soup-ssl-trust.c \
        e-source-registry-server.c \
        e-sqlite3-vfs.c \
        e-user-prompter.c \
@@ -111,6 +112,7 @@ libebackendinclude_HEADERS = \
        e-module.h \
        e-server-side-source.h \
        e-soup-auth-bearer.h \
+       e-soup-ssl-trust.h \
        e-source-registry-server.h \
        e-sqlite3-vfs.h \
        e-user-prompter.h \
diff --git a/libebackend/e-soup-ssl-trust.c b/libebackend/e-soup-ssl-trust.c
new file mode 100644
index 0000000..c96fe8e
--- /dev/null
+++ b/libebackend/e-soup-ssl-trust.c
@@ -0,0 +1,187 @@
+/*
+ * e-soup-ssl-trust.c
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/**
+ * SECTION: e-soup-ssl-trust
+ * @include: libebackend/libebackend.h
+ * @short_description: SSL certificate trust handling for WebDAV sources
+ *
+ * 
+ **/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "e-user-prompter.h"
+
+#include "e-soup-ssl-trust.h"
+
+typedef struct _ESoupSslTrustData {
+       SoupMessage *soup_message; /* weak */
+       ESource *source;
+       ESourceRegistry *registry;
+       GCancellable *cancellable;
+
+       GClosure *accept_certificate_closure;
+} ESoupSslTrustData;
+
+static ETrustPromptResponse
+trust_prompt_sync (const ENamedParameters *parameters,
+                   GCancellable *cancellable,
+                   GError **error)
+{
+       EUserPrompter *prompter;
+       gint response;
+
+       g_return_val_if_fail (parameters != NULL, E_TRUST_PROMPT_RESPONSE_UNKNOWN);
+
+       prompter = e_user_prompter_new ();
+       g_return_val_if_fail (prompter != NULL, E_TRUST_PROMPT_RESPONSE_UNKNOWN);
+
+       response = e_user_prompter_extension_prompt_sync (prompter, "ETrustPrompt::trust-prompt", parameters, 
NULL, cancellable, error);
+
+       g_object_unref (prompter);
+
+       if (response == 0)
+               return E_TRUST_PROMPT_RESPONSE_REJECT;
+       if (response == 1)
+               return E_TRUST_PROMPT_RESPONSE_ACCEPT;
+       if (response == 2)
+               return E_TRUST_PROMPT_RESPONSE_ACCEPT_TEMPORARILY;
+       if (response == -1)
+               return E_TRUST_PROMPT_RESPONSE_REJECT_TEMPORARILY;
+
+       return E_TRUST_PROMPT_RESPONSE_UNKNOWN;
+}
+
+static gboolean
+e_soup_ssl_trust_accept_certificate_cb (GTlsConnection *conn,
+                                       GTlsCertificate *peer_cert,
+                                       GTlsCertificateFlags errors,
+                                       gpointer user_data)
+{
+       ESoupSslTrustData *handler = user_data;
+       ETrustPromptResponse response;
+       ENamedParameters *parameters;
+
+       parameters = e_named_parameters_new ();
+
+       response = e_source_webdav_prepare_ssl_trust_prompt (
+               e_source_get_extension (handler->source, E_SOURCE_EXTENSION_WEBDAV_BACKEND),
+               handler->soup_message, peer_cert, errors, handler->registry, parameters);
+       if (response == E_TRUST_PROMPT_RESPONSE_UNKNOWN) {
+               response = trust_prompt_sync (parameters, handler->cancellable, NULL);
+               if (response != E_TRUST_PROMPT_RESPONSE_UNKNOWN)
+                       e_source_webdav_store_ssl_trust_prompt (
+                               e_source_get_extension (handler->source, E_SOURCE_EXTENSION_WEBDAV_BACKEND),
+                               handler->soup_message, peer_cert, response);
+       }
+
+       e_named_parameters_free (parameters);
+
+       return (response == E_TRUST_PROMPT_RESPONSE_ACCEPT ||
+               response == E_TRUST_PROMPT_RESPONSE_ACCEPT_TEMPORARILY);
+}
+
+static void
+e_soup_ssl_trust_network_event_cb (SoupMessage *msg,
+                                  GSocketClientEvent event,
+                                  GIOStream *connection,
+                                  gpointer user_data)
+{
+       ESoupSslTrustData *handler = user_data;
+
+       if (event == G_SOCKET_CLIENT_TLS_HANDSHAKING) {
+               g_signal_connect_closure (
+                       G_TLS_CONNECTION (connection), "accept-certificate",
+                       handler->accept_certificate_closure, FALSE);
+       }
+}
+
+static void
+e_soup_ssl_trust_message_finalized_cb (gpointer data,
+                                      GObject *unused_message)
+{
+       ESoupSslTrustData *handler;
+
+       /* The network event handler will be disconnected from the message just
+        * before this is called. */
+       handler = data;
+
+       g_clear_object (&handler->source);
+       g_clear_object (&handler->registry);
+       g_clear_object (&handler->cancellable);
+
+       /* Synchronously disconnects the accept certificate handler from all
+        * GTlsConnections. */
+       g_closure_invalidate (handler->accept_certificate_closure);
+       g_closure_unref (handler->accept_certificate_closure);
+
+       g_free (handler);
+}
+
+/**
+ * e_soup_ssl_trust_connect:
+ * @soup_message: a #SoupMessage about to be sent to the source
+ * @source: an #ESource that uses WebDAV
+ * @registry: (allow-none): an #ESourceRegistry, to use for parent lookups
+ * @cancellable: (allow-none): #GCancellable to cancel the trust prompt
+ *
+ * Sets up automatic SSL certificate trust handling for @message using the trust
+ * data stored in @source's WebDAV extension. If @message is about to be sent on
+ * an SSL connection with an invalid certificate, the code checks if the WebDAV
+ * extension already has a trust response for that certificate with
+ * e_source_webdav_prepare_ssl_trust_prompt and if not, prompts the user with
+ * the "ETrustPrompt::trust-prompt" extension dialog and
+ * saves the result with e_source_webdav_store_ssl_trust_prompt.
+ *
+ * This works by connecting to the "network-event" signal on @message and
+ * connecting to the "accept-certificate" signal on each #GTlsConnection for
+ * which @message reports a #G_SOCKET_CLIENT_TLS_HANDSHAKING event. These
+ * handlers are torn down automatically when @message is disposed. This process
+ * is not thread-safe; it is sufficient for safety if all use of @message's
+ * session and the disposal of @message occur in the same thread.
+ *
+ * Since: 3.14
+ **/
+void
+e_soup_ssl_trust_connect (SoupMessage *soup_message,
+                          ESource *source,
+                          ESourceRegistry *registry,
+                          GCancellable *cancellable)
+{
+       ESoupSslTrustData *handler;
+
+       g_return_if_fail (SOUP_IS_MESSAGE (soup_message));
+       g_return_if_fail (E_IS_SOURCE (source));
+
+       handler = g_malloc (sizeof (ESoupSslTrustData));
+       handler->soup_message = soup_message;
+       g_object_weak_ref (G_OBJECT (soup_message), e_soup_ssl_trust_message_finalized_cb, handler);
+       handler->source = g_object_ref (source);
+       handler->registry = registry ? g_object_ref (registry) : NULL;
+       handler->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
+       handler->accept_certificate_closure = g_cclosure_new (G_CALLBACK 
(e_soup_ssl_trust_accept_certificate_cb), handler, NULL);
+
+       g_closure_ref (handler->accept_certificate_closure);
+       g_closure_sink (handler->accept_certificate_closure);
+
+       g_signal_connect (
+               soup_message, "network-event",
+               G_CALLBACK (e_soup_ssl_trust_network_event_cb), handler);
+}
diff --git a/libebackend/e-soup-ssl-trust.h b/libebackend/e-soup-ssl-trust.h
new file mode 100644
index 0000000..846585d
--- /dev/null
+++ b/libebackend/e-soup-ssl-trust.h
@@ -0,0 +1,38 @@
+/*
+ * e-soup-ssl-trust.h
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#if !defined (__LIBEBACKEND_H_INSIDE__) && !defined (LIBEBACKEND_COMPILATION)
+#error "Only <libebackend/libebackend.h> should be included directly."
+#endif
+
+#ifndef E_SOUP_SSL_TRUST_H
+#define E_SOUP_SSL_TRUST_H
+
+#include <libedataserver/libedataserver.h>
+
+#include <libsoup/soup.h>
+
+G_BEGIN_DECLS
+
+void           e_soup_ssl_trust_connect        (SoupMessage *soup_message,
+                                                ESource *source,
+                                                ESourceRegistry *registry,
+                                                GCancellable *cancellable);
+
+G_END_DECLS
+
+#endif /* E_SOUP_SSL_TRUST_H */
diff --git a/libebackend/libebackend.h b/libebackend/libebackend.h
index dd0a242..31935d0 100644
--- a/libebackend/libebackend.h
+++ b/libebackend/libebackend.h
@@ -42,6 +42,7 @@
 #include <libebackend/e-offline-listener.h>
 #include <libebackend/e-server-side-source.h>
 #include <libebackend/e-soup-auth-bearer.h>
+#include <libebackend/e-soup-ssl-trust.h>
 #include <libebackend/e-source-registry-server.h>
 #include <libebackend/e-sqlite3-vfs.h>
 #include <libebackend/e-user-prompter.h>
diff --git a/libedataserver/e-source-webdav.c b/libedataserver/e-source-webdav.c
index fe301b6..5ec6b9a 100644
--- a/libedataserver/e-source-webdav.c
+++ b/libedataserver/e-source-webdav.c
@@ -1367,32 +1367,35 @@ encode_ssl_trust (ESourceWebdav *extension,
 /**
  * e_source_webdav_prepare_ssl_trust_prompt:
  * @extension: an #ESourceWebdav
- * @message: a #SoupMessage with #SOUP_STATUS_SSL_FAILED status code
- * @registry: an #ESourceRegistry, to use for parent lookups
+ * @message: a #SoupMessage
+ * @cert: the invalid certificate of the connection over which @message is about
+ *        to be sent
+ * @cert_errors: the error flags for @cert
+ * @registry: (allow-none): an #ESourceRegistry, to use for parent lookups
  * @parameters: an #ENamedParameters to be populated
  *
- * Checks @messages<!-- -->'s certificate against currently stored trust
- * response and either returns what to do immediately, or returns
- * #E_TRUST_PROMPT_RESPONSE_UNKNOWN and populates @parameters with necessary
- * values for a trust prompt.
+ * Checks @cert against currently stored trust response and either returns what
+ * to do immediately, or returns #E_TRUST_PROMPT_RESPONSE_UNKNOWN and populates
+ * @parameters with necessary values for a trust prompt.
  *
  * Returns: What to do with SSL connection, where
  *          #E_TRUST_PROMPT_RESPONSE_UNKNOWN means 'ask a user, with
  *          populated parameters'.
  *
- * Note: The #E_TRUST_PROMPT_RESPONSE_REJECT is returned on any errors, like
- *  the @message not being with the #SOUP_STATUS_SSL_FAILED status code,
- *  no certificate being stored in the @message and so on.
+ * Note: The #E_TRUST_PROMPT_RESPONSE_REJECT is returned on any errors, such as
+ *  invalid parameters.
  *
  * Since: 3.8
  **/
 ETrustPromptResponse
 e_source_webdav_prepare_ssl_trust_prompt (ESourceWebdav *extension,
                                           SoupMessage *message,
+                                          GTlsCertificate *cert,
+                                          GTlsCertificateFlags cert_errors,
                                           ESourceRegistry *registry,
                                           ENamedParameters *parameters)
 {
-       ESource *source, *parent_source = NULL;
+       ESource *parent_source = NULL;
        ETrustPromptResponse res;
 
        g_return_val_if_fail (
@@ -1401,28 +1404,33 @@ e_source_webdav_prepare_ssl_trust_prompt (ESourceWebdav *extension,
        g_return_val_if_fail (
                SOUP_IS_MESSAGE (message),
                E_TRUST_PROMPT_RESPONSE_REJECT);
-       g_return_val_if_fail (
-               E_IS_SOURCE_REGISTRY (registry),
-               E_TRUST_PROMPT_RESPONSE_REJECT);
+       if (registry)
+               g_return_val_if_fail (
+                       E_IS_SOURCE_REGISTRY (registry),
+                       E_TRUST_PROMPT_RESPONSE_REJECT);
        g_return_val_if_fail (
                parameters != NULL,
                E_TRUST_PROMPT_RESPONSE_REJECT);
 
-       source = e_source_extension_ref_source (E_SOURCE_EXTENSION (extension));
-       if (source != NULL) {
-               const gchar *parent_uid;
-
-               parent_uid = e_source_get_parent (source);
-
-               if (parent_uid != NULL)
-                       parent_source = e_source_registry_ref_source (
-                               registry, parent_uid);
+       if (registry != NULL) {
+               ESource *source;
 
-               g_object_unref (source);
+               source = e_source_extension_ref_source (E_SOURCE_EXTENSION (extension));
+               if (source != NULL) {
+                       const gchar *parent_uid;
+       
+                       parent_uid = e_source_get_parent (source);
+       
+                       if (parent_uid != NULL)
+                               parent_source = e_source_registry_ref_source (
+                                       registry, parent_uid);
+       
+                       g_object_unref (source);
+               }
        }
 
        res = e_source_webdav_prepare_ssl_trust_prompt_with_parent (
-               extension, message, parent_source, parameters);
+               extension, message, cert, cert_errors, parent_source, parameters);
 
        if (parent_source)
                g_object_unref (parent_source);
@@ -1433,7 +1441,10 @@ e_source_webdav_prepare_ssl_trust_prompt (ESourceWebdav *extension,
 /**
  * e_source_webdav_prepare_ssl_trust_prompt_with_parent:
  * @extension: an #ESourceWebdav
- * @message: a #SoupMessage with #SOUP_STATUS_SSL_FAILED status code
+ * @message: a #SoupMessage
+ * @cert: the invalid certificate of the connection over which @message is about
+ *        to be sent
+ * @cert_errors: the error flags for @cert
  * @parent_source: an #ESource, parent of the @extension<!-- -->'s source
  * @parameters: an #ENamedParameters to be populated
  *
@@ -1447,13 +1458,13 @@ e_source_webdav_prepare_ssl_trust_prompt (ESourceWebdav *extension,
 ETrustPromptResponse
 e_source_webdav_prepare_ssl_trust_prompt_with_parent (ESourceWebdav *extension,
                                                       SoupMessage *message,
+                                                      GTlsCertificate *cert,
+                                                      GTlsCertificateFlags cert_errors,
                                                       ESource *parent_source,
                                                       ENamedParameters *parameters)
 {
        ETrustPromptResponse response;
        ESource *source;
-       GTlsCertificate *cert = NULL;
-       GTlsCertificateFlags cert_errors = 0;
        GByteArray *bytes = NULL;
        SoupURI *soup_uri;
        const gchar *host;
@@ -1477,12 +1488,6 @@ e_source_webdav_prepare_ssl_trust_prompt_with_parent (ESourceWebdav *extension,
                parameters != NULL,
                E_TRUST_PROMPT_RESPONSE_REJECT);
 
-       if (message->status_code != SOUP_STATUS_SSL_FAILED)
-               return E_TRUST_PROMPT_RESPONSE_REJECT;
-
-       if (!soup_message_get_https_status (message, &cert, &cert_errors) || !cert)
-               return E_TRUST_PROMPT_RESPONSE_REJECT;
-
        /* Always reject revoked certificates */
        if ((cert_errors & G_TLS_CERTIFICATE_REVOKED) != 0)
                return E_TRUST_PROMPT_RESPONSE_REJECT;
@@ -1622,8 +1627,10 @@ webdav_extension_changes_written_cb (GObject *source_object,
 /**
  * e_source_webdav_store_ssl_trust_prompt:
  * @extension: an #ESourceWebdav
- * @message: a #SoupMessage with #SOUP_STATUS_SSL_FAILED status code
- * @response: user's response from a trust prompt
+ * @message: a #SoupMessage
+ * @cert: the invalid certificate of the connection over which @message is about
+ *        to be sent
+ * @response: user's response from a trust prompt for @cert
  *
  * Stores user's response from a trust prompt, thus it is re-used the next
  * time it'll be needed. An #E_TRUST_PROMPT_RESPONSE_UNKNOWN is treated as
@@ -1634,9 +1641,9 @@ webdav_extension_changes_written_cb (GObject *source_object,
 void
 e_source_webdav_store_ssl_trust_prompt (ESourceWebdav *extension,
                                         SoupMessage *message,
+                                        GTlsCertificate *cert,
                                         ETrustPromptResponse response)
 {
-       GTlsCertificate *cert = NULL;
        GByteArray *bytes = NULL;
        SoupURI *soup_uri;
        const gchar *host;
@@ -1646,12 +1653,6 @@ e_source_webdav_store_ssl_trust_prompt (ESourceWebdav *extension,
        g_return_if_fail (E_IS_SOURCE_WEBDAV (extension));
        g_return_if_fail (SOUP_IS_MESSAGE (message));
 
-       if (message->status_code != SOUP_STATUS_SSL_FAILED)
-               return;
-
-       if (!soup_message_get_https_status (message, &cert, NULL) || !cert)
-               return;
-
        soup_uri = soup_message_get_uri (message);
        if (!soup_uri || !soup_uri_get_host (soup_uri))
                return;
diff --git a/libedataserver/e-source-webdav.h b/libedataserver/e-source-webdav.h
index 120a95b..7fff9d7 100644
--- a/libedataserver/e-source-webdav.h
+++ b/libedataserver/e-source-webdav.h
@@ -22,6 +22,7 @@
 #ifndef E_SOURCE_WEBDAV_H
 #define E_SOURCE_WEBDAV_H
 
+#include <gio/gio.h>
 #include <libsoup/soup.h>
 #include <libedataserver/e-source-enums.h>
 #include <libedataserver/e-source-extension.h>
@@ -132,17 +133,22 @@ ETrustPromptResponse
                e_source_webdav_prepare_ssl_trust_prompt
                                                (ESourceWebdav *extension,
                                                 SoupMessage *message,
+                                                GTlsCertificate *cert,
+                                                GTlsCertificateFlags cert_errors,
                                                 struct _ESourceRegistry *registry,
                                                 struct _ENamedParameters *parameters);
 ETrustPromptResponse
                e_source_webdav_prepare_ssl_trust_prompt_with_parent
                                                (ESourceWebdav *extension,
                                                 SoupMessage *message,
+                                                GTlsCertificate *cert,
+                                                GTlsCertificateFlags cert_errors,
                                                 ESource *parent_source,
                                                 struct _ENamedParameters *parameters);
 void           e_source_webdav_store_ssl_trust_prompt
                                                (ESourceWebdav *extension,
                                                 SoupMessage *message,
+                                                GTlsCertificate *cert,
                                                 ETrustPromptResponse response);
 void           e_source_webdav_unset_temporary_ssl_trust
                                                (ESourceWebdav *extension);
diff --git a/modules/owncloud-backend/owncloud-utils.c b/modules/owncloud-backend/owncloud-utils.c
index 915c54e..bb860e4 100644
--- a/modules/owncloud-backend/owncloud-utils.c
+++ b/modules/owncloud-backend/owncloud-utils.c
@@ -465,39 +465,6 @@ authenticate_cb (SoupSession *session,
                        authenticator->password->str);
 }
 
-static ETrustPromptResponse
-trust_prompt_sync (const ENamedParameters *parameters,
-                   GCancellable *cancellable,
-                   GError **error)
-{
-       EUserPrompter *prompter;
-       gint response;
-
-       g_return_val_if_fail (
-               parameters != NULL, E_TRUST_PROMPT_RESPONSE_UNKNOWN);
-
-       prompter = e_user_prompter_new ();
-       g_return_val_if_fail (
-               prompter != NULL, E_TRUST_PROMPT_RESPONSE_UNKNOWN);
-
-       response = e_user_prompter_extension_prompt_sync (
-               prompter, "ETrustPrompt::trust-prompt",
-               parameters, NULL, cancellable, error);
-
-       g_object_unref (prompter);
-
-       if (response == 0)
-               return E_TRUST_PROMPT_RESPONSE_REJECT;
-       if (response == 1)
-               return E_TRUST_PROMPT_RESPONSE_ACCEPT;
-       if (response == 2)
-               return E_TRUST_PROMPT_RESPONSE_ACCEPT_TEMPORARILY;
-       if (response == -1)
-               return E_TRUST_PROMPT_RESPONSE_REJECT_TEMPORARILY;
-
-       return E_TRUST_PROMPT_RESPONSE_UNKNOWN;
-}
-
 static gboolean
 find_sources (ECollectionBackend *collection,
               OwnCloudSourceFoundCb found_cb,
@@ -565,33 +532,11 @@ find_sources (ECollectionBackend *collection,
                msg, "application/xml; charset=utf-8",
                SOUP_MEMORY_STATIC, req_body, strlen (req_body));
 
-       if (soup_session_send_message (session, msg) == SOUP_STATUS_SSL_FAILED) {
-               ETrustPromptResponse response;
-               ENamedParameters *parameters;
-               ESourceWebdav *extension;
-               ESource *source;
-
-               source = e_backend_get_source (E_BACKEND (collection));
-               extension = e_source_get_extension (source, E_SOURCE_EXTENSION_WEBDAV_BACKEND);
-               parameters = e_named_parameters_new ();
-
-               /* this is the master source, thus there is no parent_source */
-               response = e_source_webdav_prepare_ssl_trust_prompt_with_parent (extension, msg, NULL, 
parameters);
-               if (response == E_TRUST_PROMPT_RESPONSE_UNKNOWN) {
-                       response = trust_prompt_sync (parameters, NULL, NULL);
-                       if (response != E_TRUST_PROMPT_RESPONSE_UNKNOWN)
-                               e_source_webdav_store_ssl_trust_prompt (extension, msg, response);
-               }
+       /* this is the master source, thus there is no parent_source */
+       e_soup_ssl_trust_connect (
+               msg, e_backend_get_source (E_BACKEND (collection)), NULL, NULL);
 
-               e_named_parameters_free (parameters);
-
-               if (response == E_TRUST_PROMPT_RESPONSE_ACCEPT ||
-                   response == E_TRUST_PROMPT_RESPONSE_ACCEPT_TEMPORARILY) {
-                       g_object_set (session, SOUP_SESSION_SSL_STRICT, FALSE, NULL);
-
-                       soup_session_send_message (session, msg);
-               }
-       }
+       soup_session_send_message (session, msg);
 
        if (msg->status_code == SOUP_STATUS_MULTI_STATUS &&
            msg->response_body && msg->response_body->length) {
diff --git a/modules/trust-prompt/trust-prompt-gtk.c b/modules/trust-prompt/trust-prompt-gtk.c
index ec8d82f..94a6b32 100644
--- a/modules/trust-prompt/trust-prompt-gtk.c
+++ b/modules/trust-prompt/trust-prompt-gtk.c
@@ -125,7 +125,6 @@ trust_prompt_show (EUserPrompterServerExtension *extension,
        widget = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
 
        gtk_window_set_icon_name (GTK_WINDOW (dialog), "evolution");
-       gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES);
        gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
 
        grid = g_object_new (


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