refactor OID interning code
authorLuke Howard <lukeh@padl.com>
Wed, 16 Mar 2011 04:14:52 +0000 (15:14 +1100)
committerLuke Howard <lukeh@padl.com>
Wed, 16 Mar 2011 04:25:24 +0000 (15:25 +1100)
accept_sec_context.c
canonicalize_name.c
import_sec_context.c
init_sec_context.c
inquire_context.c
inquire_name.c
util.h
util_attr.cpp
util_mech.c
util_name.c

index 9ef0fc9..5d2c113 100644 (file)
@@ -871,8 +871,14 @@ gss_accept_sec_context(OM_uint32 *minor,
         goto cleanup;
 
     if (mech_type != NULL) {
-        if (!gssEapInternalizeOid(ctx->mechanismUsed, mech_type))
-            duplicateOid(&tmpMinor, ctx->mechanismUsed, mech_type);
+        OM_uint32 tmpMajor;
+
+        tmpMajor = gssEapCanonicalizeOid(&tmpMinor, ctx->mechanismUsed, 0, mech_type);
+        if (GSS_ERROR(tmpMajor)) {
+            major = tmpMajor;
+            *minor = tmpMinor;
+            goto cleanup;
+        }
     }
     if (ret_flags != NULL)
         *ret_flags = ctx->gssFlags;
index 390864b..82d96b6 100644 (file)
@@ -56,7 +56,7 @@ gss_canonicalize_name(OM_uint32 *minor,
 
     GSSEAP_MUTEX_LOCK(&input_name->mutex);
 
-    major = gssEapDuplicateName(minor, input_name, output_name);
+    major = gssEapCanonicalizeName(minor, input_name, mech_type, output_name);
 
     GSSEAP_MUTEX_UNLOCK(&input_name->mutex);
 
index 08c5005..df52410 100644 (file)
@@ -121,16 +121,9 @@ importMechanismOid(OM_uint32 *minor,
 
     oidBuf.elements = &p[4];
 
-    if (!gssEapIsConcreteMechanismOid(&oidBuf)) {
-        *minor = GSSEAP_WRONG_MECH;
-        return GSS_S_BAD_MECH;
-    }
-
-    if (!gssEapInternalizeOid(&oidBuf, pOid)) {
-        major = duplicateOid(minor, &oidBuf, pOid);
-        if (GSS_ERROR(major))
-            return major;
-    }
+    major = gssEapCanonicalizeOid(minor, &oidBuf, 0, pOid);
+    if (GSS_ERROR(major))
+        return major;
 
     *pBuf    += 4 + oidBuf.length;
     *pRemain -= 4 + oidBuf.length;
index c42fa88..a731833 100644 (file)
@@ -362,15 +362,10 @@ initBegin(OM_uint32 *minor,
         GSSEAP_MUTEX_UNLOCK(&target->mutex);
     }
 
-    if (mech == GSS_C_NULL_OID) {
-        major = gssEapDefaultMech(minor, &ctx->mechanismUsed);
-    } else if (gssEapIsConcreteMechanismOid(mech)) {
-        if (!gssEapInternalizeOid(mech, &ctx->mechanismUsed))
-            major = duplicateOid(minor, mech, &ctx->mechanismUsed);
-    } else {
-        major = GSS_S_BAD_MECH;
-        *minor = GSSEAP_WRONG_MECH;
-    }
+    major = gssEapCanonicalizeOid(minor,
+                                  mech,
+                                  OID_FLAG_NULL_VALID | OID_FLAG_MAP_NULL_TO_DEFAULT_MECH,
+                                  &ctx->mechanismUsed);
     if (GSS_ERROR(major))
         return major;
 
@@ -974,8 +969,14 @@ gss_init_sec_context(OM_uint32 *minor,
         goto cleanup;
 
     if (actual_mech_type != NULL) {
-        if (!gssEapInternalizeOid(ctx->mechanismUsed, actual_mech_type))
-            duplicateOid(&tmpMinor, ctx->mechanismUsed, actual_mech_type);
+        OM_uint32 tmpMajor;
+
+        tmpMajor = gssEapCanonicalizeOid(&tmpMinor, ctx->mechanismUsed, 0, actual_mech_type);
+        if (GSS_ERROR(tmpMajor)) {
+            major = tmpMajor;
+            *minor = tmpMinor;
+            goto cleanup;
+        }
     }
     if (ret_flags != NULL)
         *ret_flags = ctx->gssFlags;
index 796f450..0e7b586 100644 (file)
@@ -84,11 +84,9 @@ gss_inquire_context(OM_uint32 *minor,
     }
 
     if (mech_type != NULL) {
-        if (!gssEapInternalizeOid(ctx->mechanismUsed, mech_type)) {
-            major = duplicateOid(minor, ctx->mechanismUsed, mech_type);
-            if (GSS_ERROR(major))
-                goto cleanup;
-        }
+        major = gssEapCanonicalizeOid(minor, ctx->mechanismUsed, 0, mech_type);
+        if (GSS_ERROR(major))
+            goto cleanup;
     }
 
     if (ctx_flags != NULL) {
index c62ff9e..2a4e0e3 100644 (file)
@@ -47,9 +47,9 @@ OM_uint32 gss_inquire_name(OM_uint32 *minor,
     *minor = 0;
 
     if (name_is_MN != NULL)
-        *name_is_MN = 1;
+        *name_is_MN = 0;
     if (MN_mech != NULL)
-        *MN_mech = GSS_EAP_MECHANISM;
+        *MN_mech = GSS_C_NO_OID;
     if (attrs != NULL)
         *attrs = GSS_C_NO_BUFFER_SET;
 
diff --git a/util.h b/util.h
index 8756c95..0f0c99c 100644 (file)
--- a/util.h
+++ b/util.h
@@ -205,12 +205,6 @@ gssEapContextTime(OM_uint32 *minor,
                   gss_ctx_id_t context_handle,
                   OM_uint32 *time_rec);
 
-OM_uint32
-gssEapDisplayName(OM_uint32 *minor,
-                  gss_name_t name,
-                  gss_buffer_t output_name_buffer,
-                  gss_OID *output_name_type);
-
 /* util_cred.c */
 OM_uint32 gssEapAllocCred(OM_uint32 *minor, gss_cred_id_t *pCred);
 OM_uint32 gssEapReleaseCred(OM_uint32 *minor, gss_cred_id_t *pCred);
@@ -410,9 +404,16 @@ gssEapExportLucidSecContext(OM_uint32 *minor,
 /* util_mech.c */
 extern gss_OID GSS_EAP_MECHANISM;
 
-int
-gssEapInternalizeOid(const gss_OID oid,
-                     gss_OID *const pInternalizedOid);
+#define OID_FLAG_NULL_VALID                 0x00000001
+#define OID_FLAG_FAMILY_MECH_VALID          0x00000002
+#define OID_FLAG_MAP_NULL_TO_DEFAULT_MECH   0x00000004
+#define OID_FLAG_MAP_FAMILY_MECH_TO_NULL    0x00000008
+
+OM_uint32
+gssEapCanonicalizeOid(OM_uint32 *minor,
+                      const gss_OID oid,
+                      OM_uint32 flags,
+                      gss_OID *pOid);
 
 OM_uint32
 gssEapReleaseOid(OM_uint32 *minor, gss_OID *oid);
@@ -478,6 +479,18 @@ gssEapDuplicateName(OM_uint32 *minor,
                     const gss_name_t input_name,
                     gss_name_t *dest_name);
 
+OM_uint32
+gssEapCanonicalizeName(OM_uint32 *minor,
+                       const gss_name_t input_name,
+                       const gss_OID mech_type,
+                       gss_name_t *dest_name);
+
+OM_uint32
+gssEapDisplayName(OM_uint32 *minor,
+                  gss_name_t name,
+                  gss_buffer_t output_name_buffer,
+                  gss_OID *output_name_type);
+
 /* util_oid.c */
 OM_uint32
 composeOid(OM_uint32 *minor_status,
index 28065ac..a24064a 100644 (file)
@@ -760,10 +760,22 @@ gss_eap_attr_ctx::composeAttributeName(unsigned int type,
 OM_uint32
 gssEapInquireName(OM_uint32 *minor,
                   gss_name_t name,
-                  int *name_is_MN GSSEAP_UNUSED,
-                  gss_OID *MN_mech GSSEAP_UNUSED,
+                  int *name_is_MN,
+                  gss_OID *MN_mech,
                   gss_buffer_set_t *attrs)
 {
+    OM_uint32 major;
+
+    if (name_is_MN != NULL)
+        *name_is_MN = (name->mechanismUsed != GSS_C_NULL_OID);
+
+    if (MN_mech != NULL) {
+        major = gssEapCanonicalizeOid(minor, name->mechanismUsed,
+                                      OID_FLAG_NULL_VALID, MN_mech);
+        if (GSS_ERROR(major))
+            return major;
+    }
+
     if (name->attrCtx == NULL) {
         *minor = GSSEAP_NO_ATTR_CONTEXT;
         return GSS_S_UNAVAILABLE;
index 8ce658e..e12fa54 100644 (file)
@@ -71,6 +71,10 @@ gss_OID GSS_EAP_MECHANISM                            = &gssEapMechOids[0];
 gss_OID GSS_EAP_AES128_CTS_HMAC_SHA1_96_MECHANISM    = &gssEapMechOids[1];
 gss_OID GSS_EAP_AES256_CTS_HMAC_SHA1_96_MECHANISM    = &gssEapMechOids[2];
 
+static int
+internalizeOid(const gss_OID oid,
+               gss_OID *const pInternalizedOid);
+
 /*
  * Returns TRUE is the OID is a concrete mechanism OID, that is, one
  * with a Kerberos enctype as the last element.
@@ -167,7 +171,7 @@ gssEapEnctypeToOid(OM_uint32 *minor,
                        enctype,
                        oid);
     if (major == GSS_S_COMPLETE) {
-        gssEapInternalizeOid(oid, pOid);
+        internalizeOid(oid, pOid);
         *pOid = oid;
     } else {
         GSSEAP_FREE(oid->elements);
@@ -240,7 +244,7 @@ gssEapDefaultMech(OM_uint32 *minor,
         return GSS_S_BAD_MECH;
     }
 
-    if (!gssEapInternalizeOid(&mechs->elements[0], oid)) {
+    if (!internalizeOid(&mechs->elements[0], oid)) {
         /* don't double-free if we didn't internalize it */
         mechs->elements[0].length = 0;
         mechs->elements[0].elements = NULL;
@@ -252,9 +256,9 @@ gssEapDefaultMech(OM_uint32 *minor,
     return GSS_S_COMPLETE;
 }
 
-int
-gssEapInternalizeOid(const gss_OID oid,
-                     gss_OID *const pInternalizedOid)
+static int
+internalizeOid(const gss_OID oid,
+               gss_OID *const pInternalizedOid)
 {
     int i;
 
@@ -289,7 +293,7 @@ gssEapReleaseOid(OM_uint32 *minor, gss_OID *oid)
 
     *minor = 0;
 
-    if (gssEapInternalizeOid(*oid, &internalizedOid)) {
+    if (internalizeOid(*oid, &internalizedOid)) {
         /* OID was internalized, so we can mark it as "freed" */
         *oid = GSS_C_NO_OID;
         return GSS_S_COMPLETE;
@@ -299,6 +303,47 @@ gssEapReleaseOid(OM_uint32 *minor, gss_OID *oid)
     return GSS_S_CONTINUE_NEEDED;
 }
 
+OM_uint32
+gssEapCanonicalizeOid(OM_uint32 *minor,
+                      const gss_OID oid,
+                      OM_uint32 flags,
+                      gss_OID *pOid)
+{
+    OM_uint32 major;
+    int mapToNull = 0;
+
+    major = GSS_S_COMPLETE;
+    *minor = 0;
+    *pOid = GSS_C_NULL_OID;
+
+    if (oid == GSS_C_NULL_OID) {
+        if ((flags & OID_FLAG_NULL_VALID) == 0) {
+            *minor = GSSEAP_WRONG_MECH;
+            return GSS_S_BAD_MECH;
+        } else if (flags & OID_FLAG_MAP_NULL_TO_DEFAULT_MECH) {
+            return gssEapDefaultMech(minor, pOid);
+        }
+    } else if (oidEqual(oid, GSS_EAP_MECHANISM)) {
+        if ((flags & OID_FLAG_FAMILY_MECH_VALID) == 0) {
+            *minor = GSSEAP_WRONG_MECH;
+            return GSS_S_BAD_MECH;
+        } else if (flags & OID_FLAG_MAP_FAMILY_MECH_TO_NULL) {
+            mapToNull = 1;
+        }
+    } else if (!gssEapIsConcreteMechanismOid(oid)) {
+        *minor = GSSEAP_WRONG_MECH;
+        return GSS_S_BAD_MECH;
+    }
+
+    if (!mapToNull && oid != GSS_C_NO_OID) {
+        if (!internalizeOid(oid, pOid))
+            major = duplicateOid(minor, oid, pOid);
+    }
+
+    assert(!GSS_ERROR(major));
+    return major;
+}
+
 static gss_buffer_desc gssEapSaslMechs[] = {
     { sizeof("EAP") - 1,        "EAP",       }, /* not used */
     { sizeof("EAP-AES128") - 1, "EAP-AES128" },
index dad8fb9..85f8b3f 100644 (file)
@@ -276,6 +276,7 @@ gssEapImportNameInternal(OM_uint32 *minor,
     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);
 
@@ -314,19 +315,13 @@ gssEapImportNameInternal(OM_uint32 *minor,
 
         CHECK_REMAIN(mech.length);
 
-        if (!gssEapIsMechanismOid(&mech)) {
-            major = GSS_S_BAD_NAME;
-            *minor = GSSEAP_WRONG_MECH;
+        major = gssEapCanonicalizeOid(minor,
+                                      &mech,
+                                      OID_FLAG_FAMILY_MECH_VALID |
+                                        OID_FLAG_MAP_FAMILY_MECH_TO_NULL,
+                                      &mechanismUsed);
+        if (GSS_ERROR(major))
             goto cleanup;
-        }
-
-        if (oidEqual(&mech, GSS_EAP_MECHANISM)) {
-            name->mechanismUsed = GSS_C_NO_OID;
-        } else if (!gssEapInternalizeOid(&mech, &name->mechanismUsed)) {
-            major = duplicateOid(minor, &mech, &name->mechanismUsed);
-            if (GSS_ERROR(major))
-                goto cleanup;
-        }
 
         UPDATE_REMAIN(2 + mech.length);
     }
@@ -346,6 +341,9 @@ gssEapImportNameInternal(OM_uint32 *minor,
     if (GSS_ERROR(major))
         goto cleanup;
 
+    name->mechanismUsed = mechanismUsed;
+    mechanismUsed = GSS_C_NO_OID;
+
     if (flags & EXPORT_NAME_FLAG_COMPOSITE) {
         gss_buffer_desc buf;
 
@@ -361,10 +359,12 @@ gssEapImportNameInternal(OM_uint32 *minor,
     *minor = 0;
 
 cleanup:
-    if (GSS_ERROR(major))
+    if (GSS_ERROR(major)) {
+        gssEapReleaseOid(&tmpMinor, &mechanismUsed);
         gssEapReleaseName(&tmpMinor, &name);
-    else
+    } else {
         *pName = name;
+    }
 
     return major;
 }
@@ -433,9 +433,7 @@ gssEapImportName(OM_uint32 *minor,
         assert(gssEapIsConcreteMechanismOid(mechType));
         assert(name->mechanismUsed == GSS_C_NO_OID);
 
-        if (!gssEapInternalizeOid(mechType, &name->mechanismUsed)) {
-            major = duplicateOid(minor, mechType, &name->mechanismUsed);
-        }
+        major = gssEapCanonicalizeOid(minor, mechType, 0, &name->mechanismUsed);
     }
 
     if (GSS_ERROR(major))
@@ -553,13 +551,15 @@ cleanup:
 }
 
 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;
@@ -573,21 +573,17 @@ gssEapDuplicateName(OM_uint32 *minor,
         return major;
     }
 
-    if (input_name->mechanismUsed == GSS_C_NO_OID) {
-        name->mechanismUsed = GSS_C_NO_OID;
-    } else if (gssEapIsConcreteMechanismOid(input_name->mechanismUsed)) {
-        if (!gssEapInternalizeOid(input_name->mechanismUsed,
-                                  &name->mechanismUsed)) {
-            major = duplicateOid(minor, input_name->mechanismUsed,
-                                 &name->mechanismUsed);
-            if (GSS_ERROR(major))
-                goto cleanup;
-        }
-    } else {
-        major = GSS_S_BAD_MECH;
-        *minor = GSSEAP_WRONG_MECH;
+    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;
 
@@ -615,6 +611,15 @@ 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,