From c716bbb57dbf681f98aff44d4f8fbe845668d9bb Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Sat, 19 Mar 2011 00:13:18 +1100 Subject: [PATCH] Use stored identity if cached identity matches --- compare_name.c | 17 +----------- util.h | 6 +++++ util_cred.c | 82 +++++++++++++++++++++++++++++++++++----------------------- util_name.c | 24 +++++++++++++++++ 4 files changed, 80 insertions(+), 49 deletions(-) diff --git a/compare_name.c b/compare_name.c index 9621908..1da4d98 100644 --- a/compare_name.c +++ b/compare_name.c @@ -42,20 +42,5 @@ gss_compare_name(OM_uint32 *minor, 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; + return gssEapCompareName(minor, name1, name2, name_equal); } diff --git a/util.h b/util.h index 8fac347..90256ca 100644 --- a/util.h +++ b/util.h @@ -491,6 +491,12 @@ gssEapDisplayName(OM_uint32 *minor, gss_buffer_t output_name_buffer, gss_OID *output_name_type); +OM_uint32 +gssEapCompareName(OM_uint32 *minor, + gss_name_t name1, + gss_name_t name2, + int *name_equal); + /* util_oid.c */ OM_uint32 composeOid(OM_uint32 *minor_status, diff --git a/util_cred.c b/util_cred.c index 1a18911..8c4ce55 100644 --- a/util_cred.c +++ b/util_cred.c @@ -202,7 +202,10 @@ gssEapAcquireCred(OM_uint32 *minor, { OM_uint32 major, tmpMinor; gss_cred_id_t cred; + gss_buffer_desc defaultIdentity = GSS_C_EMPTY_BUFFER; + gss_name_t defaultIdentityName = GSS_C_NO_NAME; gss_buffer_desc defaultCreds = GSS_C_EMPTY_BUFFER; + gss_OID nameMech = GSS_C_NO_OID; /* XXX TODO validate with changed set_cred_option API */ *pCred = GSS_C_NO_CREDENTIAL; @@ -228,6 +231,29 @@ gssEapAcquireCred(OM_uint32 *minor, break; } + major = gssEapValidateMechs(minor, desiredMechs); + if (GSS_ERROR(major)) + goto cleanup; + + major = duplicateOidSet(minor, desiredMechs, &cred->mechanisms); + if (GSS_ERROR(major)) + goto cleanup; + + if (cred->mechanisms != GSS_C_NO_OID_SET && + cred->mechanisms->count == 1) + nameMech = &cred->mechanisms->elements[0]; + + if (cred->flags & CRED_FLAG_INITIATE) { + major = readDefaultIdentityAndCreds(minor, &defaultIdentity, &defaultCreds); + if (GSS_ERROR(major)) + goto cleanup; + + major = gssEapImportName(minor, &defaultIdentity, GSS_C_NT_USER_NAME, + nameMech, &defaultIdentityName); + if (GSS_ERROR(major)) + goto cleanup; + } + if (desiredName != GSS_C_NO_NAME) { GSSEAP_MUTEX_LOCK(&desiredName->mutex); @@ -238,12 +264,22 @@ gssEapAcquireCred(OM_uint32 *minor, } GSSEAP_MUTEX_UNLOCK(&desiredName->mutex); - } else { - gss_buffer_desc nameBuf = GSS_C_EMPTY_BUFFER; - gss_OID nameType = GSS_C_NO_OID; - char serviceName[5 + MAXHOSTNAMELEN]; + if (defaultIdentityName != GSS_C_NO_NAME) { + int nameEqual; + + major = gssEapCompareName(minor, desiredName, + defaultIdentityName, &nameEqual); + if (GSS_ERROR(major)) + goto cleanup; + else if (nameEqual) + cred->flags |= CRED_FLAG_DEFAULT_IDENTITY; + } + } else { if (cred->flags & CRED_FLAG_ACCEPT) { + gss_buffer_desc nameBuf = GSS_C_EMPTY_BUFFER; + char serviceName[5 + MAXHOSTNAMELEN]; + /* default host-based service is host@localhost */ memcpy(serviceName, "host@", 5); if (gethostname(&serviceName[5], MAXHOSTNAMELEN) != 0) { @@ -255,33 +291,19 @@ gssEapAcquireCred(OM_uint32 *minor, nameBuf.value = serviceName; nameBuf.length = strlen((char *)nameBuf.value); - nameType = GSS_C_NT_HOSTBASED_SERVICE; - } else if (cred->flags & CRED_FLAG_INITIATE) { - major = readDefaultIdentityAndCreds(minor, &nameBuf, &defaultCreds); - if (GSS_ERROR(major)) - goto cleanup; - - nameType = GSS_C_NT_USER_NAME; - } - - if (nameBuf.length != 0) { - gss_OID mech = GSS_C_NO_OID; - - if (cred->mechanisms != GSS_C_NO_OID_SET && - cred->mechanisms->count == 1) - mech = &cred->mechanisms->elements[0]; - - major = gssEapImportName(minor, &nameBuf, nameType, mech, &cred->name); + major = gssEapImportName(minor, &nameBuf, GSS_C_NT_HOSTBASED_SERVICE, + nameMech, &cred->name); if (GSS_ERROR(major)) goto cleanup; + } else if (cred->flags & CRED_FLAG_INITIATE) { + cred->name = defaultIdentityName; + defaultIdentityName = GSS_C_NO_NAME; } - - if (nameBuf.value != serviceName) - gss_release_buffer(&tmpMinor, &nameBuf); - cred->flags |= CRED_FLAG_DEFAULT_IDENTITY; } + assert(cred->name != GSS_C_NO_NAME); + if (password != GSS_C_NO_BUFFER) { major = duplicateBuffer(minor, password, &cred->password); if (GSS_ERROR(major)) @@ -309,14 +331,6 @@ gssEapAcquireCred(OM_uint32 *minor, goto cleanup; } - major = gssEapValidateMechs(minor, desiredMechs); - if (GSS_ERROR(major)) - goto cleanup; - - major = duplicateOidSet(minor, desiredMechs, &cred->mechanisms); - if (GSS_ERROR(major)) - goto cleanup; - if (pActualMechs != NULL) { major = duplicateOidSet(minor, cred->mechanisms, pActualMechs); if (GSS_ERROR(major)) @@ -334,6 +348,8 @@ gssEapAcquireCred(OM_uint32 *minor, cleanup: if (GSS_ERROR(major)) gssEapReleaseCred(&tmpMinor, &cred); + gssEapReleaseName(&tmpMinor, &defaultIdentityName); + gss_release_buffer(&tmpMinor, &defaultIdentity); if (defaultCreds.value != NULL) { memset(defaultCreds.value, 0, defaultCreds.length); gss_release_buffer(&tmpMinor, &defaultCreds); diff --git a/util_name.c b/util_name.c index 3112f88..144d26e 100644 --- a/util_name.c +++ b/util_name.c @@ -738,3 +738,27 @@ gssEapDisplayName(OM_uint32 *minor, 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; +} -- 2.1.4