From 8096a4aa162f87aaf2129a7300a3645518074b13 Mon Sep 17 00:00:00 2001
From: Tom Yu <tlyu@mit.edu>
Date: Tue, 23 Mar 2010 19:08:53 +0000
Subject: [PATCH] pull up r23832 from trunk

 ------------------------------------------------------------------------
 r23832 | tlyu | 2010-03-23 11:53:52 -0700 (Tue, 23 Mar 2010) | 8 lines

 ticket: 6690
 target_version: 1.8.1
 tags: pullup
 subject: MITKRB5-SA-2010-002 CVE-2010-0628 denial of service in SPNEGO

 The SPNEGO implementation in krb5-1.7 and later could crash due to
 assertion failure when receiving some sorts of invalid GSS-API tokens.

ticket: 6690
version_fixed: 1.8.1
status: resolved

git-svn-id: svn://anonsvn.mit.edu/krb5/branches/krb5-1-8@23833 dc483132-0cff-0310-8789-dd5450dbe970
---
 src/lib/gssapi/spnego/spnego_mech.c | 38 ++++++++++++-----------------
 1 file changed, 16 insertions(+), 22 deletions(-)

diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c
index 7a3ff2426..cda76d1ad 100644
--- a/src/lib/gssapi/spnego/spnego_mech.c
+++ b/src/lib/gssapi/spnego/spnego_mech.c
@@ -1576,7 +1576,7 @@ spnego_gss_accept_sec_context(
 	spnego_gss_ctx_id_t sc = NULL;
 	spnego_gss_cred_id_t spcred = NULL;
 	OM_uint32 mechstat = GSS_S_FAILURE;
-	int sendTokenInit = 0;
+	int sendTokenInit = 0, tmpret;
 
 	mechtok_in = mic_in = mic_out = GSS_C_NO_BUFFER;
 
@@ -1609,7 +1609,6 @@ spnego_gss_accept_sec_context(
 		if (delegated_cred_handle != NULL)
 			*delegated_cred_handle = GSS_C_NO_CREDENTIAL;
 		if (input_token->length == 0) {
-			sendTokenInit = 1;
 			ret = acc_ctx_hints(minor_status,
 					    context_handle, spcred,
 					    &mic_out,
@@ -1617,6 +1616,7 @@ spnego_gss_accept_sec_context(
 					    &return_token);
 			if (ret != GSS_S_COMPLETE)
 				goto cleanup;
+			sendTokenInit = 1;
 			ret = GSS_S_CONTINUE_NEEDED;
 		} else {
 			/* Can set negState to REQUEST_MIC */
@@ -1664,27 +1664,21 @@ spnego_gss_accept_sec_context(
 				 &negState, &return_token);
 	}
 cleanup:
-	if (return_token != NO_TOKEN_SEND && return_token != CHECK_MIC) {
-		/* For acceptor-sends-first send a tokenInit */
-		int tmpret;
-
+	if (return_token == INIT_TOKEN_SEND && sendTokenInit) {
 		assert(sc != NULL);
-
-		if (sendTokenInit) {
-			tmpret = make_spnego_tokenInit_msg(sc,
-							   1,
-							   mic_out,
-							   0,
-							   GSS_C_NO_BUFFER,
-							   return_token,
-							   output_token);
-		} else {
-			tmpret = make_spnego_tokenTarg_msg(negState,
-							   sc ? sc->internal_mech : GSS_C_NO_OID,
-							   &mechtok_out, mic_out,
-							   return_token,
-							   output_token);
-		}
+		tmpret = make_spnego_tokenInit_msg(sc, 1, mic_out, 0,
+						   GSS_C_NO_BUFFER,
+						   return_token, output_token);
+		if (tmpret < 0)
+			ret = GSS_S_FAILURE;
+	} else if (return_token != NO_TOKEN_SEND &&
+		   return_token != CHECK_MIC) {
+		tmpret = make_spnego_tokenTarg_msg(negState,
+						   sc ? sc->internal_mech :
+						   GSS_C_NO_OID,
+						   &mechtok_out, mic_out,
+						   return_token,
+						   output_token);
 		if (tmpret < 0)
 			ret = GSS_S_FAILURE;
 	}
-- 
2.26.2