]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Implement GSS_KRB5_CRED_NO_CI_FLAGS_X for SPNEGO
authorAndreas Schneider <asn@samba.org>
Tue, 23 Jun 2015 14:27:27 +0000 (16:27 +0200)
committerGreg Hudson <ghudson@mit.edu>
Thu, 2 Jul 2015 17:17:23 +0000 (13:17 -0400)
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

src/lib/gssapi/spnego/gssapiP_spnego.h
src/lib/gssapi/spnego/spnego_mech.c
src/tests/gssapi/t_ciflags.c

index bc23f567172e990333dd90e59d629347e10c2cd5..57372dec625ea142ef58afd8ade72444abc0261e 100644 (file)
@@ -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 */
index f928e554ea8f31cb54289cc639dba6cb072fede3..bf44bc0b535d8b6bbdd562b7cd05a747bb16bd95 100644 (file)
@@ -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
index 6627b7b96f683044a1e2b5442f8116afa2e914e2..315062c9e74a7f5268adbe85ceae14633fa456b0 100644 (file)
@@ -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);