OM_uint32 GSSAPI_CALLCONV gss_export_sec_context(OM_uint32 *minor, gss_ctx_id_t *context_handle, gss_buffer_t interprocess_token) { OM_uint32 major, tmpMinor; gss_ctx_id_t ctx = *context_handle; interprocess_token->length = 0; interprocess_token->value = NULL; if (ctx == GSS_C_NO_CONTEXT) { *minor = EINVAL; return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT; } *minor = 0; GSSEAP_MUTEX_LOCK(&ctx->mutex); major = gssEapExportSecContext(minor, ctx, interprocess_token); if (GSS_ERROR(major)) { GSSEAP_MUTEX_UNLOCK(&ctx->mutex); return major; } *context_handle = GSS_C_NO_CONTEXT; GSSEAP_MUTEX_UNLOCK(&ctx->mutex); gssEapReleaseContext(&tmpMinor, &ctx); return GSS_S_COMPLETE; }
OM_uint32 GSSAPI_CALLCONV gss_pseudo_random(OM_uint32 *minor, gss_ctx_id_t ctx, int prf_key, const gss_buffer_t prf_in, ssize_t desired_output_len, gss_buffer_t prf_out) { OM_uint32 major; if (ctx == GSS_C_NO_CONTEXT) { *minor = EINVAL; return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT; } prf_out->length = 0; prf_out->value = NULL; *minor = 0; GSSEAP_MUTEX_LOCK(&ctx->mutex); if (!CTX_IS_ESTABLISHED(ctx)) { major = GSS_S_NO_CONTEXT; *minor = GSSEAP_CONTEXT_INCOMPLETE; goto cleanup; } prf_out->value = GSSEAP_MALLOC(desired_output_len); if (prf_out->value == NULL) { major = GSS_S_FAILURE; *minor = ENOMEM; goto cleanup; } prf_out->length = desired_output_len; major = gssEapPseudoRandom(minor, ctx, prf_key, prf_in, prf_out); cleanup: GSSEAP_MUTEX_UNLOCK(&ctx->mutex); return major; }
OM_uint32 GSSAPI_CALLCONV gss_inquire_cred_by_oid(OM_uint32 *minor, #ifdef HAVE_HEIMDAL_VERSION gss_const_cred_id_t cred_handle, #else const gss_cred_id_t cred_handle, #endif const gss_OID desired_object GSSEAP_UNUSED, gss_buffer_set_t *data_set) { OM_uint32 major; #if 0 int i; #endif *data_set = GSS_C_NO_BUFFER_SET; if (cred_handle == GSS_C_NO_CREDENTIAL) { *minor = EINVAL; return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CRED; } GSSEAP_MUTEX_LOCK(&((gss_cred_id_t)cred_handle)->mutex); major = GSS_S_UNAVAILABLE; *minor = GSSEAP_BAD_CRED_OPTION; #if 0 for (i = 0; i < sizeof(inquireCredOps) / sizeof(inquireCredOps[0]); i++) { if (oidEqual(&inquireCredOps[i].oid, desired_object)) { major = (*inquireCredOps[i].inquire)(minor, cred_handle, desired_object, data_set); break; } } #endif GSSEAP_MUTEX_UNLOCK(&((gss_cred_id_t)cred_handle)->mutex); return major; }
OM_uint32 GSSAPI_CALLCONV gss_inquire_sec_context_by_oid(OM_uint32 *minor, const gss_ctx_id_t ctx, const gss_OID desired_object, gss_buffer_set_t *data_set) { OM_uint32 major; int i; *data_set = GSS_C_NO_BUFFER_SET; GSSEAP_MUTEX_LOCK(&ctx->mutex); #if 0 if (!CTX_IS_ESTABLISHED(ctx)) { *minor = GSSEAP_CONTEXT_INCOMPLETE; major = GSS_S_NO_CONTEXT; goto cleanup; } #endif major = GSS_S_UNAVAILABLE; *minor = GSSEAP_BAD_CONTEXT_OPTION; for (i = 0; i < sizeof(inquireCtxOps) / sizeof(inquireCtxOps[0]); i++) { if (oidEqual(&inquireCtxOps[i].oid, desired_object)) { major = (*inquireCtxOps[i].inquire)(minor, ctx, desired_object, data_set); break; } } GSSEAP_MUTEX_UNLOCK(&ctx->mutex); return major; }
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; }
OM_uint32 gssEapAcquireCred(OM_uint32 *minor, const gss_name_t desiredName, OM_uint32 timeReq GSSEAP_UNUSED, const gss_OID_set desiredMechs, int credUsage, gss_cred_id_t *pCred, gss_OID_set *pActualMechs, OM_uint32 *timeRec) { OM_uint32 major, tmpMinor; gss_cred_id_t cred; /* XXX TODO validate with changed set_cred_option API */ *pCred = GSS_C_NO_CREDENTIAL; major = gssEapAllocCred(minor, &cred); if (GSS_ERROR(major)) goto cleanup; switch (credUsage) { case GSS_C_BOTH: cred->flags |= CRED_FLAG_INITIATE | CRED_FLAG_ACCEPT; break; case GSS_C_INITIATE: cred->flags |= CRED_FLAG_INITIATE; break; case GSS_C_ACCEPT: cred->flags |= CRED_FLAG_ACCEPT; break; default: major = GSS_S_FAILURE; *minor = GSSEAP_BAD_USAGE; goto cleanup; break; } major = gssEapValidateMechs(minor, desiredMechs); if (GSS_ERROR(major)) goto cleanup; major = duplicateOidSet(minor, desiredMechs, &cred->mechanisms); if (GSS_ERROR(major)) goto cleanup; if (desiredName != GSS_C_NO_NAME) { GSSEAP_MUTEX_LOCK(&desiredName->mutex); major = gssEapDuplicateName(minor, desiredName, &cred->name); if (GSS_ERROR(major)) { GSSEAP_MUTEX_UNLOCK(&desiredName->mutex); goto cleanup; } GSSEAP_MUTEX_UNLOCK(&desiredName->mutex); } #ifdef GSSEAP_ENABLE_ACCEPTOR if (cred->flags & CRED_FLAG_ACCEPT) { #ifdef MECH_EAP struct rs_context *radContext; major = gssEapCreateRadiusContext(minor, cred, &radContext); if (GSS_ERROR(major)) goto cleanup; rs_context_destroy(radContext); #endif } #endif if (pActualMechs != NULL) { major = duplicateOidSet(minor, cred->mechanisms, pActualMechs); if (GSS_ERROR(major)) goto cleanup; } if (timeRec != NULL) *timeRec = GSS_C_INDEFINITE; *pCred = cred; major = GSS_S_COMPLETE; *minor = 0; cleanup: if (GSS_ERROR(major)) gssEapReleaseCred(&tmpMinor, &cred); return major; }