OM_uint32 timeReq __attribute__((__unused__)),
gss_channel_bindings_t chanBindings,
gss_buffer_t inputToken,
- gss_buffer_t outputToken);
+ gss_buffer_t outputToken,
+ OM_uint32 *smFlags);
#endif
/*
return GSS_S_COMPLETE;
}
+#ifdef GSSEAP_DEBUG
+static OM_uint32
+eapGssSmAcceptVendorInfo(OM_uint32 *minor,
+ gss_cred_id_t cred,
+ gss_ctx_id_t ctx,
+ gss_name_t target,
+ gss_OID mech,
+ OM_uint32 reqFlags,
+ OM_uint32 timeReq,
+ gss_channel_bindings_t chanBindings,
+ gss_buffer_t inputToken,
+ gss_buffer_t outputToken,
+ OM_uint32 *smFlags)
+{
+ fprintf(stderr, "GSS-EAP: vendor: %.*s\n",
+ (int)inputToken->length, (char *)inputToken->value);
+
+ return GSS_S_CONTINUE_NEEDED;
+}
+#endif
+
+
/*
* Emit a identity EAP request to force the initiator (peer) to identify
* itself.
OM_uint32 timeReq __attribute__((__unused__)),
gss_channel_bindings_t chanBindings __attribute__((__unused__)),
gss_buffer_t inputToken,
- gss_buffer_t outputToken)
+ gss_buffer_t outputToken,
+ OM_uint32 *smFlags)
{
OM_uint32 major;
struct wpabuf *reqData;
wpabuf_free(reqData);
+ GSSEAP_SM_TRANSITION_NEXT(ctx);
+
*minor = 0;
- return GSS_S_COMPLETE; /* advance state */
+
+ return GSS_S_CONTINUE_NEEDED;
}
/*
OM_uint32 timeReq __attribute__((__unused__)),
gss_channel_bindings_t chanBindings,
gss_buffer_t inputToken,
- gss_buffer_t outputToken)
+ gss_buffer_t outputToken,
+ OM_uint32 *smFlags)
{
OM_uint32 major, tmpMinor;
struct rs_connection *rconn;
&ctx->acceptorCtx.state, TRUE);
if (GSS_ERROR(major) && *minor != GSSEAP_NO_SUCH_ATTR)
goto cleanup;
-
- major = GSS_S_CONTINUE_NEEDED;
} else {
ctx->acceptorCtx.vps = frresp->vps;
frresp->vps = NULL;
if (GSS_ERROR(major))
goto cleanup;
- major = GSS_S_COMPLETE; /* advance state */
+ GSSEAP_SM_TRANSITION_NEXT(ctx);
}
+ major = GSS_S_CONTINUE_NEEDED;
+ *minor = 0;
+
cleanup:
if (request != NULL)
rs_request_destroy(request);
OM_uint32 timeReq __attribute__((__unused__)),
gss_channel_bindings_t chanBindings,
gss_buffer_t inputToken,
- gss_buffer_t outputToken)
+ gss_buffer_t outputToken,
+ OM_uint32 *smFlags)
{
OM_uint32 major, tmpMinor;
gss_iov_buffer_desc iov[2];
major = GSS_S_BAD_BINDINGS;
*minor = GSSEAP_BINDINGS_MISMATCH;
} else {
- major = GSS_S_CONTINUE_NEEDED; /* process additional extensions */
+ major = GSS_S_CONTINUE_NEEDED;
*minor = 0;
}
OM_uint32 timeReq __attribute__((__unused__)),
gss_channel_bindings_t chanBindings __attribute__((__unused__)),
gss_buffer_t inputToken,
- gss_buffer_t outputToken)
+ gss_buffer_t outputToken,
+ OM_uint32 *smFlags)
{
OM_uint32 major;
* fabricate a ticket from the initiator to ourselves.
*/
major = gssEapMakeReauthCreds(minor, ctx, cred, outputToken);
- if (GSS_ERROR(major))
- return major;
+ if (major == GSS_S_UNAVAILABLE)
+ major = GSS_S_COMPLETE;
+ if (major == GSS_S_COMPLETE)
+ major = GSS_S_CONTINUE_NEEDED;
- *minor = 0;
- return GSS_S_CONTINUE_NEEDED; /* process additional extensions */
+ return major;
}
#endif
static OM_uint32
-eapGssSmAcceptNegoExtFinished(OM_uint32 *minor,
- gss_cred_id_t cred,
- gss_ctx_id_t ctx,
- gss_name_t target __attribute__((__unused__)),
- gss_OID mech __attribute__((__unused__)),
- OM_uint32 reqFlags __attribute__((__unused__)),
- OM_uint32 timeReq __attribute__((__unused__)),
- gss_channel_bindings_t chanBindings __attribute__((__unused__)),
- gss_buffer_t inputToken,
- gss_buffer_t outputToken)
+eapGssSmAcceptCompleteInitiatorExts(OM_uint32 *minor,
+ gss_cred_id_t cred,
+ gss_ctx_id_t ctx,
+ gss_name_t target,
+ gss_OID mech,
+ OM_uint32 reqFlags,
+ OM_uint32 timeReq,
+ gss_channel_bindings_t chanBindings,
+ gss_buffer_t inputToken,
+ gss_buffer_t outputToken,
+ OM_uint32 *smFlags)
{
+ GSSEAP_SM_TRANSITION_NEXT(ctx);
+
*minor = 0;
- return GSS_S_COMPLETE; /* advance state */
+
+ return GSS_S_CONTINUE_NEEDED;
+}
+
+static OM_uint32
+eapGssSmAcceptCompleteAcceptorExts(OM_uint32 *minor,
+ gss_cred_id_t cred,
+ gss_ctx_id_t ctx,
+ gss_name_t target,
+ gss_OID mech,
+ OM_uint32 reqFlags,
+ OM_uint32 timeReq,
+ gss_channel_bindings_t chanBindings,
+ gss_buffer_t inputToken,
+ gss_buffer_t outputToken,
+ OM_uint32 *smFlags)
+{
+ GSSEAP_SM_TRANSITION(ctx, GSSEAP_STATE_ESTABLISHED);
+
+ *minor = 0;
+ *smFlags |= SM_FLAG_FORCE_SEND_TOKEN;
+
+ return GSS_S_COMPLETE;
}
static struct gss_eap_sm eapGssAcceptorSm[] = {
+#ifdef GSSEAP_DEBUG
+ {
+ ITOK_TYPE_VENDOR_INFO,
+ ITOK_TYPE_NONE,
+ GSSEAP_STATE_INITIAL,
+ 0,
+ eapGssSmAcceptVendorInfo,
+ },
+#endif
#ifdef GSSEAP_ENABLE_REAUTH
{
ITOK_TYPE_REAUTH_REQ,
ITOK_TYPE_REAUTH_RESP,
GSSEAP_STATE_INITIAL,
- 0, /* critical */
- 0, /* required */
+ 0,
eapGssSmAcceptGssReauth,
},
#endif
ITOK_TYPE_NONE,
ITOK_TYPE_EAP_REQ,
GSSEAP_STATE_INITIAL,
- 1, /* critical */
- 1, /* required */
+ SM_ITOK_FLAG_CRITICAL | SM_ITOK_FLAG_REQUIRED,
eapGssSmAcceptIdentity,
},
{
ITOK_TYPE_EAP_RESP,
ITOK_TYPE_EAP_REQ,
GSSEAP_STATE_AUTHENTICATE,
- 1, /* critical */
- 1, /* required */
+ SM_ITOK_FLAG_CRITICAL | SM_ITOK_FLAG_REQUIRED,
eapGssSmAcceptAuthenticate
},
{
ITOK_TYPE_GSS_CHANNEL_BINDINGS,
ITOK_TYPE_NONE,
- GSSEAP_STATE_NEGO_EXT,
- 1, /* critical */
- 1, /* required */
+ GSSEAP_STATE_INITIATOR_EXTS,
+ SM_ITOK_FLAG_CRITICAL | SM_ITOK_FLAG_REQUIRED,
eapGssSmAcceptGssChannelBindings,
},
{
ITOK_TYPE_NONE,
+ ITOK_TYPE_NONE,
+ GSSEAP_STATE_INITIATOR_EXTS,
+ 0,
+ eapGssSmAcceptCompleteInitiatorExts,
+ },
+#ifdef GSSEAP_ENABLE_REAUTH
+ {
+ ITOK_TYPE_NONE,
ITOK_TYPE_REAUTH_CREDS,
- GSSEAP_STATE_NEGO_EXT,
- 0, /* critical */
- 0, /* required */
+ GSSEAP_STATE_ACCEPTOR_EXTS,
+ 0,
eapGssSmAcceptReauthCreds,
},
+#endif
{
ITOK_TYPE_NONE,
ITOK_TYPE_NONE,
- GSSEAP_STATE_NEGO_EXT,
- 1, /* critical */
- 1, /* required */
- eapGssSmAcceptNegoExtFinished
+ GSSEAP_STATE_ACCEPTOR_EXTS,
+ 0,
+ eapGssSmAcceptCompleteAcceptorExts
},
};
if (GSS_ERROR(major))
return major;
- ctx->state = GSSEAP_STATE_NEGO_EXT; /* skip */
-
*minor = 0;
- return GSS_S_COMPLETE; /* advance state */
+ return GSS_S_COMPLETE;
}
static OM_uint32
OM_uint32 timeReq __attribute__((__unused__)),
gss_channel_bindings_t chanBindings,
gss_buffer_t inputToken,
- gss_buffer_t outputToken)
+ gss_buffer_t outputToken,
+ OM_uint32 *smFlags)
{
OM_uint32 major, tmpMinor;
gss_name_t krbInitiator = GSS_C_NO_NAME;
if (major == GSS_S_COMPLETE) {
major = acceptReadyKrb(minor, ctx, cred,
krbInitiator, mech, timeRec);
+ if (major == GSS_S_COMPLETE) {
+ GSSEAP_SM_TRANSITION(ctx, GSSEAP_STATE_ESTABLISHED);
+ }
}
ctx->gssFlags = gssFlags;