OM_uint32 gssEapReleaseCred(OM_uint32 *minor, gss_cred_id_t *pCred) { OM_uint32 tmpMinor; gss_cred_id_t cred = *pCred; if (cred == GSS_C_NO_CREDENTIAL) { return GSS_S_COMPLETE; } gssEapReleaseName(&tmpMinor, &cred->name); gssEapReleaseName(&tmpMinor, &cred->target); zeroAndReleasePassword(&cred->password); #ifndef MECH_EAP zeroAndReleasePassword(&cred->deleg_assertions); #endif gss_release_buffer(&tmpMinor, &cred->radiusConfigFile); gss_release_buffer(&tmpMinor, &cred->radiusConfigStanza); gss_release_buffer(&tmpMinor, &cred->caCertificate); gss_release_buffer(&tmpMinor, &cred->subjectNameConstraint); gss_release_buffer(&tmpMinor, &cred->subjectAltNameConstraint); GSSEAP_MUTEX_DESTROY(&cred->mutex); memset(cred, 0, sizeof(*cred)); GSSEAP_FREE(cred); *pCred = NULL; *minor = 0; return GSS_S_COMPLETE; }
OM_uint32 gssEapSetCredService(OM_uint32 *minor, gss_cred_id_t cred, const gss_name_t target) { OM_uint32 major, tmpMinor; gss_name_t newTarget = GSS_C_NO_NAME; if (cred->flags & CRED_FLAG_RESOLVED) { major = GSS_S_FAILURE; *minor = GSSEAP_CRED_RESOLVED; goto cleanup; } if (target != GSS_C_NO_NAME) { major = gssEapDuplicateName(minor, target, &newTarget); if (GSS_ERROR(major)) goto cleanup; cred->flags |= CRED_FLAG_TARGET; } else { cred->flags &= ~(CRED_FLAG_TARGET); } gssEapReleaseName(&tmpMinor, &cred->target); cred->target = newTarget; major = GSS_S_COMPLETE; *minor = 0; cleanup: return major; }
/* * Mark an acceptor context as ready for cryptographic operations */ static OM_uint32 acceptReadyEap(OM_uint32 *minor, gss_ctx_id_t ctx, gss_cred_id_t cred) { OM_uint32 major, tmpMinor; VALUE_PAIR *vp; gss_buffer_desc nameBuf = GSS_C_EMPTY_BUFFER; gssEapReleaseName(&tmpMinor, &ctx->initiatorName); major = gssEapRadiusGetRawAvp(minor, ctx->acceptorCtx.vps, PW_USER_NAME, 0, &vp); if (major == GSS_S_COMPLETE && vp->length) { nameBuf.length = vp->length; nameBuf.value = vp->vp_strvalue; } else { ctx->gssFlags |= GSS_C_ANON_FLAG; } major = gssEapImportName(minor, &nameBuf, (ctx->gssFlags & GSS_C_ANON_FLAG) ? GSS_C_NT_ANONYMOUS : GSS_C_NT_USER_NAME, ctx->mechanismUsed, &ctx->initiatorName); if (GSS_ERROR(major)) return major; major = gssEapRadiusGetRawAvp(minor, ctx->acceptorCtx.vps, PW_MS_MPPE_SEND_KEY, VENDORPEC_MS, &vp); if (GSS_ERROR(major)) { *minor = GSSEAP_KEY_UNAVAILABLE; return GSS_S_UNAVAILABLE; } major = sequenceInit(minor, &ctx->seqState, ctx->recvSeq, ((ctx->gssFlags & GSS_C_REPLAY_FLAG) != 0), ((ctx->gssFlags & GSS_C_SEQUENCE_FLAG) != 0), TRUE); if (GSS_ERROR(major)) return major; major = gssEapCreateAttrContext(minor, cred, ctx, &ctx->initiatorName->attrCtx, &ctx->expiryTime); if (GSS_ERROR(major)) return major; if (ctx->expiryTime != 0 && ctx->expiryTime < time(NULL)) { *minor = GSSEAP_CRED_EXPIRED; return GSS_S_CREDENTIALS_EXPIRED; } *minor = 0; return GSS_S_COMPLETE; }
static OM_uint32 staticIdentityFileResolveInitiatorCred(OM_uint32 *minor, gss_cred_id_t cred) { OM_uint32 major, tmpMinor; gss_buffer_desc defaultIdentity = GSS_C_EMPTY_BUFFER; gss_name_t defaultIdentityName = GSS_C_NO_NAME; gss_buffer_desc defaultPassword = GSS_C_EMPTY_BUFFER; int isDefaultIdentity = 0; major = readStaticIdentityFile(minor, &defaultIdentity, &defaultPassword); if (GSS_ERROR(major)) goto cleanup; major = gssEapImportName(minor, &defaultIdentity, GSS_C_NT_USER_NAME, gssEapPrimaryMechForCred(cred), &defaultIdentityName); if (GSS_ERROR(major)) goto cleanup; if (defaultIdentityName == GSS_C_NO_NAME) { if (cred->name == GSS_C_NO_NAME) { major = GSS_S_CRED_UNAVAIL; *minor = GSSEAP_NO_DEFAULT_IDENTITY; goto cleanup; } } else { if (cred->name == GSS_C_NO_NAME) { cred->name = defaultIdentityName; defaultIdentityName = GSS_C_NO_NAME; isDefaultIdentity = 1; } else { major = gssEapCompareName(minor, cred->name, defaultIdentityName, &isDefaultIdentity); if (GSS_ERROR(major)) goto cleanup; } } if (isDefaultIdentity && (cred->flags & CRED_FLAG_PASSWORD) == 0) { major = gssEapSetCredPassword(minor, cred, &defaultPassword); if (GSS_ERROR(major)) goto cleanup; } cleanup: gssEapReleaseName(&tmpMinor, &defaultIdentityName); zeroAndReleasePassword(&defaultPassword); gss_release_buffer(&tmpMinor, &defaultIdentity); return major; }
static OM_uint32 importName(OM_uint32 *minor, gss_OID mech, unsigned char **pBuf, size_t *pRemain, gss_name_t *pName) { OM_uint32 major, tmpMinor, flags; unsigned char *p = *pBuf; size_t remain = *pRemain; gss_buffer_desc tmp; if (remain < 4) { *minor = GSSEAP_TOK_TRUNC; return GSS_S_DEFECTIVE_TOKEN; } tmp.length = load_uint32_be(p); if (tmp.length != 0) { if (remain - 4 < tmp.length) { *minor = GSSEAP_TOK_TRUNC; return GSS_S_DEFECTIVE_TOKEN; } tmp.value = p + 4; flags = EXPORT_NAME_FLAG_COMPOSITE; if (mech == GSS_C_NO_OID) flags |= EXPORT_NAME_FLAG_OID; major = gssEapImportNameInternal(minor, &tmp, pName, flags); if (GSS_ERROR(major)) return major; if ((flags & EXPORT_NAME_FLAG_OID) == 0) { major = gssEapCanonicalizeOid(minor, mech, 0, &(*pName)->mechanismUsed); if (GSS_ERROR(major)) { gssEapReleaseName(&tmpMinor, pName); return major; } } } *pBuf += 4 + tmp.length; *pRemain -= 4 + tmp.length; *minor = 0; return GSS_S_COMPLETE; }
OM_uint32 GSSAPI_CALLCONV gss_inquire_context(OM_uint32 *minor, #ifdef HAVE_HEIMDAL_VERSION gss_const_ctx_id_t ctx, #else gss_ctx_id_t ctx, #endif gss_name_t *src_name, gss_name_t *targ_name, OM_uint32 *lifetime_rec, gss_OID *mech_type, OM_uint32 *ctx_flags, int *locally_initiated, int *open) { OM_uint32 major, tmpMinor; if (ctx == GSS_C_NO_CONTEXT) { *minor = EINVAL; return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT; } GSSEAP_MUTEX_LOCK(&((gss_ctx_id_t)ctx)->mutex); if (src_name != NULL) { if (ctx->initiatorName != GSS_C_NO_NAME) { major = gssEapDuplicateName(minor, ctx->initiatorName, src_name); if (GSS_ERROR(major)) goto cleanup; } else *src_name = GSS_C_NO_NAME; } if (targ_name != NULL) { if (ctx->acceptorName != GSS_C_NO_NAME) { major = gssEapDuplicateName(minor, ctx->acceptorName, targ_name); if (GSS_ERROR(major)) goto cleanup; } else *targ_name = GSS_C_NO_NAME; } if (lifetime_rec != NULL) gssEapContextTime(&tmpMinor, ctx, lifetime_rec); if (mech_type != NULL) { major = gssEapCanonicalizeOid(minor, ctx->mechanismUsed, 0, mech_type); if (GSS_ERROR(major)) goto cleanup; } if (ctx_flags != NULL) { *ctx_flags = ctx->gssFlags; } if (locally_initiated != NULL) { *locally_initiated = CTX_IS_INITIATOR(ctx); } if (open != NULL) { *open = CTX_IS_ESTABLISHED(ctx); } major = GSS_S_COMPLETE; *minor = 0; cleanup: GSSEAP_MUTEX_UNLOCK(&((gss_ctx_id_t)ctx)->mutex); if (GSS_ERROR(major)) { gssEapReleaseName(&tmpMinor, src_name); gssEapReleaseName(&tmpMinor, targ_name); } return major; }
/* * Mark an acceptor context as ready for cryptographic operations */ static OM_uint32 acceptReadyEap(OM_uint32 *minor, gss_ctx_id_t ctx, gss_cred_id_t cred) { OM_uint32 major, tmpMinor; rs_const_avp *vp; gss_buffer_desc nameBuf = GSS_C_EMPTY_BUFFER; /* Cache encryption type derived from selected mechanism OID */ major = gssEapOidToEnctype(minor, ctx->mechanismUsed, &ctx->encryptionType); if (GSS_ERROR(major)) return major; gssEapReleaseName(&tmpMinor, &ctx->initiatorName); major = gssEapRadiusGetRawAvp(minor, ctx->acceptorCtx.vps, PW_USER_NAME, 0, &vp); if (major == GSS_S_COMPLETE && rs_avp_length(vp) != 0) { rs_avp_octets_value_byref((rs_avp *)vp, (unsigned char **)&nameBuf.value, &nameBuf.length); } else { ctx->gssFlags |= GSS_C_ANON_FLAG; } major = gssEapImportName(minor, &nameBuf, (ctx->gssFlags & GSS_C_ANON_FLAG) ? GSS_C_NT_ANONYMOUS : GSS_C_NT_USER_NAME, ctx->mechanismUsed, &ctx->initiatorName); if (GSS_ERROR(major)) return major; major = gssEapRadiusGetRawAvp(minor, ctx->acceptorCtx.vps, PW_MS_MPPE_SEND_KEY, VENDORPEC_MICROSOFT, &vp); if (GSS_ERROR(major)) { *minor = GSSEAP_KEY_UNAVAILABLE; return GSS_S_UNAVAILABLE; } major = gssEapDeriveRfc3961Key(minor, rs_avp_octets_value_const_ptr(vp), rs_avp_length(vp), ctx->encryptionType, &ctx->rfc3961Key); if (GSS_ERROR(major)) return major; major = rfc3961ChecksumTypeForKey(minor, &ctx->rfc3961Key, &ctx->checksumType); if (GSS_ERROR(major)) return major; major = sequenceInit(minor, &ctx->seqState, ctx->recvSeq, ((ctx->gssFlags & GSS_C_REPLAY_FLAG) != 0), ((ctx->gssFlags & GSS_C_SEQUENCE_FLAG) != 0), TRUE); if (GSS_ERROR(major)) return major; major = gssEapCreateAttrContext(minor, cred, ctx, &ctx->initiatorName->attrCtx, &ctx->expiryTime); if (GSS_ERROR(major)) return major; if (ctx->expiryTime != 0 && ctx->expiryTime < time(NULL)) { *minor = GSSEAP_CRED_EXPIRED; return GSS_S_CREDENTIALS_EXPIRED; } *minor = 0; return GSS_S_COMPLETE; }
/* * Mark an acceptor context as ready for cryptographic operations */ static OM_uint32 acceptReadyEap(OM_uint32 *minor, gss_ctx_id_t ctx, gss_cred_id_t cred) { OM_uint32 major, tmpMinor; #ifdef MECH_EAP VALUE_PAIR *vp; gss_buffer_desc nameBuf = GSS_C_EMPTY_BUFFER; /* Cache encryption type derived from selected mechanism OID */ major = gssEapOidToEnctype(minor, ctx->mechanismUsed, &ctx->encryptionType); #else /* Cache encryption type specified by IdP */ major = krbStringToEnctype(gl_encryption_type, &ctx->encryptionType); #endif if (GSS_ERROR(major)) return major; #ifdef MECH_EAP gssEapReleaseName(&tmpMinor, &ctx->initiatorName); major = gssEapRadiusGetRawAvp(minor, ctx->acceptorCtx.vps, PW_USER_NAME, 0, &vp); if (major == GSS_S_COMPLETE && vp->length) { nameBuf.length = vp->length; nameBuf.value = vp->vp_strvalue; } else { ctx->gssFlags |= GSS_C_ANON_FLAG; } major = gssEapImportName(minor, &nameBuf, (ctx->gssFlags & GSS_C_ANON_FLAG) ? GSS_C_NT_ANONYMOUS : GSS_C_NT_USER_NAME, ctx->mechanismUsed, &ctx->initiatorName); if (GSS_ERROR(major)) return major; major = gssEapRadiusGetRawAvp(minor, ctx->acceptorCtx.vps, PW_MS_MPPE_SEND_KEY, VENDORPEC_MS, &vp); if (GSS_ERROR(major)) { *minor = GSSEAP_KEY_UNAVAILABLE; return GSS_S_UNAVAILABLE; } major = gssEapDeriveRfc3961Key(minor, rs_avp_octets_value_const_ptr(vp), rs_avp_length(vp), ctx->encryptionType, &ctx->rfc3961Key); #else major = gssEapDeriveRfc3961Key(minor, gl_generated_key, strlen(gl_generated_key), ctx->encryptionType, &ctx->rfc3961Key); #endif if (GSS_ERROR(major)) return major; major = rfc3961ChecksumTypeForKey(minor, &ctx->rfc3961Key, &ctx->checksumType); if (GSS_ERROR(major)) return major; major = sequenceInit(minor, &ctx->seqState, ctx->recvSeq, ((ctx->gssFlags & GSS_C_REPLAY_FLAG) != 0), ((ctx->gssFlags & GSS_C_SEQUENCE_FLAG) != 0), TRUE); if (GSS_ERROR(major)) return major; #ifdef MECH_EAP major = gssEapCreateAttrContext(minor, cred, ctx, &ctx->initiatorName->attrCtx, &ctx->expiryTime); if (GSS_ERROR(major)) return major; #else ctx->expiryTime = 0; /* indefinite */ #endif if (ctx->expiryTime != 0 && ctx->expiryTime < time(NULL)) { *minor = GSSEAP_CRED_EXPIRED; return GSS_S_CREDENTIALS_EXPIRED; } #ifndef MECH_EAP ctx->gssFlags |= GSS_C_PROT_READY_FLAG; #endif *minor = 0; return GSS_S_COMPLETE; }