Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15:Update
cyrus-sasl.22964
0004-Add-support-for-retrieving-the-mech_ssf.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0004-Add-support-for-retrieving-the-mech_ssf.patch of Package cyrus-sasl.22964
From 55173cd84d0dc40b767d98b70b642ced78354c7d Mon Sep 17 00:00:00 2001 From: Simo Sorce <simo@redhat.com> Date: Mon, 10 Apr 2017 19:54:19 -0400 Subject: [PATCH 4/4] Add support for retrieving the mech_ssf In the latest MIT Kerberos implementation it is possible to extract the calculated SSF wich is based on the encryption type that has been used to establish the GSSAPI security context. Use this method if available or fall back to the old "DES" value. Signed-off-by: Simo Sorce <simo@redhat.com> --- plugins/gssapi.c | 104 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 93 insertions(+), 11 deletions(-) diff --git a/plugins/gssapi.c b/plugins/gssapi.c index e3cb23b..b620282 100644 --- a/plugins/gssapi.c +++ b/plugins/gssapi.c @@ -51,6 +51,13 @@ #include <gssapi/gssapi.h> #endif +#ifdef HAVE_GSSAPI_GSSAPI_KRB5_H +#include <gssapi/gssapi_krb5.h> +#endif +#ifdef HAVE_GSSAPI_GSSAPI_EXT_H +#include <gssapi/gssapi_ext.h> +#endif + #ifdef WIN32 # include <winsock2.h> @@ -98,18 +105,25 @@ extern gss_OID gss_nt_service_name; /* Check if CyberSafe flag is defined */ #ifdef CSF_GSS_C_DES3_FLAG #define K5_MAX_SSF 112 +#define K5_MIN_SSF 112 #endif /* Heimdal and MIT use the following */ #ifdef GSS_KRB5_CONF_C_QOP_DES3_KD #define K5_MAX_SSF 112 +#define K5_MIN_SSF 112 #endif #endif #ifndef K5_MAX_SSF +/* All modern Kerberos implementations support AES */ +#define K5_MAX_SSF 256 +#endif + /* All Kerberos implementations support DES */ -#define K5_MAX_SSF 56 +#ifndef K5_MIN_SSF +#define K5_MIN_SSF 56 #endif /* GSSAPI SASL Mechanism by Leif Johansson <leifj@matematik.su.se> @@ -646,6 +660,47 @@ static int gssapi_wrap_sizes(context_t *text, sasl_out_params_t *oparams) return SASL_OK; } +#if !defined(HAVE_GSS_C_SEC_CONTEXT_SASL_SSF) +gss_OID_desc gss_sasl_ssf = { + 11, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0f" +}; +gss_OID GSS_C_SEC_CONTEXT_SASL_SSF = &gss_sasl_ssf; +#endif + +static int gssapi_get_ssf(context_t *text, sasl_ssf_t *mech_ssf) +{ +#ifdef HAVE_GSS_INQUIRE_SEC_CONTEXT_BY_OID + OM_uint32 maj_stat = 0, min_stat = 0; + gss_buffer_set_t bufset = GSS_C_NO_BUFFER_SET; + gss_OID ssf_oid = GSS_C_SEC_CONTEXT_SASL_SSF; + uint32_t ssf; + + maj_stat = gss_inquire_sec_context_by_oid(&min_stat, text->gss_ctx, + ssf_oid, &bufset); + switch (maj_stat) { + case GSS_S_UNAVAILABLE: + /* Not supported by the library, fallback to default */ + goto fallback; + case GSS_S_COMPLETE: + if ((bufset->count != 1) || (bufset->elements[0].length != 4)) { + /* Malformed bufset, fail */ + (void)gss_release_buffer_set(&min_stat, &bufset); + return SASL_FAIL; + } + memcpy(&ssf, bufset->elements[0].value, 4); + (void)gss_release_buffer_set(&min_stat, &bufset); + *mech_ssf = ntohl(ssf); + return SASL_OK; + default: + return SASL_FAIL; + } + +fallback: +#endif + *mech_ssf = K5_MIN_SSF; + return SASL_OK; +} + /* 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 @@ -659,7 +714,10 @@ static int gssapi_spnego_ssf(context_t *text, if (text->qop & LAYER_CONFIDENTIALITY) { oparams->encode = &gssapi_privacy_encode; oparams->decode = &gssapi_decode; - oparams->mech_ssf = K5_MAX_SSF; + ret = gssapi_get_ssf(text, &oparams->mech_ssf); + if (ret != SASL_OK) { + return ret; + } } else if (text->qop & LAYER_INTEGRITY) { oparams->encode = &gssapi_integrity_encode; oparams->decode = &gssapi_decode; @@ -1049,6 +1107,7 @@ gssapi_server_mech_ssfcap(context_t *text, gss_buffer_desc real_input_token, real_output_token; OM_uint32 maj_stat = 0, min_stat = 0; unsigned char sasldata[4]; + sasl_ssf_t mech_ssf; int ret; input_token = &real_input_token; @@ -1109,9 +1168,14 @@ gssapi_server_mech_ssfcap(context_t *text, params->props.maxbufsize) { sasldata[0] |= LAYER_INTEGRITY; } + ret = gssapi_get_ssf(text, &mech_ssf); + if (ret != SASL_OK) { + sasl_gss_free_context_contents(text); + return ret; + } if ((text->qop & LAYER_CONFIDENTIALITY) && - text->requiressf <= K5_MAX_SSF && - text->limitssf >= K5_MAX_SSF && + text->requiressf <= mech_ssf && + text->limitssf >= mech_ssf && params->props.maxbufsize) { sasldata[0] |= LAYER_CONFIDENTIALITY; } @@ -1232,10 +1296,18 @@ gssapi_server_mech_ssfreq(context_t *text, /* For compatibility with broken clients setting both bits */ layerchoice == (LAYER_CONFIDENTIALITY|LAYER_INTEGRITY)) && (text->qop & LAYER_CONFIDENTIALITY)) { /* privacy */ + int ret; oparams->encode = &gssapi_privacy_encode; oparams->decode = &gssapi_decode; - /* FIX ME: Need to extract the proper value here */ - oparams->mech_ssf = K5_MAX_SSF; + + ret = gssapi_get_ssf(text, &oparams->mech_ssf); + if (ret != SASL_OK) { + GSS_LOCK_MUTEX_CTX(params->utils, text); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX_CTX(params->utils, text); + sasl_gss_free_context_contents(text); + return ret; + } } else { /* not a supported encryption layer */ SETERROR(text->utils, @@ -1806,6 +1878,8 @@ static int gssapi_client_mech_step(void *conn_context, unsigned int alen, external = params->external_ssf; sasl_ssf_t need, allowed; char serverhas, mychoice; + sasl_ssf_t mech_ssf; + int ret; real_input_token.value = (void *) serverin; real_input_token.length = serverinlen; @@ -1840,8 +1914,17 @@ static int gssapi_client_mech_step(void *conn_context, return SASL_FAIL; } + ret = gssapi_get_ssf(text, &mech_ssf); + if (ret != SASL_OK) { + GSS_LOCK_MUTEX_CTX(params->utils, text); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX_CTX(params->utils, text); + sasl_gss_free_context_contents(text); + return SASL_FAIL; + } + /* taken from kerberos.c */ - if (secprops->min_ssf > (K5_MAX_SSF + external)) { + if (secprops->min_ssf > (mech_ssf + external)) { return SASL_TOOWEAK; } else if (secprops->min_ssf > secprops->max_ssf) { return SASL_BADPARAM; @@ -1865,8 +1948,8 @@ static int gssapi_client_mech_step(void *conn_context, /* use the strongest layer available */ if ((text->qop & LAYER_CONFIDENTIALITY) && - allowed >= K5_MAX_SSF && - need <= K5_MAX_SSF && + allowed >= mech_ssf && + need <= mech_ssf && (serverhas & LAYER_CONFIDENTIALITY)) { const char *ad_compat; @@ -1874,8 +1957,7 @@ static int gssapi_client_mech_step(void *conn_context, /* encryption */ oparams->encode = &gssapi_privacy_encode; oparams->decode = &gssapi_decode; - /* FIX ME: Need to extract the proper value here */ - oparams->mech_ssf = K5_MAX_SSF; + oparams->mech_ssf = mech_ssf; mychoice = LAYER_CONFIDENTIALITY; if (serverhas & LAYER_INTEGRITY) { -- 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