Fix for OpenSSH interoperability
authorLuke Howard <lukeh@padl.com>
Wed, 16 Mar 2011 04:18:32 +0000 (15:18 +1100)
committerLuke Howard <lukeh@padl.com>
Wed, 16 Mar 2011 04:18:32 +0000 (15:18 +1100)
OpenSSH requires the exported name token to include the actual OID
of the selected mechanism. We were using an OID that identified a
family of GSS EAP mechanisms. We now use the concrete OID where
possible.

Conflicts:

mech_eap/util_name.c

13 files changed:
cyrus-sasl
mech_eap/accept_sec_context.c
mech_eap/gssapiP_eap.h
mech_eap/import_name.c
mech_eap/init_sec_context.c
mech_eap/util.h
mech_eap/util_cred.c
mech_eap/util_name.c
mech_eap/util_reauth.c
shibboleth/opensaml2
shibboleth/resolver
shibboleth/sp
shibboleth/xmltooling

index 755d9d2..903a7fe 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 755d9d20aadc1a140d01583b586f5a6d29c3a670
+Subproject commit 903a7fe023f6cd156451ccc35ab819500f520dcd
index 5829ed9..9ef0fc9 100644 (file)
@@ -82,6 +82,7 @@ acceptReadyEap(OM_uint32 *minor, gss_ctx_id_t ctx, gss_cred_id_t cred)
     major = gssEapImportName(minor, &nameBuf,
                              (ctx->gssFlags & GSS_C_ANON_FLAG) ?
                                 GSS_C_NT_ANONYMOUS : GSS_C_NT_USER_NAME,
+                             ctx->mechanismUsed,
                              &ctx->initiatorName);
     if (GSS_ERROR(major))
         return major;
@@ -272,7 +273,7 @@ importInitiatorIdentity(OM_uint32 *minor,
     gssEapReleaseName(&tmpMinor, &ctx->initiatorName);
 
     return gssEapImportName(minor, &nameBuf, GSS_C_NT_USER_NAME,
-                            &ctx->initiatorName);
+                            ctx->mechanismUsed, &ctx->initiatorName);
 }
 
 /*
index 10cd176..0f12811 100644 (file)
@@ -105,6 +105,7 @@ struct gss_name_struct
 {
     GSSEAP_MUTEX mutex; /* mutex protects attrCtx */
     OM_uint32 flags;
+    gss_OID mechanismUsed; /* this is immutable */
     krb5_principal krbPrincipal; /* this is immutable */
     struct gss_eap_attr_ctx *attrCtx;
 };
index d20d75c..87f0830 100644 (file)
@@ -43,5 +43,5 @@ gss_import_name(OM_uint32 *minor,
                 gss_name_t *output_name)
 {
     return gssEapImportName(minor, import_name_buffer,
-                            input_name_type, output_name);
+                            input_name_type, GSS_C_NO_OID, output_name);
 }
index 1f445bc..c42fa88 100644 (file)
@@ -543,7 +543,9 @@ eapGssSmInitAcceptorName(OM_uint32 *minor,
                ctx->acceptorName == GSS_C_NO_NAME) {
         /* Accept target name hint from acceptor */
         major = gssEapImportName(minor, inputToken,
-                                 GSS_C_NT_USER_NAME, &ctx->acceptorName);
+                                 GSS_C_NT_USER_NAME,
+                                 ctx->mechanismUsed,
+                                 &ctx->acceptorName);
         if (GSS_ERROR(major))
             return major;
     }
index ddf95a9..8756c95 100644 (file)
@@ -467,6 +467,7 @@ OM_uint32 gssEapExportNameInternal(OM_uint32 *minor,
 OM_uint32 gssEapImportName(OM_uint32 *minor,
                            const gss_buffer_t input_name_buffer,
                            gss_OID input_name_type,
+                           gss_OID input_mech_type,
                            gss_name_t *output_name);
 OM_uint32 gssEapImportNameInternal(OM_uint32 *minor,
                                    const gss_buffer_t input_name_buffer,
index 64b9284..a2a01ba 100644 (file)
@@ -184,7 +184,13 @@ gssEapAcquireCred(OM_uint32 *minor,
         }
 
         if (nameBuf.length != 0) {
-            major = gssEapImportName(minor, &nameBuf, nameType, &cred->name);
+            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);
             if (GSS_ERROR(major))
                 goto cleanup;
         }
index 70d23e2..dad8fb9 100644 (file)
@@ -111,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);
 
@@ -282,7 +283,10 @@ gssEapImportNameInternal(OM_uint32 *minor,
     remain = nameBuffer->length;
 
     if (flags & EXPORT_NAME_FLAG_OID) {
-        if (remain < 6 + GSS_EAP_MECHANISM->length)
+        gss_OID_desc mech;
+
+        /* TOK_ID || MECH_OID_LEN || MECH_OID */
+        if (remain < 6)
             return GSS_S_BAD_NAME;
 
         if (flags & EXPORT_NAME_FLAG_COMPOSITE)
@@ -297,18 +301,34 @@ gssEapImportNameInternal(OM_uint32 *minor,
 
         /* MECH_OID_LEN */
         len = load_uint16_be(p);
-        if (len != 2 + GSS_EAP_MECHANISM->length)
+        if (len < 2)
             return GSS_S_BAD_NAME;
         UPDATE_REMAIN(2);
 
         /* MECH_OID */
         if (p[0] != 0x06)
             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);
+
+        if (!gssEapIsMechanismOid(&mech)) {
+            major = GSS_S_BAD_NAME;
+            *minor = GSSEAP_WRONG_MECH;
+            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);
     }
 
     /* NAME_LEN */
@@ -379,7 +399,8 @@ OM_uint32
 gssEapImportName(OM_uint32 *minor,
                  const gss_buffer_t nameBuffer,
                  gss_OID nameType,
-                 gss_name_t *name)
+                 gss_OID mechType,
+                 gss_name_t *pName)
 {
     struct gss_eap_name_import_provider nameTypes[] = {
         { GSS_C_NT_USER_NAME,               importUserName              },
@@ -393,18 +414,36 @@ gssEapImportName(OM_uint32 *minor,
 #endif
     };
     size_t i;
-
-    *name = GSS_C_NO_NAME;
+    OM_uint32 major = GSS_S_BAD_NAMETYPE;
+    OM_uint32 tmpMinor;
+    gss_name_t name = GSS_C_NO_NAME;
 
     if (nameType == GSS_C_NO_OID)
         nameType = nameTypes[0].oid;
 
     for (i = 0; i < sizeof(nameTypes) / sizeof(nameTypes[0]); i++) {
-        if (oidEqual(nameTypes[i].oid, nameType))
-            return nameTypes[i].import(minor, nameBuffer, name);
+        if (oidEqual(nameTypes[i].oid, nameType)) {
+            major = nameTypes[i].import(minor, nameBuffer, &name);
+            break;
+        }
     }
 
-    return GSS_S_BAD_NAMETYPE;
+    if (major == GSS_S_COMPLETE &&
+        mechType != GSS_C_NO_OID) {
+        assert(gssEapIsConcreteMechanismOid(mechType));
+        assert(name->mechanismUsed == GSS_C_NO_OID);
+
+        if (!gssEapInternalizeOid(mechType, &name->mechanismUsed)) {
+            major = duplicateOid(minor, mechType, &name->mechanismUsed);
+        }
+    }
+
+    if (GSS_ERROR(major))
+        gssEapReleaseName(&tmpMinor, &name);
+    else
+        *pName = name;
+
+    return major;
 }
 
 OM_uint32
@@ -428,10 +467,16 @@ gssEapExportNameInternal(OM_uint32 *minor,
     size_t krbNameLen, exportedNameLen;
     unsigned char *p;
     gss_buffer_desc attrs = GSS_C_EMPTY_BUFFER;
+    gss_OID mech;
 
     exportedName->length = 0;
     exportedName->value = NULL;
 
+    if (name->mechanismUsed != GSS_C_NO_OID)
+        mech = name->mechanismUsed;
+    else
+        mech = GSS_EAP_MECHANISM;
+
     GSSEAP_KRB_INIT(&krbContext);
 
     *minor = krb5_unparse_name(krbContext, name->krbPrincipal, &krbName);
@@ -443,7 +488,7 @@ gssEapExportNameInternal(OM_uint32 *minor,
 
     exportedNameLen = 0;
     if (flags & EXPORT_NAME_FLAG_OID) {
-        exportedNameLen += 6 + GSS_EAP_MECHANISM->length;
+        exportedNameLen += 6 + mech->length;
     }
     exportedNameLen += 4 + krbNameLen;
     if (flags & EXPORT_NAME_FLAG_COMPOSITE) {
@@ -470,14 +515,14 @@ 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 */
@@ -528,6 +573,22 @@ 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;
+        goto cleanup;
+    }
+
     name->flags = input_name->flags;
 
     *minor = krb5_copy_principal(krbContext, input_name->krbPrincipal,
index f1112ca..22f089f 100644 (file)
@@ -735,7 +735,7 @@ gssEapGlueToMechName(OM_uint32 *minor,
         goto cleanup;
 
     major = gssEapImportName(minor, &nameBuf, GSS_C_NT_USER_NAME,
-                             pMechName);
+                             ctx->mechanismUsed, pMechName);
     if (GSS_ERROR(major))
         goto cleanup;
 
index 4bc248e..bc8f231 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 4bc248e6a38e0c1c23dee3e2dec278ceebd0abfa
+Subproject commit bc8f2316372e27206992152b93621053cb6dc534
index b08a23a..dfff542 160000 (submodule)
@@ -1 +1 @@
-Subproject commit b08a23ae0714acf9f6dd7859cfb9f6b2ddcc2af3
+Subproject commit dfff542c1969dd3e59f66c24968dbd153e3e6873
index a0af8ed..0c908d7 160000 (submodule)
@@ -1 +1 @@
-Subproject commit a0af8ed86ab481af4605daf5cf837fdaa4544bdd
+Subproject commit 0c908d7f33faba3bd92260dae79bc63df3ff7698
index ec12184..21ecbfb 160000 (submodule)
@@ -1 +1 @@
-Subproject commit ec12184bd72287b88af4301bde2df916fc475615
+Subproject commit 21ecbfb331400c6acb087b809dfa07dc20d5a6fb