From cce3726fe9c2efb67dd9e63472a6360d058553b8 Mon Sep 17 00:00:00 2001 From: Jeffrey Stedfast Date: Thu, 20 Mar 2003 19:37:38 +0000 Subject: Plug in GSSAPI support. 2003-03-20 Jeffrey Stedfast * camel-sasl.c: Plug in GSSAPI support. * camel-sasl-gssapi.[c,h]: Various fixes to make it compile (fixed type-o's mostly). svn path=/trunk/; revision=20438 --- camel/ChangeLog | 7 +++++ camel/Makefile.am | 2 ++ camel/camel-sasl-gssapi.c | 74 ++++++++++++++++++++++++++++++----------------- camel/camel-sasl-gssapi.h | 2 +- camel/camel-sasl.c | 12 ++++++++ 5 files changed, 69 insertions(+), 28 deletions(-) (limited to 'camel') diff --git a/camel/ChangeLog b/camel/ChangeLog index 6eb8942efe..f2623643da 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,10 @@ +2003-03-20 Jeffrey Stedfast + + * camel-sasl.c: Plug in GSSAPI support. + + * camel-sasl-gssapi.[c,h]: Various fixes to make it compile (fixed + type-o's mostly). + 2003-03-20 Dan Winship Handle raw 8-bit From data "correctly". (The same way we handle diff --git a/camel/Makefile.am b/camel/Makefile.am index c78c9046f4..7055630273 100644 --- a/camel/Makefile.am +++ b/camel/Makefile.am @@ -85,6 +85,7 @@ libcamel_la_SOURCES = \ camel-sasl-anonymous.c \ camel-sasl-cram-md5.c \ camel-sasl-digest-md5.c \ + camel-sasl-gssapi.c \ camel-sasl-kerberos4.c \ camel-sasl-login.c \ camel-sasl-ntlm.c \ @@ -186,6 +187,7 @@ libcamelinclude_HEADERS = \ camel-sasl-anonymous.h \ camel-sasl-cram-md5.h \ camel-sasl-digest-md5.h \ + camel-sasl-gssapi.h \ camel-sasl-kerberos4.h \ camel-sasl-login.h \ camel-sasl-ntlm.h \ diff --git a/camel/camel-sasl-gssapi.c b/camel/camel-sasl-gssapi.c index a32c24fbc7..d9a3f56f9f 100644 --- a/camel/camel-sasl-gssapi.c +++ b/camel/camel-sasl-gssapi.c @@ -28,11 +28,18 @@ #ifdef HAVE_KRB5 #include +#include #ifdef HAVE_MIT_KRB5 #include +#include #else /* HAVE_HEIMDAL_KRB5 */ #include #endif +#include + +#ifndef GSS_C_OID_KRBV5_DES +#define GSS_C_OID_KRBV5_DES GSS_C_NO_OID +#endif #include "camel-sasl-gssapi.h" @@ -46,8 +53,6 @@ CamelServiceAuthType camel_sasl_gssapi_authtype = { FALSE }; -static CamelSaslClass *parent_class = NULL; - enum { GSSAPI_STATE_INIT, GSSAPI_STATE_CONTINUE_NEEDED, @@ -67,6 +72,13 @@ struct _CamelSaslGssapiPrivate { 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) { @@ -92,14 +104,16 @@ camel_sasl_gssapi_init (gpointer object, gpointer klass) static void camel_sasl_gssapi_finalize (CamelObject *object) { - CamelSaslGssapi *sasl = CAMEL_SASL_GSSAPI (object); + CamelSaslGssapi *gssapi = CAMEL_SASL_GSSAPI (object); guint32 status; - if (sasl->priv) { - gss_delete_sec_context (&status, sasl->priv->ctx); - gss_release_name (&status, sasl->priv->target); - g_free (sasl->priv); - } + 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); } @@ -131,37 +145,35 @@ gssapi_set_exception (OM_uint32 major, OM_uint32 minor, CamelException *ex) switch (major) { case GSS_S_BAD_MECH: str = _("The specified mechanism is not supported by the " - "provided credential, or is unrecognized by the " - "implementation."); + "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."); + "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."); + "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."); + "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."); + "initiation, or the credential handle did not " + "reference any credentials."); break; case GSS_S_NO_CONTEXT: - str = _("Indicates that the supplied context handle did not " - "refer to a valid context."); + str = _("The supplied context handle did not refer to a valid context."); break; case GSS_S_DEFECTIVE_TOKEN: - str = _("Indicates that consistency checks performed on " - "the input_token failed."); + 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."); @@ -170,8 +182,7 @@ gssapi_set_exception (OM_uint32 major, OM_uint32 minor, CamelException *ex) str = _("The referenced credentials have expired."); break; case GSS_S_FAILURE: - switch (minor) { - } + str = error_message (minor); break; default: str = _("Bad authentication response from server."); @@ -196,10 +207,15 @@ gssapi_challenge (CamelSasl *sasl, GByteArray *token, CamelException *ex) switch (priv->state) { case GSSAPI_STATE_INIT: - if (!(h = camel_service_gethost (sasl->service, ex))) - goto lose; + 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); + printf ("FQDN: %s (%s)\n", h->h_name, str); camel_free_host (h); inbuf.value = str; @@ -229,7 +245,7 @@ gssapi_challenge (CamelSasl *sasl, GByteArray *token, CamelException *ex) challenge: major = gss_init_sec_context (&minor, GSS_C_NO_CREDENTIAL, &priv->ctx, priv->target, - GSS_C_OID_KRBV5_DES, GSS_C_DELEG_FLAG | GSS_C_MUTAUAL_FLAG | + 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); @@ -243,11 +259,12 @@ gssapi_challenge (CamelSasl *sasl, GByteArray *token, CamelException *ex) break; default: gssapi_set_exception (major, minor, ex); + printf ("gss_init_sec_context() exception\n"); gss_release_buffer (&minor, &outbuf); return NULL; } - challenge = g_byte_array_new () + challenge = g_byte_array_new (); g_byte_array_append (challenge, outbuf.value, outbuf.length); gss_release_buffer (&minor, &outbuf); break; @@ -264,6 +281,7 @@ gssapi_challenge (CamelSasl *sasl, GByteArray *token, CamelException *ex) major = gss_unwrap (&minor, priv->ctx, &inbuf, &outbuf, &conf_state, &qop); if (major != GSS_S_COMPLETE) { gssapi_set_exception (major, minor, ex); + printf ("gss_unwrap() exception\n"); gss_release_buffer (&minor, &outbuf); return NULL; } @@ -276,7 +294,7 @@ gssapi_challenge (CamelSasl *sasl, GByteArray *token, CamelException *ex) } /* check that our desired security layer is supported */ - if (((unsigned char *) outbuf->value)[0] & DESIRED_SECURITY_LAYER) { + 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); @@ -293,6 +311,7 @@ gssapi_challenge (CamelSasl *sasl, GByteArray *token, CamelException *ex) major = gss_wrap (&minor, priv->ctx, FALSE, qop, &inbuf, &conf_state, &outbuf); if (major != 0) { gssapi_set_exception (major, minor, ex); + printf ("gss_wrap() exception\n"); gss_release_buffer (&minor, &outbuf); g_free (str); return NULL; @@ -307,6 +326,7 @@ gssapi_challenge (CamelSasl *sasl, GByteArray *token, CamelException *ex) sasl->authenticated = TRUE; break; default: + printf ("unknown state exception\n"); return NULL; } diff --git a/camel/camel-sasl-gssapi.h b/camel/camel-sasl-gssapi.h index 18d17aa978..b4a3fbc1a5 100644 --- a/camel/camel-sasl-gssapi.h +++ b/camel/camel-sasl-gssapi.h @@ -50,7 +50,7 @@ struct _CamelSaslGssapi { struct _CamelSaslGssapiClass { CamelSaslClass parent_class; -} +}; /* Standard Camel function */ CamelType camel_sasl_gssapi_get_type (void); diff --git a/camel/camel-sasl.c b/camel/camel-sasl.c index 6cc8a144e5..ec070215c9 100644 --- a/camel/camel-sasl.c +++ b/camel/camel-sasl.c @@ -31,6 +31,7 @@ #include "camel-sasl-cram-md5.h" #include "camel-sasl-digest-md5.h" +#include "camel-sasl-gssapi.h" #include "camel-sasl-kerberos4.h" #include "camel-sasl-login.h" #include "camel-sasl-plain.h" @@ -193,6 +194,10 @@ camel_sasl_new (const char *service_name, const char *mechanism, CamelService *s sasl = (CamelSasl *)camel_object_new (CAMEL_SASL_CRAM_MD5_TYPE); else if (!strcmp (mechanism, "DIGEST-MD5")) sasl = (CamelSasl *)camel_object_new (CAMEL_SASL_DIGEST_MD5_TYPE); +#ifdef HAVE_KRB5 + else if (!strcmp (mechanism, "GSSAPI")) + sasl = (CamelSasl *)camel_object_new (CAMEL_SASL_GSSAPI_TYPE); +#endif #ifdef HAVE_KRB4 else if (!strcmp (mechanism, "KERBEROS_V4")) sasl = (CamelSasl *)camel_object_new (CAMEL_SASL_KERBEROS4_TYPE); @@ -230,6 +235,9 @@ camel_sasl_authtype_list (gboolean include_plain) types = g_list_prepend (types, &camel_sasl_cram_md5_authtype); types = g_list_prepend (types, &camel_sasl_digest_md5_authtype); +#ifdef HAVE_KRB5 + types = g_list_prepend (types, &camel_sasl_gssapi_authtype); +#endif #ifdef HAVE_KRB4 types = g_list_prepend (types, &camel_sasl_kerberos4_authtype); #endif @@ -254,6 +262,10 @@ camel_sasl_authtype (const char *mechanism) return &camel_sasl_cram_md5_authtype; else if (!strcmp (mechanism, "DIGEST-MD5")) return &camel_sasl_digest_md5_authtype; +#ifdef HAVE_KRB5 + else if (!strcmp (mechanism, "GSSAPI")) + return &camel_sasl_gssapi_authtype; +#endif #ifdef HAVE_KRB4 else if (!strcmp (mechanism, "KERBEROS_V4")) return &camel_sasl_kerberos4_authtype; -- cgit v1.2.3