From: Simo Sorce Date: Thu, 25 Feb 2016 21:31:09 +0000 (-0500) Subject: Interoperate with incomplete SPNEGO responses X-Git-Tag: krb5-1.15-beta1~250 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=da748e7621ad20237f105eb1167832d4898fde66;p=thirdparty%2Fkrb5.git Interoperate with incomplete SPNEGO responses We have found at least one HTTP/Negotiate implementation in Java that does not set anything but the responseToken field in the first SPNEGO acceptor response token. This is technically a violation of RFC 4178 section 4.2.2, but it is harmless to support; we know the mechanism we were trying to negotiate, and can use that mechanism to process the token. These implementations are probably not supporting any real negotiation, as the missing negState precludes any mechanism negotiation on failure. If a supportedMech is included that differs from the opportunistic one but no negState is provided, init_ctx_reselect() will fail with GSS_S_DEFECIVE_TOKEN as it should. [ghudson@mit.edu: edit comments and commit message] ticket: 8374 (new) --- diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c index 110b886db9..bcebba8424 100644 --- a/src/lib/gssapi/spnego/spnego_mech.c +++ b/src/lib/gssapi/spnego/spnego_mech.c @@ -740,20 +740,17 @@ init_ctx_nego(OM_uint32 *minor_status, spnego_gss_ctx_id_t sc, *negState = REJECT; *tokflag = ERROR_TOKEN_SEND; ret = GSS_S_DEFECTIVE_TOKEN; + /* - * Both supportedMech and negState must be present in first - * acceptor token. + * According to RFC 4178, both supportedMech and negState must be + * present in the first acceptor token. However, some Java + * implementations include only a responseToken in the first + * NegTokenResp. In this case we can use sc->internal_mech as the + * negotiated mechanism. (We do not currently look at acc_negState + * when continuing with the optimistic mechanism.) */ - if (supportedMech == GSS_C_NO_OID) { - *minor_status = ERR_SPNEGO_NO_MECH_FROM_ACCEPTOR; - map_errcode(minor_status); - return GSS_S_DEFECTIVE_TOKEN; - } - if (acc_negState == ACCEPT_DEFECTIVE_TOKEN) { - *minor_status = ERR_SPNEGO_NEGOTIATION_FAILED; - map_errcode(minor_status); - return GSS_S_DEFECTIVE_TOKEN; - } + if (supportedMech == GSS_C_NO_OID) + supportedMech = sc->internal_mech; /* * If the mechanism we sent is not the mechanism returned from