krb5 commit: Implement GSS_KRB5_CRED_NO_CI_FLAGS_X for SPNEGO

Greg Hudson ghudson at mit.edu
Thu Jul 2 13:32:19 EDT 2015


https://github.com/krb5/krb5/commit/cf39ed349976908626cad3e05e17788f8334bce9
commit cf39ed349976908626cad3e05e17788f8334bce9
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jun 23 16:27:27 2015 +0200

    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 at mit.edu: adjust style; fix tests here instead of in a
    subsequent commit; clarify commit message]
    
    ticket: 6938

 src/lib/gssapi/spnego/gssapiP_spnego.h |    1 +
 src/lib/gssapi/spnego/spnego_mech.c    |   25 ++++++++++++++++++++++---
 src/tests/gssapi/t_ciflags.c           |   10 ++++------
 3 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/src/lib/gssapi/spnego/gssapiP_spnego.h b/src/lib/gssapi/spnego/gssapiP_spnego.h
index bc23f56..57372de 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 f928e55..bf44bc0 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 6627b7b..315062c 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);
 


More information about the cvs-krb5 mailing list