Fix support for GSS SPNEGO (#1421663)
This commit is contained in:
parent
ca0c11d6a7
commit
865b833a45
139
cyrus-sasl-2.1.26-gss-spnego.patch
Normal file
139
cyrus-sasl-2.1.26-gss-spnego.patch
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
From 67ca66685e11acc0f69d5ff8013107d4b172e67f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Simo Sorce <simo@redhat.com>
|
||||||
|
Date: Thu, 16 Feb 2017 15:25:56 -0500
|
||||||
|
Subject: [PATCH] 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 bfc278d..010c236 100644
|
||||||
|
--- a/plugins/gssapi.c
|
||||||
|
+++ b/plugins/gssapi.c
|
||||||
|
@@ -648,10 +648,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)),
|
||||||
|
@@ -673,6 +725,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;
|
||||||
|
|
||||||
|
@@ -686,7 +739,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;
|
||||||
|
@@ -965,8 +1018,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;
|
||||||
|
@@ -1391,7 +1445,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 */
|
||||||
|
@@ -1769,7 +1823,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;
|
||||||
|
|
@ -61,6 +61,8 @@ Patch55: cyrus-sasl-2.1.26-saslauthd-user.patch
|
|||||||
Patch56: cyrus-sasl-2.1.26-user-specified-logging.patch
|
Patch56: cyrus-sasl-2.1.26-user-specified-logging.patch
|
||||||
# OpenSSL 1.1.0 support
|
# OpenSSL 1.1.0 support
|
||||||
Patch57: cyrus-sasl-2.1.27-openssl-1.1.0.patch
|
Patch57: cyrus-sasl-2.1.27-openssl-1.1.0.patch
|
||||||
|
# Fix support for GSS SPNEGO to be compatible with windows (#1421663)
|
||||||
|
Patch58: cyrus-sasl-2.1.26-gss-spnego.patch
|
||||||
|
|
||||||
Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||||
BuildRequires: autoconf, automake, libtool, gdbm-devel, groff
|
BuildRequires: autoconf, automake, libtool, gdbm-devel, groff
|
||||||
@ -210,6 +212,7 @@ chmod -x include/*.h
|
|||||||
%patch55 -p1 -b .man-unprivileged
|
%patch55 -p1 -b .man-unprivileged
|
||||||
%patch56 -p1 -b .too-much-logging
|
%patch56 -p1 -b .too-much-logging
|
||||||
%patch57 -p1 -b .openssl110
|
%patch57 -p1 -b .openssl110
|
||||||
|
%patch58 -p1 -b .spnego
|
||||||
|
|
||||||
|
|
||||||
%build
|
%build
|
||||||
|
Loading…
Reference in New Issue
Block a user