Thanks for the comprehensive interop issue report.  I have one question:

> In function, src/lib/gssapi/spnego/spnego_mech.c: get_negTokenResp we return error code that it is a defective token.

This function should only return a defective token error if the packet has a bad length, which does not appear to be the case.  Is it possible that the error came from handle_mic() at the first else-if clause?

Some background:

* RFC 4178 (SPNEGO) section 5 only requires a mechlistMIC exchange if the negotiated mech is not the most-preferred mech of one of the two parties.  Otherwise the MIC exchange is optional (unless the negotiated mech has no MIC support, in which case it's impossible).

* RFC 4178 section 5 (c) (I) says, for the acceptor processing the final initiator token: "If a mechlistMIC token was included and is correctly verified, GSS_Accept_sec_context() indicates GSS_S_COMPLETE.  The output negotiation message contains a mechlistMIC token and an accept_complete state."

In this exchange both parties prefer NTLMSSP, so one would expect the MIC exchange to be optional.   However, Microsoft imposes an additional constraint for NTLMSSP.  This is both observed and documented; [MS-SPNG] Appendix A says:

    If NTLM authentication is most preferred by the client and the server, and the
    client includes a MIC in AUTHENTICATE_MESSAGE ([MS-NLMP] section
    2.2.1.3), then the mechListMIC field becomes mandatory in order for the
    authentication to succeed. Windows clients in this case send an NTLM token
    instead of an SPNEGO token.

Accordingly, we have a helper mech_requires_mechlistMIC(), so that NTLMSSP can report that it's behaving in a way that causes a SPNEGO MIC to be required.  In our code, the MIC requirement is treated as symmetrical; if we send one, we believe we must receive one, and (following RFC 4178 5.c.I) if we receive one, we send one.

From the packet traces it would appear that the Azure server does not believe a MIC is required (i.e. it is not behaving according to [MS-SPNG] Appendix A) and isn't sending a MIC in response to the initiator's MIC (i.e. it it violates RFC 4178 section 5(c)(I)).  This apparent misbehavior could be accomodated in two ways:

1. Following the hint in [MS-SPNG] Appendix A, the application could send an NTLM token instead of a SPNEGO token.  Generally if a client prefers NTLM, it can only do NTLM, so negotiation isn't required.  However, it may be difficult for an application using MIT krb5 to implement this due to the abstraction boundaries; the application doesn't know that the client is only capable of NTLM and the SPNEGO layer can't generate a non-SPNEGO token.

2. In our SPNEGO layer, a true result from mech_requires_mechlistMIC() could cause a MIC token to be generated, but not required from the other party.