X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=util_context.c;h=be422603a6a6d604de6d747db4f71d81f2439c13;hb=4866125c4be79ec72fc388eabba01505786850b4;hp=33324dee4134b644edaaa49027bbd046668e8f11;hpb=7f8be643b9781277f22ec8ad49e2280510975910;p=mech_eap.git diff --git a/util_context.c b/util_context.c index 33324de..be42260 100644 --- a/util_context.c +++ b/util_context.c @@ -53,7 +53,20 @@ gssEapAllocContext(OM_uint32 *minor, return GSS_S_FAILURE; } - ctx->state = EAP_STATE_AUTHENTICATE; + ctx->state = EAP_STATE_IDENTITY; + + /* + * Integrity, confidentiality, sequencing and replay detection are + * always available. Regardless of what flags are requested in + * GSS_Init_sec_context, implementations MUST set the flag corresponding + * to these services in the output of GSS_Init_sec_context and + * GSS_Accept_sec_context. + */ + ctx->gssFlags = GSS_C_TRANS_FLAG | /* exporting contexts */ + GSS_C_INTEG_FLAG | /* integrity */ + GSS_C_CONF_FLAG | /* confidentiality */ + GSS_C_SEQUENCE_FLAG | /* sequencing */ + GSS_C_REPLAY_FLAG; /* replay detection */ *pCtx = ctx; @@ -61,22 +74,35 @@ gssEapAllocContext(OM_uint32 *minor, } static void -releaseInitiatorContext(struct eap_gss_initiator_ctx *ctx) +releaseInitiatorContext(struct gss_eap_initiator_ctx *ctx) { + OM_uint32 minor; + + gssEapReleaseCred(&minor, &ctx->defaultCred); eap_peer_sm_deinit(ctx->eap); - wpabuf_free(ctx->eapReqData); } static void -releaseAcceptorContext(struct eap_gss_acceptor_ctx *ctx) +releaseAcceptorContext(struct gss_eap_acceptor_ctx *ctx) { + OM_uint32 tmpMinor; + + if (ctx->radConn != NULL) + rs_conn_destroy(ctx->radConn); + if (ctx->radHandle != NULL) + rs_context_destroy(ctx->radHandle); + if (ctx->radServer != NULL) + GSSEAP_FREE(ctx->radServer); + gss_release_buffer(&tmpMinor, &ctx->state); + if (ctx->avps != NULL) + pairfree(&ctx->avps); } OM_uint32 gssEapReleaseContext(OM_uint32 *minor, gss_ctx_id_t *pCtx) { - OM_uint32 major, tmpMinor; + OM_uint32 tmpMinor; gss_ctx_id_t ctx = *pCtx; krb5_context krbContext = NULL; @@ -86,6 +112,11 @@ gssEapReleaseContext(OM_uint32 *minor, gssEapKerberosInit(&tmpMinor, &krbContext); +#ifdef GSSEAP_ENABLE_REAUTH + if (ctx->flags & CTX_FLAG_KRB_REAUTH_GSS) { + gssDeleteSecContext(&tmpMinor, &ctx->kerberosCtx, GSS_C_NO_BUFFER); + } else +#endif if (CTX_IS_INITIATOR(ctx)) { releaseInitiatorContext(&ctx->initiatorCtx); } else { @@ -96,7 +127,7 @@ gssEapReleaseContext(OM_uint32 *minor, gssEapReleaseName(&tmpMinor, &ctx->initiatorName); gssEapReleaseName(&tmpMinor, &ctx->acceptorName); gss_release_oid(&tmpMinor, &ctx->mechanismUsed); - sequenceFree(ctx->seqState); + sequenceFree(&tmpMinor, &ctx->seqState); GSSEAP_MUTEX_DESTROY(&ctx->mutex); @@ -107,3 +138,93 @@ gssEapReleaseContext(OM_uint32 *minor, *minor = 0; return GSS_S_COMPLETE; } + +OM_uint32 +gssEapMakeToken(OM_uint32 *minor, + gss_ctx_id_t ctx, + const gss_buffer_t innerToken, + enum gss_eap_token_type tokenType, + gss_buffer_t outputToken) +{ + unsigned char *p; + + outputToken->length = tokenSize(ctx->mechanismUsed, innerToken->length); + outputToken->value = GSSEAP_MALLOC(outputToken->length); + if (outputToken->value == NULL) { + *minor = ENOMEM; + return GSS_S_FAILURE; + } + + p = (unsigned char *)outputToken->value; + makeTokenHeader(ctx->mechanismUsed, innerToken->length, &p, tokenType); + memcpy(p, innerToken->value, innerToken->length); + + *minor = 0; + return GSS_S_COMPLETE; +} + +OM_uint32 +gssEapVerifyToken(OM_uint32 *minor, + gss_ctx_id_t ctx, + const gss_buffer_t inputToken, + enum gss_eap_token_type *actualToken, + gss_buffer_t innerInputToken) +{ + OM_uint32 major; + size_t bodySize; + unsigned char *p = (unsigned char *)inputToken->value; + gss_OID_desc oidBuf; + gss_OID oid; + + if (ctx->mechanismUsed != GSS_C_NO_OID) { + oid = ctx->mechanismUsed; + } else { + oidBuf.elements = NULL; + oidBuf.length = 0; + oid = &oidBuf; + } + + major = verifyTokenHeader(minor, oid, &bodySize, &p, + inputToken->length, actualToken); + if (GSS_ERROR(major)) + return major; + + if (ctx->mechanismUsed == GSS_C_NO_OID) { + if (!gssEapIsConcreteMechanismOid(oid)) + return GSS_S_BAD_MECH; + + if (!gssEapInternalizeOid(oid, &ctx->mechanismUsed)) { + major = duplicateOid(minor, oid, &ctx->mechanismUsed); + if (GSS_ERROR(major)) + return major; + } + } + + innerInputToken->length = bodySize; + innerInputToken->value = p; + + *minor = 0; + return GSS_S_COMPLETE; +} + +OM_uint32 +gssEapContextTime(OM_uint32 *minor, + gss_ctx_id_t context_handle, + OM_uint32 *time_rec) +{ + if (context_handle->expiryTime == 0) { + *time_rec = GSS_C_INDEFINITE; + } else { + time_t now, lifetime; + + time(&now); + lifetime = context_handle->expiryTime - now; + if (lifetime <= 0) { + *time_rec = 0; + return GSS_S_CONTEXT_EXPIRED; + } + *time_rec = lifetime; + } + + return GSS_S_COMPLETE; +}