X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=util_context.c;h=0020ef6643c62acdb9954ec97f6640734d775445;hb=7db57acddeddad5f96d16288b3776baf6c10c0b1;hp=7121d7ff5995cc95e6b32c94883788c40f9cd83b;hpb=6800e2157097202a9e1e8ff414fb484ef4607bde;p=mech_eap.orig diff --git a/util_context.c b/util_context.c index 7121d7f..0020ef6 100644 --- a/util_context.c +++ b/util_context.c @@ -30,6 +30,10 @@ * SUCH DAMAGE. */ +/* + * Utility routines for context handles. + */ + #include "gssapiP_eap.h" OM_uint32 @@ -47,56 +51,87 @@ gssEapAllocContext(OM_uint32 *minor, return GSS_S_FAILURE; } - *minor = krb5_init_context(&ctx->kerberosCtx); - if (*minor != 0) { + if (GSSEAP_MUTEX_INIT(&ctx->mutex) != 0) { + *minor = errno; gssEapReleaseContext(&tmpMinor, &ctx); return GSS_S_FAILURE; } + ctx->state = GSSEAP_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; return GSS_S_COMPLETE; } static void -releaseInitiatorContext(struct eap_gss_initiator_ctx *ctx) +releaseInitiatorContext(struct gss_eap_initiator_ctx *ctx) { 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->radContext != NULL) + rs_context_destroy(ctx->radContext); + if (ctx->radServer != NULL) + GSSEAP_FREE(ctx->radServer); + gss_release_buffer(&tmpMinor, &ctx->state); + if (ctx->vps != NULL) + gssEapRadiusFreeAvps(&tmpMinor, &ctx->vps); } 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; if (ctx == GSS_C_NO_CONTEXT) { return GSS_S_COMPLETE; } + gssEapKerberosInit(&tmpMinor, &krbContext); + +#ifdef GSSEAP_ENABLE_REAUTH + if (ctx->flags & CTX_FLAG_KRB_REAUTH) { + gssDeleteSecContext(&tmpMinor, &ctx->kerberosCtx, GSS_C_NO_BUFFER); + } else +#endif if (CTX_IS_INITIATOR(ctx)) { releaseInitiatorContext(&ctx->initiatorCtx); } else { releaseAcceptorContext(&ctx->acceptorCtx); } - if (ctx->encryptionKey != NULL) { - krb5_free_keyblock(ctx->kerberosCtx, ctx->encryptionKey); - } - - if (ctx->kerberosCtx != NULL) { - krb5_free_context(ctx->kerberosCtx); - } - + krb5_free_keyblock_contents(krbContext, &ctx->rfc3961Key); gssEapReleaseName(&tmpMinor, &ctx->initiatorName); gssEapReleaseName(&tmpMinor, &ctx->acceptorName); + gssEapReleaseOid(&tmpMinor, &ctx->mechanismUsed); + sequenceFree(&tmpMinor, &ctx->seqState); + gssEapReleaseCred(&tmpMinor, &ctx->defaultCred); + + GSSEAP_MUTEX_DESTROY(&ctx->mutex); memset(ctx, 0, sizeof(*ctx)); GSSEAP_FREE(ctx); @@ -105,3 +140,95 @@ 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)) { + *minor = GSSEAP_WRONG_MECH; + 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; +}