From: Andreas Schneider Date: Tue, 23 Jun 2015 14:27:27 +0000 (+0200) Subject: Implement GSS_KRB5_CRED_NO_CI_FLAGS_X for SPNEGO X-Git-Tag: krb5-1.14-alpha1~86 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cf39ed349976908626cad3e05e17788f8334bce9;p=thirdparty%2Fkrb5.git Implement GSS_KRB5_CRED_NO_CI_FLAGS_X for SPNEGO In the SPNEGO mechanism, if we see the GSS_KRB5_CRED_NO_CI_FLAGS_X option, do not explicitly ask for integrity flag from underlying mechanisms. Adjust t_ciflags.c to match the new behavior, and add a SPNEGO test using a normal initiator cred. [ghudson@mit.edu: adjust style; fix tests here instead of in a subsequent commit; clarify commit message] ticket: 6938 --- diff --git a/src/lib/gssapi/spnego/gssapiP_spnego.h b/src/lib/gssapi/spnego/gssapiP_spnego.h index bc23f56717..57372dec62 100644 --- a/src/lib/gssapi/spnego/gssapiP_spnego.h +++ b/src/lib/gssapi/spnego/gssapiP_spnego.h @@ -85,6 +85,7 @@ typedef struct { typedef struct { gss_cred_id_t mcred; /* mechglue union of obtainable creds */ gss_OID_set neg_mechs; /* app-specified list of allowable mechs */ + int no_ask_integ; /* do not request integ from mechs */ } spnego_gss_cred_id_rec, *spnego_gss_cred_id_t; /* Structure for context handle */ diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c index f928e554ea..bf44bc0b53 100644 --- a/src/lib/gssapi/spnego/spnego_mech.c +++ b/src/lib/gssapi/spnego/spnego_mech.c @@ -888,16 +888,21 @@ init_ctx_call_init(OM_uint32 *minor_status, OM_uint32 *negState, send_token_flag *send_token) { - OM_uint32 ret, tmpret, tmpmin; + OM_uint32 ret, tmpret, tmpmin, mech_req_flags; gss_cred_id_t mcred; mcred = (spcred == NULL) ? GSS_C_NO_CREDENTIAL : spcred->mcred; + + mech_req_flags = req_flags; + if (spcred == NULL || !spcred->no_ask_integ) + mech_req_flags |= GSS_C_INTEG_FLAG; + ret = gss_init_sec_context(minor_status, mcred, &sc->ctx_handle, target_name, sc->internal_mech, - (req_flags | GSS_C_INTEG_FLAG), + mech_req_flags, time_req, GSS_C_NO_CHANNEL_BINDINGS, mechtok_in, @@ -2373,6 +2378,13 @@ spnego_gss_inquire_cred_by_oid( return (ret); } +/* This is the same OID as KRB5_NO_CI_FLAGS_X_OID. */ +#define NO_CI_FLAGS_X_OID_LENGTH 6 +#define NO_CI_FLAGS_X_OID "\x2a\x85\x70\x2b\x0d\x1d" +static const gss_OID_desc no_ci_flags_oid[] = { + {NO_CI_FLAGS_X_OID_LENGTH, NO_CI_FLAGS_X_OID}, +}; + OM_uint32 KRB5_CALLCONV spnego_gss_set_cred_option( OM_uint32 *minor_status, @@ -2404,7 +2416,14 @@ spnego_gss_set_cred_option( *cred_handle = (gss_cred_id_t)spcred; } - return (ret); + if (ret != GSS_S_COMPLETE) + return (ret); + + /* Recognize KRB5_NO_CI_FLAGS_X_OID and avoid asking for integrity. */ + if (g_OID_equal(desired_object, no_ci_flags_oid)) + spcred->no_ask_integ = 1; + + return (GSS_S_COMPLETE); } OM_uint32 KRB5_CALLCONV diff --git a/src/tests/gssapi/t_ciflags.c b/src/tests/gssapi/t_ciflags.c index 6627b7b96f..315062c9e7 100644 --- a/src/tests/gssapi/t_ciflags.c +++ b/src/tests/gssapi/t_ciflags.c @@ -90,6 +90,8 @@ main(int argc, char *argv[]) check_gsserr("gss_acquire_cred", major, minor); flagtest(&mech_krb5, icred, tname, 0, GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG); + flagtest(&mech_spnego, icred, tname, 0, + GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG); /* Suppress confidentiality and integrity flags on the initiator cred and * check that they are suppressed, but can still be asserted explicitly. */ @@ -104,15 +106,11 @@ main(int argc, char *argv[]) GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG); flagtest(&mech_krb5, icred, tname, GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG, GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG); - - /* Currently we cannot suppress the integ flag through SPNEGO, since SPNEGO - * always requests integrity from the underlying mech. */ - flagtest(&mech_spnego, icred, tname, 0, - GSS_C_TRANS_FLAG | GSS_C_INTEG_FLAG); + flagtest(&mech_spnego, icred, tname, 0, GSS_C_TRANS_FLAG); flagtest(&mech_spnego, icred, tname, GSS_C_INTEG_FLAG, GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG); flagtest(&mech_spnego, icred, tname, GSS_C_CONF_FLAG, - GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG); + GSS_C_CONF_FLAG | GSS_C_TRANS_FLAG); flagtest(&mech_spnego, icred, tname, GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG, GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG);