diff options
Diffstat (limited to 'camel/camel-sasl-gssapi.c')
-rw-r--r-- | camel/camel-sasl-gssapi.c | 340 |
1 files changed, 0 insertions, 340 deletions
diff --git a/camel/camel-sasl-gssapi.c b/camel/camel-sasl-gssapi.c deleted file mode 100644 index 4f15c43821..0000000000 --- a/camel/camel-sasl-gssapi.c +++ /dev/null @@ -1,340 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Authors: Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright 2003 Ximian, Inc. (www.ximian.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - * - */ - - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef HAVE_KRB5 - -#include <string.h> -#include <com_err.h> -#ifdef HAVE_MIT_KRB5 -#include <gssapi/gssapi.h> -#include <gssapi/gssapi_generic.h> -#else /* HAVE_HEIMDAL_KRB5 */ -#include <gssapi.h> -#define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE -#endif -#include <errno.h> - -#ifndef GSS_C_OID_KRBV5_DES -#define GSS_C_OID_KRBV5_DES GSS_C_NO_OID -#endif - -#include "camel-sasl-gssapi.h" - -CamelServiceAuthType camel_sasl_gssapi_authtype = { - N_("GSSAPI"), - - N_("This option will connect to the server using " - "Kerberos 5 authentication."), - - "GSSAPI", - FALSE -}; - -enum { - GSSAPI_STATE_INIT, - GSSAPI_STATE_CONTINUE_NEEDED, - GSSAPI_STATE_COMPLETE, - GSSAPI_STATE_AUTHENTICATED -}; - -#define GSSAPI_SECURITY_LAYER_NONE (1 << 0) -#define GSSAPI_SECURITY_LAYER_INTEGRITY (1 << 1) -#define GSSAPI_SECURITY_LAYER_PRIVACY (1 << 2) - -#define DESIRED_SECURITY_LAYER GSSAPI_SECURITY_LAYER_NONE - -struct _CamelSaslGssapiPrivate { - int state; - gss_ctx_id_t ctx; - gss_name_t target; -}; - - -static GByteArray *gssapi_challenge (CamelSasl *sasl, GByteArray *token, CamelException *ex); - - -static CamelSaslClass *parent_class = NULL; - - -static void -camel_sasl_gssapi_class_init (CamelSaslGssapiClass *klass) -{ - CamelSaslClass *camel_sasl_class = CAMEL_SASL_CLASS (klass); - - parent_class = CAMEL_SASL_CLASS (camel_type_get_global_classfuncs (camel_sasl_get_type ())); - - /* virtual method overload */ - camel_sasl_class->challenge = gssapi_challenge; -} - -static void -camel_sasl_gssapi_init (gpointer object, gpointer klass) -{ - CamelSaslGssapi *gssapi = CAMEL_SASL_GSSAPI (object); - - gssapi->priv = g_new (struct _CamelSaslGssapiPrivate, 1); - gssapi->priv->state = GSSAPI_STATE_INIT; - gssapi->priv->ctx = GSS_C_NO_CONTEXT; - gssapi->priv->target = GSS_C_NO_NAME; -} - -static void -camel_sasl_gssapi_finalize (CamelObject *object) -{ - CamelSaslGssapi *gssapi = CAMEL_SASL_GSSAPI (object); - guint32 status; - - if (gssapi->priv->ctx != GSS_C_NO_CONTEXT) - gss_delete_sec_context (&status, &gssapi->priv->ctx, GSS_C_NO_BUFFER); - - if (gssapi->priv->target != GSS_C_NO_NAME) - gss_release_name (&status, &gssapi->priv->target); - - g_free (gssapi->priv); -} - - -CamelType -camel_sasl_gssapi_get_type (void) -{ - static CamelType type = CAMEL_INVALID_TYPE; - - if (type == CAMEL_INVALID_TYPE) { - type = camel_type_register ( - camel_sasl_get_type (), - "CamelSaslGssapi", - sizeof (CamelSaslGssapi), - sizeof (CamelSaslGssapiClass), - (CamelObjectClassInitFunc) camel_sasl_gssapi_class_init, - NULL, - (CamelObjectInitFunc) camel_sasl_gssapi_init, - (CamelObjectFinalizeFunc) camel_sasl_gssapi_finalize); - } - - return type; -} - -static void -gssapi_set_exception (OM_uint32 major, OM_uint32 minor, CamelException *ex) -{ - const char *str; - - switch (major) { - case GSS_S_BAD_MECH: - str = _("The specified mechanism is not supported by the " - "provided credential, or is unrecognized by the " - "implementation."); - break; - case GSS_S_BAD_NAME: - str = _("The provided target_name parameter was ill-formed."); - break; - case GSS_S_BAD_NAMETYPE: - str = _("The provided target_name parameter contained an " - "invalid or unsupported type of name."); - break; - case GSS_S_BAD_BINDINGS: - str = _("The input_token contains different channel " - "bindings to those specified via the " - "input_chan_bindings parameter."); - break; - case GSS_S_BAD_SIG: - str = _("The input_token contains an invalid signature, or a " - "signature that could not be verified."); - break; - case GSS_S_NO_CRED: - str = _("The supplied credentials were not valid for context " - "initiation, or the credential handle did not " - "reference any credentials."); - break; - case GSS_S_NO_CONTEXT: - str = _("The supplied context handle did not refer to a valid context."); - break; - case GSS_S_DEFECTIVE_TOKEN: - str = _("The consistency checks performed on the input_token failed."); - break; - case GSS_S_DEFECTIVE_CREDENTIAL: - str = _("The consistency checks performed on the credential failed."); - break; - case GSS_S_CREDENTIALS_EXPIRED: - str = _("The referenced credentials have expired."); - break; - case GSS_S_FAILURE: - str = error_message (minor); - break; - default: - str = _("Bad authentication response from server."); - } - - camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, str); -} - -static GByteArray * -gssapi_challenge (CamelSasl *sasl, GByteArray *token, CamelException *ex) -{ - struct _CamelSaslGssapiPrivate *priv = CAMEL_SASL_GSSAPI (sasl)->priv; - OM_uint32 major, minor, flags, time; - gss_buffer_desc inbuf, outbuf; - GByteArray *challenge = NULL; - gss_buffer_t input_token; - struct hostent *h; - int conf_state; - gss_qop_t qop; - gss_OID mech; - char *str; - - switch (priv->state) { - case GSSAPI_STATE_INIT: - if (!(h = camel_service_gethost (sasl->service, ex))) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Failed to resolve host `%s': %s"), - sasl->service->url->host, g_strerror (errno)); - return NULL; - } - - str = g_strdup_printf ("%s@%s", sasl->service_name, h->h_name); - camel_free_host (h); - - inbuf.value = str; - inbuf.length = strlen (str); - major = gss_import_name (&minor, &inbuf, gss_nt_service_name, &priv->target); - g_free (str); - - if (major != GSS_S_COMPLETE) { - gssapi_set_exception (major, minor, ex); - return NULL; - } - - input_token = GSS_C_NO_BUFFER; - - goto challenge; - break; - case GSSAPI_STATE_CONTINUE_NEEDED: - if (token == NULL) { - camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, - _("Bad authentication response from server.")); - return NULL; - } - - inbuf.value = token->data; - inbuf.length = token->len; - input_token = &inbuf; - - challenge: - major = gss_init_sec_context (&minor, GSS_C_NO_CREDENTIAL, &priv->ctx, priv->target, - GSS_C_OID_KRBV5_DES, GSS_C_MUTUAL_FLAG | - GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG, - 0, GSS_C_NO_CHANNEL_BINDINGS, - input_token, &mech, &outbuf, &flags, &time); - - switch (major) { - case GSS_S_COMPLETE: - priv->state = GSSAPI_STATE_COMPLETE; - break; - case GSS_S_CONTINUE_NEEDED: - priv->state = GSSAPI_STATE_CONTINUE_NEEDED; - break; - default: - gssapi_set_exception (major, minor, ex); - return NULL; - } - - challenge = g_byte_array_new (); - g_byte_array_append (challenge, outbuf.value, outbuf.length); -#ifndef HAVE_HEIMDAL_KRB5 - gss_release_buffer (&minor, &outbuf); -#endif - break; - case GSSAPI_STATE_COMPLETE: - if (token == NULL) { - camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, - _("Bad authentication response from server.")); - return NULL; - } - - inbuf.value = token->data; - inbuf.length = token->len; - - major = gss_unwrap (&minor, priv->ctx, &inbuf, &outbuf, &conf_state, &qop); - if (major != GSS_S_COMPLETE) { - gssapi_set_exception (major, minor, ex); - return NULL; - } - - if (outbuf.length < 4) { - camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, - _("Bad authentication response from server.")); -#ifndef HAVE_HEIMDAL_KRB5 - gss_release_buffer (&minor, &outbuf); -#endif - return NULL; - } - - /* check that our desired security layer is supported */ - if ((((unsigned char *) outbuf.value)[0] & DESIRED_SECURITY_LAYER) != DESIRED_SECURITY_LAYER) { - camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, - _("Unsupported security layer.")); - gss_release_buffer (&minor, &outbuf); - return NULL; - } - - inbuf.length = 4 + strlen (sasl->service->url->user); - inbuf.value = str = g_malloc (inbuf.length); - memcpy (inbuf.value, outbuf.value, 4); - str[0] = DESIRED_SECURITY_LAYER; - memcpy (str + 4, sasl->service->url->user, inbuf.length - 4); - -#ifndef HAVE_HEIMDAL_KRB5 - gss_release_buffer (&minor, &outbuf); -#endif - - major = gss_wrap (&minor, priv->ctx, FALSE, qop, &inbuf, &conf_state, &outbuf); - if (major != GSS_S_COMPLETE) { - gssapi_set_exception (major, minor, ex); - g_free (str); - return NULL; - } - - g_free (str); - challenge = g_byte_array_new (); - g_byte_array_append (challenge, outbuf.value, outbuf.length); - -#ifndef HAVE_HEIMDAL_KRB5 - gss_release_buffer (&minor, &outbuf); -#endif - - priv->state = GSSAPI_STATE_AUTHENTICATED; - - sasl->authenticated = TRUE; - break; - default: - return NULL; - } - - return challenge; -} - -#endif /* HAVE_KRB5 */ |