X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=moonshot%2Fmech_eap%2Faccept_sec_context.c;h=e503477eb7293033569ef4b5f294287800d9f95b;hb=f8cc49e125b030bc7c81373984d12e54abc3cb11;hp=afbd55439d181a5ab785c86de798b1886e09ca79;hpb=5d9213b9b590926801deffb121ab8eb01eb858ad;p=moonshot.git diff --git a/moonshot/mech_eap/accept_sec_context.c b/moonshot/mech_eap/accept_sec_context.c index afbd554..e503477 100644 --- a/moonshot/mech_eap/accept_sec_context.c +++ b/moonshot/mech_eap/accept_sec_context.c @@ -328,7 +328,7 @@ setAcceptorIdentity(OM_uint32 *minor, krb5_principal krbPrinc; struct rs_context *rc = ctx->acceptorCtx.radContext; - assert(rc != NULL); + GSSEAP_ASSERT(rc != NULL); if (ctx->acceptorName == GSS_C_NO_NAME) { *minor = 0; @@ -343,8 +343,8 @@ setAcceptorIdentity(OM_uint32 *minor, GSSEAP_KRB_INIT(&krbContext); krbPrinc = ctx->acceptorName->krbPrincipal; - assert(krbPrinc != NULL); - assert(KRB_PRINC_LENGTH(krbPrinc) >= 2); + GSSEAP_ASSERT(krbPrinc != NULL); + GSSEAP_ASSERT(KRB_PRINC_LENGTH(krbPrinc) >= 2); /* Acceptor-Service-Name */ krbPrincComponentToGssBuffer(krbPrinc, 0, &nameBuf); @@ -418,58 +418,35 @@ createRadiusHandle(OM_uint32 *minor, gss_ctx_id_t ctx) { struct gss_eap_acceptor_ctx *actx = &ctx->acceptorCtx; - const char *configFile = RS_CONFIG_FILE; - const char *configStanza = "gss-eap"; - struct rs_alloc_scheme ralloc; struct rs_error *err; + const char *configStanza = "gss-eap"; + OM_uint32 major; - assert(actx->radContext == NULL); - assert(actx->radConn == NULL); + GSSEAP_ASSERT(actx->radContext == NULL); + GSSEAP_ASSERT(actx->radConn == NULL); + GSSEAP_ASSERT(cred != GSS_C_NO_CREDENTIAL); - if (rs_context_create(&actx->radContext) != 0) { - *minor = GSSEAP_RADSEC_CONTEXT_FAILURE; - return GSS_S_FAILURE; - } + major = gssEapCreateRadiusContext(minor, cred, &actx->radContext); + if (GSS_ERROR(major)) + return major; - if (cred->radiusConfigFile.value != NULL) - configFile = (const char *)cred->radiusConfigFile.value; if (cred->radiusConfigStanza.value != NULL) configStanza = (const char *)cred->radiusConfigStanza.value; - ralloc.calloc = GSSEAP_CALLOC; - ralloc.malloc = GSSEAP_MALLOC; - ralloc.free = GSSEAP_FREE; - ralloc.realloc = GSSEAP_REALLOC; - - rs_context_set_alloc_scheme(actx->radContext, &ralloc); - - if (rs_context_read_config(actx->radContext, configFile) != 0) { - err = rs_err_ctx_pop(actx->radContext); - goto fail; - } - - if (rs_context_init_freeradius_dict(actx->radContext, NULL) != 0) { - err = rs_err_ctx_pop(actx->radContext); - goto fail; - } - if (rs_conn_create(actx->radContext, &actx->radConn, configStanza) != 0) { err = rs_err_conn_pop(actx->radConn); - goto fail; + return gssEapRadiusMapError(minor, err); } if (actx->radServer != NULL) { if (rs_conn_select_peer(actx->radConn, actx->radServer) != 0) { err = rs_err_conn_pop(actx->radConn); - goto fail; + return gssEapRadiusMapError(minor, err); } } *minor = 0; return GSS_S_COMPLETE; - -fail: - return gssEapRadiusMapError(minor, err); } /* @@ -550,7 +527,7 @@ eapGssSmAcceptAuthenticate(OM_uint32 *minor, goto cleanup; } - assert(resp != NULL); + GSSEAP_ASSERT(resp != NULL); frresp = rs_packet_frpkt(resp); switch (frresp->code) { @@ -606,7 +583,7 @@ cleanup: if (resp != NULL) rs_packet_destroy(resp); if (GSSEAP_SM_STATE(ctx) == GSSEAP_STATE_INITIATOR_EXTS) { - assert(major == GSS_S_CONTINUE_NEEDED); + GSSEAP_ASSERT(major == GSS_S_CONTINUE_NEEDED); rs_conn_destroy(ctx->acceptorCtx.radConn); ctx->acceptorCtx.radConn = NULL; @@ -616,6 +593,40 @@ cleanup: } static OM_uint32 +eapGssSmAcceptGssFlags(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) +{ + unsigned char *p; + OM_uint32 initiatorGssFlags; + + GSSEAP_ASSERT((ctx->flags & CTX_FLAG_KRB_REAUTH) == 0); + + if (inputToken->length < 4) { + *minor = GSSEAP_TOK_TRUNC; + return GSS_S_DEFECTIVE_TOKEN; + } + + /* allow flags to grow for future expansion */ + p = (unsigned char *)inputToken->value + inputToken->length - 4; + + initiatorGssFlags = load_uint32_be(p); + initiatorGssFlags &= GSSEAP_WIRE_FLAGS_MASK; + + ctx->gssFlags |= initiatorGssFlags; + + return GSS_S_CONTINUE_NEEDED; +} + +static OM_uint32 eapGssSmAcceptGssChannelBindings(OM_uint32 *minor, gss_cred_id_t cred GSSEAP_UNUSED, gss_ctx_id_t ctx, @@ -628,20 +639,26 @@ eapGssSmAcceptGssChannelBindings(OM_uint32 *minor, gss_buffer_t outputToken GSSEAP_UNUSED, OM_uint32 *smFlags GSSEAP_UNUSED) { - OM_uint32 major, tmpMinor; + OM_uint32 major; gss_iov_buffer_desc iov[2]; iov[0].type = GSS_IOV_BUFFER_TYPE_DATA | GSS_IOV_BUFFER_FLAG_ALLOCATE; iov[0].buffer.length = 0; iov[0].buffer.value = NULL; - iov[1].type = GSS_IOV_BUFFER_TYPE_STREAM; - iov[1].buffer = *inputToken; + iov[1].type = GSS_IOV_BUFFER_TYPE_STREAM | GSS_IOV_BUFFER_FLAG_ALLOCATED; + + /* XXX necessary because decrypted in place and we verify it later */ + major = duplicateBuffer(minor, inputToken, &iov[1].buffer); + if (GSS_ERROR(major)) + return major; major = gssEapUnwrapOrVerifyMIC(minor, ctx, NULL, NULL, iov, 2, TOK_TYPE_WRAP); - if (GSS_ERROR(major)) + if (GSS_ERROR(major)) { + gssEapReleaseIov(iov, 2); return major; + } if (chanBindings != GSS_C_NO_CHANNEL_BINDINGS && !bufferEqual(&iov[0].buffer, &chanBindings->application_data)) { @@ -652,11 +669,36 @@ eapGssSmAcceptGssChannelBindings(OM_uint32 *minor, *minor = 0; } - gss_release_buffer(&tmpMinor, &iov[0].buffer); + gssEapReleaseIov(iov, 2); return major; } +static OM_uint32 +eapGssSmAcceptInitiatorMIC(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 = gssEapVerifyTokenMIC(minor, ctx, inputToken); + if (GSS_ERROR(major)) + return major; + + GSSEAP_SM_TRANSITION_NEXT(ctx); + + *minor = 0; + return GSS_S_CONTINUE_NEEDED; +} + #ifdef GSSEAP_ENABLE_REAUTH static OM_uint32 eapGssSmAcceptReauthCreds(OM_uint32 *minor, @@ -688,42 +730,28 @@ eapGssSmAcceptReauthCreds(OM_uint32 *minor, #endif static OM_uint32 -eapGssSmAcceptCompleteInitiatorExts(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) +eapGssSmAcceptAcceptorMIC(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_SM_TRANSITION_NEXT(ctx); - - *minor = 0; + OM_uint32 major; - return GSS_S_CONTINUE_NEEDED; -} + major = gssEapMakeTokenMIC(minor, ctx, outputToken); + if (GSS_ERROR(major)) + return major; -static OM_uint32 -eapGssSmAcceptCompleteAcceptorExts(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(ctx, GSSEAP_STATE_ESTABLISHED); *minor = 0; - *smFlags |= SM_FLAG_FORCE_SEND_TOKEN; + *smFlags |= SM_FLAG_OUTPUT_TOKEN_CRITICAL; return GSS_S_COMPLETE; } @@ -769,6 +797,13 @@ static struct gss_eap_sm eapGssAcceptorSm[] = { eapGssSmAcceptAuthenticate }, { + ITOK_TYPE_GSS_FLAGS, + ITOK_TYPE_NONE, + GSSEAP_STATE_INITIATOR_EXTS, + 0, + eapGssSmAcceptGssFlags + }, + { ITOK_TYPE_GSS_CHANNEL_BINDINGS, ITOK_TYPE_NONE, GSSEAP_STATE_INITIATOR_EXTS, @@ -776,11 +811,11 @@ static struct gss_eap_sm eapGssAcceptorSm[] = { eapGssSmAcceptGssChannelBindings, }, { - ITOK_TYPE_NONE, + ITOK_TYPE_INITIATOR_MIC, ITOK_TYPE_NONE, GSSEAP_STATE_INITIATOR_EXTS, - 0, - eapGssSmAcceptCompleteInitiatorExts, + SM_ITOK_FLAG_REQUIRED, + eapGssSmAcceptInitiatorMIC, }, #ifdef GSSEAP_ENABLE_REAUTH { @@ -793,16 +828,16 @@ static struct gss_eap_sm eapGssAcceptorSm[] = { #endif { ITOK_TYPE_NONE, - ITOK_TYPE_NONE, + ITOK_TYPE_ACCEPTOR_MIC, GSSEAP_STATE_ACCEPTOR_EXTS, 0, - eapGssSmAcceptCompleteAcceptorExts + eapGssSmAcceptAcceptorMIC }, }; OM_uint32 -gss_accept_sec_context(OM_uint32 *minor, - gss_ctx_id_t *context_handle, +gssEapAcceptSecContext(OM_uint32 *minor, + gss_ctx_id_t ctx, gss_cred_id_t cred, gss_buffer_t input_token, gss_channel_bindings_t input_chan_bindings, @@ -814,30 +849,6 @@ gss_accept_sec_context(OM_uint32 *minor, gss_cred_id_t *delegated_cred_handle) { OM_uint32 major, tmpMinor; - gss_ctx_id_t ctx = *context_handle; - - *minor = 0; - - output_token->length = 0; - output_token->value = NULL; - - if (src_name != NULL) - *src_name = GSS_C_NO_NAME; - - if (input_token == GSS_C_NO_BUFFER || input_token->length == 0) { - *minor = GSSEAP_TOK_TRUNC; - return GSS_S_DEFECTIVE_TOKEN; - } - - if (ctx == GSS_C_NO_CONTEXT) { - major = gssEapAllocContext(minor, &ctx); - if (GSS_ERROR(major)) - return major; - - *context_handle = ctx; - } - - GSSEAP_MUTEX_LOCK(&ctx->mutex); if (cred == GSS_C_NO_CREDENTIAL) { if (ctx->cred == GSS_C_NO_CREDENTIAL) { @@ -909,15 +920,11 @@ gss_accept_sec_context(OM_uint32 *minor, } } - assert(CTX_IS_ESTABLISHED(ctx) || major == GSS_S_CONTINUE_NEEDED); + GSSEAP_ASSERT(CTX_IS_ESTABLISHED(ctx) || major == GSS_S_CONTINUE_NEEDED); cleanup: if (cred != GSS_C_NO_CREDENTIAL) GSSEAP_MUTEX_UNLOCK(&cred->mutex); - GSSEAP_MUTEX_UNLOCK(&ctx->mutex); - - if (GSS_ERROR(major)) - gssEapReleaseContext(&tmpMinor, context_handle); return major; } @@ -1003,3 +1010,62 @@ eapGssSmAcceptGssReauth(OM_uint32 *minor, return major; } #endif /* GSSEAP_ENABLE_REAUTH */ + +OM_uint32 GSSAPI_CALLCONV +gss_accept_sec_context(OM_uint32 *minor, + gss_ctx_id_t *context_handle, + gss_cred_id_t cred, + gss_buffer_t input_token, + gss_channel_bindings_t input_chan_bindings, + gss_name_t *src_name, + gss_OID *mech_type, + gss_buffer_t output_token, + OM_uint32 *ret_flags, + OM_uint32 *time_rec, + gss_cred_id_t *delegated_cred_handle) +{ + OM_uint32 major, tmpMinor; + gss_ctx_id_t ctx = *context_handle; + + *minor = 0; + + output_token->length = 0; + output_token->value = NULL; + + if (src_name != NULL) + *src_name = GSS_C_NO_NAME; + + if (input_token == GSS_C_NO_BUFFER || input_token->length == 0) { + *minor = GSSEAP_TOK_TRUNC; + return GSS_S_DEFECTIVE_TOKEN; + } + + if (ctx == GSS_C_NO_CONTEXT) { + major = gssEapAllocContext(minor, &ctx); + if (GSS_ERROR(major)) + return major; + + *context_handle = ctx; + } + + GSSEAP_MUTEX_LOCK(&ctx->mutex); + + major = gssEapAcceptSecContext(minor, + ctx, + cred, + input_token, + input_chan_bindings, + src_name, + mech_type, + output_token, + ret_flags, + time_rec, + delegated_cred_handle); + + GSSEAP_MUTEX_UNLOCK(&ctx->mutex); + + if (GSS_ERROR(major)) + gssEapReleaseContext(&tmpMinor, context_handle); + + return major; +}