From 6ca842c5b7f1e2ab78e0129620098c00472c3658 Mon Sep 17 00:00:00 2001 From: Love Hornquist Astrand Date: Thu, 25 Nov 2010 21:40:25 -0800 Subject: [PATCH] gss_indicate_mechs_by_attrs --- lib/gssapi/gssapi/gssapi.h | 6 +-- lib/gssapi/gssapi/gssapi_oid.h | 24 +++------- lib/gssapi/gssapi_mech.h | 4 ++ lib/gssapi/krb5/external.c | 38 ++++++++++++++- lib/gssapi/mech/gss_mo.c | 88 ++++++++++++++++++++++++++++------ lib/gssapi/mech/gss_oid.c | 5 ++ lib/gssapi/oid.txt | 4 +- lib/gssapi/spnego/external.c | 3 -- 8 files changed, 131 insertions(+), 41 deletions(-) diff --git a/lib/gssapi/gssapi/gssapi.h b/lib/gssapi/gssapi/gssapi.h index d052277bc..12833ebe1 100644 --- a/lib/gssapi/gssapi/gssapi.h +++ b/lib/gssapi/gssapi/gssapi.h @@ -937,11 +937,11 @@ gss_import_cred(OM_uint32 * /* minor_status */, * mech option */ -GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +GSSAPI_LIB_FUNCTION int GSSAPI_LIB_CALL gss_mo_set(gss_const_OID mech, gss_const_OID option, int enable, gss_buffer_t value); -GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +GSSAPI_LIB_FUNCTION int GSSAPI_LIB_CALL gss_mo_get(gss_const_OID mech, gss_const_OID option, gss_buffer_t value); GSSAPI_LIB_FUNCTION void GSSAPI_LIB_CALL @@ -971,7 +971,7 @@ gss_indicate_mechs_by_attrs(OM_uint32 * minor_status, gss_const_OID_set desired_mech_attrs, gss_const_OID_set except_mech_attrs, gss_const_OID_set critical_mech_attrs, - gss_OID_set mechs); + gss_OID_set *mechs); GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_inquire_attrs_for_mech(OM_uint32 * minor_status, diff --git a/lib/gssapi/gssapi/gssapi_oid.h b/lib/gssapi/gssapi/gssapi_oid.h index b9dda2e33..2aa30b3ef 100644 --- a/lib/gssapi/gssapi/gssapi_oid.h +++ b/lib/gssapi/gssapi/gssapi_oid.h @@ -125,20 +125,7 @@ extern gss_OID_desc __gss_sasl_digest_md5_mechanism_oid_desc; #define GSS_SASL_DIGEST_MD5_MECHANISM (&__gss_sasl_digest_md5_mechanism_oid_desc) /* - * To support ongoing experimentation, testing, and evolution of the - * specification, the Kerberos V5 GSS-API mechanism as defined in this - * and any successor memos will be identified with the following Object - * Identifier, as defined in RFC-1510, until the specification is - * advanced to the level of Proposed Standard RFC: - * - * {iso(1), org(3), dod(5), internet(1), security(5), kerberosv5(2)} - * - * Upon advancement to the level of Proposed Standard RFC, the Kerberos - * V5 GSS-API mechanism will be identified by an Object Identifier - * having the value: - * - * {iso(1) member-body(2) United States(840) mit(113554) infosys(1) - * gssapi(2) krb5(2)} + * "Standard" mechs */ extern gss_OID_desc __gss_krb5_mechanism_oid_desc; #define GSS_KRB5_MECHANISM (&__gss_krb5_mechanism_oid_desc) @@ -146,11 +133,14 @@ extern gss_OID_desc __gss_krb5_mechanism_oid_desc; extern gss_OID_desc __gss_ntlm_mechanism_oid_desc; #define GSS_NTLM_MECHANISM (&__gss_ntlm_mechanism_oid_desc) +extern gss_OID_desc __gss_spnego_mechanism_oid_desc; +#define GSS_SPNEGO_MECHANISM (&__gss_spnego_mechanism_oid_desc) + /* From Luke Howard */ extern gss_OID_desc __gss_c_peer_has_updated_spnego_oid_desc; #define GSS_C_PEER_HAS_UPDATED_SPNEGO (&__gss_c_peer_has_updated_spnego_oid_desc) - /* - * OID mappings with name and short description and and slightly longer description - */ +/* + * OID mappings with name and short description and and slightly longer description + */ #endif /* GSSAPI_GSSAPI_OID */ diff --git a/lib/gssapi/gssapi_mech.h b/lib/gssapi/gssapi_mech.h index a1370ad8a..fd989e0f0 100644 --- a/lib/gssapi/gssapi_mech.h +++ b/lib/gssapi/gssapi_mech.h @@ -401,6 +401,9 @@ struct gss_mo_desc_struct { void *ctx; int (*get)(gss_const_OID, gss_mo_desc *, gss_buffer_t); int (*set)(gss_const_OID, gss_mo_desc *, int, gss_buffer_t); + OM_uint32 flags; +#define GSS_MO_MA 1 +#define GSS_MO_MA_CRITICAL 2 }; @@ -477,6 +480,7 @@ void gss_mg_collect_error(gss_OID, OM_uint32, OM_uint32); int _gss_mo_get_option_1(gss_const_OID, gss_mo_desc *, gss_buffer_t); int _gss_mo_get_option_0(gss_const_OID, gss_mo_desc *, gss_buffer_t); +int _gss_mo_get_ctx_as_string(gss_const_OID, gss_mo_desc *, gss_buffer_t); struct _gss_oid_name_table { gss_OID oid; diff --git a/lib/gssapi/krb5/external.c b/lib/gssapi/krb5/external.c index d08cadfcf..986adff78 100644 --- a/lib/gssapi/krb5/external.c +++ b/lib/gssapi/krb5/external.c @@ -175,6 +175,33 @@ gss_OID_desc GSSAPI_LIB_VARIABLE __gss_iakerb_min_msg_mechanism_oid_desc = * Context for krb5 calls. */ +static gss_mo_desc _gsskrb5_mech_options[] = { + { + GSS_MA_SASL_MECH_NAME, + "SASL mech name", + "GS2-KRB5", + _gss_mo_get_ctx_as_string, + NULL, + GSS_MO_MA + }, + { + GSS_MA_MECH_NAME, + "Mechanism name", + "KRB5", + _gss_mo_get_ctx_as_string, + NULL, + GSS_MO_MA, + }, + { + GSS_MA_MECH_DESCRIPTION, + "Mechanism description", + "Heimdal Kerberos 5 mech", + _gss_mo_get_ctx_as_string, + NULL, + GSS_MO_MA + } +}; + /* * */ @@ -223,7 +250,16 @@ static gssapi_mech_interface_desc krb5_mech = { _gk_wrap_iov_length, _gsskrb5_store_cred, _gsskrb5_export_cred, - _gsskrb5_import_cred + _gsskrb5_import_cred, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + _gsskrb5_mech_options, + sizeof(_gsskrb5_mech_options) / sizeof(_gsskrb5_mech_options[0]) }; gssapi_mech_interface diff --git a/lib/gssapi/mech/gss_mo.c b/lib/gssapi/mech/gss_mo.c index 4c36e27ce..1c4423fbd 100644 --- a/lib/gssapi/mech/gss_mo.c +++ b/lib/gssapi/mech/gss_mo.c @@ -55,7 +55,7 @@ _gss_mo_get_option_0(gss_const_OID mech, gss_mo_desc *mo, gss_buffer_t value) } int -_gss_mo_get_ctx_as_value(gss_const_OID mech, gss_mo_desc *mo, gss_buffer_t value) +_gss_mo_get_ctx_as_string(gss_const_OID mech, gss_mo_desc *mo, gss_buffer_t value) { if (value) { value->value = strdup((char *)mo->ctx); @@ -101,13 +101,14 @@ gss_mo_get(gss_const_OID mech, gss_const_OID option, gss_buffer_t value) } static void -add_all_mo(gssapi_mech_interface m, gss_OID_set *options) +add_all_mo(gssapi_mech_interface m, gss_OID_set *options, OM_uint32 mask) { OM_uint32 minor; size_t n; for (n = 0; n < m->gm_mo_num; n++) - gss_add_oid_set_member(&minor, m->gm_mo[n].option, options); + if ((m->gm_mo[n].flags & mask) == mask) + gss_add_oid_set_member(&minor, m->gm_mo[n].option, options); } GSSAPI_LIB_FUNCTION void GSSAPI_LIB_CALL @@ -128,7 +129,7 @@ gss_mo_list(gss_const_OID mech, gss_OID_set *options) if (major != GSS_S_COMPLETE) return; - add_all_mo(m, options); + add_all_mo(m, options, 0); } GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL @@ -240,6 +241,7 @@ gss_inquire_mech_for_saslname(OM_uint32 *minor_status, *mech_type = NULL; SLIST_FOREACH(m, &_gss_mechs, gm_link) { + major = mo_name(&m->gm_mech_oid, GSS_MA_SASL_MECH_NAME, &name); if (major) continue; @@ -272,9 +274,58 @@ gss_indicate_mechs_by_attrs(OM_uint32 * minor_status, gss_const_OID_set desired_mech_attrs, gss_const_OID_set except_mech_attrs, gss_const_OID_set critical_mech_attrs, - gss_OID_set mechs) + gss_OID_set *mechs) { - _mg_oid_set_zero(mechs); + struct _gss_mech_switch *ms; + OM_uint32 major; + size_t n, m; + + major = gss_create_empty_oid_set(minor_status, mechs); + if (major) + return major; + + _gss_load_mech(); + + SLIST_FOREACH(ms, &_gss_mechs, gm_link) { + gssapi_mech_interface mi = &ms->gm_mech; + + if (desired_mech_attrs) { + for (n = 0; n < desired_mech_attrs->count; n++) { + for (m = 0; m < mi->gm_mo_num; m++) + if (gss_oid_equal(mi->gm_mo[m].option, &desired_mech_attrs->elements[n])) + break; + if (m == mi->gm_mo_num) + goto next; + } + } + + if (except_mech_attrs) { + for (n = 0; n < desired_mech_attrs->count; n++) { + for (m = 0; m < mi->gm_mo_num; m++) { + if (gss_oid_equal(mi->gm_mo[m].option, &desired_mech_attrs->elements[n])) + goto next; + } + } + } + + if (critical_mech_attrs) { + for (n = 0; n < desired_mech_attrs->count; n++) { + for (m = 0; m < mi->gm_mo_num; m++) { + if (mi->gm_mo[m].flags & GSS_MO_MA_CRITICAL) + continue; + if (gss_oid_equal(mi->gm_mo[m].option, &desired_mech_attrs->elements[n])) + break; + } + if (m == mi->gm_mo_num) + goto next; + } + } + + + next: + do { } while(0); + } + return GSS_S_FAILURE; } @@ -301,11 +352,19 @@ gss_inquire_attrs_for_mech(OM_uint32 * minor_status, { OM_uint32 major, junk; - if (mech_attr) { - if (mech) - gss_mo_list(mech, mech_attr); - else - *mech_attr = NULL; + if (mech_attr && mech) { + gssapi_mech_interface m; + + if ((m = __gss_get_mechanism(mech)) == NULL) { + *minor_status = 0; + return GSS_S_BAD_MECH; + } + + major = gss_create_empty_oid_set(minor_status, mech_attr); + if (major != GSS_S_COMPLETE) + return major; + + add_all_mo(m, mech_attr, GSS_MO_MA); } if (known_mech_attrs) { @@ -313,14 +372,15 @@ gss_inquire_attrs_for_mech(OM_uint32 * minor_status, major = gss_create_empty_oid_set(minor_status, known_mech_attrs); if (major) { - gss_release_oid_set(&junk, mech_attr); + if (mech_attr) + gss_release_oid_set(&junk, mech_attr); return major; } _gss_load_mech(); SLIST_FOREACH(m, &_gss_mechs, gm_link) - add_all_mo(&m->gm_mech, known_mech_attrs); + add_all_mo(&m->gm_mech, known_mech_attrs, GSS_MO_MA); } @@ -357,8 +417,6 @@ gss_display_mech_attr(OM_uint32 * minor_status, if (minor_status) *minor_status = 0; - /* XXX check if the mech implements this, if it does, lets ask it for its idea first */ - for (n = 0; ma == NULL && _gss_ont_ma[n].oid; n++) if (gss_oid_equal(mech_attr, _gss_ont_ma[n].oid)) ma = &_gss_ont_ma[n]; diff --git a/lib/gssapi/mech/gss_oid.c b/lib/gssapi/mech/gss_oid.c index 2db32cde1..2030e12a1 100644 --- a/lib/gssapi/mech/gss_oid.c +++ b/lib/gssapi/mech/gss_oid.c @@ -122,6 +122,9 @@ gss_OID_desc __gss_krb5_mechanism_oid_desc = { 9, "\x2a\xc8\x06\x92\xf7\x06\x01\ /* GSS_NTLM_MECHANISM - 1.3.6.1.4.1.311.2.2.10 */ gss_OID_desc __gss_ntlm_mechanism_oid_desc = { 10, "\x2b\x06\x01\x04\x01\xb7\x02\x02\x02\x0a" }; +/* GSS_SPNEGO_MECHANISM - 1.3.6.1.5.5.2 */ +gss_OID_desc __gss_spnego_mechanism_oid_desc = { 6, "\x2b\x06\x01\x05\x05\x02" }; + /* GSS_C_PEER_HAS_UPDATED_SPNEGO - 1.3.6.1.4.1.9513.19.5 */ gss_OID_desc __gss_c_peer_has_updated_spnego_oid_desc = { 9, "\x2b\x06\x01\x04\x01\xa9\x4a\x13\x05" }; @@ -133,6 +136,8 @@ struct _gss_oid_name_table _gss_ont_ma[] = { }; struct _gss_oid_name_table _gss_ont_mech[] = { + { GSS_SPNEGO_MECHANISM, "GSS_SPNEGO_MECHANISM", "SPNEGO", "Heimdal SPNEGO mechanism" }, + { GSS_NTLM_MECHANISM, "GSS_NTLM_MECHANISM", "NTLM", "Heimdal NTLM mechanism" }, { GSS_KRB5_MECHANISM, "GSS_KRB5_MECHANISM", "Kerberos 5", "Heimdal Kerberos 5 mechanism" }, { NULL } }; diff --git a/lib/gssapi/oid.txt b/lib/gssapi/oid.txt index 45830f2f1..a242f11d7 100644 --- a/lib/gssapi/oid.txt +++ b/lib/gssapi/oid.txt @@ -68,8 +68,8 @@ oid base GSS_C_PEER_HAS_UPDATED_SPNEGO 1.3.6.1.4.1.9513.19.5 # */ desc mech GSS_KRB5_MECHANISM "Kerberos 5" "Heimdal Kerberos 5 mechanism" -/desc mech GSS_NTLM_MECHANISM "NTLM" "Heimdal NTLM mechanism" -/desc mech GSS_SPNEGO_MECHANISM "SPNEGO" "Heimdal SPNEGO mechanism" +desc mech GSS_NTLM_MECHANISM "NTLM" "Heimdal NTLM mechanism" +desc mech GSS_SPNEGO_MECHANISM "SPNEGO" "Heimdal SPNEGO mechanism" desc ma GSS_MA_MECH_NAME "GSS mech name" "The name of the GSS-API mechanism" desc ma GSS_MA_SASL_MECH_NAME "SASL mechanism name" "The name of the SASL mechanism" diff --git a/lib/gssapi/spnego/external.c b/lib/gssapi/spnego/external.c index d21e4dc7f..1eb03207e 100644 --- a/lib/gssapi/spnego/external.c +++ b/lib/gssapi/spnego/external.c @@ -92,6 +92,3 @@ __gss_spnego_initialize(void) { return &spnego_mech; } - -gss_OID_desc GSSAPI_LIB_VARIABLE __gss_spnego_mechanism_oid_desc = - {6, (void *)"\x2b\x06\x01\x05\x05\x02"};