Hi Greg,
Thanks for the prompt reply. I think you are right. I mistook mechListMIC set to GSS_C_NO_BUFFER as an invalid token. These 2 are different. I added some more logs and here is more detailed information:
In, init_ctx_cont the buf->length is 9. From init_ctx_cont, we call get_negTokenResp, which returns empty mechListMIC token with status: GSS_S_COMPLETE.
Progressing in init_ctx_cont, we hit the following if-else block
....
} else if (!sc->mech_complete ||
(sc->mic_reqd &&
(sc->ctx_flags & GSS_C_INTEG_FLAG))) {
/* Not obviously done; we may decide we're done later in
* init_ctx_call_init or handle_mic. */
*tokflag = CONT_TOKEN_SEND;
ret = GSS_S_COMPLETE;
} else {
/* mech finished on last pass and no MIC required, so done. */
*tokflag = NO_TOKEN_SEND;
ret = GSS_S_COMPLETE;
}
...
After returning from here, we return back to spnego_gss_init_sec_context function (from where we called init_ctx_cont). In this function, the handle_mic call leads to the problem. Code snippet for the call:
...
negState = ACCEPT_INCOMPLETE;
if (spnego_ctx->mech_complete &&
(spnego_ctx->ctx_flags & GSS_C_INTEG_FLAG)) {
ret = handle_mic(minor_status,
mechListMIC_in,
(mechtok_out.length != 0),
spnego_ctx, &mechListMIC_out,
&negState, &send_token);
if (HARD_ERROR(ret))
goto cleanup;
...
To be more specific, in handle_mic function, I hit the following section:
...
} else if (sc->mic_reqd && !send_mechtok) {
/*
* If the peer sends the final mechanism token, it
* must send the MIC with that token if the
* negotiation requires MICs.
*/
*negState = REJECT;
*tokflag = ERROR_TOKEN_SEND;
return GSS_S_DEFECTIVE_TOKEN;
}
...
So, I think you were right.
About, the suggestions that were made, I think what you are saying is that (1) is not possible (or very hard). If you can add more details on (2), I will be happy to make the change and test it.
Basically, I do not understand if the problem is
(a) The assumption that: if we send one, we should receive one? OR
(b) Sending MIC in the first place.
Regards,
Aman