krb5 commit: Implement GSS_KRB5_CRED_NO_CI_FLAGS_X cred option

Greg Hudson ghudson at mit.edu
Thu Jun 18 13:06:01 EDT 2015


https://github.com/krb5/krb5/commit/7e6965ae33338216650384ca559d49e90312087a
commit 7e6965ae33338216650384ca559d49e90312087a
Author: Andreas Schneider <asn at samba.org>
Date:   Thu May 7 16:16:59 2015 +0200

    Implement GSS_KRB5_CRED_NO_CI_FLAGS_X cred option
    
    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 at 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     |    1 +
 src/lib/gssapi/krb5/gssapiP_krb5.h     |    1 +
 src/lib/gssapi/krb5/gssapi_krb5.c      |   24 ++++++++++++++++++++++++
 src/lib/gssapi/krb5/gssapi_krb5.h      |   10 ++++++++++
 src/lib/gssapi/krb5/init_sec_context.c |   14 ++++++++------
 src/lib/gssapi/libgssapi_krb5.exports  |    1 +
 src/lib/gssapi32.def                   |    2 ++
 7 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c
index 86a0462..ff51901 100644
--- a/src/lib/gssapi/krb5/acquire_cred.c
+++ b/src/lib/gssapi/krb5/acquire_cred.c
@@ -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);
diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
index a0e8625..9aae12a 100644
--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
@@ -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;
diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c
index 77b7fff..aa5c403 100644
--- a/src/lib/gssapi/krb5/gssapi_krb5.c
+++ b/src/lib/gssapi/krb5/gssapi_krb5.c
@@ -124,6 +124,9 @@
  * 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
diff --git a/src/lib/gssapi/krb5/gssapi_krb5.h b/src/lib/gssapi/krb5/gssapi_krb5.h
index 3f4d0c0..f72efd0 100644
--- a/src/lib/gssapi/krb5/gssapi_krb5.h
+++ b/src/lib/gssapi/krb5/gssapi_krb5.h
@@ -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
diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c
index dc47053..4d05d78 100644
--- a/src/lib/gssapi/krb5/init_sec_context.c
+++ b/src/lib/gssapi/krb5/init_sec_context.c
@@ -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;
 
diff --git a/src/lib/gssapi/libgssapi_krb5.exports b/src/lib/gssapi/libgssapi_krb5.exports
index a949e83..9facb3f 100644
--- a/src/lib/gssapi/libgssapi_krb5.exports
+++ b/src/lib/gssapi/libgssapi_krb5.exports
@@ -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
diff --git a/src/lib/gssapi32.def b/src/lib/gssapi32.def
index 9e18a66..362b9bc 100644
--- a/src/lib/gssapi32.def
+++ b/src/lib/gssapi32.def
@@ -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


More information about the cvs-krb5 mailing list