aboutsummaryrefslogtreecommitdiffstats
path: root/mail/e-mail-session.c
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2011-10-15 21:52:08 +0800
committerMatthew Barnes <mbarnes@redhat.com>2011-10-15 22:59:53 +0800
commit315ca196bd3f7b3157fd836954c84ea0360619bd (patch)
tree08e37ce26d260cf99e2e582a4149c1c3a0562793 /mail/e-mail-session.c
parentbeee64387b7ed20a97de36a886204c958d8e513b (diff)
downloadgsoc2013-evolution-315ca196bd3f7b3157fd836954c84ea0360619bd.tar.gz
gsoc2013-evolution-315ca196bd3f7b3157fd836954c84ea0360619bd.tar.zst
gsoc2013-evolution-315ca196bd3f7b3157fd836954c84ea0360619bd.zip
Adapt to Camel's new authentication API.
Diffstat (limited to 'mail/e-mail-session.c')
-rw-r--r--mail/e-mail-session.c129
1 files changed, 129 insertions, 0 deletions
diff --git a/mail/e-mail-session.c b/mail/e-mail-session.c
index 0687d7561f..c7784447bd 100644
--- a/mail/e-mail-session.c
+++ b/mail/e-mail-session.c
@@ -1096,6 +1096,134 @@ mail_session_get_socks_proxy (CamelSession *session,
g_free (uri);
}
+static gboolean
+mail_session_authenticate_sync (CamelSession *session,
+ CamelService *service,
+ const gchar *mechanism,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelServiceAuthType *authtype = NULL;
+ CamelAuthenticationResult result;
+ CamelProvider *provider;
+ CamelURL *url;
+ const gchar *password;
+ guint32 password_flags;
+ GError *local_error = NULL;
+
+ /* Do not chain up. Camel's default method is only an example for
+ * subclasses to follow. Instead we mimic most of its logic here. */
+
+ url = camel_service_get_camel_url (service);
+ provider = camel_service_get_provider (service);
+
+ /* If a SASL mechanism was given and we can't find
+ * a CamelServiceAuthType for it, fail immediately. */
+ if (mechanism != NULL) {
+ authtype = camel_sasl_authtype (mechanism);
+ if (authtype == NULL) {
+ g_set_error (
+ error, CAMEL_SERVICE_ERROR,
+ CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
+ _("No support for %s authentication"),
+ mechanism);
+ return FALSE;
+ }
+ }
+
+ /* If the SASL mechanism does not involve a user
+ * password, then it gets one shot to authenticate. */
+ if (authtype != NULL && !authtype->need_password) {
+ result = camel_service_authenticate_sync (
+ service, mechanism, cancellable, error);
+ if (result == CAMEL_AUTHENTICATION_REJECTED)
+ g_set_error (
+ error, CAMEL_SERVICE_ERROR,
+ CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
+ _("%s authentication failed"), mechanism);
+ return (result == CAMEL_AUTHENTICATION_ACCEPTED);
+ }
+
+ /* Some SASL mechanisms can attempt to authenticate without a
+ * user password being provided (e.g. single-sign-on credentials),
+ * but can fall back to a user password. Handle that case next. */
+ if (mechanism != NULL) {
+ CamelProvider *provider;
+ CamelSasl *sasl;
+ const gchar *service_name;
+ gboolean success = FALSE;
+
+ provider = camel_service_get_provider (service);
+ service_name = provider->protocol;
+
+ /* XXX Would be nice if camel_sasl_try_empty_password_sync()
+ * returned CamelAuthenticationResult so it's easier to
+ * detect errors. */
+ sasl = camel_sasl_new (service_name, mechanism, service);
+ if (sasl != NULL) {
+ success = camel_sasl_try_empty_password_sync (
+ sasl, cancellable, &local_error);
+ g_object_unref (sasl);
+ }
+
+ if (success)
+ return TRUE;
+ }
+
+ /* Abort authentication if we got cancelled.
+ * Otherwise clear any errors and press on. */
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ return FALSE;
+
+ g_clear_error (&local_error);
+
+ password_flags = CAMEL_SESSION_PASSWORD_SECRET;
+
+retry:
+ password = camel_service_get_password (service);
+
+ if (password == NULL) {
+ gchar *prompt;
+ gchar *new_passwd;
+
+ prompt = camel_session_build_password_prompt (
+ provider->name, url->user, url->host);
+
+ new_passwd = camel_session_get_password (
+ session, service, prompt, "password",
+ password_flags, &local_error);
+ camel_service_set_password (service, new_passwd);
+ password = camel_service_get_password (service);
+ g_free (new_passwd);
+
+ g_free (prompt);
+
+ if (local_error != NULL) {
+ g_propagate_error (error, local_error);
+ return FALSE;
+ }
+
+ if (password == NULL) {
+ g_set_error (
+ error, CAMEL_SERVICE_ERROR,
+ CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
+ _("No password was provided"));
+ return FALSE;
+ }
+ }
+
+ result = camel_service_authenticate_sync (
+ service, mechanism, cancellable, error);
+
+ if (result == CAMEL_AUTHENTICATION_REJECTED) {
+ password_flags |= CAMEL_SESSION_PASSWORD_REPROMPT;
+ camel_service_set_password (service, NULL);
+ goto retry;
+ }
+
+ return (result == CAMEL_AUTHENTICATION_ACCEPTED);
+}
+
static void
e_mail_session_class_init (EMailSessionClass *class)
{
@@ -1121,6 +1249,7 @@ e_mail_session_class_init (EMailSessionClass *class)
session_class->lookup_addressbook = mail_session_lookup_addressbook;
session_class->forward_to = mail_session_forward_to;
session_class->get_socks_proxy = mail_session_get_socks_proxy;
+ session_class->authenticate_sync = mail_session_authenticate_sync;
g_object_class_install_property (
object_class,