From: Andreas Schneider Date: Thu, 7 May 2015 14:16:59 +0000 (+0200) Subject: Implement GSS_KRB5_CRED_NO_CI_FLAGS_X cred option X-Git-Tag: krb5-1.14-alpha1~99 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7e6965ae33338216650384ca559d49e90312087a;p=thirdparty%2Fkrb5.git 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@mit.edu: expand GSS_KRB5_CRED_NO_CI_FLAGS_X comment, edit commit message, use a boolean cred field] ticket: 6938 --- diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c index 86a0462b50..ff51901381 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 a0e8625d05..9aae12a654 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 77b7fff026..aa5c4031b7 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 3f4d0c0cfd..f72efd0ccf 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 dc47053297..4d05d782b2 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 a949e8337a..9facb3f426 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 9e18a66920..362b9bce84 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