[evolution-mapi] Move authentication of backends back to the client



commit e568bc225455969bf3d2ab843f6f8a4bd606af57
Author: Milan Crha <mcrha redhat com>
Date:   Mon Feb 2 14:54:07 2015 +0100

    Move authentication of backends back to the client
    
    Since this change the client is responsible to provide credentials
    to use to authenticate backends (through ESource-s, to be more precise),
    unless the credentials are already saved.

 configure.ac                                   |    4 +-
 src/addressbook/e-book-backend-mapi.c          |   44 +++---
 src/calendar/e-cal-backend-mapi.c              |   51 +++---
 src/camel/camel-mapi-store.c                   |    9 +-
 src/collection/Makefile.am                     |    2 -
 src/collection/e-mapi-backend-authenticator.c  |  163 ------------------
 src/collection/e-mapi-backend-authenticator.h  |   41 -----
 src/collection/e-mapi-backend.c                |  212 ++++++++++++++++--------
 src/configuration/e-mail-config-mapi-backend.c |  191 +++++++++-------------
 src/configuration/e-mapi-config-utils.c        |  118 +++++---------
 src/libexchangemapi/e-mapi-connection.c        |   55 +++---
 src/libexchangemapi/e-mapi-connection.h        |    6 +-
 12 files changed, 348 insertions(+), 548 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index d061210..a0f2075 100644
--- a/configure.ac
+++ b/configure.ac
@@ -30,8 +30,8 @@ m4_define([evo_minimum_version], [ema_version])
 m4_define([libmapi_minimum_version], [2.0])
 
 dnl Keep these two definitions in agreement.
-m4_define([glib_minimum_version], [2.34])
-m4_define([glib_encoded_version], [GLIB_VERSION_2_34])
+m4_define([glib_minimum_version], [2.40])
+m4_define([glib_encoded_version], [GLIB_VERSION_2_40])
 
 dnl Keep these two definitions in agreement.
 m4_define([gdk_minimum_version], [3.0])
diff --git a/src/addressbook/e-book-backend-mapi.c b/src/addressbook/e-book-backend-mapi.c
index af336d9..cbed93c 100644
--- a/src/addressbook/e-book-backend-mapi.c
+++ b/src/addressbook/e-book-backend-mapi.c
@@ -42,10 +42,7 @@
 
 #include "e-book-backend-mapi.h"
 
-static void e_book_backend_mapi_authenticator_init (ESourceAuthenticatorInterface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (EBookBackendMAPI, e_book_backend_mapi, E_TYPE_BOOK_BACKEND,
-       G_IMPLEMENT_INTERFACE (E_TYPE_SOURCE_AUTHENTICATOR, e_book_backend_mapi_authenticator_init))
+G_DEFINE_TYPE (EBookBackendMAPI, e_book_backend_mapi, E_TYPE_BOOK_BACKEND)
 
 struct _EBookBackendMAPIPrivate
 {
@@ -348,16 +345,19 @@ ebbm_maybe_invoke_cache_update (EBookBackendMAPI *ebma)
 
 static ESourceAuthenticationResult
 ebbm_connect_user (EBookBackendMAPI *ebma,
+                  const ENamedParameters *credentials,
+                  gboolean update_connection_status,
                   GCancellable *cancellable,
-                  const GString *password,
                   GError **error)
 {
        EBookBackendMAPIPrivate *priv = ebma->priv;
        EMapiConnection *old_conn;
        CamelMapiSettings *settings;
+       ESource *source;
        GError *mapi_error = NULL;
 
        settings = ebbm_get_collection_settings (ebma);
+       source = e_backend_get_source (E_BACKEND (ebma));
 
        if (!e_backend_get_online (E_BACKEND (ebma))) {
                ebbm_notify_connection_status (ebma, FALSE);
@@ -369,8 +369,12 @@ ebbm_connect_user (EBookBackendMAPI *ebma,
                }
 
                e_book_backend_mapi_lock_connection (ebma);
+               if (update_connection_status)
+                       e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTING);
 
                if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+                       if (update_connection_status)
+                               e_source_set_connection_status (source, 
E_SOURCE_CONNECTION_STATUS_DISCONNECTED);
                        e_book_backend_mapi_unlock_connection (ebma);
                        return E_SOURCE_AUTHENTICATION_ERROR;
                }
@@ -381,11 +385,11 @@ ebbm_connect_user (EBookBackendMAPI *ebma,
                priv->conn = e_mapi_connection_new (
                        e_book_backend_get_registry (E_BOOK_BACKEND (ebma)),
                        camel_mapi_settings_get_profile (settings),
-                       password, cancellable, &mapi_error);
+                       credentials, cancellable, &mapi_error);
                if (!priv->conn) {
                        priv->conn = e_mapi_connection_find (camel_mapi_settings_get_profile (settings));
                        if (priv->conn && !e_mapi_connection_connected (priv->conn))
-                               e_mapi_connection_reconnect (priv->conn, password, cancellable, &mapi_error);
+                               e_mapi_connection_reconnect (priv->conn, credentials, cancellable, 
&mapi_error);
                }
 
                if (old_conn)
@@ -401,6 +405,8 @@ ebbm_connect_user (EBookBackendMAPI *ebma,
 
                        if (is_network_error)
                                mapi_error_to_edb_error (error, mapi_error, E_DATA_BOOK_STATUS_OTHER_ERROR, 
NULL);
+                       if (update_connection_status)
+                               e_source_set_connection_status (source, 
E_SOURCE_CONNECTION_STATUS_DISCONNECTED);
                        e_book_backend_mapi_unlock_connection (ebma);
 
                        if (mapi_error)
@@ -411,6 +417,8 @@ ebbm_connect_user (EBookBackendMAPI *ebma,
                        return is_network_error ? E_SOURCE_AUTHENTICATION_ERROR : 
E_SOURCE_AUTHENTICATION_REJECTED;
                }
 
+               if (update_connection_status)
+                       e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTED);
                e_book_backend_mapi_unlock_connection (ebma);
 
                ebbm_notify_connection_status (ebma, TRUE);
@@ -440,10 +448,9 @@ e_book_backend_mapi_ensure_connected (EBookBackendMAPI *ebma,
        settings = ebbm_get_collection_settings (ebma);
 
        if (!camel_mapi_settings_get_kerberos (settings) ||
-           ebbm_connect_user (ebma, cancellable, NULL, &local_error) != E_SOURCE_AUTHENTICATION_ACCEPTED) {
-               e_backend_authenticate_sync (
-                       E_BACKEND (ebma),
-                       E_SOURCE_AUTHENTICATOR (ebma),
+           ebbm_connect_user (ebma, NULL, TRUE, cancellable, &local_error) != 
E_SOURCE_AUTHENTICATION_ACCEPTED) {
+               e_backend_credentials_required_sync (E_BACKEND (ebma),
+                       E_SOURCE_CREDENTIALS_REASON_REQUIRED, NULL, 0, NULL,
                        cancellable, &local_error);
        }
 
@@ -539,12 +546,14 @@ ebbm_open (EBookBackendMAPI *ebma,
 }
 
 static ESourceAuthenticationResult
-ebbm_try_password_sync (ESourceAuthenticator *authenticator,
-                       const GString *password,
+ebbm_authenticate_sync (EBackend *backend,
+                       const ENamedParameters *credentials,
+                       gchar **out_certificate_pem,
+                       GTlsCertificateFlags *out_certificate_errors,
                        GCancellable *cancellable,
                        GError **error)
 {
-       return ebbm_connect_user (E_BOOK_BACKEND_MAPI (authenticator), cancellable, password, error);
+       return ebbm_connect_user (E_BOOK_BACKEND_MAPI (backend), credentials, FALSE, cancellable, error);
 }
 
 static void
@@ -1400,6 +1409,7 @@ e_book_backend_mapi_class_init (EBookBackendMAPIClass *klass)
        object_class->dispose                   = ebbm_dispose;
 
        backend_class->get_destination_address  = ebbm_get_destination_address;
+       backend_class->authenticate_sync        = ebbm_authenticate_sync;
 
        book_backend_class->open                = ebbm_op_open;
        book_backend_class->create_contacts     = ebbm_op_create_contacts;
@@ -1424,12 +1434,6 @@ e_book_backend_mapi_class_init (EBookBackendMAPIClass *klass)
        klass->op_transfer_contacts             = NULL;
 }
 
-static void
-e_book_backend_mapi_authenticator_init (ESourceAuthenticatorInterface *iface)
-{
-       iface->try_password_sync = ebbm_try_password_sync;
-}
-
 const gchar *
 e_book_backend_mapi_get_book_uid (EBookBackendMAPI *ebma)
 {
diff --git a/src/calendar/e-cal-backend-mapi.c b/src/calendar/e-cal-backend-mapi.c
index d088dcc..d0b99a3 100644
--- a/src/calendar/e-cal-backend-mapi.c
+++ b/src/calendar/e-cal-backend-mapi.c
@@ -56,10 +56,7 @@
 #define EDC_ERROR(_code) e_data_cal_create_error (_code, NULL)
 #define EDC_ERROR_EX(_code, _msg) e_data_cal_create_error (_code, _msg)
 
-static void e_cal_backend_mapi_authenticator_init (ESourceAuthenticatorInterface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (ECalBackendMAPI, e_cal_backend_mapi, E_TYPE_CAL_BACKEND,
-       G_IMPLEMENT_INTERFACE (E_TYPE_SOURCE_AUTHENTICATOR, e_cal_backend_mapi_authenticator_init))
+G_DEFINE_TYPE (ECalBackendMAPI, e_cal_backend_mapi, E_TYPE_CAL_BACKEND)
 
 typedef struct {
        GCond cond;
@@ -1163,14 +1160,16 @@ ecbm_server_notification_cb (EMapiConnection *conn,
 
 static ESourceAuthenticationResult
 ecbm_connect_user (ECalBackend *backend,
+                  const ENamedParameters *credentials,
+                  gboolean update_connection_status,
                   GCancellable *cancellable,
-                  const GString *password,
                   GError **perror)
 {
        ECalBackendMAPI *cbmapi;
        ECalBackendMAPIPrivate *priv;
        CamelMapiSettings *settings;
        EMapiConnection *old_conn;
+       ESource *source;
        GError *mapi_error = NULL;
 
        g_mutex_lock (&auth_mutex);
@@ -1180,15 +1179,19 @@ ecbm_connect_user (ECalBackend *backend,
 
        old_conn = priv->conn;
        settings = ecbm_get_collection_settings (cbmapi);
+       source = e_backend_get_source (E_BACKEND (cbmapi));
+
+       if (update_connection_status)
+               e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTING);
 
        priv->conn = e_mapi_connection_new (
                e_cal_backend_get_registry (backend),
-               camel_mapi_settings_get_profile (settings), password, cancellable, &mapi_error);
+               camel_mapi_settings_get_profile (settings), credentials, cancellable, &mapi_error);
        if (!priv->conn) {
                priv->conn = e_mapi_connection_find (camel_mapi_settings_get_profile (settings));
                if (priv->conn
                    && !e_mapi_connection_connected (priv->conn)) {
-                       e_mapi_connection_reconnect (priv->conn, password, cancellable, &mapi_error);
+                       e_mapi_connection_reconnect (priv->conn, credentials, cancellable, &mapi_error);
                }
        }
 
@@ -1197,10 +1200,11 @@ ecbm_connect_user (ECalBackend *backend,
 
        if (priv->conn && e_mapi_connection_connected (priv->conn)) {
                /* Success */
-               ESource *source;
                ESourceMapiFolder *ext_mapi_folder;
 
-               source = e_backend_get_source (E_BACKEND (cbmapi));
+               if (update_connection_status)
+                       e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTED);
+
                ext_mapi_folder = e_source_get_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER);
                if (ext_mapi_folder && e_source_mapi_folder_get_server_notification (ext_mapi_folder)) {
                        mapi_object_t obj_folder;
@@ -1220,8 +1224,13 @@ ecbm_connect_user (ECalBackend *backend,
        } else {
                gboolean is_network_error = mapi_error && mapi_error->domain != E_MAPI_ERROR;
 
-               if (is_network_error)
+               if (is_network_error) {
+                       if (update_connection_status)
+                               e_source_set_connection_status (source, 
E_SOURCE_CONNECTION_STATUS_DISCONNECTED);
                        mapi_error_to_edc_error (perror, mapi_error, OtherError, NULL);
+               } else if (update_connection_status) {
+                       e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_DISCONNECTED);
+               }
                if (mapi_error)
                        g_error_free (mapi_error);
                g_mutex_unlock (&auth_mutex);
@@ -1273,10 +1282,9 @@ e_cal_backend_mapi_ensure_connected (ECalBackendMAPI *cbma,
        settings = ecbm_get_collection_settings (cbma);
 
        if (!camel_mapi_settings_get_kerberos (settings) ||
-           ecbm_connect_user (E_CAL_BACKEND (cbma), cancellable, NULL, &local_error) != 
E_SOURCE_AUTHENTICATION_ACCEPTED) {
-               e_backend_authenticate_sync (
-                       E_BACKEND (cbma),
-                       E_SOURCE_AUTHENTICATOR (cbma),
+           ecbm_connect_user (E_CAL_BACKEND (cbma), NULL, TRUE, cancellable, &local_error) != 
E_SOURCE_AUTHENTICATION_ACCEPTED) {
+               e_backend_credentials_required_sync (E_BACKEND (cbma),
+                       E_SOURCE_CREDENTIALS_REASON_REQUIRED, NULL, 0, NULL,
                        cancellable, &local_error);
        }
 
@@ -1422,12 +1430,14 @@ ecbm_open (ECalBackend *backend,
 
 
 static ESourceAuthenticationResult
-ecbm_try_password_sync (ESourceAuthenticator *authenticator,
-                       const GString *password,
+ecbm_authenticate_sync (EBackend *backend,
+                       const ENamedParameters *credentials,
+                       gchar **out_certificate_pem,
+                       GTlsCertificateFlags *out_certificate_errors,
                        GCancellable *cancellable,
                        GError **error)
 {
-       return ecbm_connect_user (E_CAL_BACKEND (authenticator), cancellable, password, error);
+       return ecbm_connect_user (E_CAL_BACKEND (backend), credentials, FALSE, cancellable, error);
 }
 
 static gboolean
@@ -3534,6 +3544,7 @@ e_cal_backend_mapi_class_init (ECalBackendMAPIClass *class)
        object_class->finalize = ecbm_finalize;
 
        backend_class->get_destination_address = ecbm_get_destination_address;
+       backend_class->authenticate_sync = ecbm_authenticate_sync;
 
        /* functions done asynchronously */
        cal_backend_class->get_backend_property = ecbm_get_backend_property;
@@ -3555,12 +3566,6 @@ e_cal_backend_mapi_class_init (ECalBackendMAPIClass *class)
 }
 
 static void
-e_cal_backend_mapi_authenticator_init (ESourceAuthenticatorInterface *iface)
-{
-       iface->try_password_sync = ecbm_try_password_sync;
-}
-
-static void
 e_cal_backend_mapi_init (ECalBackendMAPI *cbmapi)
 {
        ECalBackendMAPIPrivate *priv;
diff --git a/src/camel/camel-mapi-store.c b/src/camel/camel-mapi-store.c
index e711b1c..0fed359 100644
--- a/src/camel/camel-mapi-store.c
+++ b/src/camel/camel-mapi-store.c
@@ -2602,7 +2602,7 @@ mapi_authenticate_sync (CamelService *service,
        const gchar *profile;
        const gchar *password;
        GError *mapi_error = NULL;
-       GString *password_str;
+       ENamedParameters *credentials;
 
        settings = camel_service_ref_settings (service);
        mapi_settings = CAMEL_MAPI_SETTINGS (settings);
@@ -2634,14 +2634,15 @@ mapi_authenticate_sync (CamelService *service,
                }
        }
 
-       password_str = g_string_new (password);
+       credentials = e_named_parameters_new ();
+       e_named_parameters_set (credentials, E_SOURCE_CREDENTIAL_PASSWORD, password);
        g_rec_mutex_lock (&store->priv->connection_lock);
        session = camel_service_ref_session (service);
        store->priv->connection = e_mapi_connection_new (
                e_mail_session_get_registry (E_MAIL_SESSION (session)),
-               profile, password_str, cancellable, &mapi_error);
+               profile, credentials, cancellable, &mapi_error);
        g_object_unref (session);
-       g_string_free (password_str, TRUE);
+       e_named_parameters_free (credentials);
        if (store->priv->connection && e_mapi_connection_connected (store->priv->connection)) {
                result = CAMEL_AUTHENTICATION_ACCEPTED;
 
diff --git a/src/collection/Makefile.am b/src/collection/Makefile.am
index 63df59a..082de61 100644
--- a/src/collection/Makefile.am
+++ b/src/collection/Makefile.am
@@ -18,8 +18,6 @@ module_mapi_backend_la_SOURCES =      \
        module-mapi-backend.c           \
        e-mapi-backend.c                \
        e-mapi-backend.h                \
-       e-mapi-backend-authenticator.c  \
-       e-mapi-backend-authenticator.h  \
        e-mapi-backend-factory.c        \
        e-mapi-backend-factory.h        \
        $(NULL)
diff --git a/src/collection/e-mapi-backend.c b/src/collection/e-mapi-backend.c
index abbfb60..5f0779f 100644
--- a/src/collection/e-mapi-backend.c
+++ b/src/collection/e-mapi-backend.c
@@ -28,7 +28,6 @@
 #include <e-source-mapi-folder.h>
 #include <camel-mapi-settings.h>
 
-#include "e-mapi-backend-authenticator.h"
 #include "e-mapi-backend.h"
 
 #define E_MAPI_BACKEND_GET_PRIVATE(obj) \
@@ -40,18 +39,80 @@ struct _EMapiBackendPrivate {
        GHashTable *folders;
 
        gboolean need_update_folders;
+
+       GMutex credentials_lock;
+       ENamedParameters *credentials;
 };
 
-static void e_mapi_backend_authenticator_init (ESourceAuthenticatorInterface *iface);
+G_DEFINE_DYNAMIC_TYPE (EMapiBackend, e_mapi_backend, E_TYPE_COLLECTION_BACKEND)
+
+typedef gboolean (* EMapiBackendAuthenticatorFunc) (EBackend *backend,
+                                                   CamelMapiSettings *settings,
+                                                   EMapiConnection *conn,
+                                                   gpointer user_data,
+                                                   GCancellable *cancellable,
+                                                   GError **error);
+
+static gboolean
+e_mapi_backend_authenticator_run (EBackend *backend,
+                                 CamelMapiSettings *settings,
+                                 const ENamedParameters *credentials,
+                                 EMapiBackendAuthenticatorFunc func,
+                                 gpointer user_data,
+                                 GCancellable *cancellable,
+                                 GError **error)
+{
+       EMapiProfileData empd = { 0 };
+       EMapiConnection *conn;
+       CamelNetworkSettings *network_settings;
+       GError *mapi_error = NULL;
+       gboolean success;
+
+       g_return_val_if_fail (E_IS_BACKEND (backend), FALSE);
+       g_return_val_if_fail (CAMEL_IS_MAPI_SETTINGS (settings), FALSE);
+       g_return_val_if_fail (func != NULL, FALSE);
+
+       if (!credentials) {
+               g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_INITIALIZED,
+                       _("Cannot connect, no credentials provided"));
+               return FALSE;
+       }
+
+       g_object_ref (backend);
+       g_object_ref (settings);
+
+       network_settings = CAMEL_NETWORK_SETTINGS (settings);
+
+       empd.server = camel_network_settings_get_host (network_settings);
+       empd.username = camel_network_settings_get_user (network_settings);
+       e_mapi_util_profiledata_from_settings (&empd, settings);
+
+       conn = e_mapi_connection_new (
+               NULL,
+               camel_mapi_settings_get_profile (settings),
+               credentials, cancellable, &mapi_error);
 
-G_DEFINE_DYNAMIC_TYPE_EXTENDED (
-       EMapiBackend,
-       e_mapi_backend,
-       E_TYPE_COLLECTION_BACKEND,
-       0,
-       G_IMPLEMENT_INTERFACE_DYNAMIC (
-               E_TYPE_SOURCE_AUTHENTICATOR,
-               e_mapi_backend_authenticator_init))
+       if (mapi_error) {
+               g_warn_if_fail (!conn);
+
+               g_object_unref (backend);
+               g_object_unref (settings);
+
+               g_propagate_error (error, mapi_error);
+
+               return FALSE;
+       }
+
+       g_warn_if_fail (conn != NULL);
+
+       success = func (backend, settings, conn, user_data, cancellable, error);
+
+       g_object_unref (conn);
+       g_object_unref (backend);
+       g_object_unref (settings);
+
+       return success;
+}
 
 static CamelMapiSettings *
 mapi_backend_get_settings (EMapiBackend *backend)
@@ -303,30 +364,6 @@ mapi_backend_sync_folders_idle_cb (gpointer user_data)
        return FALSE;
 }
 
-static ESourceAuthenticationResult
-mapi_backend_try_password_sync (ESourceAuthenticator *authenticator,
-                               const GString *password,
-                               GCancellable *cancellable,
-                               GError **error);
-
-static gpointer
-mapi_backend_authenticate_kerberos_thread (gpointer user_data)
-{
-       EMapiBackend *mapi_backend = user_data;
-       CamelMapiSettings *mapi_settings;
-
-       g_return_val_if_fail (E_IS_MAPI_BACKEND (mapi_backend), NULL);
-
-       mapi_settings = mapi_backend_get_settings (mapi_backend);
-       e_mapi_util_trigger_krb_auth_from_settings (mapi_settings, NULL);
-
-       mapi_backend_try_password_sync (E_SOURCE_AUTHENTICATOR (mapi_backend), NULL, NULL, NULL);
-
-       g_object_unref (mapi_backend);
-
-       return NULL;
-}
-
 static void
 mapi_backend_queue_auth_session (EMapiBackend *backend)
 {
@@ -352,19 +389,14 @@ mapi_backend_queue_auth_session (EMapiBackend *backend)
 
        /* kerberos doesn't use passwords, do it directly */
        if (camel_mapi_settings_get_kerberos (mapi_settings)) {
-               GThread *thread;
-
-               thread = g_thread_new (NULL, mapi_backend_authenticate_kerberos_thread, g_object_ref 
(backend));
-               g_thread_unref (thread);
-
+               e_backend_schedule_authenticate (E_BACKEND (backend), NULL);
                return;
        }
 
        /* For now at least, we don't need to know the
         * results, so no callback function is needed. */
-       e_backend_authenticate (
-               E_BACKEND (backend),
-               E_SOURCE_AUTHENTICATOR (backend),
+       e_backend_credentials_required (
+               E_BACKEND (backend), E_SOURCE_CREDENTIALS_REASON_REQUIRED, NULL, 0, NULL,
                NULL, NULL, NULL);
 }
 
@@ -428,6 +460,9 @@ mapi_backend_finalize (GObject *object)
 
        g_hash_table_destroy (priv->folders);
 
+       g_mutex_clear (&priv->credentials_lock);
+       e_named_parameters_free (priv->credentials);
+
        /* Chain up to parent's finalize() method. */
        G_OBJECT_CLASS (e_mapi_backend_parent_class)->finalize (object);
 }
@@ -640,6 +675,8 @@ mapi_backend_create_resource_sync (ECollectionBackend *backend,
        ESource *parent_source;
        CamelMapiSettings *settings;
        ESourceMapiFolder *folder_ext;
+       EMapiBackend *mapi_backend;
+       ENamedParameters *credentials;
        const gchar *foreign_username;
        const gchar *cache_dir;
        const gchar *parent_uid;
@@ -653,17 +690,26 @@ mapi_backend_create_resource_sync (ECollectionBackend *backend,
                return FALSE;
        }
 
-       settings = mapi_backend_get_settings (E_MAPI_BACKEND (backend));
+       mapi_backend = E_MAPI_BACKEND (backend);
+       settings = mapi_backend_get_settings (mapi_backend);
        g_return_val_if_fail (settings != NULL, FALSE);
 
        folder_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER);
        foreign_username = e_source_mapi_folder_get_foreign_username (folder_ext);
 
+       g_mutex_lock (&mapi_backend->priv->credentials_lock);
+       credentials = mapi_backend->priv->credentials ? e_named_parameters_new_clone 
(mapi_backend->priv->credentials) : NULL;
+       g_mutex_unlock (&mapi_backend->priv->credentials_lock);
+
        if (!e_source_mapi_folder_is_public (folder_ext) &&
            !(foreign_username && *foreign_username) &&
            !e_mapi_backend_authenticator_run (
-               E_BACKEND (backend), settings, mapi_backend_create_resource_cb, source, cancellable, error))
+               E_BACKEND (backend), settings, credentials, mapi_backend_create_resource_cb, source, 
cancellable, error)) {
+               e_named_parameters_free (credentials);
                return FALSE;
+       }
+
+       e_named_parameters_free (credentials);
 
        /* Configure the source as a collection member. */
        parent_source = e_backend_get_source (E_BACKEND (backend));
@@ -728,7 +774,9 @@ mapi_backend_delete_resource_sync (ECollectionBackend *backend,
 {
        CamelMapiSettings *settings;
        ESourceMapiFolder *folder_ext;
+       EMapiBackend *mapi_backend;
        const gchar *foreign_username;
+       ENamedParameters *credentials;
 
        if (!e_source_has_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER)) {
                g_set_error (
@@ -739,44 +787,60 @@ mapi_backend_delete_resource_sync (ECollectionBackend *backend,
                return FALSE;
        }
 
-       settings = mapi_backend_get_settings (E_MAPI_BACKEND (backend));
+       mapi_backend = E_MAPI_BACKEND (backend);
+       settings = mapi_backend_get_settings (mapi_backend);
        g_return_val_if_fail (settings != NULL, FALSE);
 
        folder_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER);
        foreign_username = e_source_mapi_folder_get_foreign_username (folder_ext);
 
+       g_mutex_lock (&mapi_backend->priv->credentials_lock);
+       credentials = mapi_backend->priv->credentials ? e_named_parameters_new_clone 
(mapi_backend->priv->credentials) : NULL;
+       g_mutex_unlock (&mapi_backend->priv->credentials_lock);
+
        if (!e_source_mapi_folder_is_public (folder_ext) &&
            !(foreign_username && *foreign_username) &&
            !e_mapi_backend_authenticator_run (
-               E_BACKEND (backend), settings, mapi_backend_delete_resource_cb, source, cancellable, error))
+               E_BACKEND (backend), settings, credentials, mapi_backend_delete_resource_cb, source, 
cancellable, error)) {
+               e_named_parameters_free (credentials);
                return FALSE;
+       }
+
+       e_named_parameters_free (credentials);
 
        return e_source_remove_sync (source, cancellable, error);
 }
 
 static ESourceAuthenticationResult
-mapi_backend_try_password_sync (ESourceAuthenticator *authenticator,
-                               const GString *password,
+mapi_backend_authenticate_sync (EBackend *backend,
+                               const ENamedParameters *credentials,
+                               gchar **out_certificate_pem,
+                               GTlsCertificateFlags *out_certificate_errors,
                                GCancellable *cancellable,
                                GError **error)
 {
-       EMapiBackend *backend;
+       EMapiBackend *mapi_backend;
        EMapiConnection *conn;
        CamelMapiSettings *settings;
        GSList *mapi_folders = NULL;
        GError *mapi_error = NULL;
 
-       backend = E_MAPI_BACKEND (authenticator);
-       settings = mapi_backend_get_settings (backend);
+       g_return_val_if_fail (E_IS_MAPI_BACKEND (backend), E_SOURCE_AUTHENTICATION_ERROR);
+
+       mapi_backend = E_MAPI_BACKEND (backend);
+       settings = mapi_backend_get_settings (mapi_backend);
+
+       if (camel_mapi_settings_get_kerberos (settings))
+               e_mapi_util_trigger_krb_auth_from_settings (settings, NULL);
 
        conn = e_mapi_connection_new (NULL,
                camel_mapi_settings_get_profile (settings),
-               password, cancellable, &mapi_error);
+               credentials, cancellable, &mapi_error);
 
        if (!conn) {
                ESourceAuthenticationResult res = E_SOURCE_AUTHENTICATION_ERROR;
 
-               backend->priv->need_update_folders = TRUE;
+               mapi_backend->priv->need_update_folders = TRUE;
 
                if (g_error_matches (mapi_error, E_MAPI_ERROR, MAPI_E_PASSWORD_CHANGE_REQUIRED) ||
                    g_error_matches (mapi_error, E_MAPI_ERROR, MAPI_E_PASSWORD_EXPIRED))
@@ -793,19 +857,26 @@ mapi_backend_try_password_sync (ESourceAuthenticator *authenticator,
        if (e_mapi_connection_get_folders_list (conn, &mapi_folders, NULL, NULL, cancellable, &mapi_error)) {
                struct SyndFoldersData *sfd;
 
+               g_mutex_lock (&mapi_backend->priv->credentials_lock);
+               e_named_parameters_free (mapi_backend->priv->credentials);
+               mapi_backend->priv->credentials = credentials ? e_named_parameters_new_clone (credentials) : 
NULL;
+               g_mutex_unlock (&mapi_backend->priv->credentials_lock);
+
                sfd = g_new0 (struct SyndFoldersData, 1);
                sfd->folders = mapi_folders;
-               sfd->backend = g_object_ref (backend);
+               sfd->backend = g_object_ref (mapi_backend);
                sfd->profile = camel_mapi_settings_dup_profile (settings);
 
                g_idle_add_full (
                        G_PRIORITY_DEFAULT_IDLE,
                        mapi_backend_sync_folders_idle_cb, sfd,
                        sync_folders_data_free);
+
+               e_collection_backend_authenticate_children (E_COLLECTION_BACKEND (backend), credentials);
        } else {
-               ESource *source = e_backend_get_source (E_BACKEND (backend));
+               ESource *source = e_backend_get_source (backend);
 
-               backend->priv->need_update_folders = TRUE;
+               mapi_backend->priv->need_update_folders = TRUE;
 
                g_message ("%s: Failed to get list of user's folders for '%s': %s",
                        G_STRFUNC, e_source_get_display_name (source), mapi_error ? mapi_error->message : 
"Unknown error");
@@ -821,7 +892,8 @@ static void
 e_mapi_backend_class_init (EMapiBackendClass *class)
 {
        GObjectClass *object_class;
-       ECollectionBackendClass *backend_class;
+       EBackendClass *backend_class;
+       ECollectionBackendClass *collection_backend_class;
 
        g_type_class_add_private (class, sizeof (EMapiBackendPrivate));
 
@@ -830,13 +902,16 @@ e_mapi_backend_class_init (EMapiBackendClass *class)
        object_class->dispose = mapi_backend_dispose;
        object_class->finalize = mapi_backend_finalize;
 
-       backend_class = E_COLLECTION_BACKEND_CLASS (class);
-       backend_class->populate = mapi_backend_populate;
-       backend_class->dup_resource_id = mapi_backend_dup_resource_id;
-       backend_class->child_added = mapi_backend_child_added;
-       backend_class->child_removed = mapi_backend_child_removed;
-       backend_class->create_resource_sync = mapi_backend_create_resource_sync;
-       backend_class->delete_resource_sync = mapi_backend_delete_resource_sync;
+       backend_class = E_BACKEND_CLASS (class);
+       backend_class->authenticate_sync = mapi_backend_authenticate_sync;
+
+       collection_backend_class = E_COLLECTION_BACKEND_CLASS (class);
+       collection_backend_class->populate = mapi_backend_populate;
+       collection_backend_class->dup_resource_id = mapi_backend_dup_resource_id;
+       collection_backend_class->child_added = mapi_backend_child_added;
+       collection_backend_class->child_removed = mapi_backend_child_removed;
+       collection_backend_class->create_resource_sync = mapi_backend_create_resource_sync;
+       collection_backend_class->delete_resource_sync = mapi_backend_delete_resource_sync;
 
        /* This generates an ESourceCamel subtype for CamelMapiSettings. */
        e_source_camel_generate_subtype ("mapi", CAMEL_TYPE_MAPI_SETTINGS);
@@ -848,12 +923,6 @@ e_mapi_backend_class_finalize (EMapiBackendClass *class)
 }
 
 static void
-e_mapi_backend_authenticator_init (ESourceAuthenticatorInterface *iface)
-{
-       iface->try_password_sync = mapi_backend_try_password_sync;
-}
-
-static void
 e_mapi_backend_init (EMapiBackend *backend)
 {
        backend->priv = E_MAPI_BACKEND_GET_PRIVATE (backend);
@@ -867,6 +936,9 @@ e_mapi_backend_init (EMapiBackend *backend)
        g_signal_connect (
                backend, "notify::online",
                G_CALLBACK (mapi_backend_populate), NULL);
+
+       g_mutex_init (&backend->priv->credentials_lock);
+       backend->priv->credentials = NULL;
 }
 
 void
diff --git a/src/configuration/e-mail-config-mapi-backend.c b/src/configuration/e-mail-config-mapi-backend.c
index 0bbda9e..158d6e9 100644
--- a/src/configuration/e-mail-config-mapi-backend.c
+++ b/src/configuration/e-mail-config-mapi-backend.c
@@ -242,7 +242,7 @@ validate_credentials_test (ESourceRegistry *registry,
                status = FALSE;
                profname = e_mapi_util_profile_name (mapi_ctx, empd, FALSE);
 
-               conn = e_mapi_connection_new (registry, profname, empd->password, cancellable, perror);
+               conn = e_mapi_connection_new (registry, profname, empd->credentials, cancellable, perror);
                if (conn) {
                        status = e_mapi_connection_connected (conn);
                        g_object_unref (conn);
@@ -267,12 +267,7 @@ validate_credentials_test (ESourceRegistry *registry,
        return success;
 }
 
-typedef struct _EMailConfigMapiAuthenticator EMailConfigMapiAuthenticator;
-typedef struct _EMailConfigMapiAuthenticatorClass EMailConfigMapiAuthenticatorClass;
-
-struct _EMailConfigMapiAuthenticator {
-       GObject parent;
-
+typedef struct _TryCredentialsData {
        gchar *username;
        gchar *domain;
        gchar *server;
@@ -282,103 +277,76 @@ struct _EMailConfigMapiAuthenticator {
        CamelMapiSettings *mapi_settings;
        EMailConfigServiceBackend *backend;
        gboolean success;
-};
+} TryCredentialsData;
 
-struct _EMailConfigMapiAuthenticatorClass {
-       GObjectClass parent_class;
-};
+static void
+try_credentials_data_free (gpointer ptr)
+{
+       TryCredentialsData *data = ptr;
+
+       if (data) {
+               g_free (data->username);
+               g_free (data->domain);
+               g_free (data->server);
+               g_free (data->krb_realm);
+               g_object_unref (data->mapi_settings);
+               g_object_unref (data->backend);
+               g_free (data);
+       }
+}
 
-static ESourceAuthenticationResult
-mail_config_mapi_authenticator_try_password_sync (ESourceAuthenticator *auth,
-                                                 const GString *password,
-                                                 GCancellable *cancellable,
-                                                 GError **error)
+static gboolean
+mail_config_mapi_try_credentials_sync (ECredentialsPrompter *prompter,
+                                      ESource *source,
+                                      const ENamedParameters *credentials,
+                                      gboolean *out_authenticated,
+                                      gpointer user_data,
+                                      GCancellable *cancellable,
+                                      GError **error)
 {
-       EMailConfigMapiAuthenticator *mapi_authenticator = (EMailConfigMapiAuthenticator *) auth;
+       TryCredentialsData *data = user_data;
        EMailConfigServicePage *page;
        ESourceRegistry *registry;
        EMapiProfileData empd = { 0 };
        GError *mapi_error = NULL;
 
-       empd.username = mapi_authenticator->username;
-       empd.domain = mapi_authenticator->domain;
-       empd.server = mapi_authenticator->server;
-       empd.password = (GString *) password;
-       empd.use_ssl = mapi_authenticator->use_ssl;
-       empd.krb_sso = mapi_authenticator->krb_sso;
-       empd.krb_realm = mapi_authenticator->krb_realm;
+       empd.username = data->username;
+       empd.domain = data->domain;
+       empd.server = data->server;
+       empd.credentials = (ENamedParameters *) credentials;
+       empd.use_ssl = data->use_ssl;
+       empd.krb_sso = data->krb_sso;
+       empd.krb_realm = data->krb_realm;
 
-       page = e_mail_config_service_backend_get_page (mapi_authenticator->backend);
+       page = e_mail_config_service_backend_get_page (data->backend);
        registry = e_mail_config_service_page_get_registry (page);
 
-       mapi_authenticator->success = validate_credentials_test (
+       data->success = validate_credentials_test (
                registry,
                &empd, 
-               mapi_authenticator->mapi_settings,
+               data->mapi_settings,
                cancellable,
                &mapi_error);
 
        if (mapi_error) {
                gboolean is_network_error = mapi_error && mapi_error->domain != E_MAPI_ERROR;
 
-               g_warn_if_fail (!mapi_authenticator->success);
-               mapi_authenticator->success = FALSE;
+               g_warn_if_fail (!data->success);
+               data->success = FALSE;
 
                if (is_network_error)
                        g_propagate_error (error, mapi_error);
                else
                        g_clear_error (&mapi_error);
 
-               return is_network_error ? E_SOURCE_AUTHENTICATION_ERROR : E_SOURCE_AUTHENTICATION_REJECTED;
+               return is_network_error ? FALSE : TRUE;
        }
 
-       g_warn_if_fail (mapi_authenticator->success);
-
-       return E_SOURCE_AUTHENTICATION_ACCEPTED;
-}
-
-#define E_TYPE_MAIL_CONFIG_MAPI_AUTHENTICATOR (e_mail_config_mapi_authenticator_get_type ())
-
-GType e_mail_config_mapi_authenticator_get_type (void) G_GNUC_CONST;
-
-static void e_mail_config_mapi_authenticator_authenticator_init (ESourceAuthenticatorInterface *iface);
-
-G_DEFINE_TYPE_EXTENDED (EMailConfigMapiAuthenticator, e_mail_config_mapi_authenticator, G_TYPE_OBJECT, 0,
-       G_IMPLEMENT_INTERFACE (E_TYPE_SOURCE_AUTHENTICATOR, 
e_mail_config_mapi_authenticator_authenticator_init))
-
-static void
-mail_config_mapi_authenticator_finalize (GObject *object)
-{
-       EMailConfigMapiAuthenticator *mapi_authenticator = (EMailConfigMapiAuthenticator *) object;
+       g_warn_if_fail (data->success);
 
-       g_free (mapi_authenticator->username);
-       g_free (mapi_authenticator->domain);
-       g_free (mapi_authenticator->server);
-       g_free (mapi_authenticator->krb_realm);
-       g_object_unref (mapi_authenticator->mapi_settings);
-       g_object_unref (mapi_authenticator->backend);
+       *out_authenticated = data->success;
 
-       G_OBJECT_CLASS (e_mail_config_mapi_authenticator_parent_class)->finalize (object);
-}
-
-static void
-e_mail_config_mapi_authenticator_class_init (EMailConfigMapiAuthenticatorClass *class)
-{
-       GObjectClass *object_class;
-
-       object_class = G_OBJECT_CLASS (class);
-       object_class->finalize = mail_config_mapi_authenticator_finalize;
-}
-
-static void
-e_mail_config_mapi_authenticator_authenticator_init (ESourceAuthenticatorInterface *iface)
-{
-       iface->try_password_sync = mail_config_mapi_authenticator_try_password_sync;
-}
-
-static void
-e_mail_config_mapi_authenticator_init (EMailConfigMapiAuthenticator *mapi_authenticator)
-{
+       return TRUE;
 }
 
 static void
@@ -387,11 +355,11 @@ validate_credentials_idle (GObject *button,
                           GCancellable *cancellable,
                           GError **perror)
 {
-       EMailConfigMapiAuthenticator *mapi_authenticator = user_data;
+       TryCredentialsData *data = user_data;
 
-       g_return_if_fail (mapi_authenticator != NULL);
+       g_return_if_fail (data != NULL);
 
-       if (mapi_authenticator->success)
+       if (data->success)
                e_notice (NULL, GTK_MESSAGE_INFO, "%s", _("Authentication finished successfully."));
        else
                e_notice (NULL, GTK_MESSAGE_ERROR, "%s", _("Authentication failed."));
@@ -403,43 +371,45 @@ validate_credentials_thread (GObject *button,
                             GCancellable *cancellable,
                             GError **perror)
 {
-       EMailConfigMapiAuthenticator *mapi_authenticator = user_data;
+       TryCredentialsData *data = user_data;
        EMailConfigServicePage *page;
        ESourceRegistry *registry;
 
-       g_return_if_fail (mapi_authenticator != NULL);
+       g_return_if_fail (data != NULL);
 
-       page = e_mail_config_service_backend_get_page (mapi_authenticator->backend);
+       page = e_mail_config_service_backend_get_page (data->backend);
        registry = e_mail_config_service_page_get_registry (page);
 
-       if (mapi_authenticator->krb_sso) {
+       if (data->krb_sso) {
                GError *error = NULL;
                EMapiProfileData empd = { 0 };
 
-               empd.username = mapi_authenticator->username;
-               empd.domain = mapi_authenticator->domain;
-               empd.server = mapi_authenticator->server;
-               empd.use_ssl = mapi_authenticator->use_ssl;
-               empd.krb_sso = mapi_authenticator->krb_sso;
-               empd.krb_realm = mapi_authenticator->krb_realm;
+               empd.username = data->username;
+               empd.domain = data->domain;
+               empd.server = data->server;
+               empd.use_ssl = data->use_ssl;
+               empd.krb_sso = data->krb_sso;
+               empd.krb_realm = data->krb_realm;
 
                e_mapi_util_trigger_krb_auth (&empd, &error);
                g_clear_error (&error);
 
-               mapi_authenticator->success = validate_credentials_test (
+               data->success = validate_credentials_test (
                        registry,
                        &empd, 
-                       mapi_authenticator->mapi_settings,
+                       data->mapi_settings,
                        cancellable,
                        perror);
        } else {
+               EShell *shell;
                ESource *source;
 
-               source = e_mail_config_service_backend_get_source (mapi_authenticator->backend);
+               shell = e_shell_get_default ();
+               source = e_mail_config_service_backend_get_source (data->backend);
 
-               e_source_registry_authenticate_sync (
-                       registry, source, E_SOURCE_AUTHENTICATOR (mapi_authenticator),
-                       cancellable, perror);
+               e_credentials_prompter_loop_prompt_sync (e_shell_get_credentials_prompter (shell),
+                       source, E_CREDENTIALS_PROMPTER_PROMPT_FLAG_ALLOW_SOURCE_SAVE,
+                       mail_config_mapi_try_credentials_sync, data, cancellable, perror);
        }
 }
 
@@ -492,35 +462,30 @@ validate_credentials_cb (GtkWidget *widget,
        }
 
        if (COMPLETE_PROFILEDATA (&empd)) {
-               EMailConfigMapiAuthenticator *mapi_authenticator;
-
-               mapi_authenticator = g_object_new (E_TYPE_MAIL_CONFIG_MAPI_AUTHENTICATOR, NULL);
-
-               mapi_authenticator->username = g_strdup (empd.username);
-               mapi_authenticator->domain = g_strdup (empd.domain);
-               mapi_authenticator->server = g_strdup (empd.server);
-               mapi_authenticator->use_ssl = empd.use_ssl;
-               mapi_authenticator->krb_sso = empd.krb_sso;
-               mapi_authenticator->krb_realm = g_strdup (empd.krb_realm);
-               mapi_authenticator->mapi_settings = g_object_ref (mapi_settings);
-               mapi_authenticator->backend = g_object_ref (backend);
-               mapi_authenticator->success = FALSE;
+               TryCredentialsData *data = g_new0 (TryCredentialsData, 1);
+
+               data->username = g_strdup (empd.username);
+               data->domain = g_strdup (empd.domain);
+               data->server = g_strdup (empd.server);
+               data->use_ssl = empd.use_ssl;
+               data->krb_sso = empd.krb_sso;
+               data->krb_realm = g_strdup (empd.krb_realm);
+               data->mapi_settings = g_object_ref (mapi_settings);
+               data->backend = g_object_ref (backend);
+               data->success = FALSE;
 
                e_mapi_config_utils_run_in_thread_with_feedback_modal 
(e_mapi_config_utils_get_widget_toplevel_window (widget),
                        G_OBJECT (widget),
                        _("Connecting to the server, please wait..."),
                        validate_credentials_thread,
                        validate_credentials_idle,
-                       mapi_authenticator,
-                       g_object_unref);
+                       data,
+                       try_credentials_data_free);
        } else {
                e_notice (NULL, GTK_MESSAGE_ERROR, "%s", _("Authentication failed."));
        }
 
-       if (empd.password) {
-               memset (empd.password->str, 0, empd.password->len);
-               g_string_free (empd.password, TRUE);
-       }
+       g_warn_if_fail (empd.credentials == NULL);
 }
 
 static ESource *
diff --git a/src/configuration/e-mapi-config-utils.c b/src/configuration/e-mapi-config-utils.c
index 9bc80ee..5766542 100644
--- a/src/configuration/e-mapi-config-utils.c
+++ b/src/configuration/e-mapi-config-utils.c
@@ -26,6 +26,7 @@
 
 #include <gtk/gtk.h>
 #include <libedataserver/libedataserver.h>
+#include <libedataserverui/libedataserverui.h>
 
 #include <e-util/e-util.h>
 
@@ -246,97 +247,50 @@ e_mapi_config_utils_run_in_thread_with_feedback_modal (GtkWindow *parent,
        e_mapi_config_utils_run_in_thread_with_feedback_general (parent, with_object, description, 
thread_func, idle_func, user_data, free_user_data, TRUE);
 }
 
-typedef struct _EMapiConfigUtilsAuthenticator EMapiConfigUtilsAuthenticator;
-typedef struct _EMapiConfigUtilsAuthenticatorClass EMapiConfigUtilsAuthenticatorClass;
-
-struct _EMapiConfigUtilsAuthenticator {
-       GObject parent;
-
+typedef struct _TryCredentialsData {
        ESourceRegistry *registry;
        CamelMapiSettings *mapi_settings;
        EMapiConnection *conn;
-};
-
-struct _EMapiConfigUtilsAuthenticatorClass {
-       GObjectClass parent_class;
-};
+} TryCredentialsData;
 
-static ESourceAuthenticationResult
-mapi_config_utils_authenticator_try_password_sync (ESourceAuthenticator *auth,
-                                                  const GString *password,
-                                                  GCancellable *cancellable,
-                                                  GError **error)
+static gboolean
+mapi_config_utils_try_credentials_sync (ECredentialsPrompter *prompter,
+                                       ESource *source,
+                                       const ENamedParameters *credentials,
+                                       gboolean *out_authenticated,
+                                       gpointer user_data,
+                                       GCancellable *cancellable,
+                                       GError **error)
 {
-       EMapiConfigUtilsAuthenticator *authenticator = (EMapiConfigUtilsAuthenticator *) auth;
+       TryCredentialsData *data = user_data;
        EMapiProfileData empd = { 0 };
        CamelNetworkSettings *network_settings;
        GError *mapi_error = NULL;
 
-       network_settings = CAMEL_NETWORK_SETTINGS (authenticator->mapi_settings);
+       network_settings = CAMEL_NETWORK_SETTINGS (data->mapi_settings);
 
        empd.server = camel_network_settings_get_host (network_settings);
        empd.username = camel_network_settings_get_user (network_settings);
-       e_mapi_util_profiledata_from_settings (&empd, authenticator->mapi_settings);
+       e_mapi_util_profiledata_from_settings (&empd, data->mapi_settings);
 
-       authenticator->conn = e_mapi_connection_new (
-               authenticator->registry,
-               camel_mapi_settings_get_profile (authenticator->mapi_settings),
-               password, cancellable, &mapi_error);
+       data->conn = e_mapi_connection_new (
+               data->registry,
+               camel_mapi_settings_get_profile (data->mapi_settings),
+               credentials, cancellable, &mapi_error);
 
        if (mapi_error) {
-               g_warn_if_fail (!authenticator->conn);
-               authenticator->conn = NULL;
+               g_warn_if_fail (!data->conn);
+               data->conn = NULL;
 
                g_propagate_error (error, mapi_error);
 
-               return E_SOURCE_AUTHENTICATION_ERROR;
+               return FALSE;
        }
 
-       g_warn_if_fail (authenticator->conn);
+       g_warn_if_fail (data->conn);
+       *out_authenticated = TRUE;
 
-       return E_SOURCE_AUTHENTICATION_ACCEPTED;
-}
-
-#define E_TYPE_MAPI_CONFIG_UTILS_AUTHENTICATOR (e_mapi_config_utils_authenticator_get_type ())
-
-GType e_mapi_config_utils_authenticator_get_type (void) G_GNUC_CONST;
-
-static void e_mapi_config_utils_authenticator_authenticator_init (ESourceAuthenticatorInterface *iface);
-
-G_DEFINE_TYPE_EXTENDED (EMapiConfigUtilsAuthenticator, e_mapi_config_utils_authenticator, G_TYPE_OBJECT, 0,
-       G_IMPLEMENT_INTERFACE (E_TYPE_SOURCE_AUTHENTICATOR, 
e_mapi_config_utils_authenticator_authenticator_init))
-
-static void
-mapi_config_utils_authenticator_finalize (GObject *object)
-{
-       EMapiConfigUtilsAuthenticator *authenticator = (EMapiConfigUtilsAuthenticator *) object;
-
-       g_object_unref (authenticator->registry);
-       g_object_unref (authenticator->mapi_settings);
-       if (authenticator->conn)
-               g_object_unref (authenticator->conn);
-
-       G_OBJECT_CLASS (e_mapi_config_utils_authenticator_parent_class)->finalize (object);
-}
-
-static void
-e_mapi_config_utils_authenticator_class_init (EMapiConfigUtilsAuthenticatorClass *class)
-{
-       GObjectClass *object_class;
-
-       object_class = G_OBJECT_CLASS (class);
-       object_class->finalize = mapi_config_utils_authenticator_finalize;
-}
-
-static void
-e_mapi_config_utils_authenticator_authenticator_init (ESourceAuthenticatorInterface *iface)
-{
-       iface->try_password_sync = mapi_config_utils_authenticator_try_password_sync;
-}
-
-static void
-e_mapi_config_utils_authenticator_init (EMapiConfigUtilsAuthenticator *authenticator)
-{
+       return TRUE;
 }
 
 EMapiConnection        *
@@ -380,19 +334,25 @@ e_mapi_config_utils_open_connection_for (GtkWindow *parent,
 
                        conn = e_mapi_connection_new (registry, profile, NULL, cancellable, &local_error);
                } else {
-                       EMapiConfigUtilsAuthenticator *authenticator = g_object_new 
(E_TYPE_MAPI_CONFIG_UTILS_AUTHENTICATOR, NULL);
+                       EShell *shell;
+                       TryCredentialsData data;
+
+                       shell = e_shell_get_default ();
 
-                       authenticator->mapi_settings = g_object_ref (mapi_settings);
-                       authenticator->registry = g_object_ref (registry);
+                       data.mapi_settings = g_object_ref (mapi_settings);
+                       data.registry = g_object_ref (registry);
+                       data.conn = NULL;
 
-                       e_source_registry_authenticate_sync (
-                               registry, source, E_SOURCE_AUTHENTICATOR (authenticator),
-                               cancellable, &local_error);
+                       e_credentials_prompter_loop_prompt_sync (e_shell_get_credentials_prompter (shell),
+                               source, E_CREDENTIALS_PROMPTER_PROMPT_FLAG_ALLOW_SOURCE_SAVE,
+                               mapi_config_utils_try_credentials_sync, &data, cancellable, &local_error);
 
-                       if (authenticator->conn)
-                               conn = g_object_ref (authenticator->conn);
+                       if (data.conn)
+                               conn = g_object_ref (data.conn);
 
-                       g_object_unref (authenticator);
+                       g_clear_object (&data.mapi_settings);
+                       g_clear_object (&data.registry);
+                       g_clear_object (&data.conn);
                }
        }
 
diff --git a/src/libexchangemapi/e-mapi-connection.c b/src/libexchangemapi/e-mapi-connection.c
index ade9732..bf4945f 100644
--- a/src/libexchangemapi/e-mapi-connection.c
+++ b/src/libexchangemapi/e-mapi-connection.c
@@ -49,7 +49,7 @@
 static void register_connection (EMapiConnection *conn);
 static void unregister_connection (EMapiConnection *conn);
 static gboolean mapi_profile_create (struct mapi_context *mapi_ctx, const EMapiProfileData *empd, 
mapi_profile_callback_t callback, gconstpointer data, GCancellable *cancellable, GError **perror, gboolean 
use_locking);
-static struct mapi_session *mapi_profile_load (ESourceRegistry *registry, struct mapi_context *mapi_ctx, 
const gchar *profname, const gchar *password, GCancellable *cancellable, GError **perror);
+static struct mapi_session *mapi_profile_load (ESourceRegistry *registry, struct mapi_context *mapi_ctx, 
const gchar *profname, const ENamedParameters *credentials, GCancellable *cancellable, GError **perror);
 
 /* GObject foo - begin */
 
@@ -589,7 +589,7 @@ e_mapi_connection_find (const gchar *profile)
 EMapiConnection *
 e_mapi_connection_new (ESourceRegistry *registry,
                       const gchar *profile,
-                      const GString *password,
+                      const ENamedParameters *credentials,
                       GCancellable *cancellable,
                       GError **perror)
 {
@@ -604,7 +604,7 @@ e_mapi_connection_new (ESourceRegistry *registry,
        if (!e_mapi_utils_create_mapi_context (&mapi_ctx, perror))
                return NULL;
 
-       session = mapi_profile_load (registry, mapi_ctx, profile, password ? password->str : NULL, 
cancellable, perror);
+       session = mapi_profile_load (registry, mapi_ctx, profile, credentials, cancellable, perror);
        if (!session) {
                e_mapi_utils_destroy_mapi_context (mapi_ctx);
                return NULL;
@@ -671,7 +671,7 @@ e_mapi_connection_disconnect (EMapiConnection *conn,
 
 gboolean
 e_mapi_connection_reconnect (EMapiConnection *conn,
-                            const GString *password,
+                            const ENamedParameters *credentials,
                             GCancellable *cancellable,
                             GError **perror)
 {
@@ -685,7 +685,7 @@ e_mapi_connection_reconnect (EMapiConnection *conn,
        if (priv->session)
                e_mapi_connection_disconnect (conn, FALSE, cancellable, perror);
 
-       priv->session = mapi_profile_load (priv->registry, priv->mapi_ctx, priv->profile, password ? 
password->str : NULL, cancellable, perror);
+       priv->session = mapi_profile_load (priv->registry, priv->mapi_ctx, priv->profile, credentials, 
cancellable, perror);
        if (!priv->session) {
                e_mapi_debug_print ("%s: %s: Login failed ", G_STRLOC, G_STRFUNC);
                UNLOCK ();
@@ -7014,7 +7014,7 @@ struct tcp_data
        ESourceRegistry *registry;
        struct mapi_context *mapi_ctx;
        const gchar *profname;
-       const gchar *password;
+       const ENamedParameters *credentials;
        GCancellable *cancellable;
        GError **perror;
 
@@ -7051,13 +7051,13 @@ try_create_profile_main_thread_cb (struct tcp_data *data)
                network_settings = CAMEL_NETWORK_SETTINGS (settings);
 
                empd.server = camel_network_settings_get_host (network_settings);
-               empd.username = camel_network_settings_get_user (network_settings);
+               if (data->credentials && e_named_parameters_get (data->credentials, 
E_SOURCE_CREDENTIAL_USERNAME))
+                       empd.username = e_named_parameters_get (data->credentials, 
E_SOURCE_CREDENTIAL_USERNAME);
+               else
+                       empd.username = camel_network_settings_get_user (network_settings);
                e_mapi_util_profiledata_from_settings (&empd, CAMEL_MAPI_SETTINGS (settings));
 
-               if (data->password)
-                       empd.password = g_string_new (data->password);
-               else
-                       data->password = NULL;
+               empd.credentials = (ENamedParameters *) data->credentials;
 
                if (COMPLETE_PROFILEDATA (&empd)) {
                        gchar *profname = e_mapi_util_profile_name (data->mapi_ctx, &empd, FALSE);
@@ -7069,12 +7069,6 @@ try_create_profile_main_thread_cb (struct tcp_data *data)
 
                        g_free (profname);
                }
-
-               if (empd.password) {
-                       if (empd.password->len)
-                               memset (empd.password->str, 0, empd.password->len);
-                       g_string_free (empd.password, TRUE);
-               }
        }
 
        g_list_free_full (all_sources, g_object_unref);
@@ -7088,7 +7082,7 @@ static gboolean
 try_create_profile (ESourceRegistry *registry,
                    struct mapi_context *mapi_ctx,
                    const gchar *profname,
-                   const gchar *password,
+                   const ENamedParameters *credentials,
                    GCancellable *cancellable,
                    GError **perror)
 {
@@ -7101,7 +7095,7 @@ try_create_profile (ESourceRegistry *registry,
        data.registry = registry;
        data.mapi_ctx = mapi_ctx;
        data.profname = profname;
-       data.password = password;
+       data.credentials = credentials;
        data.eflag = e_flag_new ();
        data.has_profile = FALSE;
        data.cancellable = cancellable;
@@ -7124,7 +7118,7 @@ static struct mapi_session *
 mapi_profile_load (ESourceRegistry *registry,
                   struct mapi_context *mapi_ctx,
                   const gchar *profname,
-                  const gchar *password,
+                  const ENamedParameters *credentials,
                   GCancellable *cancellable,
                   GError **perror)
 {
@@ -7152,9 +7146,14 @@ mapi_profile_load (ESourceRegistry *registry,
 
        e_mapi_debug_print("Loading profile %s ", profname);
 
-       ms = MapiLogonEx (mapi_ctx, &session, profname, password);
-       if (ms == MAPI_E_NOT_FOUND && try_create_profile (registry, mapi_ctx, profname, password, 
cancellable, perror))
-               ms = MapiLogonEx (mapi_ctx, &session, profname, password);
+       if (credentials && e_named_parameters_get (credentials, E_SOURCE_CREDENTIAL_USERNAME)) {
+               mapi_profile_add_string_attr (mapi_ctx, profname, "username", e_named_parameters_get 
(credentials, E_SOURCE_CREDENTIAL_USERNAME));
+       }
+
+       ms = MapiLogonEx (mapi_ctx, &session, profname, credentials ? e_named_parameters_get (credentials, 
E_SOURCE_CREDENTIAL_PASSWORD) : NULL);
+       if (ms == MAPI_E_NOT_FOUND && try_create_profile (registry, mapi_ctx, profname, credentials, 
cancellable, perror))
+               ms = MapiLogonEx (mapi_ctx, &session, profname,
+               credentials ? e_named_parameters_get (credentials, E_SOURCE_CREDENTIAL_PASSWORD) : NULL);
 
        if (ms != MAPI_E_SUCCESS) {
                make_mapi_error (perror, "MapiLogonEx", ms);
@@ -7212,7 +7211,7 @@ mapi_profile_create (struct mapi_context *mapi_ctx,
        }
 
        /*We need all the params before proceeding.*/
-       e_return_val_mapi_error_if_fail (COMPLETE_PROFILEDATA (empd) && (empd->krb_sso || (empd->password && 
empd->password->len)),
+       e_return_val_mapi_error_if_fail (COMPLETE_PROFILEDATA (empd) && (empd->krb_sso || 
(empd->credentials)),
                                         MAPI_E_INVALID_PARAMETER, FALSE);
 
        if (!can_reach_mapi_server (empd->server, cancellable, perror))
@@ -7232,8 +7231,8 @@ mapi_profile_create (struct mapi_context *mapi_ctx,
        ms = DeleteProfile (mapi_ctx, profname);
        /* don't bother to check error - it would be valid if we got an error */
 
-       ms = CreateProfile (mapi_ctx, profname, empd->username,
-                           empd->krb_sso ? NULL : empd->password->str, OC_PROFILE_NOPASSWORD);
+       ms = CreateProfile (mapi_ctx, profname, empd->username, empd->krb_sso ? NULL :
+               e_named_parameters_get (empd->credentials, E_SOURCE_CREDENTIAL_PASSWORD), 
OC_PROFILE_NOPASSWORD);
        if (ms != MAPI_E_SUCCESS) {
                make_mapi_error (perror, "CreateProfile", ms);
                goto cleanup;
@@ -7265,8 +7264,8 @@ mapi_profile_create (struct mapi_context *mapi_ctx,
 
        /* Login now */
        e_mapi_debug_print("Logging into the server... ");
-       ms = MapiLogonProvider (mapi_ctx, &session, profname, empd->krb_sso ? NULL : empd->password->str,
-                               PROVIDER_ID_NSPI);
+       ms = MapiLogonProvider (mapi_ctx, &session, profname, empd->krb_sso ? NULL :
+               e_named_parameters_get (empd->credentials, E_SOURCE_CREDENTIAL_PASSWORD), PROVIDER_ID_NSPI);
        if (ms != MAPI_E_SUCCESS) {
                make_mapi_error (perror, "MapiLogonProvider", ms);
                e_mapi_debug_print ("Deleting profile %s ", profname);
diff --git a/src/libexchangemapi/e-mapi-connection.h b/src/libexchangemapi/e-mapi-connection.h
index 5cf7f5b..773b802 100644
--- a/src/libexchangemapi/e-mapi-connection.h
+++ b/src/libexchangemapi/e-mapi-connection.h
@@ -237,12 +237,12 @@ struct _EMapiConnectionClass {
 GType                  e_mapi_connection_get_type              (void);
 EMapiConnection *      e_mapi_connection_new                   (ESourceRegistry *registry,
                                                                 const gchar *profile,
-                                                                const GString *password,
+                                                                const ENamedParameters *credentials,
                                                                 GCancellable *cancellable,
                                                                 GError **perror);
 EMapiConnection *      e_mapi_connection_find                  (const gchar *profile);
 gboolean               e_mapi_connection_reconnect             (EMapiConnection *conn,
-                                                                const GString *password,
+                                                                const ENamedParameters *credentials,
                                                                 GCancellable *cancellable,
                                                                 GError **perror);
 gboolean               e_mapi_connection_disconnect            (EMapiConnection *conn,
@@ -525,7 +525,7 @@ gboolean            e_mapi_connection_disable_notifications (EMapiConnection *conn,
 
 typedef struct {
        const gchar *username;
-       GString *password;
+       ENamedParameters *credentials;
        const gchar *domain;
        const gchar *server;
        gboolean use_ssl;


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