Blame SOURCES/Pass-channel-bindings-through-SPNEGO.patch

d283c7
From d98f8867f8245b3c9dd506271897d0f03d69ae49 Mon Sep 17 00:00:00 2001
d283c7
From: Isaac Boukris <iboukris@gmail.com>
d283c7
Date: Tue, 28 Apr 2020 18:15:55 +0200
d283c7
Subject: [PATCH] Pass channel bindings through SPNEGO
d283c7
d283c7
ticket: 8907 (new)
d283c7
(cherry picked from commit d16325a24c34ec9a5f6fb4910987f162e0d4d9cd)
d283c7
(cherry picked from commit ee79bd43005245d3e5a2d3ec6d61146945e77717)
d283c7
---
d283c7
 src/lib/gssapi/spnego/gssapiP_negoex.h |  8 ++---
d283c7
 src/lib/gssapi/spnego/negoex_ctx.c     | 34 +++++++++++----------
d283c7
 src/lib/gssapi/spnego/spnego_mech.c    | 41 +++++++++++++-------------
d283c7
 3 files changed, 43 insertions(+), 40 deletions(-)
d283c7
d283c7
diff --git a/src/lib/gssapi/spnego/gssapiP_negoex.h b/src/lib/gssapi/spnego/gssapiP_negoex.h
d283c7
index 44b08f523..489ab7c42 100644
d283c7
--- a/src/lib/gssapi/spnego/gssapiP_negoex.h
d283c7
+++ b/src/lib/gssapi/spnego/gssapiP_negoex.h
d283c7
@@ -201,10 +201,10 @@ negoex_restrict_auth_schemes(spnego_gss_ctx_id_t ctx,
d283c7
 OM_uint32
d283c7
 negoex_init(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
d283c7
             gss_name_t target_name, OM_uint32 req_flags, OM_uint32 time_req,
d283c7
-            gss_buffer_t input_token, gss_buffer_t output_token,
d283c7
-            OM_uint32 *time_rec);
d283c7
+            gss_buffer_t input_token, gss_channel_bindings_t bindings,
d283c7
+            gss_buffer_t output_token, OM_uint32 *time_rec);
d283c7
 
d283c7
 OM_uint32
d283c7
 negoex_accept(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
d283c7
-              gss_buffer_t input_token, gss_buffer_t output_token,
d283c7
-              OM_uint32 *time_rec);
d283c7
+              gss_buffer_t input_token, gss_channel_bindings_t bindings,
d283c7
+              gss_buffer_t output_token, OM_uint32 *time_rec);
d283c7
diff --git a/src/lib/gssapi/spnego/negoex_ctx.c b/src/lib/gssapi/spnego/negoex_ctx.c
d283c7
index 18d9d4147..8848ee4db 100644
d283c7
--- a/src/lib/gssapi/spnego/negoex_ctx.c
d283c7
+++ b/src/lib/gssapi/spnego/negoex_ctx.c
d283c7
@@ -276,7 +276,8 @@ static OM_uint32
d283c7
 mech_init(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
d283c7
           gss_name_t target, OM_uint32 req_flags, OM_uint32 time_req,
d283c7
           struct negoex_message *messages, size_t nmessages,
d283c7
-          gss_buffer_t output_token, OM_uint32 *time_rec)
d283c7
+          gss_channel_bindings_t bindings, gss_buffer_t output_token,
d283c7
+          OM_uint32 *time_rec)
d283c7
 {
d283c7
     OM_uint32 major, first_major = 0, first_minor = 0;
d283c7
     struct negoex_auth_mech *mech = NULL;
d283c7
@@ -316,10 +317,9 @@ mech_init(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
d283c7
         mech = K5_TAILQ_FIRST(&ctx->negoex_mechs);
d283c7
 
d283c7
         major = gss_init_sec_context(minor, cred, &mech->mech_context, target,
d283c7
-                                     mech->oid, req_flags, time_req,
d283c7
-                                     GSS_C_NO_CHANNEL_BINDINGS, input_token,
d283c7
-                                     &ctx->actual_mech, output_token,
d283c7
-                                     &ctx->ctx_flags, time_rec);
d283c7
+                                     mech->oid, req_flags, time_req, bindings,
d283c7
+                                     input_token, &ctx->actual_mech,
d283c7
+                                     output_token, &ctx->ctx_flags, time_rec);
d283c7
 
d283c7
         if (major == GSS_S_COMPLETE)
d283c7
             mech->complete = 1;
d283c7
@@ -351,7 +351,8 @@ mech_init(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
d283c7
 static OM_uint32
d283c7
 mech_accept(OM_uint32 *minor, spnego_gss_ctx_id_t ctx,
d283c7
             gss_cred_id_t cred, struct negoex_message *messages,
d283c7
-            size_t nmessages, gss_buffer_t output_token, OM_uint32 *time_rec)
d283c7
+            size_t nmessages, gss_channel_bindings_t bindings,
d283c7
+            gss_buffer_t output_token, OM_uint32 *time_rec)
d283c7
 {
d283c7
     OM_uint32 major, tmpmin;
d283c7
     struct negoex_auth_mech *mech;
d283c7
@@ -395,10 +396,10 @@ mech_accept(OM_uint32 *minor, spnego_gss_ctx_id_t ctx,
d283c7
         gss_release_cred(&tmpmin, &ctx->deleg_cred);
d283c7
 
d283c7
     major = gss_accept_sec_context(minor, &mech->mech_context, cred,
d283c7
-                                   &msg->token, GSS_C_NO_CHANNEL_BINDINGS,
d283c7
-                                   &ctx->internal_name, &ctx->actual_mech,
d283c7
-                                   output_token, &ctx->ctx_flags,
d283c7
-                                   time_rec, &ctx->deleg_cred);
d283c7
+                                   &msg->token, bindings, &ctx->internal_name,
d283c7
+                                   &ctx->actual_mech, output_token,
d283c7
+                                   &ctx->ctx_flags, time_rec,
d283c7
+                                   &ctx->deleg_cred);
d283c7
 
d283c7
     if (major == GSS_S_COMPLETE)
d283c7
         mech->complete = 1;
d283c7
@@ -609,8 +610,8 @@ make_output_token(OM_uint32 *minor, spnego_gss_ctx_id_t ctx,
d283c7
 OM_uint32
d283c7
 negoex_init(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
d283c7
             gss_name_t target_name, OM_uint32 req_flags, OM_uint32 time_req,
d283c7
-            gss_buffer_t input_token, gss_buffer_t output_token,
d283c7
-            OM_uint32 *time_rec)
d283c7
+            gss_buffer_t input_token, gss_channel_bindings_t bindings,
d283c7
+            gss_buffer_t output_token, OM_uint32 *time_rec)
d283c7
 {
d283c7
     OM_uint32 major, tmpmin;
d283c7
     gss_buffer_desc mech_output_token = GSS_C_EMPTY_BUFFER;
d283c7
@@ -663,7 +664,8 @@ negoex_init(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
d283c7
     /* Process the input token and/or produce an output token.  This may prune
d283c7
      * the mech list, but on success there will be at least one mech entry. */
d283c7
     major = mech_init(minor, ctx, cred, target_name, req_flags, time_req,
d283c7
-                      messages, nmessages, &mech_output_token, time_rec);
d283c7
+                      messages, nmessages, bindings, &mech_output_token,
d283c7
+                      time_rec);
d283c7
     if (major != GSS_S_COMPLETE)
d283c7
         goto cleanup;
d283c7
     assert(!K5_TAILQ_EMPTY(&ctx->negoex_mechs));
d283c7
@@ -701,8 +703,8 @@ cleanup:
d283c7
 
d283c7
 OM_uint32
d283c7
 negoex_accept(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
d283c7
-              gss_buffer_t input_token, gss_buffer_t output_token,
d283c7
-              OM_uint32 *time_rec)
d283c7
+              gss_buffer_t input_token, gss_channel_bindings_t bindings,
d283c7
+              gss_buffer_t output_token, OM_uint32 *time_rec)
d283c7
 {
d283c7
     OM_uint32 major, tmpmin;
d283c7
     gss_buffer_desc mech_output_token = GSS_C_EMPTY_BUFFER;
d283c7
@@ -754,7 +756,7 @@ negoex_accept(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
d283c7
      * prune the list to a single mech.  Continue on error if an output token
d283c7
      * is generated, so that we send the token to the initiator.
d283c7
      */
d283c7
-    major = mech_accept(minor, ctx, cred, messages, nmessages,
d283c7
+    major = mech_accept(minor, ctx, cred, messages, nmessages, bindings,
d283c7
                         &mech_output_token, time_rec);
d283c7
     if (major != GSS_S_COMPLETE && mech_output_token.length == 0)
d283c7
         goto cleanup;
d283c7
diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c
d283c7
index 594fc5894..4cf011143 100644
d283c7
--- a/src/lib/gssapi/spnego/spnego_mech.c
d283c7
+++ b/src/lib/gssapi/spnego/spnego_mech.c
d283c7
@@ -130,6 +130,7 @@ init_ctx_reselect(OM_uint32 *, spnego_gss_ctx_id_t, OM_uint32,
d283c7
 static OM_uint32
d283c7
 init_ctx_call_init(OM_uint32 *, spnego_gss_ctx_id_t, spnego_gss_cred_id_t,
d283c7
 		   OM_uint32, gss_name_t, OM_uint32, OM_uint32, gss_buffer_t,
d283c7
+		   gss_channel_bindings_t,
d283c7
 		   gss_buffer_t, OM_uint32 *, send_token_flag *);
d283c7
 
d283c7
 static OM_uint32
d283c7
@@ -144,8 +145,8 @@ acc_ctx_vfy_oid(OM_uint32 *, spnego_gss_ctx_id_t, gss_OID,
d283c7
 		OM_uint32 *, send_token_flag *);
d283c7
 static OM_uint32
d283c7
 acc_ctx_call_acc(OM_uint32 *, spnego_gss_ctx_id_t, spnego_gss_cred_id_t,
d283c7
-		 gss_buffer_t, gss_buffer_t, OM_uint32 *, OM_uint32 *,
d283c7
-		 send_token_flag *);
d283c7
+		 gss_buffer_t, gss_channel_bindings_t, gss_buffer_t,
d283c7
+		 OM_uint32 *, OM_uint32 *, send_token_flag *);
d283c7
 
d283c7
 static gss_OID
d283c7
 negotiate_mech(spnego_gss_ctx_id_t, gss_OID_set, OM_uint32 *);
d283c7
@@ -905,6 +906,7 @@ init_ctx_call_init(OM_uint32 *minor_status,
d283c7
 		   OM_uint32 req_flags,
d283c7
 		   OM_uint32 time_req,
d283c7
 		   gss_buffer_t mechtok_in,
d283c7
+		   gss_channel_bindings_t bindings,
d283c7
 		   gss_buffer_t mechtok_out,
d283c7
 		   OM_uint32 *time_rec,
d283c7
 		   send_token_flag *send_token)
d283c7
@@ -921,15 +923,14 @@ init_ctx_call_init(OM_uint32 *minor_status,
d283c7
 	if (gss_oid_equal(sc->internal_mech, &negoex_mech)) {
d283c7
 		ret = negoex_init(minor_status, sc, mcred, target_name,
d283c7
 				  mech_req_flags, time_req, mechtok_in,
d283c7
-				  mechtok_out, time_rec);
d283c7
+				  bindings, mechtok_out, time_rec);
d283c7
 	} else {
d283c7
 		ret = gss_init_sec_context(minor_status, mcred,
d283c7
 					   &sc->ctx_handle, target_name,
d283c7
 					   sc->internal_mech, mech_req_flags,
d283c7
-					   time_req, GSS_C_NO_CHANNEL_BINDINGS,
d283c7
-					   mechtok_in, &sc->actual_mech,
d283c7
-					   mechtok_out, &sc->ctx_flags,
d283c7
-					   time_rec);
d283c7
+					   time_req, bindings, mechtok_in,
d283c7
+					   &sc->actual_mech, mechtok_out,
d283c7
+					   &sc->ctx_flags, time_rec);
d283c7
 	}
d283c7
 
d283c7
 	/* Bail out if the acceptor gave us an error token but the mech didn't
d283c7
@@ -981,8 +982,8 @@ init_ctx_call_init(OM_uint32 *minor_status,
d283c7
 	gss_delete_sec_context(&tmpmin, &sc->ctx_handle, GSS_C_NO_BUFFER);
d283c7
 	tmpret = init_ctx_call_init(&tmpmin, sc, spcred, acc_negState,
d283c7
 				    target_name, req_flags, time_req,
d283c7
-				    mechtok_in, mechtok_out, time_rec,
d283c7
-				    send_token);
d283c7
+				    mechtok_in, bindings, mechtok_out,
d283c7
+				    time_rec, send_token);
d283c7
 	if (HARD_ERROR(tmpret))
d283c7
 		goto fail;
d283c7
 	*minor_status = tmpmin;
d283c7
@@ -1004,7 +1005,7 @@ spnego_gss_init_sec_context(
d283c7
 			gss_OID mech_type,
d283c7
 			OM_uint32 req_flags,
d283c7
 			OM_uint32 time_req,
d283c7
-			gss_channel_bindings_t input_chan_bindings,
d283c7
+			gss_channel_bindings_t bindings,
d283c7
 			gss_buffer_t input_token,
d283c7
 			gss_OID *actual_mech,
d283c7
 			gss_buffer_t output_token,
d283c7
@@ -1084,8 +1085,8 @@ spnego_gss_init_sec_context(
d283c7
 	if (!spnego_ctx->mech_complete) {
d283c7
 		ret = init_ctx_call_init(minor_status, spnego_ctx, spcred,
d283c7
 					 acc_negState, target_name, req_flags,
d283c7
-					 time_req, mechtok_in, &mechtok_out,
d283c7
-					 time_rec, &send_token);
d283c7
+					 time_req, mechtok_in, bindings,
d283c7
+					 &mechtok_out, time_rec, &send_token);
d283c7
 		if (ret != GSS_S_COMPLETE)
d283c7
 			goto cleanup;
d283c7
 
d283c7
@@ -1542,8 +1543,9 @@ cleanup:
d283c7
 static OM_uint32
d283c7
 acc_ctx_call_acc(OM_uint32 *minor_status, spnego_gss_ctx_id_t sc,
d283c7
 		 spnego_gss_cred_id_t spcred, gss_buffer_t mechtok_in,
d283c7
-		 gss_buffer_t mechtok_out, OM_uint32 *time_rec,
d283c7
-		 OM_uint32 *negState, send_token_flag *tokflag)
d283c7
+		 gss_channel_bindings_t bindings, gss_buffer_t mechtok_out,
d283c7
+		 OM_uint32 *time_rec, OM_uint32 *negState,
d283c7
+		 send_token_flag *tokflag)
d283c7
 {
d283c7
 	OM_uint32 ret, tmpmin;
d283c7
 	gss_OID_desc mechoid;
d283c7
@@ -1568,13 +1570,12 @@ acc_ctx_call_acc(OM_uint32 *minor_status, spnego_gss_ctx_id_t sc,
d283c7
 	mcred = (spcred == NULL) ? GSS_C_NO_CREDENTIAL : spcred->mcred;
d283c7
 	if (negoex) {
d283c7
 		ret = negoex_accept(minor_status, sc, mcred, mechtok_in,
d283c7
-				    mechtok_out, time_rec);
d283c7
+				    bindings, mechtok_out, time_rec);
d283c7
 	} else {
d283c7
 		(void) gss_release_name(&tmpmin, &sc->internal_name);
d283c7
 		(void) gss_release_cred(&tmpmin, &sc->deleg_cred);
d283c7
 		ret = gss_accept_sec_context(minor_status, &sc->ctx_handle,
d283c7
-					     mcred, mechtok_in,
d283c7
-					     GSS_C_NO_CHANNEL_BINDINGS,
d283c7
+					     mcred, mechtok_in, bindings,
d283c7
 					     &sc->internal_name,
d283c7
 					     &sc->actual_mech, mechtok_out,
d283c7
 					     &sc->ctx_flags, time_rec,
d283c7
@@ -1620,7 +1621,7 @@ spnego_gss_accept_sec_context(
d283c7
 			    gss_ctx_id_t *context_handle,
d283c7
 			    gss_cred_id_t verifier_cred_handle,
d283c7
 			    gss_buffer_t input_token,
d283c7
-			    gss_channel_bindings_t input_chan_bindings,
d283c7
+			    gss_channel_bindings_t bindings,
d283c7
 			    gss_name_t *src_name,
d283c7
 			    gss_OID *mech_type,
d283c7
 			    gss_buffer_t output_token,
d283c7
@@ -1734,8 +1735,8 @@ spnego_gss_accept_sec_context(
d283c7
 	 */
d283c7
 	if (negState != REQUEST_MIC && mechtok_in != GSS_C_NO_BUFFER) {
d283c7
 		ret = acc_ctx_call_acc(minor_status, sc, spcred, mechtok_in,
d283c7
-				       &mechtok_out, time_rec, &negState,
d283c7
-				       &return_token);
d283c7
+				       bindings, &mechtok_out, time_rec,
d283c7
+				       &negState, &return_token);
d283c7
 	}
d283c7
 
d283c7
 	/* Step 3: process or generate the MIC, if the negotiated mech is