Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP7:GA
cyrus-sasl.14126
0001-Fix-GSS-SPNEGO-mechanism-s-incompatible-be...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0001-Fix-GSS-SPNEGO-mechanism-s-incompatible-behavior.patch of Package cyrus-sasl.14126
From 070b96df8c6620843083e1ff81822272712dc787 Mon Sep 17 00:00:00 2001 From: Simo Sorce <simo@redhat.com> Date: Thu, 16 Feb 2017 15:25:56 -0500 Subject: [PATCH 1/4] Fix GSS-SPNEGO mechanism's incompatible behavior The GSS-SPNEGO mechanism has been designed and introduced by Microsoft for use by Active Directory clients. It allows to negotiate an underlying Security Mechanism like Krb5 or NTLMSSP. However, the implementaion in cyrus-sasl is broken and never correctly interoperated with Microsoft servers or clients. This patch fixes the compatibility issue which is caused by incorrectly trying to negotiate SSF layers explicitly instead of using the flags negotiated by GSSAPI as required by Microsoft's implementation. Signed-off-by: Simo Sorce <simo@redhat.com> --- plugins/gssapi.c | 70 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 6 deletions(-) diff --git a/plugins/gssapi.c b/plugins/gssapi.c index 2fd1b3b..9da1362 100644 --- a/plugins/gssapi.c +++ b/plugins/gssapi.c @@ -620,10 +620,62 @@ static void gssapi_common_mech_free(void *global_context __attribute__((unused)) #endif } +/* The GSS-SPNEGO mechanism does not do SSF negotiation, instead it uses the + * flags negotiated by GSSAPI to determine If confidentiality or integrity are + * used. These flags are stored in text->qop transalated as layers by the + * caller */ +static int gssapi_spnego_ssf(context_t *text, const sasl_utils_t *utils, + sasl_security_properties_t *props, + sasl_out_params_t *oparams) +{ + OM_uint32 maj_stat = 0, min_stat = 0; + OM_uint32 max_input; + + if (text->qop & LAYER_CONFIDENTIALITY) { + oparams->encode = &gssapi_privacy_encode; + oparams->decode = &gssapi_decode; + oparams->mech_ssf = K5_MAX_SSF; + } else if (text->qop & LAYER_INTEGRITY) { + oparams->encode = &gssapi_integrity_encode; + oparams->decode = &gssapi_decode; + oparams->mech_ssf = 1; + } else { + oparams->encode = NULL; + oparams->decode = NULL; + oparams->mech_ssf = 0; + } + + if (oparams->mech_ssf) { + maj_stat = gss_wrap_size_limit(&min_stat, + text->gss_ctx, + 1, + GSS_C_QOP_DEFAULT, + (OM_uint32)oparams->maxoutbuf, + &max_input); + + if (max_input > oparams->maxoutbuf) { + /* Heimdal appears to get this wrong */ + oparams->maxoutbuf -= (max_input - oparams->maxoutbuf); + } else { + /* This code is actually correct */ + oparams->maxoutbuf = max_input; + } + } + + text->state = SASL_GSSAPI_STATE_AUTHENTICATED; + + /* used by layers */ + _plug_decode_init(&text->decode_context, text->utils, + (props->maxbufsize > 0xFFFFFF) ? 0xFFFFFF : + props->maxbufsize); + + return SASL_OK; +} + /***************************** Server Section *****************************/ static int -gssapi_server_mech_new(void *glob_context __attribute__((unused)), +gssapi_server_mech_new(void *glob_context, sasl_server_params_t *params, const char *challenge __attribute__((unused)), unsigned challen __attribute__((unused)), @@ -645,6 +697,7 @@ gssapi_server_mech_new(void *glob_context __attribute__((unused)), text->state = SASL_GSSAPI_STATE_AUTHNEG; text->http_mode = (params->flags & SASL_NEED_HTTP); + text->mech_type = (gss_OID) glob_context; *conn_context = text; @@ -658,7 +711,7 @@ gssapi_server_mech_authneg(context_t *text, unsigned clientinlen, const char **serverout, unsigned *serveroutlen, - sasl_out_params_t *oparams __attribute__((unused))) + sasl_out_params_t *oparams) { gss_buffer_t input_token, output_token; gss_buffer_desc real_input_token, real_output_token; @@ -937,8 +990,9 @@ gssapi_server_mech_authneg(context_t *text, /* HTTP doesn't do any ssf negotiation */ text->state = SASL_GSSAPI_STATE_AUTHENTICATED; ret = SASL_OK; - } - else { + } else if (text->mech_type && text->mech_type == &gss_spnego_oid) { + ret = gssapi_spnego_ssf(text, params->utils, ¶ms->props, oparams); + } else { /* Switch to ssf negotiation */ text->state = SASL_GSSAPI_STATE_SSFCAP; ret = SASL_CONTINUE; @@ -1352,7 +1406,7 @@ static sasl_server_plug_t gssapi_server_plugins[] = | SASL_FEAT_ALLOWS_PROXY | SASL_FEAT_DONTUSE_USERPASSWD | SASL_FEAT_SUPPORTS_HTTP, /* features */ - NULL, /* glob_context */ + &gss_spnego_oid, /* glob_context */ &gssapi_server_mech_new, /* mech_new */ &gssapi_server_mech_step, /* mech_step */ &gssapi_common_mech_dispose, /* mech_dispose */ @@ -1730,7 +1784,11 @@ static int gssapi_client_mech_step(void *conn_context, text->state = SASL_GSSAPI_STATE_AUTHENTICATED; oparams->doneflag = 1; return SASL_OK; - } + } else if (text->mech_type && text->mech_type == &gss_spnego_oid) { + oparams->doneflag = 1; + return gssapi_spnego_ssf(text, params->utils, ¶ms->props, + oparams); + } /* Switch to ssf negotiation */ text->state = SASL_GSSAPI_STATE_SSFCAP; -- 2.25.0
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor