}
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,
{
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;
}
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,
{
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;
}
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,
{
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;
}
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,
{
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;
#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,
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;
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);
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;
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;
}