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; SoupURI *soup_uri; const gchar *host; gchar *auth_host = NULL; soup_uri = soup_message_get_uri (handler->soup_message); if (!soup_uri || !soup_uri_get_host (soup_uri)) return FALSE; host = soup_uri_get_host (soup_uri); if (e_source_has_extension (handler->source, E_SOURCE_EXTENSION_AUTHENTICATION)) { ESourceAuthentication *extension_authentication; extension_authentication = e_source_get_extension (handler->source, E_SOURCE_EXTENSION_AUTHENTICATION); auth_host = e_source_authentication_dup_host (extension_authentication); if (auth_host && *auth_host) { /* Use the 'host' from the Authentication extension, because it's the one used when storing the trust prompt result. The SoupMessage can be redirected, thus it would not ever match. */ host = auth_host; } else { g_free (auth_host); auth_host = NULL; } } response = e_source_webdav_verify_ssl_trust ( e_source_get_extension (handler->source, E_SOURCE_EXTENSION_WEBDAV_BACKEND), host, peer_cert, errors); g_free (auth_host); return (response == E_TRUST_PROMPT_RESPONSE_ACCEPT || response == E_TRUST_PROMPT_RESPONSE_ACCEPT_TEMPORARILY); }
/** * e_trust_prompt_run_for_source: * @parent: A #GtkWindow to use as a parent for the trust prompt dialog * @source: an #ESource, with %E_SOURCE_EXTENSION_AUTHENTICATION * @certificate_pem: a PEM-encoded certificate for which to show the trust prompt * @certificate_errors: errors of the @certificate_pem * @error_text: (allow-none): an optional error text to show in the dialog; can be %NULL * @allow_source_save: whether can also save any @source changes * @cancellable: (allow-none): a #GCancellable, or %NULL * @callback: a callback to call, when the prompt (an @source save) is done * @user_data: user data passed into @callback * * Similar to e_trust_prompt_run_modal(), except it also manages all the necessary things * around the @source<!-- -->'s SSL/TLS trust properties when it also contains %E_SOURCE_EXTENSION_WEBDAV, * thus the SSL/TLS trust on the WebDAV @source is properly updated based on the user's choice. * The call is finished with e_trust_prompt_run_for_source_finish(), * which also returns the user's choice. The finish happens in the @callback. * This is necessary, because the @source can be also saved. * * The function fails, if the @source doesn't contain the %E_SOURCE_EXTENSION_AUTHENTICATION. * * Note: The dialog is not shown when the stored certificate trust in the WebDAV @source * matches the @certificate_pem and the stored result is #E_TRUST_PROMPT_RESPONSE_REJECT. * * Since: 3.16 **/ void e_trust_prompt_run_for_source (GtkWindow *parent, ESource *source, const gchar *certificate_pem, GTlsCertificateFlags certificate_errors, const gchar *error_text, gboolean allow_source_save, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { ESourceAuthentication *extension_authentication = NULL; ESourceWebdav *extension_webdav = NULL; SaveSourceData *save_data; GTlsCertificate *certificate; gchar *host; GTask *task; if (parent) g_return_if_fail (GTK_IS_WINDOW (parent)); g_return_if_fail (E_IS_SOURCE (source)); g_return_if_fail (certificate_pem != NULL); if (e_source_has_extension (source, E_SOURCE_EXTENSION_GOA) || e_source_has_extension (source, E_SOURCE_EXTENSION_UOA)) { /* Make sure that GOA/UOA collection sources contain these extensions too */ g_warn_if_fail (e_source_get_extension (source, E_SOURCE_EXTENSION_AUTHENTICATION)); g_warn_if_fail (e_source_get_extension (source, E_SOURCE_EXTENSION_WEBDAV_BACKEND)); } if (e_source_has_extension (source, E_SOURCE_EXTENSION_AUTHENTICATION)) extension_authentication = e_source_get_extension (source, E_SOURCE_EXTENSION_AUTHENTICATION); if (e_source_has_extension (source, E_SOURCE_EXTENSION_WEBDAV_BACKEND)) extension_webdav = e_source_get_extension (source, E_SOURCE_EXTENSION_WEBDAV_BACKEND); save_data = g_new0 (SaveSourceData, 1); save_data->response = E_TRUST_PROMPT_RESPONSE_UNKNOWN; save_data->call_save = FALSE; /* Lookup used host name */ if (extension_authentication) host = e_source_authentication_dup_host (extension_authentication); else host = NULL; if (!host || !*host) { g_free (host); host = NULL; if (e_source_has_extension (source, E_SOURCE_EXTENSION_GOA)) { ESourceGoa *goa_extension; gchar *url; goa_extension = e_source_get_extension (source, E_SOURCE_EXTENSION_GOA); url = e_source_goa_dup_calendar_url (goa_extension); host = trust_prompt_get_host_from_url (url); g_free (url); if (!host) { url = e_source_goa_dup_contacts_url (goa_extension); host = trust_prompt_get_host_from_url (url); g_free (url); } } } certificate = g_tls_certificate_new_from_pem (certificate_pem, -1, &save_data->error); if (certificate) { if (extension_webdav && host) save_data->response = e_source_webdav_verify_ssl_trust (extension_webdav, host, certificate, 0); else save_data->response = E_TRUST_PROMPT_RESPONSE_REJECT_TEMPORARILY; if (save_data->response != E_TRUST_PROMPT_RESPONSE_REJECT) { const gchar *source_extension = NULL; if (e_source_has_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK)) source_extension = E_SOURCE_EXTENSION_ADDRESS_BOOK; if (e_source_has_extension (source, E_SOURCE_EXTENSION_CALENDAR)) { if (!source_extension) source_extension = E_SOURCE_EXTENSION_CALENDAR; else source_extension = E_SOURCE_EXTENSION_COLLECTION; } if (e_source_has_extension (source, E_SOURCE_EXTENSION_MEMO_LIST)) { if (!source_extension) source_extension = E_SOURCE_EXTENSION_MEMO_LIST; else source_extension = E_SOURCE_EXTENSION_COLLECTION; } if (e_source_has_extension (source, E_SOURCE_EXTENSION_TASK_LIST)) { if (!source_extension) source_extension = E_SOURCE_EXTENSION_TASK_LIST; else source_extension = E_SOURCE_EXTENSION_COLLECTION; } if (e_source_has_extension (source, E_SOURCE_EXTENSION_MAIL_ACCOUNT)) { if (!source_extension) source_extension = E_SOURCE_EXTENSION_MAIL_ACCOUNT; else source_extension = E_SOURCE_EXTENSION_COLLECTION; } if (e_source_has_extension (source, E_SOURCE_EXTENSION_MAIL_TRANSPORT)) { if (!source_extension) source_extension = E_SOURCE_EXTENSION_MAIL_TRANSPORT; else source_extension = E_SOURCE_EXTENSION_COLLECTION; } save_data->response = e_trust_prompt_run_with_dialog_ready_callback (parent, source_extension, e_source_get_display_name (source), host, certificate_pem, certificate_errors, error_text, trust_prompt_listen_for_source_changes_cb, source); } } g_signal_handlers_disconnect_matched (source, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, source_connection_status_changed_cb, NULL); if (save_data->response != E_TRUST_PROMPT_RESPONSE_UNKNOWN) { if (certificate && extension_webdav) { e_source_webdav_update_ssl_trust (extension_webdav, host, certificate, save_data->response); save_data->call_save = allow_source_save; } } g_clear_object (&certificate); g_free (host); task = g_task_new (source, cancellable, callback, user_data); g_task_set_source_tag (task, e_trust_prompt_run_for_source); g_task_set_task_data (task, save_data, save_source_data_free); g_task_run_in_thread (task, save_source_thread); g_object_unref (task); }