X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=util_name.c;h=fd47bac9548516aa2cca8ce47e6fcbc81b566197;hb=d4fe7ce93304facaf069792c347b01b25ab765ae;hp=abe60c019f1c73fd394f887a865e8ae75cc5fd2c;hpb=aa0df2f91c1dcede24c7dbf60d71414ca157dd51;p=mech_eap.orig diff --git a/util_name.c b/util_name.c index abe60c0..fd47bac 100644 --- a/util_name.c +++ b/util_name.c @@ -55,13 +55,12 @@ #include "gssapiP_eap.h" -static const gss_OID_desc gssEapNtPrincipalName = { +static gss_OID_desc gssEapNtPrincipalName = { /* 1.3.6.1.4.1.5322.21.2.1 */ 12, "\x06\x0A\x2B\x06\x01\x04\x01\xA9\x4A\x15\x02\x01" }; -const gss_OID_desc *const GSS_EAP_NT_PRINCIPAL_NAME = - &gssEapNtPrincipalName; +gss_OID GSS_EAP_NT_PRINCIPAL_NAME = &gssEapNtPrincipalName; OM_uint32 gssEapAllocName(OM_uint32 *minor, gss_name_t *pName) @@ -69,7 +68,7 @@ gssEapAllocName(OM_uint32 *minor, gss_name_t *pName) OM_uint32 tmpMinor; gss_name_t name; - assert(*pName == GSS_C_NO_NAME); + *pName = GSS_C_NO_NAME; name = (gss_name_t)GSSEAP_CALLOC(1, sizeof(*name)); if (name == NULL) { @@ -133,7 +132,15 @@ krbPrincipalToName(OM_uint32 *minor, name->krbPrincipal = *principal; *principal = NULL; + if (name->krbPrincipal->length == 1) { + name->flags |= NAME_FLAG_NAI; + } else { + name->flags |= NAME_FLAG_SERVICE; + } + + *pName = name; *minor = 0; + return GSS_S_COMPLETE; } @@ -218,6 +225,7 @@ importExportedName(OM_uint32 *minor, int composite = 0; size_t len, remain; gss_buffer_desc buf; + enum gss_eap_token_type tok_type; GSSEAP_KRB_INIT(&krbContext); @@ -227,44 +235,39 @@ importExportedName(OM_uint32 *minor, if (remain < 6 + GSS_EAP_MECHANISM->length + 4) return GSS_S_BAD_NAME; - if (*p++ != 0x04) + /* TOK_ID */ + tok_type = load_uint16_be(p); + if (tok_type != TOK_TYPE_EXPORT_NAME && + tok_type != TOK_TYPE_EXPORT_NAME_COMPOSITE) return GSS_S_BAD_NAME; - - switch (*p++) { - case 0x02: - composite = 1; - break; - case 0x01: - break; - default: - return GSS_S_BAD_NAME; - break; - } + p += 2; remain -= 2; + /* MECH_OID_LEN */ len = load_uint16_be(p); if (len != 2 + GSS_EAP_MECHANISM->length) return GSS_S_BAD_NAME; p += 2; remain -= 2; - if (*p++ != 0x06) + /* MECH_OID */ + if (p[0] != 0x06) return GSS_S_BAD_NAME; - if (*p++ != GSS_EAP_MECHANISM->length) + if (p[1] != GSS_EAP_MECHANISM->length) return GSS_S_BAD_MECH; - remain -= 2; - if (memcmp(p, GSS_EAP_MECHANISM->elements, GSS_EAP_MECHANISM->length)) return GSS_S_BAD_MECH; - p += GSS_EAP_MECHANISM->length; - remain -= GSS_EAP_MECHANISM->length; + p += 2 + GSS_EAP_MECHANISM->length; + remain -= 2 + GSS_EAP_MECHANISM->length; + /* NAME_LEN */ len = load_uint32_be(p); p += 4; if (remain < len) return GSS_S_BAD_NAME; + /* NAME */ buf.length = len; buf.value = p; @@ -315,7 +318,7 @@ OM_uint32 gssEapExportName(OM_uint32 *minor, gss_buffer_t exportedName, int composite) { - OM_uint32 major, tmpMinor; + OM_uint32 major = GSS_S_FAILURE, tmpMinor; krb5_context krbContext; char *krbName = NULL; size_t krbNameLen; @@ -325,27 +328,17 @@ OM_uint32 gssEapExportName(OM_uint32 *minor, exportedName->value = NULL; GSSEAP_KRB_INIT(&krbContext); - - if (name == GSS_C_NO_NAME) { - *minor = EINVAL; - return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME; - } - GSSEAP_MUTEX_LOCK(&name->mutex); /* * Don't export a composite name if we don't have any attributes. */ - if (composite && - (name->flags & (NAME_FLAG_SAML | NAME_FLAG_RADIUS)) == 0) { + if (composite && !NAME_HAS_ATTRIBUTES(name)) composite = 0; - } *minor = krb5_unparse_name(krbContext, name->krbPrincipal, &krbName); - if (*minor != 0) { - major = GSS_S_FAILURE; + if (*minor != 0) goto cleanup; - } krbNameLen = strlen(krbName); exportedName->length = 6 + GSS_EAP_MECHANISM->length + 4 + krbNameLen; @@ -357,26 +350,30 @@ OM_uint32 gssEapExportName(OM_uint32 *minor, exportedName->value = GSSEAP_MALLOC(exportedName->length); if (exportedName->value == NULL) { *minor = ENOMEM; - major = GSS_S_FAILURE; goto cleanup; } + /* TOK | MECH_OID_LEN */ p = (unsigned char *)exportedName->value; - *p++ = 0x04; - if (composite) { - *p++ = 0x02; - } else { - *p++ = 0x01; - } + store_uint16_be(composite + ? TOK_TYPE_EXPORT_NAME_COMPOSITE + : TOK_TYPE_EXPORT_NAME, + p); + p += 2; store_uint16_be(GSS_EAP_MECHANISM->length + 2, p); p += 2; + + /* MECH_OID */ *p++ = 0x06; *p++ = GSS_EAP_MECHANISM->length & 0xff; memcpy(p, GSS_EAP_MECHANISM->elements, GSS_EAP_MECHANISM->length); p += GSS_EAP_MECHANISM->length; + /* NAME_LEN */ store_uint32_be(krbNameLen, p); p += 4; + + /* NAME */ memcpy(p, krbName, krbNameLen); p += krbNameLen; @@ -391,3 +388,126 @@ cleanup: return major; } + +static gss_buffer_desc attributePrefixes[] = { + { + /* ATTR_TYPE_NONE */ + 0, + NULL, + }, + { + /* ATTR_TYPE_SAML_AAA_ASSERTION */ + sizeof("urn:ietf:params:gss-eap:saml-aaa-assertion"), + "urn:ietf:params:gss-eap:saml-aaa-assertion" + }, + { + /* ATTR_TYPE_SAML_ATTR */ + sizeof("urn:ietf:params:gss-eap:saml-attr"), + "urn:ietf:params:gss-eap:saml-attr" + }, + { + /* ATTR_TYPE_RADIUS_AVP */ + sizeof("urn:ietf:params:gss-eap:radius-avp"), + "urn:ietf:params:gss-eap:radius-avp", + } +}; + +enum gss_eap_attribute_type +gssEapAttributePrefixToType(const gss_buffer_t prefix) +{ + enum gss_eap_attribute_type i; + + for (i = ATTR_TYPE_SAML_AAA_ASSERTION; + i < sizeof(attributePrefixes) / sizeof(attributePrefixes[0]); + i++) + { + gss_buffer_t p = &attributePrefixes[i]; + + if (p->length == prefix->length && + memcmp(p->value, prefix->value, prefix->length) == 0) { + return i; + } + } + + return ATTR_TYPE_NONE; +} + +gss_buffer_t +gssEapAttributeTypeToPrefix(enum gss_eap_attribute_type type) +{ + if (type <= ATTR_TYPE_NONE || + type > ATTR_TYPE_RADIUS_AVP) + return GSS_C_NO_BUFFER; + + return &attributePrefixes[type]; +} + +OM_uint32 +decomposeAttributeName(OM_uint32 *minor, + const gss_buffer_t attribute, + gss_buffer_t prefix, + gss_buffer_t suffix) +{ + char *p = NULL; + int i; + + for (i = 0; i < attribute->length; i++) { + if (((char *)attribute->value)[i] == ' ') { + p = (char *)attribute->value + i + 1; + break; + } + } + + prefix->value = attribute->value; + prefix->length = i; + + if (p != NULL && *p != '\0') { + suffix->length = attribute->length - 1 - prefix->length; + suffix->value = p; + } else { + suffix->length = 0; + suffix->value = NULL; + } + + *minor = 0; + return GSS_S_COMPLETE; +} + +OM_uint32 +composeAttributeName(OM_uint32 *minor, + const gss_buffer_t prefix, + const gss_buffer_t suffix, + gss_buffer_t attribute) +{ + size_t len = 0; + char *p; + + attribute->length = 0; + attribute->value = NULL; + + if (prefix == GSS_C_NO_BUFFER || prefix->length == 0) + return GSS_S_COMPLETE; + + len = prefix->length; + if (suffix != NULL) { + len += 1 + suffix->length; + } + + p = attribute->value = GSSEAP_MALLOC(len + 1); + if (attribute->value == NULL) { + *minor = ENOMEM; + return GSS_S_FAILURE; + } + attribute->length = len; + + memcpy(p, prefix->value, prefix->length); + if (suffix != NULL) { + p[prefix->length] = ' '; + memcpy(p + prefix->length + 1, suffix->value, suffix->length); + } + + p[attribute->length] = '\0'; + + *minor = 0; + return GSS_S_COMPLETE; +}