X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=init_sec_context.c;h=becb767750676a7d131798825316ee1c21975cd3;hb=4c1ce555f314832913d633f716eb9baca7fd309e;hp=930eb32600cbe44037e1caf4b9a62a8a508751dc;hpb=b79cb354e8440f9d56aabd7957de7d25e5b9cf85;p=mech_eap.orig diff --git a/init_sec_context.c b/init_sec_context.c index 930eb32..becb767 100644 --- a/init_sec_context.c +++ b/init_sec_context.c @@ -223,7 +223,11 @@ peerConfigInit(OM_uint32 *minor, assert(cred->name != GSS_C_NO_NAME); - if ((cred->name->flags & (NAME_FLAG_NAI | NAME_FLAG_SERVICE)) == 0) { + /* + * draft-ietf-abfab-gss-eap-01: the host portion is empty + * for initiators. + */ + if ((cred->name->flags & NAME_FLAG_NAI) == 0) { *minor = GSSEAP_BAD_INITIATOR_NAME; return GSS_S_BAD_NAME; } @@ -443,21 +447,31 @@ eapGssSmInitGssReauth(OM_uint32 *minor, gss_OID mech GSSEAP_UNUSED, OM_uint32 reqFlags, OM_uint32 timeReq, - gss_channel_bindings_t chanBindings, + gss_channel_bindings_t userChanBindings, gss_buffer_t inputToken, gss_buffer_t outputToken, - OM_uint32 *smFlags GSSEAP_UNUSED) + OM_uint32 *smFlags) { OM_uint32 major, tmpMinor; gss_name_t mechTarget = GSS_C_NO_NAME; gss_OID actualMech = GSS_C_NO_OID; OM_uint32 gssFlags, timeRec; + struct gss_channel_bindings_struct wireChanBindings = { 0 }; assert(cred != GSS_C_NO_CREDENTIAL); if (GSSEAP_SM_STATE(ctx) == GSSEAP_STATE_INITIAL) { - if (!gssEapCanReauthP(cred, target, timeReq)) - return GSS_S_CONTINUE_NEEDED; + if (!gssEapCanReauthP(cred, target, timeReq)) { + major = GSS_S_CONTINUE_NEEDED; + goto cleanup; + } + + major = gssEapMakeTokenChannelBindings(minor, ctx, + userChanBindings, + GSS_C_NO_BUFFER, + &wireChanBindings); + if (GSS_ERROR(major)) + goto cleanup; ctx->flags |= CTX_FLAG_KRB_REAUTH; } else if ((ctx->flags & CTX_FLAG_KRB_REAUTH) == 0) { @@ -477,7 +491,7 @@ eapGssSmInitGssReauth(OM_uint32 *minor, (gss_OID)gss_mech_krb5, reqFlags | GSS_C_MUTUAL_FLAG, timeReq, - chanBindings, + &wireChanBindings, inputToken, &actualMech, outputToken, @@ -494,13 +508,18 @@ eapGssSmInitGssReauth(OM_uint32 *minor, major = gssEapReauthComplete(minor, ctx, cred, actualMech, timeRec); if (GSS_ERROR(major)) goto cleanup; - GSSEAP_SM_TRANSITION(ctx, GSSEAP_STATE_ESTABLISHED); + + GSSEAP_SM_TRANSITION(ctx, GSSEAP_STATE_ACCEPTOR_EXTS); } else { GSSEAP_SM_TRANSITION(ctx, GSSEAP_STATE_REAUTHENTICATE); + *smFlags |= SM_FLAG_SEND_TOKEN; } + major = GSS_S_CONTINUE_NEEDED; + cleanup: gssReleaseName(&tmpMinor, &mechTarget); + gss_release_buffer(&tmpMinor, &wireChanBindings.application_data); return major; } @@ -577,6 +596,50 @@ eapGssSmInitAcceptorName(OM_uint32 *minor, } static OM_uint32 +gssEapSupportedAcceptorExts[] = { + ITOK_TYPE_REAUTH_CREDS, +}; + +static struct gss_eap_itok_map +gssEapInitiatorExtsFlagMap[] = { +}; + +static OM_uint32 +eapGssSmInitExts(OM_uint32 *minor, + gss_cred_id_t cred GSSEAP_UNUSED, + gss_ctx_id_t ctx GSSEAP_UNUSED, + gss_name_t target GSSEAP_UNUSED, + gss_OID mech GSSEAP_UNUSED, + OM_uint32 reqFlags GSSEAP_UNUSED, + OM_uint32 timeReq GSSEAP_UNUSED, + gss_channel_bindings_t chanBindings GSSEAP_UNUSED, + gss_buffer_t inputToken, + gss_buffer_t outputToken, + OM_uint32 *smFlags GSSEAP_UNUSED) +{ + OM_uint32 major = GSS_S_COMPLETE; + + if (GSSEAP_SM_STATE(ctx) == GSSEAP_STATE_INITIAL) { + major = gssEapEncodeSupportedExts(minor, + gssEapSupportedAcceptorExts, + sizeof(gssEapSupportedAcceptorExts) / + sizeof(gssEapSupportedAcceptorExts[0]), + outputToken); + } else if (inputToken != GSS_C_NO_BUFFER) { + major = gssEapProcessSupportedExts(minor, inputToken, + gssEapInitiatorExtsFlagMap, + sizeof(gssEapInitiatorExtsFlagMap) / + sizeof(gssEapInitiatorExtsFlagMap[0]), + &ctx->flags); + } + + if (GSS_ERROR(major)) + return major; + + return GSS_S_CONTINUE_NEEDED; +} + +static OM_uint32 eapGssSmInitIdentity(OM_uint32 *minor, gss_cred_id_t cred GSSEAP_UNUSED, gss_ctx_id_t ctx, @@ -601,7 +664,7 @@ eapGssSmInitIdentity(OM_uint32 *minor, GSSEAP_SM_TRANSITION(ctx, GSSEAP_STATE_INITIAL); } else #endif - *smFlags |= SM_FLAG_FORCE_SEND_TOKEN; + *smFlags |= SM_FLAG_SEND_TOKEN; assert((ctx->flags & CTX_FLAG_KRB_REAUTH) == 0); assert(inputToken == GSS_C_NO_BUFFER); @@ -705,7 +768,7 @@ cleanup: *minor = tmpMinor; } - *smFlags |= SM_FLAG_OUTPUT_TOKEN_CRITICAL; + *smFlags |= SM_FLAG_SEND_TOKEN | SM_FLAG_OUTPUT_TOKEN_CRITICAL; } wpabuf_set(&ctx->initiatorCtx.reqData, NULL, 0); @@ -715,6 +778,30 @@ cleanup: } static OM_uint32 +eapGssSmInitGssFlags(OM_uint32 *minor, + gss_cred_id_t cred GSSEAP_UNUSED, + gss_ctx_id_t ctx, + gss_name_t target GSSEAP_UNUSED, + gss_OID mech GSSEAP_UNUSED, + OM_uint32 reqFlags GSSEAP_UNUSED, + OM_uint32 timeReq GSSEAP_UNUSED, + gss_channel_bindings_t chanBindings GSSEAP_UNUSED, + gss_buffer_t inputToken GSSEAP_UNUSED, + gss_buffer_t outputToken, + OM_uint32 *smFlags GSSEAP_UNUSED) +{ + unsigned char wireFlags[4]; + gss_buffer_desc flagsBuf; + + store_uint32_be(ctx->gssFlags & GSSEAP_WIRE_FLAGS_MASK, wireFlags); + + flagsBuf.length = sizeof(wireFlags); + flagsBuf.value = wireFlags; + + return duplicateBuffer(minor, &flagsBuf, outputToken); +} + +static OM_uint32 eapGssSmInitGssChannelBindings(OM_uint32 *minor, gss_cred_id_t cred GSSEAP_UNUSED, gss_ctx_id_t ctx, @@ -725,24 +812,19 @@ eapGssSmInitGssChannelBindings(OM_uint32 *minor, gss_channel_bindings_t chanBindings, gss_buffer_t inputToken GSSEAP_UNUSED, gss_buffer_t outputToken, - OM_uint32 *smFlags) + OM_uint32 *smFlags GSSEAP_UNUSED) { OM_uint32 major; - gss_buffer_desc buffer = GSS_C_EMPTY_BUFFER; - if (chanBindings != GSS_C_NO_CHANNEL_BINDINGS) - buffer = chanBindings->application_data; - - major = gssEapWrap(minor, ctx, TRUE, GSS_C_QOP_DEFAULT, - &buffer, NULL, outputToken); - if (GSS_ERROR(major)) - return major; - - assert(outputToken->value != NULL); + if ((ctx->flags & CTX_FLAG_KRB_REAUTH) == 0 && + chanBindings != GSS_C_NO_CHANNEL_BINDINGS) { + major = gssEapWrap(minor, ctx, TRUE, GSS_C_QOP_DEFAULT, + &chanBindings->application_data, NULL, outputToken); + if (GSS_ERROR(major)) + return major; + } *minor = 0; - *smFlags |= SM_FLAG_OUTPUT_TOKEN_CRITICAL; - return GSS_S_CONTINUE_NEEDED; } @@ -774,39 +856,51 @@ eapGssSmInitReauthCreds(OM_uint32 *minor, #endif /* GSSEAP_ENABLE_REAUTH */ static OM_uint32 -eapGssSmInitCompleteInitiatorExts(OM_uint32 *minor, - gss_cred_id_t cred GSSEAP_UNUSED, - gss_ctx_id_t ctx, - gss_name_t target GSSEAP_UNUSED, - gss_OID mech GSSEAP_UNUSED, - OM_uint32 reqFlags GSSEAP_UNUSED, - OM_uint32 timeReq GSSEAP_UNUSED, - gss_channel_bindings_t chanBindings GSSEAP_UNUSED, - gss_buffer_t inputToken GSSEAP_UNUSED, - gss_buffer_t outputToken GSSEAP_UNUSED, - OM_uint32 *smFlags) +eapGssSmInitInitiatorMIC(OM_uint32 *minor, + gss_cred_id_t cred GSSEAP_UNUSED, + gss_ctx_id_t ctx, + gss_name_t target GSSEAP_UNUSED, + gss_OID mech GSSEAP_UNUSED, + OM_uint32 reqFlags GSSEAP_UNUSED, + OM_uint32 timeReq GSSEAP_UNUSED, + gss_channel_bindings_t chanBindings GSSEAP_UNUSED, + gss_buffer_t inputToken GSSEAP_UNUSED, + gss_buffer_t outputToken, + OM_uint32 *smFlags) { + OM_uint32 major; + + major = gssEapGetConversationMIC(minor, ctx, outputToken); + if (GSS_ERROR(major)) + return major; + GSSEAP_SM_TRANSITION_NEXT(ctx); *minor = 0; - *smFlags |= SM_FLAG_FORCE_SEND_TOKEN; + *smFlags |= SM_FLAG_SEND_TOKEN | SM_FLAG_OUTPUT_TOKEN_CRITICAL; return GSS_S_CONTINUE_NEEDED; } static OM_uint32 -eapGssSmInitCompleteAcceptorExts(OM_uint32 *minor, - gss_cred_id_t cred GSSEAP_UNUSED, - gss_ctx_id_t ctx, - gss_name_t target GSSEAP_UNUSED, - gss_OID mech GSSEAP_UNUSED, - OM_uint32 reqFlags GSSEAP_UNUSED, - OM_uint32 timeReq GSSEAP_UNUSED, - gss_channel_bindings_t chanBindings GSSEAP_UNUSED, - gss_buffer_t inputToken GSSEAP_UNUSED, - gss_buffer_t outputToken GSSEAP_UNUSED, - OM_uint32 *smFlags GSSEAP_UNUSED) +eapGssSmInitAcceptorMIC(OM_uint32 *minor, + gss_cred_id_t cred GSSEAP_UNUSED, + gss_ctx_id_t ctx, + gss_name_t target GSSEAP_UNUSED, + gss_OID mech GSSEAP_UNUSED, + OM_uint32 reqFlags GSSEAP_UNUSED, + OM_uint32 timeReq GSSEAP_UNUSED, + gss_channel_bindings_t chanBindings GSSEAP_UNUSED, + gss_buffer_t inputToken, + gss_buffer_t outputToken GSSEAP_UNUSED, + OM_uint32 *smFlags GSSEAP_UNUSED) { + OM_uint32 major; + + major = gssEapVerifyConversationMIC(minor, ctx, inputToken); + if (GSS_ERROR(major)) + return major; + GSSEAP_SM_TRANSITION(ctx, GSSEAP_STATE_ESTABLISHED); *minor = 0; @@ -814,6 +908,9 @@ eapGssSmInitCompleteAcceptorExts(OM_uint32 *minor, return GSS_S_COMPLETE; } +/* + * Initiator state machine. + */ static struct gss_eap_sm eapGssInitiatorSm[] = { { ITOK_TYPE_CONTEXT_ERR, @@ -829,6 +926,13 @@ static struct gss_eap_sm eapGssInitiatorSm[] = { 0, eapGssSmInitAcceptorName }, + { + ITOK_TYPE_SUPPORTED_INITIATOR_EXTS, + ITOK_TYPE_SUPPORTED_ACCEPTOR_EXTS, + GSSEAP_STATE_INITIAL | GSSEAP_STATE_AUTHENTICATE, + 0, + eapGssSmInitExts + }, #ifdef GSSEAP_DEBUG { ITOK_TYPE_NONE, @@ -866,17 +970,24 @@ static struct gss_eap_sm eapGssInitiatorSm[] = { }, { ITOK_TYPE_NONE, + ITOK_TYPE_GSS_FLAGS, + GSSEAP_STATE_INITIATOR_EXTS, + 0, + eapGssSmInitGssFlags + }, + { + ITOK_TYPE_NONE, ITOK_TYPE_GSS_CHANNEL_BINDINGS, GSSEAP_STATE_INITIATOR_EXTS, - SM_ITOK_FLAG_REQUIRED, + 0, eapGssSmInitGssChannelBindings }, { ITOK_TYPE_NONE, - ITOK_TYPE_NONE, + ITOK_TYPE_INITIATOR_MIC, GSSEAP_STATE_INITIATOR_EXTS, 0, - eapGssSmInitCompleteInitiatorExts + eapGssSmInitInitiatorMIC }, #ifdef GSSEAP_ENABLE_REAUTH { @@ -889,11 +1000,11 @@ static struct gss_eap_sm eapGssInitiatorSm[] = { #endif /* other extensions go here */ { - ITOK_TYPE_NONE, + ITOK_TYPE_ACCEPTOR_MIC, ITOK_TYPE_NONE, GSSEAP_STATE_ACCEPTOR_EXTS, - 0, - eapGssSmInitCompleteAcceptorExts + SM_ITOK_FLAG_REQUIRED, + eapGssSmInitAcceptorMIC } };