X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=mech_eap%2Finit_sec_context.c;h=2e4b23b9c79788fc562bdc646d78b1f84ca4c4b5;hb=e82fcf22c3b6961beae883fc66bf4567896b7c4b;hp=5d3ebb7df848a0e8bf35faaa767d37fd92f6dd20;hpb=fbfc586dcd594017a692f664f600dcba0db7ecca;p=moonshot.git diff --git a/mech_eap/init_sec_context.c b/mech_eap/init_sec_context.c index 5d3ebb7..2e4b23b 100644 --- a/mech_eap/init_sec_context.c +++ b/mech_eap/init_sec_context.c @@ -161,18 +161,20 @@ peerGetEapReqData(void *ctx) } static void -peerSetConfigBlob(void *ctx, struct wpa_config_blob *blob) +peerSetConfigBlob(void *ctx GSSEAP_UNUSED, + struct wpa_config_blob *blob GSSEAP_UNUSED) { } static const struct wpa_config_blob * -peerGetConfigBlob(void *ctx, const char *name) +peerGetConfigBlob(void *ctx GSSEAP_UNUSED, + const char *name GSSEAP_UNUSED) { return NULL; } static void -peerNotifyPending(void *ctx) +peerNotifyPending(void *ctx GSSEAP_UNUSED) { } @@ -197,13 +199,16 @@ peerConfigInit(OM_uint32 *minor, gss_cred_id_t cred, gss_ctx_id_t ctx) { + OM_uint32 major; krb5_context krbContext; struct eap_peer_config *eapPeerConfig = &ctx->initiatorCtx.eapPeerConfig; - krb5_error_code code; - char *identity, *anonymousIdentity; + gss_buffer_desc identity = GSS_C_EMPTY_BUFFER; + gss_buffer_desc realm = GSS_C_EMPTY_BUFFER; eapPeerConfig->identity = NULL; eapPeerConfig->identity_len = 0; + eapPeerConfig->anonymous_identity = NULL; + eapPeerConfig->anonymous_identity_len = 0; eapPeerConfig->password = NULL; eapPeerConfig->password_len = 0; @@ -223,20 +228,29 @@ peerConfigInit(OM_uint32 *minor, return GSS_S_BAD_NAME; } - code = krb5_unparse_name(krbContext, cred->name->krbPrincipal, &identity); - if (code != 0) { - *minor = code; + /* identity */ + major = gssEapDisplayName(minor, cred->name, &identity, NULL); + if (GSS_ERROR(major)) + return major; + + eapPeerConfig->identity = (unsigned char *)identity.value; + eapPeerConfig->identity_len = identity.length; + + krbPrincRealmToGssBuffer(cred->name->krbPrincipal, &realm); + + /* anonymous_identity */ + eapPeerConfig->anonymous_identity = GSSEAP_MALLOC(realm.length + 2); + if (eapPeerConfig->anonymous_identity == NULL) { + *minor = ENOMEM; return GSS_S_FAILURE; } - anonymousIdentity = strchr(identity, '@'); - if (anonymousIdentity == NULL) - anonymousIdentity = ""; + eapPeerConfig->anonymous_identity[0] = '@'; + memcpy(eapPeerConfig->anonymous_identity + 1, realm.value, realm.length); + eapPeerConfig->anonymous_identity[1 + realm.length] = '\0'; + eapPeerConfig->anonymous_identity_len = 1 + realm.length; - eapPeerConfig->identity = (unsigned char *)identity; - eapPeerConfig->identity_len = strlen(identity); - eapPeerConfig->anonymous_identity = (unsigned char *)anonymousIdentity; - eapPeerConfig->anonymous_identity_len = strlen(anonymousIdentity); + /* password */ eapPeerConfig->password = (unsigned char *)cred->password.value; eapPeerConfig->password_len = cred->password.length; @@ -248,12 +262,19 @@ static OM_uint32 peerConfigFree(OM_uint32 *minor, gss_ctx_id_t ctx) { - krb5_context krbContext; struct eap_peer_config *eapPeerConfig = &ctx->initiatorCtx.eapPeerConfig; - GSSEAP_KRB_INIT(&krbContext); + if (eapPeerConfig->identity != NULL) { + GSSEAP_FREE(eapPeerConfig->identity); + eapPeerConfig->identity = NULL; + eapPeerConfig->identity_len = 0; + } - krb5_free_unparsed_name(krbContext, (char *)eapPeerConfig->identity); + if (eapPeerConfig->anonymous_identity != NULL) { + GSSEAP_FREE(eapPeerConfig->anonymous_identity); + eapPeerConfig->anonymous_identity = NULL; + eapPeerConfig->anonymous_identity_len = 0; + } *minor = 0; return GSS_S_COMPLETE; @@ -324,10 +345,9 @@ initBegin(OM_uint32 *minor, gss_ctx_id_t ctx, gss_name_t target, gss_OID mech, - OM_uint32 reqFlags, + OM_uint32 reqFlags GSSEAP_UNUSED, OM_uint32 timeReq, - gss_channel_bindings_t chanBindings, - gss_buffer_t inputToken) + gss_channel_bindings_t chanBindings GSSEAP_UNUSED) { OM_uint32 major; @@ -349,25 +369,22 @@ initBegin(OM_uint32 *minor, if (GSS_ERROR(major)) return major; - GSSEAP_MUTEX_LOCK(&target->mutex); + if (target != GSS_C_NO_NAME) { + GSSEAP_MUTEX_LOCK(&target->mutex); + + major = gssEapDuplicateName(minor, target, &ctx->acceptorName); + if (GSS_ERROR(major)) { + GSSEAP_MUTEX_UNLOCK(&target->mutex); + return major; + } - major = gssEapDuplicateName(minor, target, &ctx->acceptorName); - if (GSS_ERROR(major)) { GSSEAP_MUTEX_UNLOCK(&target->mutex); - return major; } - GSSEAP_MUTEX_UNLOCK(&target->mutex); - - if (mech == GSS_C_NULL_OID) { - 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; - *minor = GSSEAP_WRONG_MECH; - } + major = gssEapCanonicalizeOid(minor, + mech, + OID_FLAG_NULL_VALID | OID_FLAG_MAP_NULL_TO_DEFAULT_MECH, + &ctx->mechanismUsed); if (GSS_ERROR(major)) return major; @@ -383,16 +400,16 @@ initBegin(OM_uint32 *minor, static OM_uint32 eapGssSmInitError(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_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) + gss_buffer_t outputToken GSSEAP_UNUSED, + OM_uint32 *smFlags GSSEAP_UNUSED) { OM_uint32 major; unsigned char *p; @@ -423,13 +440,13 @@ eapGssSmInitGssReauth(OM_uint32 *minor, gss_cred_id_t cred, gss_ctx_id_t ctx, gss_name_t target, - gss_OID mech, + gss_OID mech GSSEAP_UNUSED, OM_uint32 reqFlags, OM_uint32 timeReq, gss_channel_bindings_t chanBindings, gss_buffer_t inputToken, gss_buffer_t outputToken, - OM_uint32 *smFlags) + OM_uint32 *smFlags GSSEAP_UNUSED) { OM_uint32 major, tmpMinor; gss_name_t mechTarget = GSS_C_NO_NAME; @@ -438,16 +455,10 @@ eapGssSmInitGssReauth(OM_uint32 *minor, assert(cred != GSS_C_NO_CREDENTIAL); - if (ctx->state == GSSEAP_STATE_INITIAL) { + if (GSSEAP_SM_STATE(ctx) == GSSEAP_STATE_INITIAL) { if (!gssEapCanReauthP(cred, target, timeReq)) return GSS_S_CONTINUE_NEEDED; - major = initBegin(minor, cred, ctx, target, mech, - reqFlags, timeReq, chanBindings, - inputToken); - if (GSS_ERROR(major)) - goto cleanup; - ctx->flags |= CTX_FLAG_KRB_REAUTH; } else if ((ctx->flags & CTX_FLAG_KRB_REAUTH) == 0) { major = GSS_S_DEFECTIVE_TOKEN; @@ -461,10 +472,10 @@ eapGssSmInitGssReauth(OM_uint32 *minor, major = gssInitSecContext(minor, cred->krbCred, - &ctx->kerberosCtx, + &ctx->reauthCtx, mechTarget, (gss_OID)gss_mech_krb5, - reqFlags, + reqFlags | GSS_C_MUTUAL_FLAG, timeReq, chanBindings, inputToken, @@ -478,14 +489,16 @@ eapGssSmInitGssReauth(OM_uint32 *minor, ctx->gssFlags = gssFlags; if (major == GSS_S_COMPLETE) { + assert(GSSEAP_SM_STATE(ctx) == GSSEAP_STATE_REAUTHENTICATE); + major = gssEapReauthComplete(minor, ctx, cred, actualMech, timeRec); if (GSS_ERROR(major)) goto cleanup; - ctx->state = GSSEAP_STATE_ACCEPTOR_EXTS; + GSSEAP_SM_TRANSITION(ctx, GSSEAP_STATE_ESTABLISHED); + } else { + GSSEAP_SM_TRANSITION(ctx, GSSEAP_STATE_REAUTHENTICATE); } - *smFlags |= SM_FLAG_TRANSITION | SM_FLAG_STOP_EVAL; - cleanup: gssReleaseName(&tmpMinor, &mechTarget); @@ -496,16 +509,16 @@ cleanup: #ifdef GSSEAP_DEBUG static OM_uint32 eapGssSmInitVendorInfo(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_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 GSSEAP_UNUSED, gss_buffer_t outputToken, - OM_uint32 *smFlags) + OM_uint32 *smFlags GSSEAP_UNUSED) { OM_uint32 major; @@ -518,30 +531,81 @@ eapGssSmInitVendorInfo(OM_uint32 *minor, #endif static OM_uint32 +eapGssSmInitAcceptorName(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) +{ + OM_uint32 major; + + if (GSSEAP_SM_STATE(ctx) == GSSEAP_STATE_INITIAL && + ctx->acceptorName != GSS_C_NO_NAME) { + + /* Send desired target name to acceptor */ + major = gssEapDisplayName(minor, ctx->acceptorName, + outputToken, NULL); + if (GSS_ERROR(major)) + return major; + } else if (inputToken != GSS_C_NO_BUFFER && + ctx->acceptorName == GSS_C_NO_NAME) { + /* Accept target name hint from acceptor */ + major = gssEapImportName(minor, inputToken, + GSS_C_NT_USER_NAME, + ctx->mechanismUsed, + &ctx->acceptorName); + if (GSS_ERROR(major)) + return major; + } + + /* + * Currently, other parts of the code assume that the acceptor name + * is available, hence this check. + */ + if (ctx->acceptorName == GSS_C_NO_NAME) { + *minor = GSSEAP_NO_ACCEPTOR_NAME; + return GSS_S_FAILURE; + } + + return GSS_S_CONTINUE_NEEDED; +} + +static OM_uint32 eapGssSmInitIdentity(OM_uint32 *minor, - gss_cred_id_t cred, + gss_cred_id_t cred GSSEAP_UNUSED, 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, + 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) { - OM_uint32 major; struct eap_config eapConfig; +#ifdef GSSEAP_ENABLE_REAUTH + if (GSSEAP_SM_STATE(ctx) == GSSEAP_STATE_REAUTHENTICATE) { + OM_uint32 tmpMinor; + + /* server didn't support reauthentication, sent EAP request */ + gssDeleteSecContext(&tmpMinor, &ctx->reauthCtx, GSS_C_NO_BUFFER); + ctx->flags &= ~(CTX_FLAG_KRB_REAUTH); + GSSEAP_SM_TRANSITION(ctx, GSSEAP_STATE_INITIAL); + } else +#endif + *smFlags |= SM_FLAG_FORCE_SEND_TOKEN; + assert((ctx->flags & CTX_FLAG_KRB_REAUTH) == 0); assert(inputToken == GSS_C_NO_BUFFER); - major = initBegin(minor, cred, ctx, target, mech, - reqFlags, timeReq, chanBindings, - inputToken); - if (GSS_ERROR(major)) - return major; - memset(&eapConfig, 0, sizeof(eapConfig)); ctx->initiatorCtx.eap = eap_peer_sm_init(ctx, @@ -561,9 +625,9 @@ eapGssSmInitIdentity(OM_uint32 *minor, return GSS_S_FAILURE; } - /* force sending of empty token */ + GSSEAP_SM_TRANSITION_NEXT(ctx); + *minor = 0; - *smFlags |= SM_FLAG_TRANSITION | SM_FLAG_FORCE_SEND_TOKEN; return GSS_S_CONTINUE_NEEDED; } @@ -572,12 +636,12 @@ static OM_uint32 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_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) { @@ -616,7 +680,7 @@ eapGssSmInitAuthenticate(OM_uint32 *minor, ctx->flags &= ~(CTX_FLAG_EAP_SUCCESS); major = GSS_S_CONTINUE_NEEDED; - *smFlags |= SM_FLAG_TRANSITION; + GSSEAP_SM_TRANSITION_NEXT(ctx); } else if (ctx->flags & CTX_FLAG_EAP_FAIL) { major = GSS_S_DEFECTIVE_CREDENTIAL; *minor = GSSEAP_PEER_AUTH_FAILURE; @@ -640,6 +704,8 @@ cleanup: major = tmpMajor; *minor = tmpMinor; } + + *smFlags |= SM_FLAG_OUTPUT_TOKEN_CRITICAL; } wpabuf_set(&ctx->initiatorCtx.reqData, NULL, 0); @@ -650,14 +716,14 @@ cleanup: static OM_uint32 eapGssSmInitGssChannelBindings(OM_uint32 *minor, - gss_cred_id_t cred, + gss_cred_id_t cred GSSEAP_UNUSED, gss_ctx_id_t ctx, - gss_name_t target, - gss_OID mech, - OM_uint32 reqFlags, - OM_uint32 timeReq, + 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, - gss_buffer_t inputToken, + gss_buffer_t inputToken GSSEAP_UNUSED, gss_buffer_t outputToken, OM_uint32 *smFlags) { @@ -675,6 +741,8 @@ eapGssSmInitGssChannelBindings(OM_uint32 *minor, assert(outputToken->value != NULL); *minor = 0; + *smFlags |= SM_FLAG_OUTPUT_TOKEN_CRITICAL; + return GSS_S_CONTINUE_NEEDED; } @@ -683,20 +751,22 @@ static OM_uint32 eapGssSmInitReauthCreds(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_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) + gss_buffer_t outputToken GSSEAP_UNUSED, + OM_uint32 *smFlags GSSEAP_UNUSED) { OM_uint32 major; - major = gssEapStoreReauthCreds(minor, ctx, cred, inputToken); - if (GSS_ERROR(major)) - return major; + if (ctx->gssFlags & GSS_C_MUTUAL_FLAG) { + major = gssEapStoreReauthCreds(minor, ctx, cred, inputToken); + if (GSS_ERROR(major)) + return major; + } *minor = 0; return GSS_S_CONTINUE_NEEDED; @@ -704,99 +774,108 @@ eapGssSmInitReauthCreds(OM_uint32 *minor, #endif /* GSSEAP_ENABLE_REAUTH */ static OM_uint32 -eapGssSmInitCompleteAcceptorExts(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 *smFlags) +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) { + GSSEAP_SM_TRANSITION_NEXT(ctx); + *minor = 0; - *smFlags |= SM_FLAG_TRANSITION | SM_FLAG_STOP_EVAL; - return GSS_S_COMPLETE; + *smFlags |= SM_FLAG_FORCE_SEND_TOKEN; + + return GSS_S_CONTINUE_NEEDED; } static OM_uint32 -eapGssSmInitCompleteInitiatorExts(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 *smFlags) +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) { + GSSEAP_SM_TRANSITION(ctx, GSSEAP_STATE_ESTABLISHED); + *minor = 0; - *smFlags |= SM_FLAG_TRANSITION | SM_FLAG_STOP_EVAL; - return GSS_S_CONTINUE_NEEDED; + + return GSS_S_COMPLETE; } + static struct gss_eap_sm eapGssInitiatorSm[] = { { ITOK_TYPE_CONTEXT_ERR, ITOK_TYPE_NONE, GSSEAP_STATE_ALL & ~(GSSEAP_STATE_INITIAL), - 1, /* critical */ - 0, /* required */ - eapGssSmInitError, + 0, + eapGssSmInitError }, -#ifdef GSSEAP_ENABLE_REAUTH { - ITOK_TYPE_REAUTH_RESP, - ITOK_TYPE_REAUTH_REQ, + ITOK_TYPE_ACCEPTOR_NAME_RESP, + ITOK_TYPE_ACCEPTOR_NAME_REQ, GSSEAP_STATE_INITIAL | GSSEAP_STATE_AUTHENTICATE, - 0, /* critical */ - 0, /* required */ - eapGssSmInitGssReauth, + 0, + eapGssSmInitAcceptorName }, -#endif -#if 0 +#ifdef GSSEAP_DEBUG { ITOK_TYPE_NONE, ITOK_TYPE_VENDOR_INFO, GSSEAP_STATE_INITIAL, - 0, /* critical */ - 0, /* required */ - eapGssSmInitVendorInfo, + 0, + eapGssSmInitVendorInfo + }, +#endif +#ifdef GSSEAP_ENABLE_REAUTH + { + ITOK_TYPE_REAUTH_RESP, + ITOK_TYPE_REAUTH_REQ, + GSSEAP_STATE_INITIAL | GSSEAP_STATE_REAUTHENTICATE, + 0, + eapGssSmInitGssReauth }, #endif { ITOK_TYPE_NONE, ITOK_TYPE_NONE, +#ifdef GSSEAP_ENABLE_REAUTH + GSSEAP_STATE_REAUTHENTICATE | +#endif GSSEAP_STATE_INITIAL, - 1, /* critical */ - 1, /* required */ - eapGssSmInitIdentity, + SM_ITOK_FLAG_REQUIRED, + eapGssSmInitIdentity }, { ITOK_TYPE_EAP_REQ, ITOK_TYPE_EAP_RESP, GSSEAP_STATE_AUTHENTICATE, - 1, /* critical */ - 1, /* required */ - eapGssSmInitAuthenticate, + SM_ITOK_FLAG_REQUIRED, + eapGssSmInitAuthenticate }, { ITOK_TYPE_NONE, ITOK_TYPE_GSS_CHANNEL_BINDINGS, GSSEAP_STATE_INITIATOR_EXTS, - 1, /* critical */ - 1, /* required */ - eapGssSmInitGssChannelBindings, + SM_ITOK_FLAG_REQUIRED, + eapGssSmInitGssChannelBindings }, { ITOK_TYPE_NONE, ITOK_TYPE_NONE, GSSEAP_STATE_INITIATOR_EXTS, - 1, /* critical */ - 1, /* required */ + 0, eapGssSmInitCompleteInitiatorExts }, #ifdef GSSEAP_ENABLE_REAUTH @@ -804,9 +883,8 @@ static struct gss_eap_sm eapGssInitiatorSm[] = { ITOK_TYPE_REAUTH_CREDS, ITOK_TYPE_NONE, GSSEAP_STATE_ACCEPTOR_EXTS, - 0, /* critical */ - 0, /* required */ - eapGssSmInitReauthCreds, + 0, + eapGssSmInitReauthCreds }, #endif /* other extensions go here */ @@ -814,8 +892,7 @@ static struct gss_eap_sm eapGssInitiatorSm[] = { ITOK_TYPE_NONE, ITOK_TYPE_NONE, GSSEAP_STATE_ACCEPTOR_EXTS, - 1, /* critical */ - 1, /* required */ + 0, eapGssSmInitCompleteAcceptorExts } }; @@ -837,6 +914,7 @@ gss_init_sec_context(OM_uint32 *minor, { OM_uint32 major, tmpMinor; gss_ctx_id_t ctx = *context_handle; + int initialContextToken = 0; *minor = 0; @@ -854,6 +932,7 @@ gss_init_sec_context(OM_uint32 *minor, return major; ctx->flags |= CTX_FLAG_INITIATOR; + initialContextToken = 1; *context_handle = ctx; } @@ -880,13 +959,19 @@ gss_init_sec_context(OM_uint32 *minor, GSSEAP_MUTEX_LOCK(&cred->mutex); - if ((cred->flags & CRED_FLAG_INITIATE) == 0) { major = GSS_S_NO_CRED; *minor = GSSEAP_CRED_USAGE_MISMATCH; goto cleanup; } + if (initialContextToken) { + major = initBegin(minor, cred, ctx, target_name, mech_type, + req_flags, time_req, input_chan_bindings); + if (GSS_ERROR(major)) + goto cleanup; + } + major = gssEapSmStep(minor, cred, ctx, @@ -903,15 +988,21 @@ gss_init_sec_context(OM_uint32 *minor, goto cleanup; if (actual_mech_type != NULL) { - if (!gssEapInternalizeOid(ctx->mechanismUsed, actual_mech_type)) - duplicateOid(&tmpMinor, ctx->mechanismUsed, actual_mech_type); + OM_uint32 tmpMajor; + + tmpMajor = gssEapCanonicalizeOid(&tmpMinor, ctx->mechanismUsed, 0, actual_mech_type); + if (GSS_ERROR(tmpMajor)) { + major = tmpMajor; + *minor = tmpMinor; + goto cleanup; + } } if (ret_flags != NULL) *ret_flags = ctx->gssFlags; if (time_rec != NULL) gssEapContextTime(&tmpMinor, ctx, time_rec); - assert(ctx->state == GSSEAP_STATE_ESTABLISHED || major == GSS_S_CONTINUE_NEEDED); + assert(CTX_IS_ESTABLISHED(ctx) || major == GSS_S_CONTINUE_NEEDED); cleanup: if (cred != GSS_C_NO_CREDENTIAL)