From dec02b8411e735e47b6513a84b99f43a5ab5adc4 Mon Sep 17 00:00:00 2001 From: Robbie Harwood Date: Tue, 26 May 2020 14:34:53 -0400 Subject: [PATCH] Pass channel bindings through SPNEGO --- Pass-channel-bindings-through-SPNEGO.patch | 256 +++++++++++++++++++++ krb5.spec | 6 +- 2 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 Pass-channel-bindings-through-SPNEGO.patch diff --git a/Pass-channel-bindings-through-SPNEGO.patch b/Pass-channel-bindings-through-SPNEGO.patch new file mode 100644 index 0000000..0137f0c --- /dev/null +++ b/Pass-channel-bindings-through-SPNEGO.patch @@ -0,0 +1,256 @@ +From dd82ae2d390c4de1b8a7737a918d80d6829366dd Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Tue, 28 Apr 2020 18:15:55 +0200 +Subject: [PATCH] Pass channel bindings through SPNEGO + +ticket: 8907 (new) +(cherry picked from commit d16325a24c34ec9a5f6fb4910987f162e0d4d9cd) +--- + src/lib/gssapi/spnego/gssapiP_negoex.h | 8 ++--- + src/lib/gssapi/spnego/negoex_ctx.c | 34 +++++++++++---------- + src/lib/gssapi/spnego/spnego_mech.c | 41 +++++++++++++------------- + 3 files changed, 43 insertions(+), 40 deletions(-) + +diff --git a/src/lib/gssapi/spnego/gssapiP_negoex.h b/src/lib/gssapi/spnego/gssapiP_negoex.h +index 44b08f523..489ab7c42 100644 +--- a/src/lib/gssapi/spnego/gssapiP_negoex.h ++++ b/src/lib/gssapi/spnego/gssapiP_negoex.h +@@ -201,10 +201,10 @@ negoex_restrict_auth_schemes(spnego_gss_ctx_id_t ctx, + OM_uint32 + negoex_init(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred, + gss_name_t target_name, OM_uint32 req_flags, OM_uint32 time_req, +- gss_buffer_t input_token, gss_buffer_t output_token, +- OM_uint32 *time_rec); ++ gss_buffer_t input_token, gss_channel_bindings_t bindings, ++ gss_buffer_t output_token, OM_uint32 *time_rec); + + OM_uint32 + negoex_accept(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred, +- gss_buffer_t input_token, gss_buffer_t output_token, +- OM_uint32 *time_rec); ++ gss_buffer_t input_token, gss_channel_bindings_t bindings, ++ gss_buffer_t output_token, OM_uint32 *time_rec); +diff --git a/src/lib/gssapi/spnego/negoex_ctx.c b/src/lib/gssapi/spnego/negoex_ctx.c +index 18d9d4147..8848ee4db 100644 +--- a/src/lib/gssapi/spnego/negoex_ctx.c ++++ b/src/lib/gssapi/spnego/negoex_ctx.c +@@ -276,7 +276,8 @@ static OM_uint32 + mech_init(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred, + gss_name_t target, OM_uint32 req_flags, OM_uint32 time_req, + struct negoex_message *messages, size_t nmessages, +- gss_buffer_t output_token, OM_uint32 *time_rec) ++ gss_channel_bindings_t bindings, gss_buffer_t output_token, ++ OM_uint32 *time_rec) + { + OM_uint32 major, first_major = 0, first_minor = 0; + struct negoex_auth_mech *mech = NULL; +@@ -316,10 +317,9 @@ mech_init(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred, + mech = K5_TAILQ_FIRST(&ctx->negoex_mechs); + + major = gss_init_sec_context(minor, cred, &mech->mech_context, target, +- mech->oid, req_flags, time_req, +- GSS_C_NO_CHANNEL_BINDINGS, input_token, +- &ctx->actual_mech, output_token, +- &ctx->ctx_flags, time_rec); ++ mech->oid, req_flags, time_req, bindings, ++ input_token, &ctx->actual_mech, ++ output_token, &ctx->ctx_flags, time_rec); + + if (major == GSS_S_COMPLETE) + mech->complete = 1; +@@ -351,7 +351,8 @@ mech_init(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred, + static OM_uint32 + mech_accept(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, + gss_cred_id_t cred, struct negoex_message *messages, +- size_t nmessages, gss_buffer_t output_token, OM_uint32 *time_rec) ++ size_t nmessages, gss_channel_bindings_t bindings, ++ gss_buffer_t output_token, OM_uint32 *time_rec) + { + OM_uint32 major, tmpmin; + struct negoex_auth_mech *mech; +@@ -395,10 +396,10 @@ mech_accept(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, + gss_release_cred(&tmpmin, &ctx->deleg_cred); + + major = gss_accept_sec_context(minor, &mech->mech_context, cred, +- &msg->token, GSS_C_NO_CHANNEL_BINDINGS, +- &ctx->internal_name, &ctx->actual_mech, +- output_token, &ctx->ctx_flags, +- time_rec, &ctx->deleg_cred); ++ &msg->token, bindings, &ctx->internal_name, ++ &ctx->actual_mech, output_token, ++ &ctx->ctx_flags, time_rec, ++ &ctx->deleg_cred); + + if (major == GSS_S_COMPLETE) + mech->complete = 1; +@@ -609,8 +610,8 @@ make_output_token(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, + OM_uint32 + negoex_init(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred, + gss_name_t target_name, OM_uint32 req_flags, OM_uint32 time_req, +- gss_buffer_t input_token, gss_buffer_t output_token, +- OM_uint32 *time_rec) ++ gss_buffer_t input_token, gss_channel_bindings_t bindings, ++ gss_buffer_t output_token, OM_uint32 *time_rec) + { + OM_uint32 major, tmpmin; + gss_buffer_desc mech_output_token = GSS_C_EMPTY_BUFFER; +@@ -663,7 +664,8 @@ negoex_init(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred, + /* Process the input token and/or produce an output token. This may prune + * the mech list, but on success there will be at least one mech entry. */ + major = mech_init(minor, ctx, cred, target_name, req_flags, time_req, +- messages, nmessages, &mech_output_token, time_rec); ++ messages, nmessages, bindings, &mech_output_token, ++ time_rec); + if (major != GSS_S_COMPLETE) + goto cleanup; + assert(!K5_TAILQ_EMPTY(&ctx->negoex_mechs)); +@@ -701,8 +703,8 @@ cleanup: + + OM_uint32 + negoex_accept(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred, +- gss_buffer_t input_token, gss_buffer_t output_token, +- OM_uint32 *time_rec) ++ gss_buffer_t input_token, gss_channel_bindings_t bindings, ++ gss_buffer_t output_token, OM_uint32 *time_rec) + { + OM_uint32 major, tmpmin; + gss_buffer_desc mech_output_token = GSS_C_EMPTY_BUFFER; +@@ -754,7 +756,7 @@ negoex_accept(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred, + * prune the list to a single mech. Continue on error if an output token + * is generated, so that we send the token to the initiator. + */ +- major = mech_accept(minor, ctx, cred, messages, nmessages, ++ major = mech_accept(minor, ctx, cred, messages, nmessages, bindings, + &mech_output_token, time_rec); + if (major != GSS_S_COMPLETE && mech_output_token.length == 0) + goto cleanup; +diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c +index 594fc5894..4cf011143 100644 +--- a/src/lib/gssapi/spnego/spnego_mech.c ++++ b/src/lib/gssapi/spnego/spnego_mech.c +@@ -130,6 +130,7 @@ init_ctx_reselect(OM_uint32 *, spnego_gss_ctx_id_t, OM_uint32, + static OM_uint32 + init_ctx_call_init(OM_uint32 *, spnego_gss_ctx_id_t, spnego_gss_cred_id_t, + OM_uint32, gss_name_t, OM_uint32, OM_uint32, gss_buffer_t, ++ gss_channel_bindings_t, + gss_buffer_t, OM_uint32 *, send_token_flag *); + + static OM_uint32 +@@ -144,8 +145,8 @@ acc_ctx_vfy_oid(OM_uint32 *, spnego_gss_ctx_id_t, gss_OID, + OM_uint32 *, send_token_flag *); + static OM_uint32 + acc_ctx_call_acc(OM_uint32 *, spnego_gss_ctx_id_t, spnego_gss_cred_id_t, +- gss_buffer_t, gss_buffer_t, OM_uint32 *, OM_uint32 *, +- send_token_flag *); ++ gss_buffer_t, gss_channel_bindings_t, gss_buffer_t, ++ OM_uint32 *, OM_uint32 *, send_token_flag *); + + static gss_OID + negotiate_mech(spnego_gss_ctx_id_t, gss_OID_set, OM_uint32 *); +@@ -905,6 +906,7 @@ init_ctx_call_init(OM_uint32 *minor_status, + OM_uint32 req_flags, + OM_uint32 time_req, + gss_buffer_t mechtok_in, ++ gss_channel_bindings_t bindings, + gss_buffer_t mechtok_out, + OM_uint32 *time_rec, + send_token_flag *send_token) +@@ -921,15 +923,14 @@ init_ctx_call_init(OM_uint32 *minor_status, + if (gss_oid_equal(sc->internal_mech, &negoex_mech)) { + ret = negoex_init(minor_status, sc, mcred, target_name, + mech_req_flags, time_req, mechtok_in, +- mechtok_out, time_rec); ++ bindings, mechtok_out, time_rec); + } else { + ret = gss_init_sec_context(minor_status, mcred, + &sc->ctx_handle, target_name, + sc->internal_mech, mech_req_flags, +- time_req, GSS_C_NO_CHANNEL_BINDINGS, +- mechtok_in, &sc->actual_mech, +- mechtok_out, &sc->ctx_flags, +- time_rec); ++ time_req, bindings, mechtok_in, ++ &sc->actual_mech, mechtok_out, ++ &sc->ctx_flags, time_rec); + } + + /* Bail out if the acceptor gave us an error token but the mech didn't +@@ -981,8 +982,8 @@ init_ctx_call_init(OM_uint32 *minor_status, + gss_delete_sec_context(&tmpmin, &sc->ctx_handle, GSS_C_NO_BUFFER); + tmpret = init_ctx_call_init(&tmpmin, sc, spcred, acc_negState, + target_name, req_flags, time_req, +- mechtok_in, mechtok_out, time_rec, +- send_token); ++ mechtok_in, bindings, mechtok_out, ++ time_rec, send_token); + if (HARD_ERROR(tmpret)) + goto fail; + *minor_status = tmpmin; +@@ -1004,7 +1005,7 @@ spnego_gss_init_sec_context( + gss_OID mech_type, + OM_uint32 req_flags, + OM_uint32 time_req, +- gss_channel_bindings_t input_chan_bindings, ++ gss_channel_bindings_t bindings, + gss_buffer_t input_token, + gss_OID *actual_mech, + gss_buffer_t output_token, +@@ -1084,8 +1085,8 @@ spnego_gss_init_sec_context( + if (!spnego_ctx->mech_complete) { + ret = init_ctx_call_init(minor_status, spnego_ctx, spcred, + acc_negState, target_name, req_flags, +- time_req, mechtok_in, &mechtok_out, +- time_rec, &send_token); ++ time_req, mechtok_in, bindings, ++ &mechtok_out, time_rec, &send_token); + if (ret != GSS_S_COMPLETE) + goto cleanup; + +@@ -1542,8 +1543,9 @@ cleanup: + static OM_uint32 + acc_ctx_call_acc(OM_uint32 *minor_status, spnego_gss_ctx_id_t sc, + spnego_gss_cred_id_t spcred, gss_buffer_t mechtok_in, +- gss_buffer_t mechtok_out, OM_uint32 *time_rec, +- OM_uint32 *negState, send_token_flag *tokflag) ++ gss_channel_bindings_t bindings, gss_buffer_t mechtok_out, ++ OM_uint32 *time_rec, OM_uint32 *negState, ++ send_token_flag *tokflag) + { + OM_uint32 ret, tmpmin; + gss_OID_desc mechoid; +@@ -1568,13 +1570,12 @@ acc_ctx_call_acc(OM_uint32 *minor_status, spnego_gss_ctx_id_t sc, + mcred = (spcred == NULL) ? GSS_C_NO_CREDENTIAL : spcred->mcred; + if (negoex) { + ret = negoex_accept(minor_status, sc, mcred, mechtok_in, +- mechtok_out, time_rec); ++ bindings, mechtok_out, time_rec); + } else { + (void) gss_release_name(&tmpmin, &sc->internal_name); + (void) gss_release_cred(&tmpmin, &sc->deleg_cred); + ret = gss_accept_sec_context(minor_status, &sc->ctx_handle, +- mcred, mechtok_in, +- GSS_C_NO_CHANNEL_BINDINGS, ++ mcred, mechtok_in, bindings, + &sc->internal_name, + &sc->actual_mech, mechtok_out, + &sc->ctx_flags, time_rec, +@@ -1620,7 +1621,7 @@ spnego_gss_accept_sec_context( + gss_ctx_id_t *context_handle, + gss_cred_id_t verifier_cred_handle, + gss_buffer_t input_token, +- gss_channel_bindings_t input_chan_bindings, ++ gss_channel_bindings_t bindings, + gss_name_t *src_name, + gss_OID *mech_type, + gss_buffer_t output_token, +@@ -1734,8 +1735,8 @@ spnego_gss_accept_sec_context( + */ + if (negState != REQUEST_MIC && mechtok_in != GSS_C_NO_BUFFER) { + ret = acc_ctx_call_acc(minor_status, sc, spcred, mechtok_in, +- &mechtok_out, time_rec, &negState, +- &return_token); ++ bindings, &mechtok_out, time_rec, ++ &negState, &return_token); + } + + /* Step 3: process or generate the MIC, if the negotiated mech is diff --git a/krb5.spec b/krb5.spec index eb99d26..4aef2f9 100644 --- a/krb5.spec +++ b/krb5.spec @@ -18,7 +18,7 @@ Summary: The Kerberos network authentication system Name: krb5 Version: 1.18.2 # for prerelease, should be e.g., 0.% {prerelease}.1% { ?dist } (without spaces) -Release: 1%{?dist} +Release: 2%{?dist} # rharwood has trust path to signing key and verifies on check-in Source0: https://web.mit.edu/kerberos/dist/krb5/1.18/krb5-%{version}%{prerelease}.tar.gz @@ -59,6 +59,7 @@ Patch16: Do-expiration-warnings-for-all-init_creds-APIs.patch Patch17: Pass-gss_localname-through-SPNEGO.patch Patch18: Omit-KDC-indicator-check-for-S4U2Self-requests.patch Patch19: Fix-typo-in-in-in-the-ksu-man-page.patch +Patch20: Pass-channel-bindings-through-SPNEGO.patch License: MIT URL: https://web.mit.edu/kerberos/www/ @@ -631,6 +632,9 @@ exit 0 %{_libdir}/libkadm5srv_mit.so.* %changelog +* Tue May 26 2020 Robbie Harwood - 1.18.2-2 +- Pass channel bindings through SPNEGO + * Fri May 22 2020 Robbie Harwood - 1.18.2-1 - New upstream release (1.18.2)