#include <glib/gi18n-lib.h>
#include "camel-net-utils.h"
+#include "camel-network-settings.h"
#include "camel-sasl-gssapi.h"
#include "camel-session.h"
#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
/* DBUS Specific code */
static gboolean
-send_dbus_message (gchar *name)
+send_dbus_message (const gchar *name)
{
gint success = FALSE;
GError *error = NULL;
/* 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);
}
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);
}
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;
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);
if (major != GSS_S_COMPLETE) {
gssapi_set_exception (major, minor, error);
- return NULL;
+ goto exit;
}
input_token = GSS_C_NO_BUFFER;
error, CAMEL_SERVICE_ERROR,
CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
_("Bad authentication response from server."));
- return NULL;
+ goto exit;
}
inbuf.value = token->data;
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 ();
error, CAMEL_SERVICE_ERROR,
CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
_("Bad authentication response from server."));
- return NULL;
+ goto exit;
}
inbuf.value = token->data;
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) {
#ifndef HAVE_HEIMDAL_KRB5
gss_release_buffer (&minor, &outbuf);
#endif
- return NULL;
+ goto exit;
}
/* check that our desired security layer is supported */
#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);
if (major != GSS_S_COMPLETE) {
gssapi_set_exception (major, minor, error);
g_free (str);
- return NULL;
+ goto exit;
}
g_free (str);
camel_sasl_set_authenticated (sasl, TRUE);
break;
default:
- return NULL;
+ break;
}
+exit:
+ g_free (host);
+ g_free (user);
+
return challenge;
}
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;