Path: blob/main/crypto/krb5/src/lib/gssapi/mechglue/g_mechattr.c
39586 views
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */1/* lib/gssapi/mechglue/g_mechattr.c */2/*3* Copyright (C) 2010 by the Massachusetts Institute of Technology.4* All rights reserved.5*6* Export of this software from the United States of America may7* require a specific license from the United States Government.8* It is the responsibility of any person or organization contemplating9* export to obtain such a license before exporting.10*11* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and12* distribute this software and its documentation for any purpose and13* without fee is hereby granted, provided that the above copyright14* notice appear in all copies and that both that copyright notice and15* this permission notice appear in supporting documentation, and that16* the name of M.I.T. not be used in advertising or publicity pertaining17* to distribution of the software without specific, written prior18* permission. Furthermore if you modify this software you must label19* your software as modified software and not distribute it in such a20* fashion that it might be confused with the original M.I.T. software.21* M.I.T. makes no representations about the suitability of22* this software for any purpose. It is provided "as is" without express23* or implied warranty.24*/2526#include "mglueP.h"2728static int29testMechAttr(gss_const_OID attr,30gss_const_OID_set against)31{32int present = 0;33OM_uint32 minor;3435if (GSS_ERROR(generic_gss_test_oid_set_member(&minor, attr,36(gss_OID_set)against,37&present)))38return 0;3940return present;41}4243/*44* Return TRUE iff all the elements of desired and none of the elements45* of except exist in available.46*/47static int48testMechAttrsOffered(gss_const_OID_set desired,49gss_const_OID_set except,50gss_const_OID_set available)51{52size_t i;5354if (desired != GSS_C_NO_OID_SET) {55for (i = 0; i < desired->count; i++) {56if (!testMechAttr(&desired->elements[i], available))57return 0;58}59}6061if (except != GSS_C_NO_OID_SET) {62for (i = 0; i < except->count; i++) {63if (testMechAttr(&except->elements[i], available))64return 0;65}66}6768return 1;69}7071/*72* Return TRUE iff all the elements of critical exist in known.73*/74static int75testMechAttrsKnown(gss_const_OID_set critical,76gss_const_OID_set known)77{78size_t i;7980if (critical != GSS_C_NO_OID_SET) {81for (i = 0; i < critical->count; i++) {82if (!testMechAttr(&critical->elements[i], known))83return 0;84}85}8687return 1;88}8990OM_uint32 KRB5_CALLCONV91gss_indicate_mechs_by_attrs(92OM_uint32 *minor,93gss_const_OID_set desired_mech_attrs,94gss_const_OID_set except_mech_attrs,95gss_const_OID_set critical_mech_attrs,96gss_OID_set *mechs)97{98OM_uint32 status, tmpMinor;99gss_OID_set allMechs = GSS_C_NO_OID_SET;100size_t i;101102if (minor != NULL)103*minor = 0;104105if (mechs != NULL)106*mechs = GSS_C_NO_OID_SET;107108if (minor == NULL || mechs == NULL)109return GSS_S_CALL_INACCESSIBLE_WRITE;110111status = gss_indicate_mechs(minor, &allMechs);112if (GSS_ERROR(status))113goto cleanup;114115status = generic_gss_create_empty_oid_set(minor, mechs);116if (GSS_ERROR(status))117goto cleanup;118119for (i = 0; i < allMechs->count; i++) {120gss_OID_set supportedAttrs = GSS_C_NO_OID_SET;121gss_OID_set knownAttrs = GSS_C_NO_OID_SET;122123status = gss_inquire_attrs_for_mech(minor, &allMechs->elements[i],124&supportedAttrs, &knownAttrs);125if (GSS_ERROR(status))126continue;127128if (testMechAttrsOffered(desired_mech_attrs,129except_mech_attrs, supportedAttrs) &&130testMechAttrsKnown(critical_mech_attrs, knownAttrs)) {131status = gss_add_oid_set_member(minor, &allMechs->elements[i],132mechs);133if (GSS_ERROR(status)) {134gss_release_oid_set(&tmpMinor, &supportedAttrs);135gss_release_oid_set(&tmpMinor, &knownAttrs);136goto cleanup;137}138}139140gss_release_oid_set(&tmpMinor, &supportedAttrs);141gss_release_oid_set(&tmpMinor, &knownAttrs);142}143144*minor = 0;145status = GSS_S_COMPLETE;146147cleanup:148gss_release_oid_set(&tmpMinor, &allMechs);149150return status;151}152153OM_uint32 KRB5_CALLCONV154gss_inquire_attrs_for_mech(155OM_uint32 *minor,156gss_const_OID mech_oid,157gss_OID_set *mech_attrs,158gss_OID_set *known_mech_attrs)159{160OM_uint32 status, tmpMinor;161gss_OID selected_mech, public_mech;162gss_mechanism mech;163164if (minor != NULL)165*minor = 0;166167if (mech_attrs != NULL)168*mech_attrs = GSS_C_NO_OID_SET;169170if (known_mech_attrs != NULL)171*known_mech_attrs = GSS_C_NO_OID_SET;172173if (minor == NULL)174return GSS_S_CALL_INACCESSIBLE_WRITE;175176status = gssint_select_mech_type(minor, mech_oid, &selected_mech);177if (status != GSS_S_COMPLETE)178return status;179180mech = gssint_get_mechanism(selected_mech);181if (mech == NULL)182return GSS_S_BAD_MECH;183184if (mech->gss_inquire_attrs_for_mech != NULL) {185public_mech = gssint_get_public_oid(selected_mech);186status = mech->gss_inquire_attrs_for_mech(minor, public_mech,187mech_attrs,188known_mech_attrs);189if (GSS_ERROR(status)) {190map_error(minor, mech);191return status;192}193}194195/* Make sure *mech_attrs is a proper OID set, as GSS_C_NO_OID_SET is not196* accepted by gss_test_oid_set_member(). */197if (mech_attrs != NULL && *mech_attrs == GSS_C_NO_OID_SET) {198status = generic_gss_create_empty_oid_set(minor, mech_attrs);199if (status != GSS_S_COMPLETE) {200if (known_mech_attrs != NULL)201gss_release_oid_set(&tmpMinor, known_mech_attrs);202return status;203}204}205206if (known_mech_attrs != NULL && *known_mech_attrs == GSS_C_NO_OID_SET) {207if (mech->gss_inquire_attrs_for_mech != NULL) {208/* A mech can leave *known_mech_attrs alone as shorthand for209* understanding the RFC 5587 attribute set. */210status = generic_gss_copy_oid_set(minor,211gss_ma_known_attrs,212known_mech_attrs);213} else {214/* The mech does not implement RFC 5587. Indicate that it doesn't215* know about any attributes. */216status = generic_gss_create_empty_oid_set(minor, known_mech_attrs);217}218if (GSS_ERROR(status)) {219gss_release_oid_set(&tmpMinor, mech_attrs);220if (mech_attrs != NULL)221*mech_attrs = GSS_C_NO_OID_SET;222}223}224225return GSS_S_COMPLETE;226}227228OM_uint32 KRB5_CALLCONV229gss_display_mech_attr(230OM_uint32 *minor,231gss_const_OID mech_attr,232gss_buffer_t name,233gss_buffer_t short_desc,234gss_buffer_t long_desc)235{236return generic_gss_display_mech_attr(minor, mech_attr,237name, short_desc, long_desc);238}239240241