OM_uint32 timeReq __attribute__((__unused__)),
gss_channel_bindings_t chanBindings,
gss_buffer_t inputToken,
- gss_buffer_t outputToken);
+ gss_buffer_t outputToken,
+ int *transitionState);
#endif
/*
OM_uint32 timeReq __attribute__((__unused__)),
gss_channel_bindings_t chanBindings __attribute__((__unused__)),
gss_buffer_t inputToken,
- gss_buffer_t outputToken)
+ gss_buffer_t outputToken,
+ int *transitionState)
{
OM_uint32 major;
struct wpabuf *reqData;
wpabuf_free(reqData);
*minor = 0;
- return GSS_S_COMPLETE; /* advance state */
+ *transitionState = 1;
+
+ 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,
+ int *transitionState)
{
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 */
+ *transitionState = 1;
}
+ 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,
+ int *transitionState)
{
OM_uint32 major, tmpMinor;
gss_iov_buffer_desc iov[2];
!bufferEqual(&iov[0].buffer, &chanBindings->application_data)) {
major = GSS_S_BAD_BINDINGS;
*minor = GSSEAP_BINDINGS_MISMATCH;
- } else {
- major = GSS_S_CONTINUE_NEEDED; /* process additional extensions */
- *minor = 0;
}
gss_release_buffer(&tmpMinor, &iov[0].buffer);
OM_uint32 timeReq __attribute__((__unused__)),
gss_channel_bindings_t chanBindings __attribute__((__unused__)),
gss_buffer_t inputToken,
- gss_buffer_t outputToken)
+ gss_buffer_t outputToken,
+ int *transitionState)
{
OM_uint32 major;
if (GSS_ERROR(major))
return major;
- *minor = 0;
- return GSS_S_CONTINUE_NEEDED; /* process additional extensions */
+ return major;
}
#endif
OM_uint32 timeReq __attribute__((__unused__)),
gss_channel_bindings_t chanBindings __attribute__((__unused__)),
gss_buffer_t inputToken,
- gss_buffer_t outputToken)
+ gss_buffer_t outputToken,
+ int *transitionState)
{
*minor = 0;
- return GSS_S_COMPLETE; /* advance state */
+ *transitionState = 1;
+ return GSS_S_COMPLETE;
}
static struct gss_eap_sm eapGssAcceptorSm[] = {
1, /* required */
eapGssSmAcceptGssChannelBindings,
},
+#ifdef GSSEAP_ENABLE_REAUTH
{
ITOK_TYPE_NONE,
ITOK_TYPE_REAUTH_CREDS,
0, /* required */
eapGssSmAcceptReauthCreds,
},
+#endif
{
ITOK_TYPE_NONE,
ITOK_TYPE_NONE,
OM_uint32 timeReq __attribute__((__unused__)),
gss_channel_bindings_t chanBindings,
gss_buffer_t inputToken,
- gss_buffer_t outputToken)
+ gss_buffer_t outputToken,
+ int *transitionState)
{
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);
+ *transitionState = 1;
}
ctx->gssFlags = gssFlags;
OM_uint32,
gss_channel_bindings_t,
gss_buffer_t,
- gss_buffer_t);
+ gss_buffer_t,
+ int *);
};
#define CTX_IS_ESTABLISHED(ctx) ((ctx)->state == GSSEAP_STATE_ESTABLISHED)
OM_uint32 timeReq,
gss_channel_bindings_t chanBindings,
gss_buffer_t inputToken,
- gss_buffer_t outputToken)
+ gss_buffer_t outputToken,
+ int *transitionState)
{
OM_uint32 major;
unsigned char *p;
OM_uint32 timeReq,
gss_channel_bindings_t chanBindings,
gss_buffer_t inputToken,
- gss_buffer_t outputToken)
+ gss_buffer_t outputToken,
+ int *transitionState)
{
OM_uint32 major, tmpMinor;
gss_name_t mechTarget = GSS_C_NO_NAME;
if (GSS_ERROR(major))
goto cleanup;
ctx->state = GSSEAP_STATE_NEGO_EXT; /* skip */
- } else {
- major = GSS_S_COMPLETE; /* advance state */
}
+ *transitionState = 1;
+
cleanup:
gssReleaseName(&tmpMinor, &mechTarget);
OM_uint32 timeReq,
gss_channel_bindings_t chanBindings,
gss_buffer_t inputToken,
- gss_buffer_t outputToken)
+ gss_buffer_t outputToken,
+ int *transitionState)
{
OM_uint32 major;
int initialContextToken;
outputToken->value = NULL;
*minor = 0;
- return GSS_S_COMPLETE; /* advance state */
+ *transitionState = 1;
+
+ return GSS_S_COMPLETE;
}
static struct wpabuf emptyWpaBuffer;
OM_uint32 timeReq,
gss_channel_bindings_t chanBindings,
gss_buffer_t inputToken,
- gss_buffer_t outputToken)
+ gss_buffer_t outputToken,
+ int *transitionState)
{
OM_uint32 major;
OM_uint32 tmpMinor;
ctx->flags |= CTX_FLAG_EAP_REQ; /* we have a Request from the acceptor */
+ major = GSS_S_CONTINUE_NEEDED;
+
wpabuf_set(&ctx->initiatorCtx.reqData,
inputToken->value, inputToken->length);
ctx->flags &= ~(CTX_FLAG_EAP_RESP);
resp = eap_get_eapRespData(ctx->initiatorCtx.eap);
- major = GSS_S_CONTINUE_NEEDED;
} else if (ctx->flags & CTX_FLAG_EAP_SUCCESS) {
major = initReady(minor, ctx, reqFlags);
if (GSS_ERROR(major))
goto cleanup;
ctx->flags &= ~(CTX_FLAG_EAP_SUCCESS);
- major = GSS_S_COMPLETE; /* advance state */
+ *transitionState = 1;
} else if (ctx->flags & CTX_FLAG_EAP_FAIL) {
major = GSS_S_DEFECTIVE_CREDENTIAL;
*minor = GSSEAP_PEER_AUTH_FAILURE;
} else if (code == 0 && initialContextToken) {
- major = GSS_S_CONTINUE_NEEDED;
+ /* */
} else {
major = GSS_S_DEFECTIVE_TOKEN;
*minor = GSSEAP_PEER_BAD_MESSAGE;
OM_uint32 timeReq,
gss_channel_bindings_t chanBindings,
gss_buffer_t inputToken,
- gss_buffer_t outputToken)
+ gss_buffer_t outputToken,
+ int *transitionState)
{
OM_uint32 major;
gss_buffer_desc buffer = GSS_C_EMPTY_BUFFER;
OM_uint32 timeReq,
gss_channel_bindings_t chanBindings,
gss_buffer_t inputToken,
- gss_buffer_t outputToken)
+ gss_buffer_t outputToken,
+ int *transitionState)
{
OM_uint32 major;
OM_uint32 timeReq,
gss_channel_bindings_t chanBindings,
gss_buffer_t inputToken,
- gss_buffer_t outputToken)
+ gss_buffer_t outputToken,
+ int *transitionState)
{
*minor = 0;
- return GSS_S_COMPLETE; /* advance state */
+ *transitionState = 1;
+ return GSS_S_COMPLETE;
}
static struct gss_eap_sm eapGssInitiatorSm[] = {
eapGssSmInitGssReauth,
},
#endif
- /* first-leg extensions go here, they should return GSS_S_CONTINUE_NEEDED */
{
ITOK_TYPE_NONE,
ITOK_TYPE_NONE,
* is reached.
*/
do {
+ int transitionState = 0;
+
major = GSS_S_COMPLETE;
for (i = 0; i < smCount; i++) {
if (processToken) {
major = smp->processToken(minor, cred, ctx, target, mech, reqFlags,
timeReq, chanBindings, innerInputToken,
- &innerOutputToken);
+ &innerOutputToken, &transitionState);
if (GSS_ERROR(major))
break;
outputTokenTypes[innerOutputTokens->count] |= ITOK_FLAG_CRITICAL;
innerOutputTokens->count++;
}
- if (major == GSS_S_COMPLETE)
+ if (transitionState)
break;
} else if (smp->required && smp->inputTokenType != ITOK_TYPE_NONE) {
major = GSS_S_DEFECTIVE_TOKEN;
}
}
- if (major != GSS_S_COMPLETE)
- break; /* GSS_S_CONTINUE_NEEDED or error */
+ if (GSS_ERROR(major) || !transitionState)
+ break;
assert(ctx->state < GSSEAP_STATE_ESTABLISHED);
ctx->state = GSSEAP_STATE_NEXT(ctx->state);
if (innerOutputTokens->count != 0) {
- major = GSS_S_CONTINUE_NEEDED;
+ assert(major == GSS_S_CONTINUE_NEEDED);
break; /* send any tokens if we have them */
}
} while (ctx->state != GSSEAP_STATE_ESTABLISHED);