Fixes for Heimdal (macOS) builds from Stefan.
[mech_eap.git] / mech_eap / util_name.c
index fbd4b8a..b85565c 100644 (file)
@@ -60,8 +60,8 @@
 #include "gssapiP_eap.h"
 
 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"
+    /* 1.3.6.1.5.5.15.2.1 */
+    8, "\x2B\x06\x01\x05\x05\x0f\x02\x01"
 };
 
 gss_OID GSS_EAP_NT_EAP_NAME = &gssEapNtEapName;
@@ -81,7 +81,7 @@ gssEapAllocName(OM_uint32 *minor, gss_name_t *pName)
     }
 
     if (GSSEAP_MUTEX_INIT(&name->mutex) != 0) {
-        *minor = errno;
+        *minor = GSSEAP_GET_LAST_ERROR();
         gssEapReleaseName(&tmpMinor, &name);
         return GSS_S_FAILURE;
     }
@@ -112,8 +112,9 @@ gssEapReleaseName(OM_uint32 *minor, gss_name_t *pName)
     GSSEAP_KRB_INIT(&krbContext);
     krb5_free_principal(krbContext, name->krbPrincipal);
     gssEapReleaseOid(&tmpMinor, &name->mechanismUsed);
-
+#ifdef GSSEAP_ENABLE_ACCEPTOR
     gssEapReleaseAttrContext(&tmpMinor, name);
+#endif
 
     GSSEAP_MUTEX_DESTROY(&name->mutex);
     GSSEAP_FREE(name);
@@ -137,9 +138,10 @@ krbPrincipalToName(OM_uint32 *minor,
     name->krbPrincipal = *principal;
     *principal = NULL;
 
-    if (KRB_PRINC_LENGTH(name->krbPrincipal) > 1) {
+    if (KRB_PRINC_LENGTH(name->krbPrincipal) >= 1) {
         name->flags |= NAME_FLAG_SERVICE;
-    } else {
+    }
+    if (KRB_PRINC_LENGTH(name->krbPrincipal) == 1) {
         name->flags |= NAME_FLAG_NAI;
     }
 
@@ -204,8 +206,13 @@ importServiceName(OM_uint32 *minor,
         *minor = GSSEAP_BAD_SERVICE_NAME;
     }
 
-    if (realm != NULL)
-        GSSEAP_FREE(realm);
+    if (realm != NULL) {
+#ifdef HAVE_HEIMDAL_VERSION
+        krb5_xfree(realm);
+#else
+        krb5_free_default_realm(krbContext, realm);
+#endif
+    }
     GSSEAP_FREE(service);
 
     return major;
@@ -264,14 +271,15 @@ importEapNameFlags(OM_uint32 *minor,
 
 #ifdef HAVE_HEIMDAL_VERSION
         if (code == 0 && KRB_PRINC_REALM(krbPrinc) == NULL) {
-            KRB_PRINC_REALM(krbPrinc) = GSSEAP_CALLOC(1, sizeof(char));
+            KRB_PRINC_REALM(krbPrinc) = KRB_CALLOC(1, sizeof(char));
             if (KRB_PRINC_REALM(krbPrinc) == NULL)
                 code = ENOMEM;
         }
-#endif
-
+        krb5_xfree(defaultRealm);
+#else
         if (defaultRealm != NULL)
-            GSSEAP_FREE(defaultRealm);
+            krb5_free_default_realm(krbContext, defaultRealm);
+#endif
     }
 
     if (nameBuffer != GSS_C_NO_BUFFER)
@@ -282,7 +290,7 @@ importEapNameFlags(OM_uint32 *minor,
         return GSS_S_FAILURE;
     }
 
-    assert(krbPrinc != NULL);
+    GSSEAP_ASSERT(krbPrinc != NULL);
 
     major = krbPrincipalToName(minor, &krbPrinc, pName);
     if (GSS_ERROR(major))
@@ -426,6 +434,7 @@ gssEapImportNameInternal(OM_uint32 *minor,
     name->mechanismUsed = mechanismUsed;
     mechanismUsed = GSS_C_NO_OID;
 
+#ifdef GSSEAP_ENABLE_ACCEPTOR
     if (flags & EXPORT_NAME_FLAG_COMPOSITE) {
         gss_buffer_desc buf;
 
@@ -436,6 +445,7 @@ gssEapImportNameInternal(OM_uint32 *minor,
         if (GSS_ERROR(major))
             goto cleanup;
     }
+#endif
 
     major = GSS_S_COMPLETE;
     *minor = 0;
@@ -512,8 +522,9 @@ gssEapImportName(OM_uint32 *minor,
 
     if (major == GSS_S_COMPLETE &&
         mechType != GSS_C_NO_OID) {
-        assert(gssEapIsConcreteMechanismOid(mechType));
-        assert(name->mechanismUsed == GSS_C_NO_OID);
+        GSSEAP_ASSERT(gssEapIsConcreteMechanismOid(mechType));
+        GSSEAP_ASSERT(name != GSS_C_NO_NAME);
+        GSSEAP_ASSERT(name->mechanismUsed == GSS_C_NO_OID);
 
         major = gssEapCanonicalizeOid(minor, mechType, 0, &name->mechanismUsed);
     }
@@ -528,7 +539,7 @@ gssEapImportName(OM_uint32 *minor,
 
 OM_uint32
 gssEapExportName(OM_uint32 *minor,
-                 const gss_name_t name,
+                 gss_const_name_t name,
                  gss_buffer_t exportedName)
 {
     return gssEapExportNameInternal(minor, name, exportedName,
@@ -537,7 +548,7 @@ gssEapExportName(OM_uint32 *minor,
 
 OM_uint32
 gssEapExportNameInternal(OM_uint32 *minor,
-                         const gss_name_t name,
+                         gss_const_name_t name,
                          gss_buffer_t exportedName,
                          OM_uint32 flags)
 {
@@ -565,12 +576,14 @@ gssEapExportNameInternal(OM_uint32 *minor,
         exportedNameLen += 6 + mech->length;
     }
     exportedNameLen += 4 + nameBuf.length;
+#ifdef GSSEAP_ENABLE_ACCEPTOR
     if (flags & EXPORT_NAME_FLAG_COMPOSITE) {
         major = gssEapExportAttrContext(minor, name, &attrs);
         if (GSS_ERROR(major))
             goto cleanup;
         exportedNameLen += attrs.length;
     }
+#endif
 
     exportedName->value = GSSEAP_MALLOC(exportedNameLen);
     if (exportedName->value == NULL) {
@@ -612,7 +625,7 @@ gssEapExportNameInternal(OM_uint32 *minor,
         p += attrs.length;
     }
 
-    assert(p == (unsigned char *)exportedName->value + exportedNameLen);
+    GSSEAP_ASSERT(p == (unsigned char *)exportedName->value + exportedNameLen);
 
     major = GSS_S_COMPLETE;
     *minor = 0;
@@ -628,7 +641,7 @@ cleanup:
 
 OM_uint32
 gssEapCanonicalizeName(OM_uint32 *minor,
-                       const gss_name_t input_name,
+                       gss_const_name_t input_name,
                        const gss_OID mech_type,
                        gss_name_t *dest_name)
 {
@@ -670,11 +683,13 @@ gssEapCanonicalizeName(OM_uint32 *minor,
         goto cleanup;
     }
 
+#ifdef GSSEAP_ENABLE_ACCEPTOR
     if (input_name->attrCtx != NULL) {
         major = gssEapDuplicateAttrContext(minor, input_name, name);
         if (GSS_ERROR(major))
             goto cleanup;
     }
+#endif
 
     *dest_name = name;
 
@@ -688,16 +703,30 @@ cleanup:
 
 OM_uint32
 gssEapDuplicateName(OM_uint32 *minor,
-                    const gss_name_t input_name,
+                    gss_const_name_t input_name,
                     gss_name_t *dest_name)
 {
     return gssEapCanonicalizeName(minor, input_name,
                                   GSS_C_NO_OID, dest_name);
 }
 
+static int
+hasRealmP(gss_const_name_t name)
+{
+#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
+        return TRUE;
+
+    return FALSE;
+}
+
 OM_uint32
 gssEapDisplayName(OM_uint32 *minor,
-                  gss_name_t name,
+                  gss_const_name_t name,
                   gss_buffer_t output_name_buffer,
                   gss_OID *output_name_type)
 {
@@ -721,12 +750,7 @@ gssEapDisplayName(OM_uint32 *minor,
      * 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
+    if (!hasRealmP(name))
         flags |= KRB5_PRINCIPAL_UNPARSE_NO_REALM;
 
     *minor = krb5_unparse_name_flags(krbContext, name->krbPrincipal,
@@ -736,12 +760,13 @@ gssEapDisplayName(OM_uint32 *minor,
     }
 
     major = makeStringBuffer(minor, krbName, output_name_buffer);
-    if (GSS_ERROR(major)) {
-        krb5_free_unparsed_name(krbContext, krbName);
-        return major;
-    }
-
+#ifdef HAVE_HEIMDAL_VERSION
+    krb5_xfree(krbName);
+#else
     krb5_free_unparsed_name(krbContext, krbName);
+#endif
+    if (GSS_ERROR(major))
+        return major;
 
     if (output_name_buffer->length == 0) {
         name_type = GSS_C_NT_ANONYMOUS;
@@ -759,8 +784,9 @@ gssEapDisplayName(OM_uint32 *minor,
 
 OM_uint32
 gssEapCompareName(OM_uint32 *minor,
-                  gss_name_t name1,
-                  gss_name_t name2,
+                  gss_const_name_t name1,
+                  gss_const_name_t name2,
+                  OM_uint32 flags,
                   int *name_equal)
 {
     krb5_context krbContext;
@@ -773,9 +799,18 @@ gssEapCompareName(OM_uint32 *minor,
         GSSEAP_KRB_INIT(&krbContext);
 
         /* krbPrincipal is immutable, so lock not required */
-        *name_equal = krb5_principal_compare(krbContext,
-                                             name1->krbPrincipal,
-                                             name2->krbPrincipal);
+        if ((flags & COMPARE_NAME_FLAG_IGNORE_EMPTY_REALMS) &&
+            (hasRealmP(name1) == FALSE || hasRealmP(name2) == FALSE)) {
+            *name_equal = krb5_principal_compare_any_realm(krbContext,
+                                                           name1->krbPrincipal,
+                                                           name2->krbPrincipal);
+        } else {
+            *name_equal = krb5_principal_compare(krbContext,
+                                                 name1->krbPrincipal,
+                                                 name2->krbPrincipal);
+        }
+    } else {
+        *name_equal = 0;
     }
 
     return GSS_S_COMPLETE;