]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Implement GSS_KRB5_CRED_NO_CI_FLAGS_X cred option
authorAndreas Schneider <asn@samba.org>
Thu, 7 May 2015 14:16:59 +0000 (16:16 +0200)
committerGreg Hudson <ghudson@mit.edu>
Thu, 18 Jun 2015 16:48:07 +0000 (12:48 -0400)
Microsoft implements GSS-SPNEGO, a non-standard SASL mechanism which
omits the usual wrap exchange after the GSS context is established.
As a result, it does not support authzids, does not negotiate a
maximum message size, and implicitly negotiates a security layer based
on the GSS flags asserted by the client.  If the client asserts GSS
flags corresponding to a security layer the server can't support, the
server has no recourse except to reject the connection.

Implement Heimdal's GSS_KRB5_CRED_NO_CI_FLAGS_X cred option.  When set
on an initiator cred, do not assert the confidentiality and integrity
flags in initiator tokens unless they were requested by the caller.

Our SPNEGO mechanism always requests integrity from the underlying
mechanism, which limits the utility of this option.  That issue will
be addressed in the future; even if it isn't, Samba currently uses its
own SPNEGO implementation, so can benefit from the cred option in
krb5.

[ghudson@mit.edu: expand GSS_KRB5_CRED_NO_CI_FLAGS_X comment, edit
commit message, use a boolean cred field]

ticket: 6938

src/lib/gssapi/krb5/acquire_cred.c
src/lib/gssapi/krb5/gssapiP_krb5.h
src/lib/gssapi/krb5/gssapi_krb5.c
src/lib/gssapi/krb5/gssapi_krb5.h
src/lib/gssapi/krb5/init_sec_context.c
src/lib/gssapi/libgssapi_krb5.exports
src/lib/gssapi32.def

index 86a0462b500ca2d81aed638f8b825cc5de47e6c2..ff5190138131f83d587575182868d96f08bb9d44 100644 (file)
@@ -758,6 +758,7 @@ acquire_cred_context(krb5_context context, OM_uint32 *minor_status,
     cred->keytab = NULL;
 #endif /* LEAN_CLIENT */
     cred->destroy_ccache = 0;
+    cred->suppress_ci_flags = 0;
     cred->ccache = NULL;
 
     code = k5_mutex_init(&cred->lock);
index a0e8625d05b6de7e37ba5f4c9adbb15ef352d400..9aae12a654dc4f316aae46ef44a7ac53f070b871 100644 (file)
@@ -178,6 +178,7 @@ typedef struct _krb5_gss_cred_id_rec {
     unsigned int default_identity : 1;
     unsigned int iakerb_mech : 1;
     unsigned int destroy_ccache : 1;
+    unsigned int suppress_ci_flags : 1;
 
     /* keytab (accept) data */
     krb5_keytab keytab;
index 77b7fff026a2d9f0602cd73b2cdf4f53929da999..aa5c4031b72aae841e33051f91fae541da0e6b50 100644 (file)
  * except the last in each value's encoding.
  */
 
+#define NO_CI_FLAGS_X_OID_LENGTH 6
+#define NO_CI_FLAGS_X_OID "\x2a\x85\x70\x2b\x0d\x1d"
+
 const gss_OID_desc krb5_gss_oid_array[] = {
     /* this is the official, rfc-specified OID */
     {GSS_MECH_KRB5_OID_LENGTH, GSS_MECH_KRB5_OID},
@@ -144,6 +147,7 @@ const gss_OID_desc krb5_gss_oid_array[] = {
     {10, "\052\206\110\206\367\022\001\002\002\001"},
     /* gss_nt_krb5_principal.  Object identifier for a krb5_principal. Do not use. */
     {10, "\052\206\110\206\367\022\001\002\002\002"},
+    {NO_CI_FLAGS_X_OID_LENGTH, NO_CI_FLAGS_X_OID},
     { 0, 0 }
 };
 
@@ -157,6 +161,8 @@ const gss_OID_desc * const gss_nt_krb5_name           = krb5_gss_oid_array+5;
 const gss_OID_desc * const gss_nt_krb5_principal      = krb5_gss_oid_array+6;
 const gss_OID_desc * const GSS_KRB5_NT_PRINCIPAL_NAME = krb5_gss_oid_array+5;
 
+const gss_OID_desc * const GSS_KRB5_CRED_NO_CI_FLAGS_X = krb5_gss_oid_array+7;
+
 static const gss_OID_set_desc oidsets[] = {
     {1, (gss_OID) krb5_gss_oid_array+0}, /* RFC OID */
     {1, (gss_OID) krb5_gss_oid_array+1}, /* pre-RFC OID */
@@ -497,6 +503,20 @@ krb5_gss_set_sec_context_option (OM_uint32 *minor_status,
     return GSS_S_UNAVAILABLE;
 }
 
+static OM_uint32
+no_ci_flags(OM_uint32 *minor_status,
+            gss_cred_id_t *cred_handle,
+            const gss_OID desired_oid,
+            const gss_buffer_t value)
+{
+    krb5_gss_cred_id_t cred;
+
+    cred = (krb5_gss_cred_id_t) *cred_handle;
+    cred->suppress_ci_flags = 1;
+
+    *minor_status = 0;
+    return GSS_S_COMPLETE;
+}
 /*
  * gssspi_set_cred_option() methods
  */
@@ -520,6 +540,10 @@ static struct {
         {GSS_KRB5_IMPORT_CRED_OID_LENGTH, GSS_KRB5_IMPORT_CRED_OID},
         gss_krb5int_import_cred
     },
+    {
+        {NO_CI_FLAGS_X_OID_LENGTH, NO_CI_FLAGS_X_OID},
+        no_ci_flags
+    },
 };
 
 static OM_uint32 KRB5_CALLCONV
index 3f4d0c0cfd6abf6b26ec1567499bac979d42ac1f..f72efd0ccff633afc1d3d3c8bce7af3ec0b7de4c 100644 (file)
@@ -86,6 +86,16 @@ GSS_DLLIMP extern const gss_OID_desc * const gss_nt_krb5_principal;
 
 GSS_DLLIMP extern const gss_OID_desc krb5_gss_oid_array[];
 
+/*
+ * This OID can be used with gss_set_cred_option() to suppress the
+ * confidentiality and integrity flags from being asserted in initial context
+ * tokens.
+ *
+ * iso(1) member-body(2) Sweden(752) Stockholm University(43) Heimdal GSS-API
+ * Extensions(13) no_ci_flags(29)
+ */
+GSS_DLLIMP extern const gss_OID_desc * const GSS_KRB5_CRED_NO_CI_FLAGS_X;
+
 #define gss_krb5_nt_general_name        gss_nt_krb5_name
 #define gss_krb5_nt_principal           gss_nt_krb5_principal
 #define gss_krb5_nt_service_name        gss_nt_service_name
index dc47053297f76486604a1d1ae5778969efe90516..4d05d782b25a2a24f641736a3dfa1115b1a6adf6 100644 (file)
@@ -552,15 +552,17 @@ kg_new_connection(
     }
 
     ctx->initiate = 1;
-    ctx->gss_flags = (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG |
-                      GSS_C_TRANS_FLAG |
-                      ((req_flags) & (GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG |
-                                      GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG |
-                                      GSS_C_DCE_STYLE | GSS_C_IDENTIFY_FLAG |
-                                      GSS_C_EXTENDED_ERROR_FLAG)));
     ctx->seed_init = 0;
     ctx->seqstate = 0;
 
+    ctx->gss_flags = req_flags & (GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG |
+                                  GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG |
+                                  GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG |
+                                  GSS_C_DCE_STYLE | GSS_C_IDENTIFY_FLAG |
+                                  GSS_C_EXTENDED_ERROR_FLAG);
+    ctx->gss_flags |= GSS_C_TRANS_FLAG;
+    if (!cred->suppress_ci_flags)
+        ctx->gss_flags |= (GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG);
     if (req_flags & GSS_C_DCE_STYLE)
         ctx->gss_flags |= GSS_C_MUTUAL_FLAG;
 
index a949e8337adb8c1f1107736bc8296f3ed8681529..9facb3f4267122e9478d085378e4a0a63880082d 100644 (file)
@@ -9,6 +9,7 @@ GSS_C_NT_MACHINE_UID_NAME
 GSS_C_NT_STRING_UID_NAME
 GSS_C_NT_USER_NAME
 GSS_KRB5_NT_PRINCIPAL_NAME
+GSS_KRB5_CRED_NO_CI_FLAGS_X
 GSS_C_MA_MECH_CONCRETE
 GSS_C_MA_MECH_PSEUDO
 GSS_C_MA_MECH_COMPOSITE
index 9e18a6692050bed4ee00e07e22e542b173482b8f..362b9bce848f0a5a1385962f0dfdf95f834fc087 100644 (file)
@@ -180,3 +180,5 @@ EXPORTS
        gss_get_mic_iov                                 @144
        gss_get_mic_iov_length                          @145
        gss_verify_mic_iov                              @146
+; Added in 1.14
+       GSS_KRB5_CRED_NO_CI_FLAGS_X                     @147    DATA