Rename camel_service_get_settings().
[platform/upstream/evolution-data-server.git] / camel / camel-sasl-gssapi.c
index 45e934b..75745e2 100644 (file)
@@ -40,6 +40,7 @@
 #include <glib/gi18n-lib.h>
 
 #include "camel-net-utils.h"
+#include "camel-network-settings.h"
 #include "camel-sasl-gssapi.h"
 #include "camel-session.h"
 
@@ -74,6 +75,10 @@ extern gss_OID gss_nt_service_name;
 #endif /* HAVE_SUN_KRB5 */
 #endif /* HAVE_HEIMDAL_KRB5 */
 
+#define CAMEL_SASL_GSSAPI_GET_PRIVATE(obj) \
+       (G_TYPE_INSTANCE_GET_PRIVATE \
+       ((obj), CAMEL_TYPE_SASL_GSSAPI, CamelSaslGssapiPrivate))
+
 #ifndef GSS_C_OID_KRBV5_DES
 #define GSS_C_OID_KRBV5_DES GSS_C_NO_OID
 #endif
@@ -196,7 +201,7 @@ sasl_gssapi_finalize (GObject *object)
 /* DBUS Specific code */
 
 static gboolean
-send_dbus_message (gchar *name)
+send_dbus_message (const gchar *name)
 {
        gint success = FALSE;
        GError *error = NULL;
@@ -228,7 +233,15 @@ send_dbus_message (gchar *name)
        /* Sends the message: Have a 300 sec wait timeout  */
        reply = g_dbus_connection_send_message_with_reply_sync (connection, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, 300 * 1000, NULL, NULL, &error);
 
+       if (!error && reply) {
+               if (g_dbus_message_to_gerror (reply, &error)) {
+                       g_object_unref (reply);
+                       reply = NULL;
+               }
+       }
+
        if (error) {
+               g_dbus_error_strip_remote_error (error);
                g_warning ("%s: %s\n", G_STRFUNC, error->message);
                g_error_free (error);
        }
@@ -236,7 +249,8 @@ send_dbus_message (gchar *name)
        if (reply) {
                GVariant *body = g_dbus_message_get_body (reply);
 
-               success = body && g_variant_get_boolean (body);
+               if (body)
+                       g_variant_get (body, "(b)", &success);
 
                g_object_unref (reply);
        }
@@ -257,8 +271,9 @@ sasl_gssapi_challenge_sync (CamelSasl *sasl,
                             GError **error)
 {
        CamelSaslGssapiPrivate *priv;
+       CamelNetworkSettings *network_settings;
+       CamelSettings *settings;
        CamelService *service;
-       CamelURL *url;
        OM_uint32 major, minor, flags, time;
        gss_buffer_desc inbuf, outbuf;
        GByteArray *challenge = NULL;
@@ -269,23 +284,36 @@ sasl_gssapi_challenge_sync (CamelSasl *sasl,
        gchar *str;
        struct addrinfo *ai, hints;
        const gchar *service_name;
+       gchar *host;
+       gchar *user;
 
-       priv = CAMEL_SASL_GSSAPI (sasl)->priv;
+       priv = CAMEL_SASL_GSSAPI_GET_PRIVATE (sasl);
 
        service = camel_sasl_get_service (sasl);
        service_name = camel_sasl_get_service_name (sasl);
 
-       url = camel_service_get_camel_url (service);
+       settings = camel_service_ref_settings (service);
+       g_return_val_if_fail (CAMEL_IS_NETWORK_SETTINGS (settings), NULL);
+
+       network_settings = CAMEL_NETWORK_SETTINGS (settings);
+       host = camel_network_settings_dup_host (network_settings);
+       user = camel_network_settings_dup_user (network_settings);
+
+       g_object_unref (settings);
+
+       g_return_val_if_fail (user != NULL, NULL);
+
+       if (host == NULL)
+               host = g_strdup ("localhost");
 
        switch (priv->state) {
        case GSSAPI_STATE_INIT:
                memset (&hints, 0, sizeof (hints));
                hints.ai_flags = AI_CANONNAME;
                ai = camel_getaddrinfo (
-                       url->host ? url->host : "localhost",
-                       NULL, &hints, cancellable, error);
+                       host, NULL, &hints, cancellable, error);
                if (ai == NULL)
-                       return NULL;
+                       goto exit;
 
                str = g_strdup_printf("%s@%s", service_name, ai->ai_canonname);
                camel_freeaddrinfo (ai);
@@ -297,7 +325,7 @@ sasl_gssapi_challenge_sync (CamelSasl *sasl,
 
                if (major != GSS_S_COMPLETE) {
                        gssapi_set_exception (major, minor, error);
-                       return NULL;
+                       goto exit;
                }
 
                input_token = GSS_C_NO_BUFFER;
@@ -310,7 +338,7 @@ sasl_gssapi_challenge_sync (CamelSasl *sasl,
                                error, CAMEL_SERVICE_ERROR,
                                CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
                                _("Bad authentication response from server."));
-                       return NULL;
+                       goto exit;
                }
 
                inbuf.value = token->data;
@@ -335,11 +363,11 @@ sasl_gssapi_challenge_sync (CamelSasl *sasl,
                        if (major == (OM_uint32) GSS_S_FAILURE &&
                            (minor == (OM_uint32) KRB5KRB_AP_ERR_TKT_EXPIRED ||
                             minor == (OM_uint32) KRB5KDC_ERR_NEVER_VALID) &&
-                           send_dbus_message (url->user))
+                           send_dbus_message (user))
                                        goto challenge;
 
                        gssapi_set_exception (major, minor, error);
-                       return NULL;
+                       goto exit;
                }
 
                challenge = g_byte_array_new ();
@@ -354,7 +382,7 @@ sasl_gssapi_challenge_sync (CamelSasl *sasl,
                                error, CAMEL_SERVICE_ERROR,
                                CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
                                _("Bad authentication response from server."));
-                       return NULL;
+                       goto exit;
                }
 
                inbuf.value = token->data;
@@ -363,7 +391,7 @@ sasl_gssapi_challenge_sync (CamelSasl *sasl,
                major = gss_unwrap (&minor, priv->ctx, &inbuf, &outbuf, &conf_state, &qop);
                if (major != GSS_S_COMPLETE) {
                        gssapi_set_exception (major, minor, error);
-                       return NULL;
+                       goto exit;
                }
 
                if (outbuf.length < 4) {
@@ -374,7 +402,7 @@ sasl_gssapi_challenge_sync (CamelSasl *sasl,
 #ifndef HAVE_HEIMDAL_KRB5
                        gss_release_buffer (&minor, &outbuf);
 #endif
-                       return NULL;
+                       goto exit;
                }
 
                /* check that our desired security layer is supported */
@@ -386,14 +414,14 @@ sasl_gssapi_challenge_sync (CamelSasl *sasl,
 #ifndef HAVE_HEIMDAL_KRB5
                        gss_release_buffer (&minor, &outbuf);
 #endif
-                       return NULL;
+                       goto exit;
                }
 
-               inbuf.length = 4 + strlen (url->user);
+               inbuf.length = 4 + strlen (user);
                inbuf.value = str = g_malloc (inbuf.length);
                memcpy (inbuf.value, outbuf.value, 4);
                str[0] = DESIRED_SECURITY_LAYER;
-               memcpy (str + 4, url->user, inbuf.length - 4);
+               memcpy (str + 4, user, inbuf.length - 4);
 
 #ifndef HAVE_HEIMDAL_KRB5
                gss_release_buffer (&minor, &outbuf);
@@ -403,7 +431,7 @@ sasl_gssapi_challenge_sync (CamelSasl *sasl,
                if (major != GSS_S_COMPLETE) {
                        gssapi_set_exception (major, minor, error);
                        g_free (str);
-                       return NULL;
+                       goto exit;
                }
 
                g_free (str);
@@ -419,9 +447,13 @@ sasl_gssapi_challenge_sync (CamelSasl *sasl,
                camel_sasl_set_authenticated (sasl, TRUE);
                break;
        default:
-               return NULL;
+               break;
        }
 
+exit:
+       g_free (host);
+       g_free (user);
+
        return challenge;
 }
 
@@ -449,8 +481,7 @@ static void
 camel_sasl_gssapi_init (CamelSaslGssapi *sasl)
 {
 #ifdef HAVE_KRB5
-       sasl->priv = G_TYPE_INSTANCE_GET_PRIVATE (
-               sasl, CAMEL_TYPE_SASL_GSSAPI, CamelSaslGssapiPrivate);
+       sasl->priv = CAMEL_SASL_GSSAPI_GET_PRIVATE (sasl);
        sasl->priv->state = GSSAPI_STATE_INIT;
        sasl->priv->ctx = GSS_C_NO_CONTEXT;
        sasl->priv->target = GSS_C_NO_NAME;