X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=init_sec_context.c;h=3194f990b4e3da9dabeead0e225d519439d4b739;hb=refs%2Fheads%2Fjson-name;hp=4c8296464b33c9efa7a657696e4be2abfad0ee80;hpb=a8f5b12ce0b0cb0fa928852dcaecf9a8012e4ef1;p=mech_eap.orig diff --git a/init_sec_context.c b/init_sec_context.c index 4c82964..3194f99 100644 --- a/init_sec_context.c +++ b/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; @@ -464,7 +475,7 @@ eapGssSmInitGssReauth(OM_uint32 *minor, &ctx->kerberosCtx, mechTarget, (gss_OID)gss_mech_krb5, - reqFlags, + reqFlags | GSS_C_MUTUAL_FLAG, timeReq, chanBindings, inputToken, @@ -477,15 +488,15 @@ eapGssSmInitGssReauth(OM_uint32 *minor, ctx->gssFlags = gssFlags; - *smFlags |= SM_FLAG_STOP_EVAL; - 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; - gssEapSmTransition(ctx, GSSEAP_STATE_ESTABLISHED); + GSSEAP_SM_TRANSITION(ctx, GSSEAP_STATE_ESTABLISHED); } else { - gssEapSmTransition(ctx, GSSEAP_STATE_REAUTHENTICATE); + GSSEAP_SM_TRANSITION(ctx, GSSEAP_STATE_REAUTHENTICATE); } cleanup: @@ -498,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; @@ -520,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->kerberosCtx, 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, @@ -563,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; } @@ -574,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) { @@ -618,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; @@ -642,6 +704,8 @@ cleanup: major = tmpMajor; *minor = tmpMinor; } + + *smFlags |= SM_FLAG_OUTPUT_TOKEN_CRITICAL; } wpabuf_set(&ctx->initiatorCtx.reqData, NULL, 0); @@ -652,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) { @@ -677,6 +741,8 @@ eapGssSmInitGssChannelBindings(OM_uint32 *minor, assert(outputToken->value != NULL); *minor = 0; + *smFlags |= SM_FLAG_OUTPUT_TOKEN_CRITICAL; + return GSS_S_CONTINUE_NEEDED; } @@ -685,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; @@ -707,41 +775,41 @@ eapGssSmInitReauthCreds(OM_uint32 *minor, static OM_uint32 eapGssSmInitCompleteInitiatorExts(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) { - *minor = 0; + GSSEAP_SM_TRANSITION_NEXT(ctx); - *smFlags |= SM_FLAG_TRANSITION | SM_FLAG_STOP_EVAL; + *minor = 0; + *smFlags |= SM_FLAG_FORCE_SEND_TOKEN; return GSS_S_CONTINUE_NEEDED; } static OM_uint32 eapGssSmInitCompleteAcceptorExts(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, - OM_uint32 *smFlags) + 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) { - *minor = 0; + GSSEAP_SM_TRANSITION(ctx, GSSEAP_STATE_ESTABLISHED); - gssEapSmTransition(ctx, GSSEAP_STATE_ESTABLISHED); - *smFlags |= SM_FLAG_STOP_EVAL; + *minor = 0; return GSS_S_COMPLETE; } @@ -751,8 +819,15 @@ static struct gss_eap_sm eapGssInitiatorSm[] = { ITOK_TYPE_CONTEXT_ERR, ITOK_TYPE_NONE, GSSEAP_STATE_ALL & ~(GSSEAP_STATE_INITIAL), - SM_ITOK_FLAG_CRITICAL, - eapGssSmInitError, + 0, + eapGssSmInitError + }, + { + ITOK_TYPE_ACCEPTOR_NAME_RESP, + ITOK_TYPE_ACCEPTOR_NAME_REQ, + GSSEAP_STATE_INITIAL | GSSEAP_STATE_AUTHENTICATE, + 0, + eapGssSmInitAcceptorName }, #ifdef GSSEAP_DEBUG { @@ -760,7 +835,7 @@ static struct gss_eap_sm eapGssInitiatorSm[] = { ITOK_TYPE_VENDOR_INFO, GSSEAP_STATE_INITIAL, 0, - eapGssSmInitVendorInfo, + eapGssSmInitVendorInfo }, #endif #ifdef GSSEAP_ENABLE_REAUTH @@ -769,29 +844,32 @@ static struct gss_eap_sm eapGssInitiatorSm[] = { ITOK_TYPE_REAUTH_REQ, GSSEAP_STATE_INITIAL | GSSEAP_STATE_REAUTHENTICATE, 0, - eapGssSmInitGssReauth, + eapGssSmInitGssReauth }, #endif { ITOK_TYPE_NONE, ITOK_TYPE_NONE, +#ifdef GSSEAP_ENABLE_REAUTH + GSSEAP_STATE_REAUTHENTICATE | +#endif GSSEAP_STATE_INITIAL, - SM_ITOK_FLAG_CRITICAL | SM_ITOK_FLAG_REQUIRED, - eapGssSmInitIdentity, + SM_ITOK_FLAG_REQUIRED, + eapGssSmInitIdentity }, { ITOK_TYPE_EAP_REQ, ITOK_TYPE_EAP_RESP, GSSEAP_STATE_AUTHENTICATE, - SM_ITOK_FLAG_CRITICAL | SM_ITOK_FLAG_REQUIRED, - eapGssSmInitAuthenticate, + SM_ITOK_FLAG_REQUIRED, + eapGssSmInitAuthenticate }, { ITOK_TYPE_NONE, ITOK_TYPE_GSS_CHANNEL_BINDINGS, GSSEAP_STATE_INITIATOR_EXTS, - SM_ITOK_FLAG_CRITICAL | SM_ITOK_FLAG_REQUIRED, - eapGssSmInitGssChannelBindings, + SM_ITOK_FLAG_REQUIRED, + eapGssSmInitGssChannelBindings }, { ITOK_TYPE_NONE, @@ -806,7 +884,7 @@ static struct gss_eap_sm eapGssInitiatorSm[] = { ITOK_TYPE_NONE, GSSEAP_STATE_ACCEPTOR_EXTS, 0, - eapGssSmInitReauthCreds, + eapGssSmInitReauthCreds }, #endif /* other extensions go here */ @@ -836,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; @@ -853,6 +932,7 @@ gss_init_sec_context(OM_uint32 *minor, return major; ctx->flags |= CTX_FLAG_INITIATOR; + initialContextToken = 1; *context_handle = ctx; } @@ -879,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, @@ -902,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)