From 2578cdaa1d058cb74644cb9a0ddee990221abd74 Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Fri, 18 Mar 2011 16:16:20 +1100 Subject: [PATCH] Go to great lengths to avoid accidentally appending the default Kerberos realm --- util_krb.c | 8 ++++--- util_name.c | 79 ++++++++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 62 insertions(+), 25 deletions(-) diff --git a/util_krb.c b/util_krb.c index 2176d9b..abc9e61 100644 --- a/util_krb.c +++ b/util_krb.c @@ -70,9 +70,11 @@ initKrbContext(krb5_context *pKrbContext) krb5_appdefault_string(krbContext, "eap_gss", NULL, "default_realm", "", &defaultRealm); - code = krb5_set_default_realm(krbContext, defaultRealm); - if (code != 0) - goto cleanup; + if (defaultRealm != NULL && defaultRealm[0] != '\0') { + code = krb5_set_default_realm(krbContext, defaultRealm); + if (code != 0) + goto cleanup; + } *pKrbContext = krbContext; diff --git a/util_name.c b/util_name.c index af34d67..4add1fe 100644 --- a/util_name.c +++ b/util_name.c @@ -149,6 +149,17 @@ krbPrincipalToName(OM_uint32 *minor, return GSS_S_COMPLETE; } +static krb5_error_code +gssEapGetDefaultRealm(krb5_context krbContext, char **defaultRealm) +{ + *defaultRealm = NULL; + + krb5_appdefault_string(krbContext, "eap_gss", + NULL, "default_realm", "", defaultRealm); + + return (*defaultRealm != NULL) ? 0 : KRB5_CONFIG_NODEFREALM; +} + static OM_uint32 importServiceName(OM_uint32 *minor, const gss_buffer_t nameBuffer, @@ -172,7 +183,7 @@ importServiceName(OM_uint32 *minor, host++; } - krb5_get_default_realm(krbContext, &realm); + gssEapGetDefaultRealm(krbContext, &realm); code = krb5_build_principal(krbContext, &krbPrinc, @@ -182,9 +193,6 @@ importServiceName(OM_uint32 *minor, host, NULL); - if (realm != NULL) - krb5_free_default_realm(krbContext, realm); - if (code == 0) { KRB_PRINC_TYPE(krbPrinc) = KRB5_NT_SRV_HST; @@ -196,6 +204,8 @@ importServiceName(OM_uint32 *minor, *minor = GSSEAP_BAD_SERVICE_NAME; } + if (realm != NULL) + GSSEAP_FREE(realm); GSSEAP_FREE(service); return major; @@ -208,42 +218,67 @@ importUserName(OM_uint32 *minor, { OM_uint32 major; krb5_context krbContext; - krb5_principal krbPrinc; - char *nameString, *realm = NULL; - int flags = 0; + krb5_principal krbPrinc = NULL; krb5_error_code code; GSSEAP_KRB_INIT(&krbContext); - code = krb5_get_default_realm(krbContext, &realm); - if (code != 0 || realm == NULL) - flags |= KRB5_PRINCIPAL_PARSE_REQUIRE_REALM; - else - krb5_free_default_realm(krbContext, realm); - if (nameBuffer == GSS_C_NO_BUFFER) { - *minor = krb5_copy_principal(krbContext, - krbAnonymousPrincipal(), &krbPrinc); - if (*minor != 0) + code = krb5_copy_principal(krbContext, + krbAnonymousPrincipal(), &krbPrinc); + if (code != 0) { + *minor = code; return GSS_S_FAILURE; + } } else { + char *nameString; + major = bufferToString(minor, nameBuffer, &nameString); if (GSS_ERROR(major)) return major; - *minor = krb5_parse_name_flags(krbContext, nameString, flags, &krbPrinc); - if (*minor != 0) { - GSSEAP_FREE(nameString); + /* + * First, attempt to parse the name on the assumption that it includes + * a qualifying realm. + */ + code = krb5_parse_name_flags(krbContext, nameString, + KRB5_PRINCIPAL_PARSE_REQUIRE_REALM, &krbPrinc); + if (code == KRB5_PARSE_MALFORMED) { + char *defaultRealm = NULL; + int flags = 0; + + /* + * We need an explicit appdefaults check because, at least with MIT + * Kerberos, setting the context realm to NULL will reset it to the + * default Kerberos realm after the second call to get_default_realm. + * We want to make sure that the default Kerberos realm does not end + * up accidentally appended to an unqualified name. + */ + gssEapGetDefaultRealm(krbContext, &defaultRealm); + + if (defaultRealm == NULL || defaultRealm[0] == '\0') + flags |= KRB5_PRINCIPAL_PARSE_NO_REALM; + + code = krb5_parse_name_flags(krbContext, nameString, flags, &krbPrinc); + + if (defaultRealm != NULL) + GSSEAP_FREE(defaultRealm); + } + + 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; } -- 2.1.4