X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=init_sec_context.c;h=b9ff0be71564e8355281c9e2e8417a44e7303405;hb=c782e76527626566bb4d6fddf38f83beea0aa72a;hp=57298425b78fc4b3235460991fc6b6eff8d680d7;hpb=26d07bde1b02d61dee0357b849aefcf8bfa05f89;p=mech_eap.orig diff --git a/init_sec_context.c b/init_sec_context.c index 5729842..b9ff0be 100644 --- a/init_sec_context.c +++ b/init_sec_context.c @@ -140,32 +140,77 @@ peerSetInt(void *data, enum eapol_int_var variable, } static OM_uint32 -eapGssSmAuthenticate(OM_uint32 *minor, - gss_cred_id_t cred, - gss_ctx_id_t ctx, - gss_name_t target_name, - gss_OID mech_type, - OM_uint32 req_flags, - OM_uint32 time_req, - gss_channel_bindings_t input_chan_bindings, - gss_buffer_t input_token, - gss_buffer_t output_token) +eapGssSmInitAuthenticate(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) { - GSSEAP_NOT_IMPLEMENTED; + OM_uint32 major, tmpMinor; + time_t now; + + if (inputToken == GSS_C_NO_BUFFER || inputToken->length == 0) { + /* first time */ + reqFlags &= GSS_C_TRANS_FLAG | GSS_C_REPLAY_FLAG | GSS_C_DCE_STYLE; + ctx->gssFlags |= reqFlags; + + time(&now); + + if (timeReq == 0 || timeReq == GSS_C_INDEFINITE) + ctx->expiryTime = 0; + else + ctx->expiryTime = now + timeReq; + + major = gss_duplicate_name(minor, cred->name, &ctx->initiatorName); + if (GSS_ERROR(major)) + goto cleanup; + + major = gss_duplicate_name(minor, target, &ctx->acceptorName); + if (GSS_ERROR(major)) + goto cleanup; + + if (mech == GSS_C_NULL_OID || oidEqual(mech, GSS_EAP_MECHANISM)) { + major = gssEapDefaultMech(minor, &ctx->mechanismUsed); + } else if (gssEapIsConcreteMechanismOid(mech)) { + if (!gssEapInternalizeOid(mech, &ctx->mechanismUsed)) + major = duplicateOid(minor, mech, &ctx->mechanismUsed); + } else { + major = GSS_S_BAD_MECH; + } + if (GSS_ERROR(major)) + goto cleanup; + } + +cleanup: + return major; } -static eap_gss_initiator_sm eapGssSm[] = { - eapGssSmAuthenticate, - NULL, - NULL, - NULL, - NULL, +static struct eap_gss_initiator_sm { + enum gss_eap_token_type inputTokenType; + enum gss_eap_token_type outputTokenType; + OM_uint32 (*processToken)(OM_uint32 *, + gss_cred_id_t, + gss_ctx_id_t, + gss_name_t, + gss_OID, + OM_uint32, + OM_uint32, + gss_channel_bindings_t, + gss_buffer_t, + gss_buffer_t); +} eapGssInitiatorSm[] = { + { TOK_TYPE_EAP_REQ, TOK_TYPE_EAP_RESP, eapGssSmInitAuthenticate }, }; OM_uint32 gss_init_sec_context(OM_uint32 *minor, gss_cred_id_t cred, - gss_ctx_id_t *pCtx, + gss_ctx_id_t *context_handle, gss_name_t target_name, gss_OID mech_type, OM_uint32 req_flags, @@ -178,60 +223,87 @@ gss_init_sec_context(OM_uint32 *minor, OM_uint32 *time_rec) { OM_uint32 major, tmpMinor; - gss_ctx_id_t ctx = *pCtx; + gss_ctx_id_t ctx = *context_handle; + struct eap_gss_initiator_sm *sm = NULL; + gss_buffer_desc innerInputToken, innerOutputToken; *minor = 0; + innerOutputToken.length = 0; + innerOutputToken.value = NULL; + output_token->length = 0; output_token->value = NULL; if (cred != GSS_C_NO_CREDENTIAL && !(cred->flags & CRED_FLAG_INITIATE)) { - major = GSS_S_NO_CRED; - goto cleanup; + return GSS_S_NO_CRED; } if (ctx == GSS_C_NO_CONTEXT) { if (input_token != GSS_C_NO_BUFFER && input_token->length != 0) { - major = GSS_S_DEFECTIVE_TOKEN; - goto cleanup; + return GSS_S_DEFECTIVE_TOKEN; } major = gssEapAllocContext(minor, &ctx); if (GSS_ERROR(major)) - goto cleanup; + return major; + + ctx->flags |= CTX_FLAG_INITIATOR; + + *context_handle = ctx; } - for (; ctx->state != EAP_STATE_ESTABLISHED; ctx->state++) { - major = (eapGssSm[ctx->state])(minor, - cred, - ctx, - target_name, - mech_type, - req_flags, - time_req, - input_chan_bindings, - input_token, - output_token); + GSSEAP_MUTEX_LOCK(&ctx->mutex); + + sm = &eapGssInitiatorSm[ctx->state]; + + if (input_token != GSS_C_NO_BUFFER) { + major = gssEapVerifyToken(minor, ctx, input_token, + sm->inputTokenType, &innerInputToken); if (GSS_ERROR(major)) goto cleanup; - if (output_token->length != 0) { - assert(major == GSS_S_CONTINUE_NEEDED); - break; - } + } else { + innerInputToken.length = 0; + innerInputToken.value = NULL; } - if (actual_mech_type != NULL) - *actual_mech_type = ctx->mechanismUsed; + major = (sm->processToken)(minor, + cred, + ctx, + target_name, + mech_type, + req_flags, + time_req, + input_chan_bindings, + &innerInputToken, + &innerOutputToken); + if (GSS_ERROR(major)) + goto cleanup; + + if (actual_mech_type != NULL) { + if (!gssEapInternalizeOid(ctx->mechanismUsed, actual_mech_type)) + duplicateOid(&tmpMinor, ctx->mechanismUsed, actual_mech_type); + } + if (innerOutputToken.length != 0) { + major = gssEapMakeToken(minor, ctx, &innerOutputToken, + sm->outputTokenType, output_token); + if (GSS_ERROR(major)) + goto cleanup; + } if (ret_flags != NULL) *ret_flags = ctx->gssFlags; if (time_rec != NULL) gss_context_time(&tmpMinor, ctx, time_rec); - assert(ctx->state == EAP_STATE_ESTABLISHED || output_token->length != 0); + assert(ctx->state == EAP_STATE_ESTABLISHED || major == GSS_S_CONTINUE_NEEDED); cleanup: + GSSEAP_MUTEX_UNLOCK(&ctx->mutex); + if (GSS_ERROR(major)) - gssEapReleaseContext(&tmpMinor, &ctx); + gssEapReleaseContext(&tmpMinor, context_handle); + + gss_release_buffer(&tmpMinor, &innerOutputToken); return major; }