refactory extensions code per Sam's comments
authorLuke Howard <lukeh@padl.com>
Sun, 10 Oct 2010 23:57:24 +0000 (01:57 +0200)
committerLuke Howard <lukeh@padl.com>
Sun, 10 Oct 2010 23:57:24 +0000 (01:57 +0200)
mech_eap/accept_sec_context.c
mech_eap/init_sec_context.c
mech_eap/util.h
mech_eap/util_exts.c

index debe76a..4a0fe01 100644 (file)
@@ -405,45 +405,6 @@ cleanup:
 }
 
 static OM_uint32
-verifyGssChannelBindings(OM_uint32 *minor,
-                         gss_cred_id_t cred,
-                         gss_ctx_id_t ctx,
-                         gss_channel_bindings_t chanBindings,
-                         gss_buffer_t inputToken)
-{
-    OM_uint32 major, tmpMinor;
-    gss_iov_buffer_desc iov[2];
-
-    iov[0].type = GSS_IOV_BUFFER_TYPE_DATA | GSS_IOV_BUFFER_FLAG_ALLOCATE;
-    iov[0].buffer.length = 0;
-    iov[0].buffer.value = NULL;
-
-    iov[1].type = GSS_IOV_BUFFER_TYPE_STREAM;
-    iov[1].buffer = *inputToken;
-
-    major = gssEapUnwrapOrVerifyMIC(minor, ctx, NULL, NULL,
-                                    iov, 2, TOK_TYPE_WRAP);
-    if (GSS_ERROR(major))
-        return major;
-
-    if (chanBindings != GSS_C_NO_CHANNEL_BINDINGS &&
-        !bufferEqual(&iov[0].buffer, &chanBindings->application_data)) {
-        major = GSS_S_BAD_BINDINGS;
-    } else {
-        major = GSS_S_COMPLETE;
-    }
-
-    gss_release_buffer(&tmpMinor, &iov[0].buffer);
-
-    return major;
-}
-
-static struct gss_eap_extension_provider
-eapGssVerifyInitExtensions[] = {
-    { EXT_TYPE_GSS_CHANNEL_BINDINGS, 1, verifyGssChannelBindings },
-};
-
-static OM_uint32
 eapGssSmAcceptExtensionsReq(OM_uint32 *minor,
                             gss_ctx_id_t ctx,
                             gss_cred_id_t cred,
@@ -453,10 +414,7 @@ eapGssSmAcceptExtensionsReq(OM_uint32 *minor,
 {
     OM_uint32 major;
 
-    major = gssEapVerifyExtensions(minor, cred, ctx, eapGssVerifyInitExtensions,
-                                   sizeof(eapGssVerifyInitExtensions) /
-                                        sizeof(eapGssVerifyInitExtensions[0]),
-                                   chanBindings, inputToken);
+    major = gssEapVerifyExtensions(minor, cred, ctx, chanBindings, inputToken);
     if (GSS_ERROR(major))
         return major;
 
@@ -466,31 +424,6 @@ eapGssSmAcceptExtensionsReq(OM_uint32 *minor,
 }
 
 static OM_uint32
-makeReauthCreds(OM_uint32 *minor,
-                gss_cred_id_t cred,
-                gss_ctx_id_t ctx,
-                gss_channel_bindings_t chanBindings,
-                gss_buffer_t outputToken)
-{
-    OM_uint32 major = GSS_S_UNAVAILABLE;
-
-#ifdef GSSEAP_ENABLE_REAUTH
-    /*
-     * If we're built with fast reauthentication enabled, then
-     * fabricate a ticket from the initiator to ourselves.
-     */
-    major = gssEapMakeReauthCreds(minor, ctx, cred, outputToken);
-#endif
-
-    return major;
-}
-
-static struct gss_eap_extension_provider
-eapGssMakeAcceptExtensions[] = {
-    { EXT_TYPE_REAUTH_CREDS, 0, makeReauthCreds },
-};
-
-static OM_uint32
 eapGssSmAcceptExtensionsResp(OM_uint32 *minor,
                              gss_ctx_id_t ctx,
                              gss_cred_id_t cred,
@@ -500,10 +433,7 @@ eapGssSmAcceptExtensionsResp(OM_uint32 *minor,
 {
     OM_uint32 major;
 
-    major = gssEapMakeExtensions(minor, cred, ctx, eapGssMakeAcceptExtensions,
-                                 sizeof(eapGssMakeAcceptExtensions) /
-                                    sizeof(eapGssMakeAcceptExtensions[0]),
-                                 chanBindings, outputToken);
+    major = gssEapMakeExtensions(minor, cred, ctx, chanBindings, outputToken);
     if (GSS_ERROR(major))
         return major;
 
index 80abb05..996e250 100644 (file)
@@ -487,32 +487,6 @@ cleanup:
 }
 
 static OM_uint32
-makeGssChannelBindings(OM_uint32 *minor,
-                       gss_cred_id_t cred,
-                       gss_ctx_id_t ctx,
-                       gss_channel_bindings_t chanBindings,
-                       gss_buffer_t outputToken)
-{
-    OM_uint32 major;
-    gss_buffer_desc buffer = GSS_C_EMPTY_BUFFER;
-
-    if (chanBindings != GSS_C_NO_CHANNEL_BINDINGS)
-        buffer = chanBindings->application_data;
-
-    major = gssEapWrap(minor, ctx, TRUE, GSS_C_QOP_DEFAULT,
-                       &buffer, NULL, outputToken);
-    if (GSS_ERROR(major))
-        return major;                       
-
-    return GSS_S_COMPLETE;
-}
-
-static struct gss_eap_extension_provider
-eapGssMakeInitExtensions[] = {
-    { EXT_TYPE_GSS_CHANNEL_BINDINGS, 1, makeGssChannelBindings },
-};
-
-static OM_uint32
 eapGssSmInitExtensionsReq(OM_uint32 *minor,
                           gss_cred_id_t cred,
                           gss_ctx_id_t ctx,
@@ -526,10 +500,7 @@ eapGssSmInitExtensionsReq(OM_uint32 *minor,
 {
     OM_uint32 major;
 
-    major = gssEapMakeExtensions(minor, cred, ctx, eapGssMakeInitExtensions,
-                                 sizeof(eapGssMakeInitExtensions) /
-                                    sizeof(eapGssMakeInitExtensions[0]),
-                                 chanBindings, outputToken);
+    major = gssEapMakeExtensions(minor, cred, ctx, chanBindings, outputToken);
     if (GSS_ERROR(major))
         return major;
 
@@ -541,25 +512,6 @@ eapGssSmInitExtensionsReq(OM_uint32 *minor,
 }
 
 static OM_uint32
-verifyReauthCreds(OM_uint32 *minor,
-                  gss_cred_id_t cred,
-                  gss_ctx_id_t ctx,
-                  gss_channel_bindings_t chanBindings,
-                  gss_buffer_t inputToken)
-{
-#ifdef GSSEAP_ENABLE_REAUTH
-    return gssEapStoreReauthCreds(minor, ctx, cred, inputToken);
-#else
-    return GSS_S_UNAVAILABLE;
-#endif
-}
-
-static struct gss_eap_extension_provider
-eapGssVerifyAcceptExtensions[] = {
-    { EXT_TYPE_REAUTH_CREDS, 0, verifyReauthCreds },
-};
-
-static OM_uint32
 eapGssSmInitExtensionsResp(OM_uint32 *minor,
                            gss_cred_id_t cred,
                            gss_ctx_id_t ctx,
@@ -573,10 +525,7 @@ eapGssSmInitExtensionsResp(OM_uint32 *minor,
 {
     OM_uint32 major;
 
-    major = gssEapVerifyExtensions(minor, cred, ctx, eapGssVerifyAcceptExtensions,
-                                   sizeof(eapGssVerifyAcceptExtensions) /
-                                        sizeof(eapGssVerifyAcceptExtensions[0]),
-                                   chanBindings, inputToken);
+    major = gssEapVerifyExtensions(minor, cred, ctx, chanBindings, inputToken);
     if (GSS_ERROR(major))
         return major;
 
index 9184ebf..3494aab 100644 (file)
@@ -253,20 +253,24 @@ gssEapDeriveRfc3961Key(OM_uint32 *minor,
 
 struct gss_eap_extension_provider {
     OM_uint32 type;
-    int critical;
-    OM_uint32 (*callback)(OM_uint32 *,
-                          gss_cred_id_t,
-                          gss_ctx_id_t,
-                          gss_channel_bindings_t,
-                          gss_buffer_t);
+    int critical; /* client */
+    int required; /* server */
+    OM_uint32 (*make)(OM_uint32 *,
+                      gss_cred_id_t,
+                      gss_ctx_id_t,
+                      gss_channel_bindings_t,
+                      gss_buffer_t);
+    OM_uint32 (*verify)(OM_uint32 *,
+                        gss_cred_id_t,
+                        gss_ctx_id_t,
+                        gss_channel_bindings_t,
+                        const gss_buffer_t);
 };
 
 OM_uint32
 gssEapMakeExtensions(OM_uint32 *minor,
                      gss_cred_id_t cred,
                      gss_ctx_id_t ctx,
-                     const struct gss_eap_extension_provider *exts,
-                     size_t count,
                      gss_channel_bindings_t chanBindings,
                      gss_buffer_t buffer);
 
@@ -274,8 +278,6 @@ OM_uint32
 gssEapVerifyExtensions(OM_uint32 *minor,
                        gss_cred_id_t cred,
                        gss_ctx_id_t ctx,
-                       const struct gss_eap_extension_provider *exts,
-                       size_t count,
                        gss_channel_bindings_t chanBindings,
                        const gss_buffer_t buffer);
 
index 906430c..0cdeed0 100644 (file)
 #include "gssapiP_eap.h"
 
 static OM_uint32
+makeGssChannelBindings(OM_uint32 *minor,
+                       gss_cred_id_t cred,
+                       gss_ctx_id_t ctx,
+                       gss_channel_bindings_t chanBindings,
+                       gss_buffer_t outputToken)
+{
+    OM_uint32 major;
+    gss_buffer_desc buffer = GSS_C_EMPTY_BUFFER;
+
+    if (chanBindings != GSS_C_NO_CHANNEL_BINDINGS)
+        buffer = chanBindings->application_data;
+
+    major = gssEapWrap(minor, ctx, TRUE, GSS_C_QOP_DEFAULT,
+                       &buffer, NULL, outputToken);
+    if (GSS_ERROR(major))
+        return major;
+
+    return GSS_S_COMPLETE;
+}
+
+static OM_uint32
+verifyGssChannelBindings(OM_uint32 *minor,
+                         gss_cred_id_t cred,
+                         gss_ctx_id_t ctx,
+                         gss_channel_bindings_t chanBindings,
+                         gss_buffer_t inputToken)
+{
+    OM_uint32 major, tmpMinor;
+    gss_iov_buffer_desc iov[2];
+
+    iov[0].type = GSS_IOV_BUFFER_TYPE_DATA | GSS_IOV_BUFFER_FLAG_ALLOCATE;
+    iov[0].buffer.length = 0;
+    iov[0].buffer.value = NULL;
+
+    iov[1].type = GSS_IOV_BUFFER_TYPE_STREAM;
+    iov[1].buffer = *inputToken;
+
+    major = gssEapUnwrapOrVerifyMIC(minor, ctx, NULL, NULL,
+                                    iov, 2, TOK_TYPE_WRAP);
+    if (GSS_ERROR(major))
+        return major;
+
+    if (chanBindings != GSS_C_NO_CHANNEL_BINDINGS &&
+        !bufferEqual(&iov[0].buffer, &chanBindings->application_data)) {
+        major = GSS_S_BAD_BINDINGS;
+    } else {
+        major = GSS_S_COMPLETE;
+    }
+
+    gss_release_buffer(&tmpMinor, &iov[0].buffer);
+
+    return major;
+}
+
+static struct gss_eap_extension_provider
+eapGssInitExtensions[] = {
+    {
+        EXT_TYPE_GSS_CHANNEL_BINDINGS,
+        1, /* critical */
+        1, /* required */
+        makeGssChannelBindings,
+        verifyGssChannelBindings
+    },
+};
+
+static OM_uint32
+makeReauthCreds(OM_uint32 *minor,
+                gss_cred_id_t cred,
+                gss_ctx_id_t ctx,
+                gss_channel_bindings_t chanBindings,
+                gss_buffer_t outputToken)
+{
+    OM_uint32 major = GSS_S_UNAVAILABLE;
+
+#ifdef GSSEAP_ENABLE_REAUTH
+    /*
+     * If we're built with fast reauthentication enabled, then
+     * fabricate a ticket from the initiator to ourselves.
+     */
+    major = gssEapMakeReauthCreds(minor, ctx, cred, outputToken);
+#endif
+
+    return major;
+}
+
+static OM_uint32
+verifyReauthCreds(OM_uint32 *minor,
+                  gss_cred_id_t cred,
+                  gss_ctx_id_t ctx,
+                  gss_channel_bindings_t chanBindings,
+                  gss_buffer_t inputToken)
+{
+#ifdef GSSEAP_ENABLE_REAUTH
+    return gssEapStoreReauthCreds(minor, ctx, cred, inputToken);
+#else
+    return GSS_S_UNAVAILABLE;
+#endif
+}
+
+static struct gss_eap_extension_provider
+eapGssAcceptExtensions[] = {
+    {
+        EXT_TYPE_REAUTH_CREDS,
+        0, /* critical */
+        0, /* required */
+        makeReauthCreds,
+        verifyReauthCreds
+    },
+};
+
+static OM_uint32
 encodeExtensions(OM_uint32 *minor,
                  gss_buffer_set_t extensions,
                  OM_uint32 *types,
@@ -174,29 +285,36 @@ OM_uint32
 gssEapMakeExtensions(OM_uint32 *minor,
                      gss_cred_id_t cred,
                      gss_ctx_id_t ctx,
-                     const struct gss_eap_extension_provider *exts,
-                     size_t count,
                      gss_channel_bindings_t chanBindings,
                      gss_buffer_t buffer)
 {
     OM_uint32 major, tmpMinor;
-    size_t i, j;
+    size_t i, j, nexts;
     gss_buffer_set_t extensions = GSS_C_NO_BUFFER_SET;
     OM_uint32 *types;
+    const struct gss_eap_extension_provider *exts;
+
+    if (CTX_IS_INITIATOR(ctx)) {
+        exts = eapGssInitExtensions;
+        nexts = sizeof(eapGssInitExtensions) / sizeof(eapGssInitExtensions[0]);
+    } else {
+        exts = eapGssAcceptExtensions;
+        nexts = sizeof(eapGssAcceptExtensions) / sizeof(eapGssAcceptExtensions[0]);
+    }
 
     assert(buffer != GSS_C_NO_BUFFER);
 
     buffer->length = 0;
     buffer->value = NULL;
 
-    types = GSSEAP_CALLOC(count, sizeof(OM_uint32));
+    types = GSSEAP_CALLOC(nexts, sizeof(OM_uint32));
     if (types == NULL) {
         *minor = ENOMEM;
         major = GSS_S_FAILURE;
         goto cleanup;
     }
 
-    for (i = 0, j = 0; i < count; i++) {
+    for (i = 0, j = 0; i < nexts; i++) {
         const struct gss_eap_extension_provider *ext = &exts[i];
         gss_buffer_desc extension = GSS_C_EMPTY_BUFFER;
 
@@ -204,12 +322,12 @@ gssEapMakeExtensions(OM_uint32 *minor,
         if (ext->critical)
             types[j] |= EXT_FLAG_CRITICAL;
 
-        major = ext->callback(minor, cred, ctx, chanBindings, &extension);
+        major = ext->make(minor, cred, ctx, chanBindings, &extension);
         if (GSS_ERROR(major)) {
             if (ext->critical)
-                continue;
-            else
                 goto cleanup;
+            else
+                continue;
         }
 
         major = gss_add_buffer_set_member(minor, &extension, &extensions);
@@ -237,21 +355,28 @@ OM_uint32
 gssEapVerifyExtensions(OM_uint32 *minor,
                        gss_cred_id_t cred,
                        gss_ctx_id_t ctx,
-                       const struct gss_eap_extension_provider *exts,
-                       size_t count,
                        gss_channel_bindings_t chanBindings,
                        const gss_buffer_t buffer)
 {
     OM_uint32 major, tmpMinor;
     gss_buffer_set_t extensions = GSS_C_NO_BUFFER_SET;
     OM_uint32 *types = NULL;
-    size_t i;
+    size_t i, nexts;
+    const struct gss_eap_extension_provider *exts;
+
+    if (CTX_IS_INITIATOR(ctx)) {
+        exts = eapGssAcceptExtensions;
+        nexts = sizeof(eapGssAcceptExtensions) / sizeof(eapGssAcceptExtensions[0]);
+    } else {
+        exts = eapGssInitExtensions;
+        nexts = sizeof(eapGssInitExtensions) / sizeof(eapGssInitExtensions[0]);
+    }
 
     major = decodeExtensions(minor, buffer, &extensions, &types);
     if (GSS_ERROR(major))
         goto cleanup;
 
-    for (i = 0; i < count; i++) {
+    for (i = 0; i < nexts; i++) {
         const struct gss_eap_extension_provider *ext = &exts[i];
         gss_buffer_t extension = GSS_C_NO_BUFFER;
         size_t j;
@@ -265,18 +390,18 @@ gssEapVerifyExtensions(OM_uint32 *minor,
 
         if (extension != GSS_C_NO_BUFFER) {
             /* Process extension and mark as verified */
-            major = ext->callback(minor, cred, ctx, chanBindings,
-                                  &extensions->elements[j]);
+            major = ext->verify(minor, cred, ctx, chanBindings,
+                                &extensions->elements[j]);
             if (GSS_ERROR(major))
                 goto cleanup;
 
             types[j] |= EXT_FLAG_VERIFIED;
-        } else if (ext->critical) {
-            /* Critical extension missing */
+        } else if (ext->required) {
+            /* Required extension missing */
             *minor = ENOENT;
             major = GSS_S_UNAVAILABLE;
             gssEapSaveStatusInfo(*minor,
-                                 "Missing critical GSS EAP extension %08x",
+                                 "Missing required GSS EAP extension %08x",
                                  ext->type);
             goto cleanup;
         }