From: Luke Howard Date: Thu, 23 Sep 2010 18:10:36 +0000 (+0200) Subject: make reauth support conditionaly compilable X-Git-Tag: vm/20110310~233^2~3 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=mech_eap.git;a=commitdiff_plain;h=aa3e3279477f71dbe2efb212cedea1c0929f25e8 make reauth support conditionaly compilable --- diff --git a/Makefile.am b/Makefile.am index b59b57c..9f2167a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -72,7 +72,6 @@ mech_eap_la_SOURCES = \ util_oid.c \ util_ordering.c \ util_radius.cpp \ - util_reauth.c \ util_saml.cpp \ util_shib.cpp \ util_token.c \ @@ -82,6 +81,9 @@ mech_eap_la_SOURCES = \ wrap_iov_length.c \ wrap_size_limit.c +if GSSEAP_ENABLE_REAUTH +mech_eap_la_SOURCES += util_reauth.c + krb5pluginsdir = $(libdir)/krb5/plugins/authdata krb5plugins_LTLIBRARIES = radius_ad.la @@ -91,3 +93,4 @@ radius_ad_la_LDFLAGS = -avoid-version -module \ -export-symbols radius_ad.exports -no-undefined radius_ad_la_LIBADD = @KRB5_LIBS@ radius_ad_la_SOURCES = util_adshim.c +endif diff --git a/accept_sec_context.c b/accept_sec_context.c index a65d7a9..2258d24 100644 --- a/accept_sec_context.c +++ b/accept_sec_context.c @@ -32,6 +32,16 @@ #include "gssapiP_eap.h" +#ifdef GSSEAP_ENABLE_REAUTH +static OM_uint32 +eapGssSmAcceptGssReauth(OM_uint32 *minor, + gss_ctx_id_t ctx, + gss_cred_id_t cred, + gss_buffer_t inputToken, + gss_channel_bindings_t chanBindings, + gss_buffer_t outputToken); +#endif + /* * Mark a context as ready for cryptographic operations */ @@ -406,11 +416,13 @@ eapGssSmAcceptExtensionsResp(OM_uint32 *minor, OM_uint32 major, tmpMinor; gss_buffer_desc credsToken = GSS_C_EMPTY_BUFFER; +#ifdef GSSEAP_ENABLE_REAUTH major = gssEapMakeReauthCreds(minor, ctx, cred, &credsToken); if (GSS_ERROR(major)) return major; - - ctx->state = EAP_STATE_ESTABLISHED; +#else + credsToken.value = ""; +#endif /* GSSEAP_ENABLE_REAUTH */ major = duplicateBuffer(minor, &credsToken, outputToken); if (GSS_ERROR(major)) { @@ -418,7 +430,11 @@ eapGssSmAcceptExtensionsResp(OM_uint32 *minor, return major; } +#ifdef GSSEAP_ENABLE_REAUTH gss_release_buffer(&tmpMinor, &credsToken); +#endif + + ctx->state = EAP_STATE_ESTABLISHED; return GSS_S_COMPLETE; } @@ -436,77 +452,6 @@ eapGssSmAcceptEstablished(OM_uint32 *minor, return GSS_S_BAD_STATUS; } -static OM_uint32 -acceptReadyKrb(OM_uint32 *minor, - gss_ctx_id_t ctx, - gss_cred_id_t cred, - const gss_name_t initiator, - const gss_OID mech, - OM_uint32 timeRec) -{ - OM_uint32 major; - - major = gssEapGlueToMechName(minor, initiator, &ctx->initiatorName); - if (GSS_ERROR(major)) - return major; - - if (cred != GSS_C_NO_CREDENTIAL && cred->name != GSS_C_NO_NAME) { - major = gssEapDuplicateName(minor, cred->name, &ctx->acceptorName); - if (GSS_ERROR(major)) - return major; - } - - major = gssEapReauthComplete(minor, ctx, cred, mech, timeRec); - if (GSS_ERROR(major)) - return major; - - ctx->state = EAP_STATE_ESTABLISHED; - - return GSS_S_COMPLETE; -} - -static OM_uint32 -eapGssSmAcceptGssReauth(OM_uint32 *minor, - gss_ctx_id_t ctx, - gss_cred_id_t cred, - gss_buffer_t inputToken, - gss_channel_bindings_t chanBindings, - gss_buffer_t outputToken) -{ - OM_uint32 major, tmpMinor; - gss_cred_id_t krbCred = GSS_C_NO_CREDENTIAL; - gss_name_t krbInitiator = GSS_C_NO_NAME; - gss_OID mech = GSS_C_NO_OID; - OM_uint32 gssFlags, timeRec = GSS_C_INDEFINITE; - - ctx->flags |= CTX_FLAG_KRB_REAUTH_GSS; - - if (cred != GSS_C_NO_CREDENTIAL) - krbCred = cred->krbCred; - - major = gssAcceptSecContext(minor, - &ctx->kerberosCtx, - krbCred, - inputToken, - chanBindings, - &krbInitiator, - &mech, - outputToken, - &gssFlags, - &timeRec, - NULL); - if (major == GSS_S_COMPLETE) { - major = acceptReadyKrb(minor, ctx, cred, - krbInitiator, mech, timeRec); - } - - ctx->gssFlags = gssFlags; - - gssReleaseName(&tmpMinor, &krbInitiator); - - return major; -} - static struct gss_eap_acceptor_sm { enum gss_eap_token_type inputTokenType; enum gss_eap_token_type outputTokenType; @@ -522,7 +467,9 @@ static struct gss_eap_acceptor_sm { { TOK_TYPE_EXT_REQ, TOK_TYPE_NONE, eapGssSmAcceptExtensionsReq }, { TOK_TYPE_NONE, TOK_TYPE_EXT_RESP, eapGssSmAcceptExtensionsResp }, { TOK_TYPE_NONE, TOK_TYPE_NONE, eapGssSmAcceptEstablished }, +#ifdef GSSEAP_ENABLE_REAUTH { TOK_TYPE_GSS_REAUTH, TOK_TYPE_GSS_REAUTH, eapGssSmAcceptGssReauth }, +#endif }; OM_uint32 @@ -578,9 +525,12 @@ gss_accept_sec_context(OM_uint32 *minor, if (GSS_ERROR(major)) goto cleanup; +#ifdef GSSEAP_ENABLE_REAUTH if (tokType == TOK_TYPE_GSS_REAUTH && initialContextToken) { ctx->state = EAP_STATE_KRB_REAUTH_GSS; - } else if (tokType != sm->inputTokenType) { + } else +#endif + if (tokType != sm->inputTokenType) { major = GSS_S_DEFECTIVE_TOKEN; goto cleanup; } @@ -645,3 +595,76 @@ cleanup: return major; } + +#ifdef GSSEAP_ENABLE_REAUTH +static OM_uint32 +acceptReadyKrb(OM_uint32 *minor, + gss_ctx_id_t ctx, + gss_cred_id_t cred, + const gss_name_t initiator, + const gss_OID mech, + OM_uint32 timeRec) +{ + OM_uint32 major; + + major = gssEapGlueToMechName(minor, initiator, &ctx->initiatorName); + if (GSS_ERROR(major)) + return major; + + if (cred != GSS_C_NO_CREDENTIAL && cred->name != GSS_C_NO_NAME) { + major = gssEapDuplicateName(minor, cred->name, &ctx->acceptorName); + if (GSS_ERROR(major)) + return major; + } + + major = gssEapReauthComplete(minor, ctx, cred, mech, timeRec); + if (GSS_ERROR(major)) + return major; + + ctx->state = EAP_STATE_ESTABLISHED; + + return GSS_S_COMPLETE; +} + +static OM_uint32 +eapGssSmAcceptGssReauth(OM_uint32 *minor, + gss_ctx_id_t ctx, + gss_cred_id_t cred, + gss_buffer_t inputToken, + gss_channel_bindings_t chanBindings, + gss_buffer_t outputToken) +{ + OM_uint32 major, tmpMinor; + gss_cred_id_t krbCred = GSS_C_NO_CREDENTIAL; + gss_name_t krbInitiator = GSS_C_NO_NAME; + gss_OID mech = GSS_C_NO_OID; + OM_uint32 gssFlags, timeRec = GSS_C_INDEFINITE; + + ctx->flags |= CTX_FLAG_KRB_REAUTH_GSS; + + if (cred != GSS_C_NO_CREDENTIAL) + krbCred = cred->krbCred; + + major = gssAcceptSecContext(minor, + &ctx->kerberosCtx, + krbCred, + inputToken, + chanBindings, + &krbInitiator, + &mech, + outputToken, + &gssFlags, + &timeRec, + NULL); + if (major == GSS_S_COMPLETE) { + major = acceptReadyKrb(minor, ctx, cred, + krbInitiator, mech, timeRec); + } + + ctx->gssFlags = gssFlags; + + gssReleaseName(&tmpMinor, &krbInitiator); + + return major; +} +#endif /* GSSEAP_ENABLE_REAUTH */ diff --git a/configure.ac b/configure.ac index 9f95e44..43ca2ec 100644 --- a/configure.ac +++ b/configure.ac @@ -26,6 +26,23 @@ dnl TARGET_CFLAGS="-Wall -pedantic -pthread" dnl TARGET_LDFLAGS="" dnl esac +reauth=no +AC_ARG_ENABLE(reauth, + [ --enable-reauth whether to enable fast reauthentication protocol: yes/no; default no ], + [ if test "x$enableval" = "xyes" -o "x$enableval" = "xno" ; then + reauth=$enableval + else + echo "--enable-reauth argument must be yes or no" + exit -1 + fi + ]) + +if test "x$reauth" = "xyes" ; then + echo "Fast reauthentication protocol enabled" + TARGET_CFLAGS="$TARGET_CFLAGS -DGSSEAP_ENABLE_REAUTH" +fi +AM_CONDITIONAL(GSSEAP_ENABLE_REAUTH, test "$reauth" = "yes") + AC_SUBST(TARGET_CFLAGS) AC_SUBST(TARGET_LDFLAGS) AX_CHECK_KRB5 diff --git a/eap_mech.c b/eap_mech.c index 2f3081c..26ee5ec 100644 --- a/eap_mech.c +++ b/eap_mech.c @@ -285,8 +285,10 @@ gssEapInit(void) major = gssEapLocalAttrProviderInit(&minor); assert(major == GSS_S_COMPLETE); +#ifdef GSSEAP_ENABLE_REAUTH major = gssEapReauthInitialize(&minor); assert(major == GSS_S_COMPLETE); +#endif } static void diff --git a/gssapiP_eap.h b/gssapiP_eap.h index 846c3ed..b46c2bc 100644 --- a/gssapiP_eap.h +++ b/gssapiP_eap.h @@ -92,8 +92,10 @@ struct gss_cred_id_struct { gss_OID_set mechanisms; time_t expiryTime; char *radiusConfigFile; +#ifdef GSSEAP_ENABLE_REAUTH krb5_ccache krbCredCache; gss_cred_id_t krbCred; +#endif }; #define CTX_FLAG_INITIATOR 0x00000001 @@ -107,7 +109,9 @@ enum gss_eap_state { EAP_STATE_EXTENSIONS_REQ, EAP_STATE_EXTENSIONS_RESP, EAP_STATE_ESTABLISHED, +#ifdef GSSEAP_ENABLE_REAUTH EAP_STATE_KRB_REAUTH_GSS +#endif }; #define CTX_IS_ESTABLISHED(ctx) ((ctx)->state == EAP_STATE_ESTABLISHED) @@ -159,8 +163,10 @@ struct gss_ctx_id_struct { #define initiatorCtx ctxU.initiator struct gss_eap_acceptor_ctx acceptor; #define acceptorCtx ctxU.acceptor +#ifdef GSSEAP_ENABLE_REAUTH gss_ctx_id_t kerberos; #define kerberosCtx ctxU.kerberos +#endif } ctxU; }; diff --git a/init_sec_context.c b/init_sec_context.c index f1f260a..e3b4d63 100644 --- a/init_sec_context.c +++ b/init_sec_context.c @@ -32,6 +32,23 @@ #include "gssapiP_eap.h" +#ifdef GSSEAP_ENABLE_REAUTH +static int +canReauthP(gss_cred_id_t cred); + +static OM_uint32 +eapGssSmInitGssReauth(OM_uint32 *minor, + gss_cred_id_t cred, + gss_ctx_id_t ctx, + gss_name_t target, + gss_OID mech, + OM_uint32 reqFlags, + OM_uint32 timeReq, + gss_channel_bindings_t chanBindings, + gss_buffer_t inputToken, + gss_buffer_t outputToken); +#endif + static OM_uint32 policyVariableToFlag(enum eapol_bool_var variable) { @@ -526,11 +543,13 @@ eapGssSmInitExtensionsResp(OM_uint32 *minor, gss_buffer_t inputToken, gss_buffer_t outputToken) { +#ifdef GSSEAP_ENABLE_REAUTH OM_uint32 major; major = gssEapStoreReauthCreds(minor, ctx, cred, inputToken); if (GSS_ERROR(major)) return major; +#endif ctx->state = EAP_STATE_ESTABLISHED; @@ -554,79 +573,6 @@ eapGssSmInitEstablished(OM_uint32 *minor, return GSS_S_BAD_STATUS; } -static int -canReauthP(gss_cred_id_t cred) -{ - return (cred != GSS_C_NO_CREDENTIAL && - cred->krbCred != GSS_C_NO_CREDENTIAL && - cred->expiryTime > time(NULL)); -} - -static OM_uint32 -eapGssSmInitGssReauth(OM_uint32 *minor, - gss_cred_id_t cred, - gss_ctx_id_t ctx, - gss_name_t target, - gss_OID mech, - OM_uint32 reqFlags, - OM_uint32 timeReq, - gss_channel_bindings_t chanBindings, - gss_buffer_t inputToken, - gss_buffer_t outputToken) -{ - OM_uint32 major, tmpMinor; - gss_name_t mechTarget = GSS_C_NO_NAME; - gss_OID actualMech = GSS_C_NO_OID; - OM_uint32 gssFlags, timeRec; - - assert(cred != GSS_C_NO_CREDENTIAL); - - ctx->flags |= CTX_FLAG_KRB_REAUTH_GSS; - - if (inputToken->length == 0) { - major = initBegin(minor, cred, ctx, target, mech, - reqFlags, timeReq, chanBindings, - inputToken, outputToken); - if (GSS_ERROR(major)) - goto cleanup; - } - - major = gssEapMechToGlueName(minor, target, &mechTarget); - if (GSS_ERROR(major)) - goto cleanup; - - major = gssInitSecContext(minor, - cred->krbCred, - &ctx->kerberosCtx, - mechTarget, - (gss_OID)gss_mech_krb5, - reqFlags | GSS_C_DCE_STYLE, - timeReq, - chanBindings, - inputToken, - &actualMech, - outputToken, - &gssFlags, - &timeRec); - if (GSS_ERROR(major)) - goto cleanup; - - ctx->gssFlags = gssFlags; - - if (major == GSS_S_COMPLETE) { - major = gssEapReauthComplete(minor, ctx, cred, actualMech, timeRec); - if (GSS_ERROR(major)) - goto cleanup; - - ctx->state = EAP_STATE_ESTABLISHED; - } - -cleanup: - gssReleaseName(&tmpMinor, &mechTarget); - - return major; -} - static struct gss_eap_initiator_sm { enum gss_eap_token_type inputTokenType; enum gss_eap_token_type outputTokenType; @@ -646,7 +592,9 @@ static struct gss_eap_initiator_sm { { TOK_TYPE_NONE, TOK_TYPE_EXT_REQ, eapGssSmInitExtensionsReq }, { TOK_TYPE_EXT_RESP,TOK_TYPE_NONE, eapGssSmInitExtensionsResp }, { TOK_TYPE_NONE, TOK_TYPE_NONE, eapGssSmInitEstablished }, +#ifdef GSSEAP_ENABLE_REAUTH { TOK_TYPE_GSS_REAUTH, TOK_TYPE_GSS_REAUTH, eapGssSmInitGssReauth }, +#endif }; OM_uint32 @@ -692,8 +640,10 @@ gss_init_sec_context(OM_uint32 *minor, ctx->flags |= CTX_FLAG_INITIATOR; +#ifdef GSSEAP_ENABLE_REAUTH if (canReauthP(cred)) ctx->state = EAP_STATE_KRB_REAUTH_GSS; +#endif *context_handle = ctx; } @@ -768,3 +718,79 @@ cleanup: return major; } + +#ifdef GSSEAP_ENABLE_REAUTH +static int +canReauthP(gss_cred_id_t cred) +{ + return (cred != GSS_C_NO_CREDENTIAL && + cred->krbCred != GSS_C_NO_CREDENTIAL && + cred->expiryTime > time(NULL)); +} + +static OM_uint32 +eapGssSmInitGssReauth(OM_uint32 *minor, + gss_cred_id_t cred, + gss_ctx_id_t ctx, + gss_name_t target, + gss_OID mech, + OM_uint32 reqFlags, + OM_uint32 timeReq, + gss_channel_bindings_t chanBindings, + gss_buffer_t inputToken, + gss_buffer_t outputToken) +{ + OM_uint32 major, tmpMinor; + gss_name_t mechTarget = GSS_C_NO_NAME; + gss_OID actualMech = GSS_C_NO_OID; + OM_uint32 gssFlags, timeRec; + + assert(cred != GSS_C_NO_CREDENTIAL); + + ctx->flags |= CTX_FLAG_KRB_REAUTH_GSS; + + if (inputToken->length == 0) { + major = initBegin(minor, cred, ctx, target, mech, + reqFlags, timeReq, chanBindings, + inputToken, outputToken); + if (GSS_ERROR(major)) + goto cleanup; + } + + major = gssEapMechToGlueName(minor, target, &mechTarget); + if (GSS_ERROR(major)) + goto cleanup; + + major = gssInitSecContext(minor, + cred->krbCred, + &ctx->kerberosCtx, + mechTarget, + (gss_OID)gss_mech_krb5, + reqFlags, /* | GSS_C_DCE_STYLE, */ + timeReq, + chanBindings, + inputToken, + &actualMech, + outputToken, + &gssFlags, + &timeRec); + if (GSS_ERROR(major)) + goto cleanup; + + ctx->gssFlags = gssFlags; + + if (major == GSS_S_COMPLETE) { + major = gssEapReauthComplete(minor, ctx, cred, actualMech, timeRec); + if (GSS_ERROR(major)) + goto cleanup; + ctx->state = EAP_STATE_ESTABLISHED; + } + +cleanup: + gssReleaseName(&tmpMinor, &mechTarget); + + return major; +} +#endif /* GSSEAP_ENABLE_REAUTH */ + + diff --git a/store_cred.c b/store_cred.c index aec3277..b1e5e54 100644 --- a/store_cred.c +++ b/store_cred.c @@ -50,6 +50,7 @@ gss_store_cred(OM_uint32 *minor, if (input_cred_handle == GSS_C_NO_CREDENTIAL) return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CRED; +#ifdef GSSEAP_ENABLE_REAUTH if (input_cred_handle->krbCred != GSS_C_NO_CREDENTIAL) { return gssStoreCred(minor, input_cred_handle->krbCred, @@ -60,6 +61,7 @@ gss_store_cred(OM_uint32 *minor, elements_stored, cred_usage_stored); } +#endif *minor = 0; return GSS_S_UNAVAILABLE; diff --git a/util.h b/util.h index f667440..6b47283 100644 --- a/util.h +++ b/util.h @@ -561,6 +561,8 @@ gssBufferToKrbData(gss_buffer_t buffer, krb5_data *data) #endif #include "util_attr.h" +#ifdef GSSEAP_ENABLE_REAUTH #include "util_reauth.h" +#endif #endif /* _UTIL_H_ */ diff --git a/util_context.c b/util_context.c index 972afa6..37edb63 100644 --- a/util_context.c +++ b/util_context.c @@ -106,9 +106,12 @@ gssEapReleaseContext(OM_uint32 *minor, gssEapKerberosInit(&tmpMinor, &krbContext); +#ifdef GSSEAP_ENABLE_REAUTH if (ctx->flags & CTX_FLAG_KRB_REAUTH_GSS) { gssDeleteSecContext(&tmpMinor, &ctx->kerberosCtx, GSS_C_NO_BUFFER); - } else if (CTX_IS_INITIATOR(ctx)) { + } else +#endif + if (CTX_IS_INITIATOR(ctx)) { releaseInitiatorContext(&ctx->initiatorCtx); } else { releaseAcceptorContext(&ctx->acceptorCtx); diff --git a/util_cred.c b/util_cred.c index df31460..3893ff6 100644 --- a/util_cred.c +++ b/util_cred.c @@ -81,10 +81,12 @@ gssEapReleaseCred(OM_uint32 *minor, gss_cred_id_t *pCred) if (cred->radiusConfigFile != NULL) GSSEAP_FREE(cred->radiusConfigFile); +#ifdef GSSEAP_ENABLE_REAUTH if (cred->krbCredCache != NULL) krb5_cc_destroy(krbContext, cred->krbCredCache); if (cred->krbCred != GSS_C_NO_CREDENTIAL) gssReleaseCred(&tmpMinor, &cred->krbCred); +#endif GSSEAP_MUTEX_DESTROY(&cred->mutex); memset(cred, 0, sizeof(*cred));