gss: pass mechanism error tokens through SPNEGO
Fix for issue #486 based on a patch by Nico Williams. A GSS-API acceptor can return an error token to be sent to the initiator. Our SPNEGO implementation discarded these when sending a SPNEGO reject response. This patch fixes the SPNEGO acceptor to convey those in the SPNEGO response. The SPNEGO initiator is also updated to not bail out early on receiving a SPNEGO reject response from the acceptor, but instead pass the response token (if any) to gss_init_sec_context(). A reject response with no response token will continue to return an error.
This commit is contained in:
		| @@ -35,10 +35,12 @@ | ||||
|  | ||||
| static OM_uint32 | ||||
| send_reject (OM_uint32 *minor_status, | ||||
| 	     gss_buffer_t mech_token, | ||||
| 	     gss_buffer_t output_token) | ||||
| { | ||||
|     NegotiationToken nt; | ||||
|     size_t size; | ||||
|     heim_octet_string responseToken; | ||||
|  | ||||
|     nt.element = choice_NegotiationToken_negTokenResp; | ||||
|  | ||||
| @@ -50,6 +52,13 @@ send_reject (OM_uint32 *minor_status, | ||||
|     *(nt.u.negTokenResp.negState)  = reject; | ||||
|     nt.u.negTokenResp.supportedMech = NULL; | ||||
|     nt.u.negTokenResp.responseToken = NULL; | ||||
|  | ||||
|     if (mech_token != GSS_C_NO_BUFFER && mech_token->value != NULL) { | ||||
| 	responseToken.length = mech_token->length; | ||||
| 	responseToken.data   = mech_token->value; | ||||
| 	nt.u.negTokenResp.responseToken = &responseToken; | ||||
|      } else | ||||
| 	nt.u.negTokenResp.responseToken = NULL; | ||||
|     nt.u.negTokenResp.mechListMIC   = NULL; | ||||
|  | ||||
|     ASN1_MALLOC_ENCODE(NegotiationToken, | ||||
| @@ -513,7 +522,7 @@ acceptor_complete(OM_uint32 * minor_status, | ||||
| 	    ret = _gss_spnego_verify_mechtypes_mic(minor_status, ctx, mic); | ||||
| 	    if (ret) { | ||||
| 		if (*get_mic) | ||||
| 		    send_reject(minor_status, output_token); | ||||
| 		    send_reject(minor_status, GSS_C_NO_BUFFER, output_token); | ||||
| 		if (buf.value) | ||||
| 		    free(buf.value); | ||||
| 		return ret; | ||||
| @@ -888,12 +897,11 @@ acceptor_continue | ||||
| 			      input_chan_bindings, | ||||
| 			      &obuf, | ||||
| 			      delegated_cred_handle); | ||||
| 	    if (ret == GSS_S_COMPLETE || ret == GSS_S_CONTINUE_NEEDED) { | ||||
| 		mech_output_token = &obuf; | ||||
| 	    } | ||||
| 	    mech_output_token = &obuf; | ||||
| 	    if (ret != GSS_S_COMPLETE && ret != GSS_S_CONTINUE_NEEDED) { | ||||
| 		free_NegotiationToken(&nt); | ||||
| 		send_reject(&junk, output_token); | ||||
| 		send_reject(&junk, mech_output_token, output_token); | ||||
| 		gss_release_buffer(&junk, mech_output_token); | ||||
| 		HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); | ||||
| 		return ret; | ||||
| 	    } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Luke Howard
					Luke Howard