X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=mech_eap%2Futil_name.c;h=fbd4b8a6e347c7f6c941247648949b06c015908b;hb=de13ec1bef665ffca5093daa5e957018cc0bc5b8;hp=f4a6338a8bb18db6e7533b61c2ef5e70b93ee6de;hpb=5a68e5d384f6988b0591d842655b3ad9f2d755e4;p=moonshot.git diff --git a/mech_eap/util_name.c b/mech_eap/util_name.c index f4a6338..fbd4b8a 100644 --- a/mech_eap/util_name.c +++ b/mech_eap/util_name.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, JANET(UK) + * Copyright (c) 2011, JANET(UK) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -53,14 +53,18 @@ * or implied warranty. */ +/* + * Name utility routines. + */ + #include "gssapiP_eap.h" -static gss_OID_desc gssEapNtPrincipalName = { - /* 1.3.6.1.4.1.5322.21.2.1 */ - 10, "\x2B\x06\x01\x04\x01\xA9\x4A\x15\x02\x01" +static gss_OID_desc gssEapNtEapName = { + /* 1.3.6.1.4.1.5322.22.2.1 */ + 10, "\x2B\x06\x01\x04\x01\xA9\x4A\x16\x02\x01" }; -gss_OID GSS_EAP_NT_PRINCIPAL_NAME = &gssEapNtPrincipalName; +gss_OID GSS_EAP_NT_EAP_NAME = &gssEapNtEapName; OM_uint32 gssEapAllocName(OM_uint32 *minor, gss_name_t *pName) @@ -94,6 +98,8 @@ gssEapReleaseName(OM_uint32 *minor, gss_name_t *pName) krb5_context krbContext = NULL; OM_uint32 tmpMinor; + *minor = 0; + if (pName == NULL) { return GSS_S_COMPLETE; } @@ -105,6 +111,7 @@ gssEapReleaseName(OM_uint32 *minor, gss_name_t *pName) GSSEAP_KRB_INIT(&krbContext); krb5_free_principal(krbContext, name->krbPrincipal); + gssEapReleaseOid(&tmpMinor, &name->mechanismUsed); gssEapReleaseAttrContext(&tmpMinor, name); @@ -112,7 +119,6 @@ gssEapReleaseName(OM_uint32 *minor, gss_name_t *pName) GSSEAP_FREE(name); *pName = NULL; - *minor = 0; return GSS_S_COMPLETE; } @@ -131,10 +137,10 @@ krbPrincipalToName(OM_uint32 *minor, name->krbPrincipal = *principal; *principal = NULL; - if (name->krbPrincipal->length == 1) { - name->flags |= NAME_FLAG_NAI; - } else { + if (KRB_PRINC_LENGTH(name->krbPrincipal) > 1) { name->flags |= NAME_FLAG_SERVICE; + } else { + name->flags |= NAME_FLAG_NAI; } *pName = name; @@ -143,15 +149,27 @@ krbPrincipalToName(OM_uint32 *minor, return GSS_S_COMPLETE; } +static char * +gssEapGetDefaultRealm(krb5_context krbContext) +{ + char *defaultRealm = NULL; + + krb5_appdefault_string(krbContext, "eap_gss", + NULL, "default_realm", "", &defaultRealm); + + return defaultRealm; +} + static OM_uint32 importServiceName(OM_uint32 *minor, const gss_buffer_t nameBuffer, gss_name_t *pName) { OM_uint32 major; + krb5_error_code code; krb5_context krbContext; krb5_principal krbPrinc; - char *service, *host; + char *service, *host, *realm = NULL; GSSEAP_KRB_INIT(&krbContext); @@ -165,61 +183,138 @@ importServiceName(OM_uint32 *minor, host++; } - /* XXX this is probably NOT what we want to be doing */ - *minor = krb5_sname_to_principal(krbContext, host, service, - KRB5_NT_SRV_HST, &krbPrinc); - if (*minor != 0) { - GSSEAP_FREE(service); - return GSS_S_FAILURE; - } + realm = gssEapGetDefaultRealm(krbContext); - major = krbPrincipalToName(minor, &krbPrinc, pName); - if (GSS_ERROR(major)) { - krb5_free_principal(krbContext, krbPrinc); + code = krb5_build_principal(krbContext, + &krbPrinc, + realm != NULL ? strlen(realm) : 0, + realm != NULL ? realm : "", + service, + host, + NULL); + + if (code == 0) { + KRB_PRINC_TYPE(krbPrinc) = KRB5_NT_SRV_HST; + + major = krbPrincipalToName(minor, &krbPrinc, pName); + if (GSS_ERROR(major)) + krb5_free_principal(krbContext, krbPrinc); + } else { + major = GSS_S_FAILURE; + *minor = GSSEAP_BAD_SERVICE_NAME; } + if (realm != NULL) + GSSEAP_FREE(realm); GSSEAP_FREE(service); + return major; } +#define IMPORT_FLAG_DEFAULT_REALM 0x1 + +/* + * Import an EAP name, possibly appending the default GSS EAP realm, + */ static OM_uint32 -importUserName(OM_uint32 *minor, - const gss_buffer_t nameBuffer, - gss_name_t *pName) +importEapNameFlags(OM_uint32 *minor, + const gss_buffer_t nameBuffer, + OM_uint32 importFlags, + gss_name_t *pName) { OM_uint32 major; krb5_context krbContext; - krb5_principal krbPrinc; + krb5_principal krbPrinc = NULL; + krb5_error_code code; char *nameString; GSSEAP_KRB_INIT(&krbContext); if (nameBuffer == GSS_C_NO_BUFFER) { - *minor = krb5_copy_principal(krbContext, - krb5_anonymous_principal(), &krbPrinc); - if (*minor != 0) - return GSS_S_FAILURE; + nameString = ""; + code = KRB5_PARSE_MALFORMED; } else { major = bufferToString(minor, nameBuffer, &nameString); if (GSS_ERROR(major)) return major; - *minor = krb5_parse_name(krbContext, nameString, &krbPrinc); - if (*minor != 0) { - GSSEAP_FREE(nameString); - return GSS_S_FAILURE; + /* + * First, attempt to parse the name on the assumption that it includes + * a qualifying realm. This allows us to avoid accidentally appending + * the default Kerberos realm to an unqualified name. (A bug in MIT + * Kerberos prevents the default realm being set to an empty value.) + */ + code = krb5_parse_name_flags(krbContext, nameString, + KRB5_PRINCIPAL_PARSE_REQUIRE_REALM, &krbPrinc); + } + + if (code == KRB5_PARSE_MALFORMED) { + char *defaultRealm = NULL; + int parseFlags = 0; + + /* Possibly append the default EAP realm if required */ + if (importFlags & IMPORT_FLAG_DEFAULT_REALM) + defaultRealm = gssEapGetDefaultRealm(krbContext); + + /* If no default realm, leave the realm empty in the parsed name */ + if (defaultRealm == NULL || defaultRealm[0] == '\0') + parseFlags |= KRB5_PRINCIPAL_PARSE_NO_REALM; + + code = krb5_parse_name_flags(krbContext, nameString, parseFlags, &krbPrinc); + +#ifdef HAVE_HEIMDAL_VERSION + if (code == 0 && KRB_PRINC_REALM(krbPrinc) == NULL) { + KRB_PRINC_REALM(krbPrinc) = GSSEAP_CALLOC(1, sizeof(char)); + if (KRB_PRINC_REALM(krbPrinc) == NULL) + code = ENOMEM; } +#endif + + if (defaultRealm != NULL) + GSSEAP_FREE(defaultRealm); + } + + if (nameBuffer != GSS_C_NO_BUFFER) + GSSEAP_FREE(nameString); + + if (code != 0) { + *minor = code; + return GSS_S_FAILURE; } + assert(krbPrinc != NULL); + major = krbPrincipalToName(minor, &krbPrinc, pName); - if (GSS_ERROR(major)) { + if (GSS_ERROR(major)) krb5_free_principal(krbContext, krbPrinc); - } - GSSEAP_FREE(nameString); return major; } +static OM_uint32 +importEapName(OM_uint32 *minor, + const gss_buffer_t nameBuffer, + gss_name_t *pName) +{ + return importEapNameFlags(minor, nameBuffer, 0, pName); +} + +static OM_uint32 +importUserName(OM_uint32 *minor, + const gss_buffer_t nameBuffer, + gss_name_t *pName) +{ + return importEapNameFlags(minor, nameBuffer, IMPORT_FLAG_DEFAULT_REALM, pName); +} + +static OM_uint32 +importAnonymousName(OM_uint32 *minor, + const gss_buffer_t nameBuffer GSSEAP_UNUSED, + gss_name_t *pName) +{ + return importEapNameFlags(minor, GSS_C_NO_BUFFER, 0, pName); +} + #define UPDATE_REMAIN(n) do { \ p += (n); \ remain -= (n); \ @@ -227,8 +322,8 @@ importUserName(OM_uint32 *minor, #define CHECK_REMAIN(n) do { \ if (remain < (n)) { \ - *minor = ERANGE; \ major = GSS_S_BAD_NAME; \ + *minor = GSSEAP_TOK_TRUNC; \ goto cleanup; \ } \ } while (0) @@ -237,15 +332,15 @@ OM_uint32 gssEapImportNameInternal(OM_uint32 *minor, const gss_buffer_t nameBuffer, gss_name_t *pName, - unsigned int flags) + OM_uint32 flags) { OM_uint32 major, tmpMinor; krb5_context krbContext; unsigned char *p; size_t len, remain; gss_buffer_desc buf; - enum gss_eap_token_type tokType; gss_name_t name = GSS_C_NO_NAME; + gss_OID mechanismUsed = GSS_C_NO_OID; GSSEAP_KRB_INIT(&krbContext); @@ -253,8 +348,15 @@ gssEapImportNameInternal(OM_uint32 *minor, remain = nameBuffer->length; if (flags & EXPORT_NAME_FLAG_OID) { - if (remain < 6 + GSS_EAP_MECHANISM->length + 4) + gss_OID_desc mech; + enum gss_eap_token_type tokType; + uint16_t wireTokType; + + /* TOK_ID || MECH_OID_LEN || MECH_OID */ + if (remain < 6) { + *minor = GSSEAP_BAD_NAME_TOKEN; return GSS_S_BAD_NAME; + } if (flags & EXPORT_NAME_FLAG_COMPOSITE) tokType = TOK_TYPE_EXPORT_NAME_COMPOSITE; @@ -262,27 +364,52 @@ gssEapImportNameInternal(OM_uint32 *minor, tokType = TOK_TYPE_EXPORT_NAME; /* TOK_ID */ - if (load_uint16_be(p) != tokType) + wireTokType = load_uint16_be(p); + + if ((flags & EXPORT_NAME_FLAG_ALLOW_COMPOSITE) && + wireTokType == TOK_TYPE_EXPORT_NAME_COMPOSITE) { + tokType = TOK_TYPE_EXPORT_NAME_COMPOSITE; + flags |= EXPORT_NAME_FLAG_COMPOSITE; + } + + if (wireTokType != tokType) { + *minor = GSSEAP_WRONG_TOK_ID; return GSS_S_BAD_NAME; + } UPDATE_REMAIN(2); /* MECH_OID_LEN */ len = load_uint16_be(p); - if (len != 2 + GSS_EAP_MECHANISM->length) + if (len < 2) { + *minor = GSSEAP_BAD_NAME_TOKEN; return GSS_S_BAD_NAME; + } UPDATE_REMAIN(2); /* MECH_OID */ - if (p[0] != 0x06) + if (p[0] != 0x06) { + *minor = GSSEAP_BAD_NAME_TOKEN; return GSS_S_BAD_NAME; - if (p[1] != GSS_EAP_MECHANISM->length) - return GSS_S_BAD_MECH; - if (memcmp(&p[2], GSS_EAP_MECHANISM->elements, GSS_EAP_MECHANISM->length)) - return GSS_S_BAD_MECH; - UPDATE_REMAIN(2 + GSS_EAP_MECHANISM->length); + } + + mech.length = p[1]; + mech.elements = &p[2]; + + CHECK_REMAIN(mech.length); + + major = gssEapCanonicalizeOid(minor, + &mech, + OID_FLAG_FAMILY_MECH_VALID | + OID_FLAG_MAP_FAMILY_MECH_TO_NULL, + &mechanismUsed); + if (GSS_ERROR(major)) + goto cleanup; + + UPDATE_REMAIN(2 + mech.length); } /* NAME_LEN */ + CHECK_REMAIN(4); len = load_uint32_be(p); UPDATE_REMAIN(4); @@ -292,20 +419,18 @@ gssEapImportNameInternal(OM_uint32 *minor, buf.value = p; UPDATE_REMAIN(len); - major = importUserName(minor, &buf, &name); + major = importEapNameFlags(minor, &buf, 0, &name); if (GSS_ERROR(major)) goto cleanup; + name->mechanismUsed = mechanismUsed; + mechanismUsed = GSS_C_NO_OID; + if (flags & EXPORT_NAME_FLAG_COMPOSITE) { gss_buffer_desc buf; - CHECK_REMAIN(4); - buf.length = load_uint32_be(p); - UPDATE_REMAIN(4); - - CHECK_REMAIN(buf.length); + buf.length = remain; buf.value = p; - UPDATE_REMAIN(buf.length); major = gssEapImportAttrContext(minor, &buf, name); if (GSS_ERROR(major)) @@ -313,47 +438,90 @@ gssEapImportNameInternal(OM_uint32 *minor, } major = GSS_S_COMPLETE; + *minor = 0; cleanup: - if (GSS_ERROR(major)) + if (GSS_ERROR(major)) { + gssEapReleaseOid(&tmpMinor, &mechanismUsed); gssEapReleaseName(&tmpMinor, &name); - else + } else { *pName = name; + } return major; } -OM_uint32 -gssEapImportName(OM_uint32 *minor, +static OM_uint32 +importExportName(OM_uint32 *minor, const gss_buffer_t nameBuffer, - gss_OID nameType, gss_name_t *name) { - OM_uint32 major, tmpMinor; + return gssEapImportNameInternal(minor, nameBuffer, name, + EXPORT_NAME_FLAG_OID | + EXPORT_NAME_FLAG_ALLOW_COMPOSITE); +} - *name = GSS_C_NO_NAME; - - if (nameType == GSS_C_NULL_OID || - oidEqual(nameType, GSS_C_NT_USER_NAME) || - oidEqual(nameType, GSS_EAP_NT_PRINCIPAL_NAME)) - major = importUserName(minor, nameBuffer, name); - else if (oidEqual(nameType, GSS_C_NT_HOSTBASED_SERVICE) || - oidEqual(nameType, GSS_C_NT_HOSTBASED_SERVICE_X)) - major = importServiceName(minor, nameBuffer, name); - else if (oidEqual(nameType, GSS_C_NT_EXPORT_NAME)) - major = gssEapImportNameInternal(minor, nameBuffer, name, - EXPORT_NAME_FLAG_OID); #ifdef HAVE_GSS_C_NT_COMPOSITE_EXPORT - else if (oidEqual(nameType, GSS_C_NT_COMPOSITE_EXPORT)) - major = gssEapImportNameInternal(minor, nameBuffer, name, - EXPORT_NAME_FLAG_OID | - EXPORT_NAME_FLAG_COMPOSITE); +static OM_uint32 +importCompositeExportName(OM_uint32 *minor, + const gss_buffer_t nameBuffer, + gss_name_t *name) +{ + return gssEapImportNameInternal(minor, nameBuffer, name, + EXPORT_NAME_FLAG_OID | + EXPORT_NAME_FLAG_COMPOSITE); +} #endif - else - major = GSS_S_BAD_NAMETYPE; + +struct gss_eap_name_import_provider { + gss_const_OID oid; + OM_uint32 (*import)(OM_uint32 *, const gss_buffer_t, gss_name_t *); +}; + +OM_uint32 +gssEapImportName(OM_uint32 *minor, + const gss_buffer_t nameBuffer, + const gss_OID nameType, + const gss_OID mechType, + gss_name_t *pName) +{ + struct gss_eap_name_import_provider nameTypes[] = { + { GSS_EAP_NT_EAP_NAME, importEapName }, + { GSS_C_NT_USER_NAME, importUserName }, + { GSS_C_NT_HOSTBASED_SERVICE, importServiceName }, + { GSS_C_NT_HOSTBASED_SERVICE_X, importServiceName }, + { GSS_C_NT_ANONYMOUS, importAnonymousName }, + { GSS_C_NT_EXPORT_NAME, importExportName }, + { GSS_KRB5_NT_PRINCIPAL_NAME, importUserName }, +#ifdef HAVE_GSS_C_NT_COMPOSITE_EXPORT + { GSS_C_NT_COMPOSITE_EXPORT, importCompositeExportName }, +#endif + }; + size_t i; + OM_uint32 major = GSS_S_BAD_NAMETYPE; + OM_uint32 tmpMinor; + gss_name_t name = GSS_C_NO_NAME; + + for (i = 0; i < sizeof(nameTypes) / sizeof(nameTypes[0]); i++) { + if (oidEqual(nameTypes[i].oid, + nameType == GSS_C_NO_OID ? GSS_EAP_NT_EAP_NAME : nameType)) { + major = nameTypes[i].import(minor, nameBuffer, &name); + break; + } + } + + if (major == GSS_S_COMPLETE && + mechType != GSS_C_NO_OID) { + assert(gssEapIsConcreteMechanismOid(mechType)); + assert(name->mechanismUsed == GSS_C_NO_OID); + + major = gssEapCanonicalizeOid(minor, mechType, 0, &name->mechanismUsed); + } if (GSS_ERROR(major)) - gssEapReleaseName(&tmpMinor, name); + gssEapReleaseName(&tmpMinor, &name); + else + *pName = name; return major; } @@ -371,38 +539,37 @@ OM_uint32 gssEapExportNameInternal(OM_uint32 *minor, const gss_name_t name, gss_buffer_t exportedName, - unsigned int flags) + OM_uint32 flags) { OM_uint32 major = GSS_S_FAILURE, tmpMinor; - krb5_context krbContext; - char *krbName = NULL; - size_t krbNameLen, exportedNameLen; + gss_buffer_desc nameBuf = GSS_C_EMPTY_BUFFER; + size_t exportedNameLen; unsigned char *p; gss_buffer_desc attrs = GSS_C_EMPTY_BUFFER; + gss_OID mech; exportedName->length = 0; exportedName->value = NULL; - GSSEAP_KRB_INIT(&krbContext); - GSSEAP_MUTEX_LOCK(&name->mutex); + if (name->mechanismUsed != GSS_C_NO_OID) + mech = name->mechanismUsed; + else + mech = GSS_EAP_MECHANISM; - *minor = krb5_unparse_name(krbContext, name->krbPrincipal, &krbName); - if (*minor != 0) { - major = GSS_S_FAILURE; + major = gssEapDisplayName(minor, name, &nameBuf, NULL); + if (GSS_ERROR(major)) goto cleanup; - } - krbNameLen = strlen(krbName); exportedNameLen = 0; if (flags & EXPORT_NAME_FLAG_OID) { - exportedNameLen += 6 + GSS_EAP_MECHANISM->length; + exportedNameLen += 6 + mech->length; } - exportedNameLen += 4 + krbNameLen; + exportedNameLen += 4 + nameBuf.length; if (flags & EXPORT_NAME_FLAG_COMPOSITE) { major = gssEapExportAttrContext(minor, name, &attrs); if (GSS_ERROR(major)) goto cleanup; - exportedNameLen += 4 + attrs.length; + exportedNameLen += attrs.length; } exportedName->value = GSSEAP_MALLOC(exportedNameLen); @@ -422,51 +589,53 @@ gssEapExportNameInternal(OM_uint32 *minor, : TOK_TYPE_EXPORT_NAME, p); p += 2; - store_uint16_be(GSS_EAP_MECHANISM->length + 2, p); + store_uint16_be(mech->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; + *p++ = mech->length & 0xff; + memcpy(p, mech->elements, mech->length); + p += mech->length; } /* NAME_LEN */ - store_uint32_be(krbNameLen, p); + store_uint32_be(nameBuf.length, p); p += 4; /* NAME */ - memcpy(p, krbName, krbNameLen); - p += krbNameLen; + memcpy(p, nameBuf.value, nameBuf.length); + p += nameBuf.length; if (flags & EXPORT_NAME_FLAG_COMPOSITE) { - store_uint32_be(attrs.length, p); - memcpy(&p[4], attrs.value, attrs.length); - p += 4 + attrs.length; + memcpy(p, attrs.value, attrs.length); + p += attrs.length; } - *minor = 0; + assert(p == (unsigned char *)exportedName->value + exportedNameLen); + major = GSS_S_COMPLETE; + *minor = 0; cleanup: - GSSEAP_MUTEX_UNLOCK(&name->mutex); gss_release_buffer(&tmpMinor, &attrs); + gss_release_buffer(&tmpMinor, &nameBuf); if (GSS_ERROR(major)) gss_release_buffer(&tmpMinor, exportedName); - krb5_free_unparsed_name(krbContext, krbName); return major; } OM_uint32 -gssEapDuplicateName(OM_uint32 *minor, - const gss_name_t input_name, - gss_name_t *dest_name) +gssEapCanonicalizeName(OM_uint32 *minor, + const gss_name_t input_name, + const gss_OID mech_type, + gss_name_t *dest_name) { OM_uint32 major, tmpMinor; krb5_context krbContext; gss_name_t name; + gss_OID mech_used; if (input_name == GSS_C_NO_NAME) { *minor = EINVAL; @@ -480,8 +649,19 @@ gssEapDuplicateName(OM_uint32 *minor, return major; } - /* Lock mutex for copying mutable attributes */ - GSSEAP_MUTEX_LOCK(&input_name->mutex); + if (mech_type != GSS_C_NO_OID) + mech_used = mech_type; + else + mech_used = input_name->mechanismUsed; + + major = gssEapCanonicalizeOid(minor, + mech_used, + OID_FLAG_NULL_VALID, + &name->mechanismUsed); + if (GSS_ERROR(major)) + goto cleanup; + + name->flags = input_name->flags; *minor = krb5_copy_principal(krbContext, input_name->krbPrincipal, &name->krbPrincipal); @@ -499,8 +679,6 @@ gssEapDuplicateName(OM_uint32 *minor, *dest_name = name; cleanup: - GSSEAP_MUTEX_UNLOCK(&input_name->mutex); - if (GSS_ERROR(major)) { gssEapReleaseName(&tmpMinor, &name); } @@ -509,14 +687,25 @@ cleanup: } OM_uint32 +gssEapDuplicateName(OM_uint32 *minor, + const gss_name_t input_name, + gss_name_t *dest_name) +{ + return gssEapCanonicalizeName(minor, input_name, + GSS_C_NO_OID, dest_name); +} + +OM_uint32 gssEapDisplayName(OM_uint32 *minor, gss_name_t name, gss_buffer_t output_name_buffer, gss_OID *output_name_type) { - OM_uint32 major, tmpMinor; + OM_uint32 major; krb5_context krbContext; char *krbName; + gss_OID name_type; + int flags = 0; GSSEAP_KRB_INIT(&krbContext); @@ -528,7 +717,20 @@ gssEapDisplayName(OM_uint32 *minor, return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME; } - *minor = krb5_unparse_name(krbContext, name->krbPrincipal, &krbName); + /* + * According to draft-ietf-abfab-gss-eap-01, when the realm is + * absent the trailing '@' is not included. + */ +#ifdef HAVE_HEIMDAL_VERSION + if (KRB_PRINC_REALM(name->krbPrincipal) == NULL || + KRB_PRINC_REALM(name->krbPrincipal)[0] == '\0') +#else + if (KRB_PRINC_REALM(name->krbPrincipal)->length == 0) +#endif + flags |= KRB5_PRINCIPAL_UNPARSE_NO_REALM; + + *minor = krb5_unparse_name_flags(krbContext, name->krbPrincipal, + flags, &krbName); if (*minor != 0) { return GSS_S_FAILURE; } @@ -541,8 +743,40 @@ gssEapDisplayName(OM_uint32 *minor, krb5_free_unparsed_name(krbContext, krbName); + if (output_name_buffer->length == 0) { + name_type = GSS_C_NT_ANONYMOUS; + } else if (name->flags & NAME_FLAG_NAI) { + name_type = GSS_C_NT_USER_NAME; + } else { + name_type = GSS_EAP_NT_EAP_NAME; + } + if (output_name_type != NULL) - *output_name_type = GSS_EAP_NT_PRINCIPAL_NAME; + *output_name_type = name_type; + + return GSS_S_COMPLETE; +} + +OM_uint32 +gssEapCompareName(OM_uint32 *minor, + gss_name_t name1, + gss_name_t name2, + int *name_equal) +{ + krb5_context krbContext; + + *minor = 0; + + if (name1 == GSS_C_NO_NAME && name2 == GSS_C_NO_NAME) { + *name_equal = 1; + } else if (name1 != GSS_C_NO_NAME && name2 != GSS_C_NO_NAME) { + GSSEAP_KRB_INIT(&krbContext); + + /* krbPrincipal is immutable, so lock not required */ + *name_equal = krb5_principal_compare(krbContext, + name1->krbPrincipal, + name2->krbPrincipal); + } return GSS_S_COMPLETE; }