|
|
b9abc1 |
From 862b60c249c8a51095315062b22c0702a6500d80 Mon Sep 17 00:00:00 2001
|
|
|
b9abc1 |
From: Simo Sorce <simo@redhat.com>
|
|
|
b9abc1 |
Date: Tue, 11 Apr 2017 18:31:46 -0400
|
|
|
b9abc1 |
Subject: [PATCH 1/3] Drop unused parameter from gssapi_spnego_ssf()
|
|
|
b9abc1 |
|
|
|
b9abc1 |
Signed-off-by: Simo Sorce <simo@redhat.com>
|
|
|
b9abc1 |
---
|
|
|
b9abc1 |
plugins/gssapi.c | 7 +++----
|
|
|
b9abc1 |
1 file changed, 3 insertions(+), 4 deletions(-)
|
|
|
b9abc1 |
|
|
|
b9abc1 |
diff --git a/plugins/gssapi.c b/plugins/gssapi.c
|
|
|
b9abc1 |
index 010c236d..3050962e 100644
|
|
|
b9abc1 |
--- a/plugins/gssapi.c
|
|
|
b9abc1 |
+++ b/plugins/gssapi.c
|
|
|
b9abc1 |
@@ -652,7 +652,7 @@ static void gssapi_common_mech_free(void *global_context __attribute__((unused))
|
|
|
b9abc1 |
* flags negotiated by GSSAPI to determine If confidentiality or integrity are
|
|
|
b9abc1 |
* used. These flags are stored in text->qop transalated as layers by the
|
|
|
b9abc1 |
* caller */
|
|
|
b9abc1 |
-static int gssapi_spnego_ssf(context_t *text, const sasl_utils_t *utils,
|
|
|
b9abc1 |
+static int gssapi_spnego_ssf(context_t *text,
|
|
|
b9abc1 |
sasl_security_properties_t *props,
|
|
|
b9abc1 |
sasl_out_params_t *oparams)
|
|
|
b9abc1 |
{
|
|
|
b9abc1 |
@@ -1019,7 +1019,7 @@ gssapi_server_mech_authneg(context_t *text,
|
|
|
b9abc1 |
text->state = SASL_GSSAPI_STATE_AUTHENTICATED;
|
|
|
b9abc1 |
ret = SASL_OK;
|
|
|
b9abc1 |
} else if (text->mech_type && text->mech_type == &gss_spnego_oid) {
|
|
|
b9abc1 |
- ret = gssapi_spnego_ssf(text, params->utils, ¶ms->props, oparams);
|
|
|
b9abc1 |
+ ret = gssapi_spnego_ssf(text, ¶ms->props, oparams);
|
|
|
b9abc1 |
} else {
|
|
|
b9abc1 |
/* Switch to ssf negotiation */
|
|
|
b9abc1 |
text->state = SASL_GSSAPI_STATE_SSFCAP;
|
|
|
b9abc1 |
@@ -1825,8 +1825,7 @@ static int gssapi_client_mech_step(void *conn_context,
|
|
|
b9abc1 |
return SASL_OK;
|
|
|
b9abc1 |
} else if (text->mech_type && text->mech_type == &gss_spnego_oid) {
|
|
|
b9abc1 |
oparams->doneflag = 1;
|
|
|
b9abc1 |
- return gssapi_spnego_ssf(text, params->utils, ¶ms->props,
|
|
|
b9abc1 |
- oparams);
|
|
|
b9abc1 |
+ return gssapi_spnego_ssf(text, ¶ms->props, oparams);
|
|
|
b9abc1 |
}
|
|
|
b9abc1 |
|
|
|
b9abc1 |
/* Switch to ssf negotiation */
|
|
|
b9abc1 |
|
|
|
b9abc1 |
From 72181257d77bda09afa7d0d640d322c4472f4833 Mon Sep 17 00:00:00 2001
|
|
|
b9abc1 |
From: Simo Sorce <simo@redhat.com>
|
|
|
b9abc1 |
Date: Mon, 10 Apr 2017 18:35:10 -0400
|
|
|
b9abc1 |
Subject: [PATCH 2/3] Check return error from gss_wrap_size_limit()
|
|
|
b9abc1 |
|
|
|
b9abc1 |
The return error of this function is ignored and potentially
|
|
|
b9abc1 |
uninitialized values returned by this function are used.
|
|
|
b9abc1 |
|
|
|
b9abc1 |
Fix this by moving the function into a proper helper as it is used in an
|
|
|
b9abc1 |
identical way in 3 different places.
|
|
|
b9abc1 |
|
|
|
b9abc1 |
Signed-off-by: Simo Sorce <simo@redhat.com>
|
|
|
b9abc1 |
---
|
|
|
b9abc1 |
plugins/gssapi.c | 104 +++++++++++++++++++++++++++----------------------------
|
|
|
b9abc1 |
1 file changed, 51 insertions(+), 53 deletions(-)
|
|
|
b9abc1 |
|
|
|
b9abc1 |
diff --git a/plugins/gssapi.c b/plugins/gssapi.c
|
|
|
b9abc1 |
index 3050962e..348debe0 100644
|
|
|
b9abc1 |
--- a/plugins/gssapi.c
|
|
|
b9abc1 |
+++ b/plugins/gssapi.c
|
|
|
b9abc1 |
@@ -648,6 +648,32 @@ static void gssapi_common_mech_free(void *global_context __attribute__((unused))
|
|
|
b9abc1 |
#endif
|
|
|
b9abc1 |
}
|
|
|
b9abc1 |
|
|
|
b9abc1 |
+static int gssapi_wrap_sizes(context_t *text, sasl_out_params_t *oparams)
|
|
|
b9abc1 |
+{
|
|
|
b9abc1 |
+ OM_uint32 maj_stat = 0, min_stat = 0;
|
|
|
b9abc1 |
+ OM_uint32 max_input = 0;
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
+ maj_stat = gss_wrap_size_limit(&min_stat,
|
|
|
b9abc1 |
+ text->gss_ctx,
|
|
|
b9abc1 |
+ 1,
|
|
|
b9abc1 |
+ GSS_C_QOP_DEFAULT,
|
|
|
b9abc1 |
+ (OM_uint32)oparams->maxoutbuf,
|
|
|
b9abc1 |
+ &max_input);
|
|
|
b9abc1 |
+ if (maj_stat != GSS_S_COMPLETE) {
|
|
|
b9abc1 |
+ return SASL_FAIL;
|
|
|
b9abc1 |
+ }
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
+ if (max_input > oparams->maxoutbuf) {
|
|
|
b9abc1 |
+ /* Heimdal appears to get this wrong */
|
|
|
b9abc1 |
+ oparams->maxoutbuf -= (max_input - oparams->maxoutbuf);
|
|
|
b9abc1 |
+ } else {
|
|
|
b9abc1 |
+ /* This code is actually correct */
|
|
|
b9abc1 |
+ oparams->maxoutbuf = max_input;
|
|
|
b9abc1 |
+ }
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
+ return SASL_OK;
|
|
|
b9abc1 |
+}
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
/* The GSS-SPNEGO mechanism does not do SSF negotiation, instead it uses the
|
|
|
b9abc1 |
* flags negotiated by GSSAPI to determine If confidentiality or integrity are
|
|
|
b9abc1 |
* used. These flags are stored in text->qop transalated as layers by the
|
|
|
b9abc1 |
@@ -656,8 +682,7 @@ static int gssapi_spnego_ssf(context_t *text,
|
|
|
b9abc1 |
sasl_security_properties_t *props,
|
|
|
b9abc1 |
sasl_out_params_t *oparams)
|
|
|
b9abc1 |
{
|
|
|
b9abc1 |
- OM_uint32 maj_stat = 0, min_stat = 0;
|
|
|
b9abc1 |
- OM_uint32 max_input;
|
|
|
b9abc1 |
+ int ret;
|
|
|
b9abc1 |
|
|
|
b9abc1 |
if (text->qop & LAYER_CONFIDENTIALITY) {
|
|
|
b9abc1 |
oparams->encode = &gssapi_privacy_encode;
|
|
|
b9abc1 |
@@ -674,20 +699,10 @@ static int gssapi_spnego_ssf(context_t *text,
|
|
|
b9abc1 |
}
|
|
|
b9abc1 |
|
|
|
b9abc1 |
if (oparams->mech_ssf) {
|
|
|
b9abc1 |
- maj_stat = gss_wrap_size_limit(&min_stat,
|
|
|
b9abc1 |
- text->gss_ctx,
|
|
|
b9abc1 |
- 1,
|
|
|
b9abc1 |
- GSS_C_QOP_DEFAULT,
|
|
|
b9abc1 |
- (OM_uint32)oparams->maxoutbuf,
|
|
|
b9abc1 |
- &max_input);
|
|
|
b9abc1 |
-
|
|
|
b9abc1 |
- if (max_input > oparams->maxoutbuf) {
|
|
|
b9abc1 |
- /* Heimdal appears to get this wrong */
|
|
|
b9abc1 |
- oparams->maxoutbuf -= (max_input - oparams->maxoutbuf);
|
|
|
b9abc1 |
- } else {
|
|
|
b9abc1 |
- /* This code is actually correct */
|
|
|
b9abc1 |
- oparams->maxoutbuf = max_input;
|
|
|
b9abc1 |
- }
|
|
|
b9abc1 |
+ ret = gssapi_wrap_sizes(text, oparams);
|
|
|
b9abc1 |
+ if (ret != SASL_OK) {
|
|
|
b9abc1 |
+ return ret;
|
|
|
b9abc1 |
+ }
|
|
|
b9abc1 |
}
|
|
|
b9abc1 |
|
|
|
b9abc1 |
text->state = SASL_GSSAPI_STATE_AUTHENTICATED;
|
|
|
b9abc1 |
@@ -1208,7 +1223,6 @@ gssapi_server_mech_ssfreq(context_t *text,
|
|
|
b9abc1 |
gss_buffer_t input_token, output_token;
|
|
|
b9abc1 |
gss_buffer_desc real_input_token, real_output_token;
|
|
|
b9abc1 |
OM_uint32 maj_stat = 0, min_stat = 0;
|
|
|
b9abc1 |
- OM_uint32 max_input;
|
|
|
b9abc1 |
int layerchoice;
|
|
|
b9abc1 |
|
|
|
b9abc1 |
input_token = &real_input_token;
|
|
|
b9abc1 |
@@ -1297,27 +1311,20 @@ gssapi_server_mech_ssfreq(context_t *text,
|
|
|
b9abc1 |
(((unsigned char *) output_token->value)[2] << 8) |
|
|
|
b9abc1 |
(((unsigned char *) output_token->value)[3] << 0);
|
|
|
b9abc1 |
|
|
|
b9abc1 |
- if (oparams->mech_ssf) {
|
|
|
b9abc1 |
- maj_stat = gss_wrap_size_limit( &min_stat,
|
|
|
b9abc1 |
- text->gss_ctx,
|
|
|
b9abc1 |
- 1,
|
|
|
b9abc1 |
- GSS_C_QOP_DEFAULT,
|
|
|
b9abc1 |
- (OM_uint32) oparams->maxoutbuf,
|
|
|
b9abc1 |
- &max_input);
|
|
|
b9abc1 |
-
|
|
|
b9abc1 |
- if(max_input > oparams->maxoutbuf) {
|
|
|
b9abc1 |
- /* Heimdal appears to get this wrong */
|
|
|
b9abc1 |
- oparams->maxoutbuf -= (max_input - oparams->maxoutbuf);
|
|
|
b9abc1 |
- } else {
|
|
|
b9abc1 |
- /* This code is actually correct */
|
|
|
b9abc1 |
- oparams->maxoutbuf = max_input;
|
|
|
b9abc1 |
- }
|
|
|
b9abc1 |
- }
|
|
|
b9abc1 |
-
|
|
|
b9abc1 |
GSS_LOCK_MUTEX_CTX(params->utils, text);
|
|
|
b9abc1 |
gss_release_buffer(&min_stat, output_token);
|
|
|
b9abc1 |
GSS_UNLOCK_MUTEX_CTX(params->utils, text);
|
|
|
b9abc1 |
|
|
|
b9abc1 |
+ if (oparams->mech_ssf) {
|
|
|
b9abc1 |
+ int ret;
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
+ ret = gssapi_wrap_sizes(text, oparams);
|
|
|
b9abc1 |
+ if (ret != SASL_OK) {
|
|
|
b9abc1 |
+ sasl_gss_free_context_contents(text);
|
|
|
b9abc1 |
+ return ret;
|
|
|
b9abc1 |
+ }
|
|
|
b9abc1 |
+ }
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
text->state = SASL_GSSAPI_STATE_AUTHENTICATED;
|
|
|
b9abc1 |
|
|
|
b9abc1 |
/* used by layers */
|
|
|
b9abc1 |
@@ -1569,7 +1576,6 @@ static int gssapi_client_mech_step(void *conn_context,
|
|
|
b9abc1 |
gss_buffer_t input_token, output_token;
|
|
|
b9abc1 |
gss_buffer_desc real_input_token, real_output_token;
|
|
|
b9abc1 |
OM_uint32 maj_stat = 0, min_stat = 0;
|
|
|
b9abc1 |
- OM_uint32 max_input;
|
|
|
b9abc1 |
gss_buffer_desc name_token;
|
|
|
b9abc1 |
int ret;
|
|
|
b9abc1 |
OM_uint32 req_flags = 0, out_req_flags = 0;
|
|
|
b9abc1 |
@@ -1952,27 +1958,19 @@ static int gssapi_client_mech_step(void *conn_context,
|
|
|
b9abc1 |
(((unsigned char *) output_token->value)[2] << 8) |
|
|
|
b9abc1 |
(((unsigned char *) output_token->value)[3] << 0);
|
|
|
b9abc1 |
|
|
|
b9abc1 |
- if (oparams->mech_ssf) {
|
|
|
b9abc1 |
- maj_stat = gss_wrap_size_limit( &min_stat,
|
|
|
b9abc1 |
- text->gss_ctx,
|
|
|
b9abc1 |
- 1,
|
|
|
b9abc1 |
- GSS_C_QOP_DEFAULT,
|
|
|
b9abc1 |
- (OM_uint32) oparams->maxoutbuf,
|
|
|
b9abc1 |
- &max_input);
|
|
|
b9abc1 |
-
|
|
|
b9abc1 |
- if (max_input > oparams->maxoutbuf) {
|
|
|
b9abc1 |
- /* Heimdal appears to get this wrong */
|
|
|
b9abc1 |
- oparams->maxoutbuf -= (max_input - oparams->maxoutbuf);
|
|
|
b9abc1 |
- } else {
|
|
|
b9abc1 |
- /* This code is actually correct */
|
|
|
b9abc1 |
- oparams->maxoutbuf = max_input;
|
|
|
b9abc1 |
- }
|
|
|
b9abc1 |
- }
|
|
|
b9abc1 |
-
|
|
|
b9abc1 |
GSS_LOCK_MUTEX_CTX(params->utils, text);
|
|
|
b9abc1 |
gss_release_buffer(&min_stat, output_token);
|
|
|
b9abc1 |
GSS_UNLOCK_MUTEX_CTX(params->utils, text);
|
|
|
b9abc1 |
-
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
+ if (oparams->mech_ssf) {
|
|
|
b9abc1 |
+ int ret;
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
+ ret = gssapi_wrap_sizes(text, oparams);
|
|
|
b9abc1 |
+ if (ret != SASL_OK) {
|
|
|
b9abc1 |
+ sasl_gss_free_context_contents(text);
|
|
|
b9abc1 |
+ return ret;
|
|
|
b9abc1 |
+ }
|
|
|
b9abc1 |
+ }
|
|
|
b9abc1 |
/* oparams->user is always set, due to canon_user requirements.
|
|
|
b9abc1 |
* Make sure the client actually requested it though, by checking
|
|
|
b9abc1 |
* if our context was set.
|
|
|
b9abc1 |
|
|
|
b9abc1 |
From ff9f9caeb6db6d7513128fff9321f9bd445f58b7 Mon Sep 17 00:00:00 2001
|
|
|
b9abc1 |
From: Simo Sorce <simo@redhat.com>
|
|
|
b9abc1 |
Date: Mon, 10 Apr 2017 19:54:19 -0400
|
|
|
b9abc1 |
Subject: [PATCH 3/3] Add support for retrieving the mech_ssf
|
|
|
b9abc1 |
|
|
|
b9abc1 |
In the latest MIT Kerberos implementation it is possible to extract
|
|
|
b9abc1 |
the calculated SSF wich is based on the encryption type that has been
|
|
|
b9abc1 |
used to establish the GSSAPI security context.
|
|
|
b9abc1 |
|
|
|
b9abc1 |
Use this method if available or fall back to the old "DES" value.
|
|
|
b9abc1 |
|
|
|
b9abc1 |
Signed-off-by: Simo Sorce <simo@redhat.com>
|
|
|
b9abc1 |
---
|
|
|
b9abc1 |
cmulocal/sasl2.m4 | 20 +++++++++++
|
|
|
b9abc1 |
plugins/gssapi.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++------
|
|
|
b9abc1 |
2 files changed, 111 insertions(+), 11 deletions(-)
|
|
|
b9abc1 |
|
|
|
b9abc1 |
diff --git a/cmulocal/sasl2.m4 b/cmulocal/sasl2.m4
|
|
|
b9abc1 |
index 66b291b0..686c4bc7 100644
|
|
|
b9abc1 |
--- a/cmulocal/sasl2.m4
|
|
|
b9abc1 |
+++ b/cmulocal/sasl2.m4
|
|
|
b9abc1 |
@@ -290,6 +290,26 @@ if test "$gssapi" != no; then
|
|
|
b9abc1 |
|
|
|
b9abc1 |
cmu_save_LIBS="$LIBS"
|
|
|
b9abc1 |
LIBS="$LIBS $GSSAPIBASE_LIBS"
|
|
|
b9abc1 |
+ AC_CHECK_FUNCS(gss_inquire_sec_context_by_oid)
|
|
|
b9abc1 |
+ if test "$ac_cv_func_gss_inquire_sec_context_by_oid" = no ; then
|
|
|
b9abc1 |
+ if test "$ac_cv_header_gssapi_gssapi_ext_h" = "yes"; then
|
|
|
b9abc1 |
+ AC_CHECK_DECL(gss_inquire_sec_context_by_oid,
|
|
|
b9abc1 |
+ [AC_DEFINE(HAVE_GSS_INQUIRE_SEC_CONTEXT_BY_OID,1,
|
|
|
b9abc1 |
+ [Define if your GSSAPI implementation defines gss_inquire_sec_context_by_oid])],,
|
|
|
b9abc1 |
+ [
|
|
|
b9abc1 |
+ AC_INCLUDES_DEFAULT
|
|
|
b9abc1 |
+ #include <gssapi/gssapi_ext.h>
|
|
|
b9abc1 |
+ ])
|
|
|
b9abc1 |
+ fi
|
|
|
b9abc1 |
+ fi
|
|
|
b9abc1 |
+ if test "$ac_cv_header_gssapi_gssapi_ext_h" = "yes"; then
|
|
|
b9abc1 |
+ AC_EGREP_HEADER(GSS_C_SEC_CONTEXT_SASL_SSF, gssapi/gssapi_ext.h,
|
|
|
b9abc1 |
+ [AC_DEFINE(HAVE_GSS_C_SEC_CONTEXT_SASL_SSF,,
|
|
|
b9abc1 |
+ [Define if your GSSAPI implementation defines GSS_C_SEC_CONTEXT_SASL_SSF])])
|
|
|
b9abc1 |
+ fi
|
|
|
b9abc1 |
+ cmu_save_LIBS="$LIBS"
|
|
|
b9abc1 |
+ LIBS="$LIBS $GSSAPIBASE_LIBS"
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
AC_MSG_CHECKING([for SPNEGO support in GSSAPI libraries])
|
|
|
b9abc1 |
AC_TRY_RUN([
|
|
|
b9abc1 |
#ifdef HAVE_GSSAPI_H
|
|
|
b9abc1 |
diff --git a/plugins/gssapi.c b/plugins/gssapi.c
|
|
|
b9abc1 |
index 348debe0..5f554ce3 100644
|
|
|
b9abc1 |
--- a/plugins/gssapi.c
|
|
|
b9abc1 |
+++ b/plugins/gssapi.c
|
|
|
b9abc1 |
@@ -51,6 +51,9 @@
|
|
|
b9abc1 |
#endif
|
|
|
b9abc1 |
|
|
|
b9abc1 |
#include <gssapi/gssapi_krb5.h>
|
|
|
b9abc1 |
+#ifdef HAVE_GSSAPI_GSSAPI_EXT_H
|
|
|
b9abc1 |
+#include <gssapi/gssapi_ext.h>
|
|
|
b9abc1 |
+#endif
|
|
|
b9abc1 |
|
|
|
b9abc1 |
#ifdef WIN32
|
|
|
b9abc1 |
# include <winsock2.h>
|
|
|
b9abc1 |
@@ -98,18 +103,25 @@ extern gss_OID gss_nt_service_name;
|
|
|
b9abc1 |
/* Check if CyberSafe flag is defined */
|
|
|
b9abc1 |
#ifdef CSF_GSS_C_DES3_FLAG
|
|
|
b9abc1 |
#define K5_MAX_SSF 112
|
|
|
b9abc1 |
+#define K5_MIN_SSF 112
|
|
|
b9abc1 |
#endif
|
|
|
b9abc1 |
|
|
|
b9abc1 |
/* Heimdal and MIT use the following */
|
|
|
b9abc1 |
#ifdef GSS_KRB5_CONF_C_QOP_DES3_KD
|
|
|
b9abc1 |
#define K5_MAX_SSF 112
|
|
|
b9abc1 |
+#define K5_MIN_SSF 112
|
|
|
b9abc1 |
#endif
|
|
|
b9abc1 |
|
|
|
b9abc1 |
#endif
|
|
|
b9abc1 |
|
|
|
b9abc1 |
#ifndef K5_MAX_SSF
|
|
|
b9abc1 |
+/* All modern Kerberos implementations support AES */
|
|
|
b9abc1 |
+#define K5_MAX_SSF 256
|
|
|
b9abc1 |
+#endif
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
/* All Kerberos implementations support DES */
|
|
|
b9abc1 |
-#define K5_MAX_SSF 56
|
|
|
b9abc1 |
+#ifndef K5_MIN_SSF
|
|
|
b9abc1 |
+#define K5_MIN_SSF 56
|
|
|
b9abc1 |
#endif
|
|
|
b9abc1 |
|
|
|
b9abc1 |
/* GSSAPI SASL Mechanism by Leif Johansson <leifj@matematik.su.se>
|
|
|
b9abc1 |
@@ -674,6 +686,47 @@ static int gssapi_wrap_sizes(context_t *text, sasl_out_params_t *oparams)
|
|
|
b9abc1 |
return SASL_OK;
|
|
|
b9abc1 |
}
|
|
|
b9abc1 |
|
|
|
b9abc1 |
+#if !defined(HAVE_GSS_C_SEC_CONTEXT_SASL_SSF)
|
|
|
b9abc1 |
+gss_OID_desc gss_sasl_ssf = {
|
|
|
b9abc1 |
+ 11, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0f"
|
|
|
b9abc1 |
+};
|
|
|
b9abc1 |
+gss_OID GSS_C_SEC_CONTEXT_SASL_SSF = &gss_sasl_ssf;
|
|
|
b9abc1 |
+#endif
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
+static int gssapi_get_ssf(context_t *text, sasl_ssf_t *mech_ssf)
|
|
|
b9abc1 |
+{
|
|
|
b9abc1 |
+#ifdef HAVE_GSS_INQUIRE_SEC_CONTEXT_BY_OID
|
|
|
b9abc1 |
+ OM_uint32 maj_stat = 0, min_stat = 0;
|
|
|
b9abc1 |
+ gss_buffer_set_t bufset = GSS_C_NO_BUFFER_SET;
|
|
|
b9abc1 |
+ gss_OID ssf_oid = GSS_C_SEC_CONTEXT_SASL_SSF;
|
|
|
b9abc1 |
+ uint32_t ssf;
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
+ maj_stat = gss_inquire_sec_context_by_oid(&min_stat, text->gss_ctx,
|
|
|
b9abc1 |
+ ssf_oid, &bufset);
|
|
|
b9abc1 |
+ switch (maj_stat) {
|
|
|
b9abc1 |
+ case GSS_S_UNAVAILABLE:
|
|
|
b9abc1 |
+ /* Not supported by the library, fallback to default */
|
|
|
b9abc1 |
+ goto fallback;
|
|
|
b9abc1 |
+ case GSS_S_COMPLETE:
|
|
|
b9abc1 |
+ if ((bufset->count != 1) || (bufset->elements[0].length != 4)) {
|
|
|
b9abc1 |
+ /* Malformed bufset, fail */
|
|
|
b9abc1 |
+ (void)gss_release_buffer_set(&min_stat, &bufset);
|
|
|
b9abc1 |
+ return SASL_FAIL;
|
|
|
b9abc1 |
+ }
|
|
|
b9abc1 |
+ memcpy(&ssf, bufset->elements[0].value, 4);
|
|
|
b9abc1 |
+ (void)gss_release_buffer_set(&min_stat, &bufset);
|
|
|
b9abc1 |
+ *mech_ssf = ntohl(ssf);
|
|
|
b9abc1 |
+ return SASL_OK;
|
|
|
b9abc1 |
+ default:
|
|
|
b9abc1 |
+ return SASL_FAIL;
|
|
|
b9abc1 |
+ }
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
+fallback:
|
|
|
b9abc1 |
+#endif
|
|
|
b9abc1 |
+ *mech_ssf = K5_MIN_SSF;
|
|
|
b9abc1 |
+ return SASL_OK;
|
|
|
b9abc1 |
+}
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
/* The GSS-SPNEGO mechanism does not do SSF negotiation, instead it uses the
|
|
|
b9abc1 |
* flags negotiated by GSSAPI to determine If confidentiality or integrity are
|
|
|
b9abc1 |
* used. These flags are stored in text->qop transalated as layers by the
|
|
|
b9abc1 |
@@ -687,7 +740,10 @@ static int gssapi_spnego_ssf(context_t *text,
|
|
|
b9abc1 |
if (text->qop & LAYER_CONFIDENTIALITY) {
|
|
|
b9abc1 |
oparams->encode = &gssapi_privacy_encode;
|
|
|
b9abc1 |
oparams->decode = &gssapi_decode;
|
|
|
b9abc1 |
- oparams->mech_ssf = K5_MAX_SSF;
|
|
|
b9abc1 |
+ ret = gssapi_get_ssf(text, &oparams->mech_ssf);
|
|
|
b9abc1 |
+ if (ret != SASL_OK) {
|
|
|
b9abc1 |
+ return ret;
|
|
|
b9abc1 |
+ }
|
|
|
b9abc1 |
} else if (text->qop & LAYER_INTEGRITY) {
|
|
|
b9abc1 |
oparams->encode = &gssapi_integrity_encode;
|
|
|
b9abc1 |
oparams->decode = &gssapi_decode;
|
|
|
b9abc1 |
@@ -1089,6 +1145,7 @@ gssapi_server_mech_ssfcap(context_t *text,
|
|
|
b9abc1 |
gss_buffer_desc real_input_token, real_output_token;
|
|
|
b9abc1 |
OM_uint32 maj_stat = 0, min_stat = 0;
|
|
|
b9abc1 |
unsigned char sasldata[4];
|
|
|
b9abc1 |
+ sasl_ssf_t mech_ssf;
|
|
|
b9abc1 |
int ret;
|
|
|
b9abc1 |
|
|
|
b9abc1 |
input_token = &real_input_token;
|
|
|
b9abc1 |
@@ -1149,9 +1206,14 @@ gssapi_server_mech_ssfcap(context_t *text,
|
|
|
b9abc1 |
params->props.maxbufsize) {
|
|
|
b9abc1 |
sasldata[0] |= LAYER_INTEGRITY;
|
|
|
b9abc1 |
}
|
|
|
b9abc1 |
+ ret = gssapi_get_ssf(text, &mech_ssf);
|
|
|
b9abc1 |
+ if (ret != SASL_OK) {
|
|
|
b9abc1 |
+ sasl_gss_free_context_contents(text);
|
|
|
b9abc1 |
+ return ret;
|
|
|
b9abc1 |
+ }
|
|
|
b9abc1 |
if ((text->qop & LAYER_CONFIDENTIALITY) &&
|
|
|
b9abc1 |
- text->requiressf <= K5_MAX_SSF &&
|
|
|
b9abc1 |
- text->limitssf >= K5_MAX_SSF &&
|
|
|
b9abc1 |
+ text->requiressf <= mech_ssf &&
|
|
|
b9abc1 |
+ text->limitssf >= mech_ssf &&
|
|
|
b9abc1 |
params->props.maxbufsize) {
|
|
|
b9abc1 |
sasldata[0] |= LAYER_CONFIDENTIALITY;
|
|
|
b9abc1 |
}
|
|
|
b9abc1 |
@@ -1271,10 +1333,18 @@ gssapi_server_mech_ssfreq(context_t *text,
|
|
|
b9abc1 |
} else if (/* For compatibility with broken clients setting both bits */
|
|
|
b9abc1 |
(layerchoice & (LAYER_CONFIDENTIALITY | LAYER_INTEGRITY)) &&
|
|
|
b9abc1 |
(text->qop & LAYER_CONFIDENTIALITY)) { /* privacy */
|
|
|
b9abc1 |
+ int ret;
|
|
|
b9abc1 |
oparams->encode = &gssapi_privacy_encode;
|
|
|
b9abc1 |
oparams->decode = &gssapi_decode;
|
|
|
b9abc1 |
- /* FIX ME: Need to extract the proper value here */
|
|
|
b9abc1 |
- oparams->mech_ssf = K5_MAX_SSF;
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
+ ret = gssapi_get_ssf(text, &oparams->mech_ssf);
|
|
|
b9abc1 |
+ if (ret != SASL_OK) {
|
|
|
b9abc1 |
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
|
|
|
b9abc1 |
+ gss_release_buffer(&min_stat, output_token);
|
|
|
b9abc1 |
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
|
|
|
b9abc1 |
+ sasl_gss_free_context_contents(text);
|
|
|
b9abc1 |
+ return ret;
|
|
|
b9abc1 |
+ }
|
|
|
b9abc1 |
} else {
|
|
|
b9abc1 |
/* not a supported encryption layer */
|
|
|
b9abc1 |
SETERROR(text->utils,
|
|
|
b9abc1 |
@@ -1845,6 +1915,8 @@ static int gssapi_client_mech_step(void *conn_context,
|
|
|
b9abc1 |
unsigned int alen, external = params->external_ssf;
|
|
|
b9abc1 |
sasl_ssf_t need, allowed;
|
|
|
b9abc1 |
char serverhas, mychoice;
|
|
|
b9abc1 |
+ sasl_ssf_t mech_ssf;
|
|
|
b9abc1 |
+ int ret;
|
|
|
b9abc1 |
|
|
|
b9abc1 |
real_input_token.value = (void *) serverin;
|
|
|
b9abc1 |
real_input_token.length = serverinlen;
|
|
|
b9abc1 |
@@ -1879,8 +1951,17 @@ static int gssapi_client_mech_step(void *conn_context,
|
|
|
b9abc1 |
return SASL_FAIL;
|
|
|
b9abc1 |
}
|
|
|
b9abc1 |
|
|
|
b9abc1 |
+ ret = gssapi_get_ssf(text, &mech_ssf);
|
|
|
b9abc1 |
+ if (ret != SASL_OK) {
|
|
|
b9abc1 |
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
|
|
|
b9abc1 |
+ gss_release_buffer(&min_stat, output_token);
|
|
|
b9abc1 |
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
|
|
|
b9abc1 |
+ sasl_gss_free_context_contents(text);
|
|
|
b9abc1 |
+ return SASL_FAIL;
|
|
|
b9abc1 |
+ }
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
/* taken from kerberos.c */
|
|
|
b9abc1 |
- if (secprops->min_ssf > (K5_MAX_SSF + external)) {
|
|
|
b9abc1 |
+ if (secprops->min_ssf > (mech_ssf + external)) {
|
|
|
b9abc1 |
return SASL_TOOWEAK;
|
|
|
b9abc1 |
} else if (secprops->min_ssf > secprops->max_ssf) {
|
|
|
b9abc1 |
return SASL_BADPARAM;
|
|
|
b9abc1 |
@@ -1904,8 +1985,8 @@ static int gssapi_client_mech_step(void *conn_context,
|
|
|
b9abc1 |
|
|
|
b9abc1 |
/* use the strongest layer available */
|
|
|
b9abc1 |
if ((text->qop & LAYER_CONFIDENTIALITY) &&
|
|
|
b9abc1 |
- allowed >= K5_MAX_SSF &&
|
|
|
b9abc1 |
- need <= K5_MAX_SSF &&
|
|
|
b9abc1 |
+ allowed >= mech_ssf &&
|
|
|
b9abc1 |
+ need <= mech_ssf &&
|
|
|
b9abc1 |
(serverhas & LAYER_CONFIDENTIALITY)) {
|
|
|
b9abc1 |
|
|
|
b9abc1 |
const char *ad_compat;
|
|
|
b9abc1 |
@@ -1913,8 +1994,7 @@ static int gssapi_client_mech_step(void *conn_context,
|
|
|
b9abc1 |
/* encryption */
|
|
|
b9abc1 |
oparams->encode = &gssapi_privacy_encode;
|
|
|
b9abc1 |
oparams->decode = &gssapi_decode;
|
|
|
b9abc1 |
- /* FIX ME: Need to extract the proper value here */
|
|
|
b9abc1 |
- oparams->mech_ssf = K5_MAX_SSF;
|
|
|
b9abc1 |
+ oparams->mech_ssf = mech_ssf;
|
|
|
b9abc1 |
mychoice = LAYER_CONFIDENTIALITY;
|
|
|
b9abc1 |
|
|
|
b9abc1 |
if (serverhas & LAYER_INTEGRITY) {
|
|
|
b9abc1 |
|
|
|
b9abc1 |
|
|
|
b9abc1 |
|
|
|
b9abc1 |
diff -U3 cyrus-sasl-2.1.26.old/config.h.in cyrus-sasl-2.1.26/config.h.in
|
|
|
b9abc1 |
--- cyrus-sasl-2.1.26.old/config.h.in 2012-11-06 20:20:59.000000000 +0100
|
|
|
b9abc1 |
+++ cyrus-sasl-2.1.26/config.h.in 2017-09-21 10:33:36.225258244 +0200
|
|
|
b9abc1 |
@@ -132,6 +135,9 @@
|
|
|
b9abc1 |
/* Define if your GSSAPI implementation defines GSS_C_NT_USER_NAME */
|
|
|
b9abc1 |
#undef HAVE_GSS_C_NT_USER_NAME
|
|
|
b9abc1 |
|
|
|
b9abc1 |
+/* Define if your GSSAPI implementation defines GSS_C_SEC_CONTEXT_SASL_SSF */
|
|
|
b9abc1 |
+#undef HAVE_GSS_C_SEC_CONTEXT_SASL_SSF
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
/* Define to 1 if you have the `gss_decapsulate_token' function. */
|
|
|
b9abc1 |
#undef HAVE_GSS_DECAPSULATE_TOKEN
|
|
|
b9abc1 |
|
|
|
b9abc1 |
@@ -141,6 +147,10 @@
|
|
|
b9abc1 |
/* Define to 1 if you have the `gss_get_name_attribute' function. */
|
|
|
b9abc1 |
#undef HAVE_GSS_GET_NAME_ATTRIBUTE
|
|
|
b9abc1 |
|
|
|
b9abc1 |
+/* Define if your GSSAPI implementation defines gss_inquire_sec_context_by_oid
|
|
|
b9abc1 |
+ */
|
|
|
b9abc1 |
+#undef HAVE_GSS_INQUIRE_SEC_CONTEXT_BY_OID
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
/* Define to 1 if you have the `gss_oid_equal' function. */
|
|
|
b9abc1 |
#undef HAVE_GSS_OID_EQUAL
|
|
|
b9abc1 |
|
|
|
b9abc1 |
diff -U3 cyrus-sasl-2.1.26.old/configure cyrus-sasl-2.1.26/configure
|
|
|
b9abc1 |
--- cyrus-sasl-2.1.26.old/configure 2017-09-21 10:11:30.557021831 +0200
|
|
|
b9abc1 |
+++ cyrus-sasl-2.1.26/configure 2017-09-21 10:33:40.389277838 +0200
|
|
|
b9abc1 |
@@ -13984,6 +13984,50 @@
|
|
|
b9abc1 |
|
|
|
b9abc1 |
LIBS="$cmu_save_LIBS"
|
|
|
b9abc1 |
|
|
|
b9abc1 |
+ cmu_save_LIBS="$LIBS"
|
|
|
b9abc1 |
+ LIBS="$LIBS $GSSAPIBASE_LIBS"
|
|
|
b9abc1 |
+ for ac_func in gss_inquire_sec_context_by_oid
|
|
|
b9abc1 |
+do :
|
|
|
b9abc1 |
+ ac_fn_c_check_func "$LINENO" "gss_inquire_sec_context_by_oid" "ac_cv_func_gss_inquire_sec_context_by_oid"
|
|
|
b9abc1 |
+if test "x$ac_cv_func_gss_inquire_sec_context_by_oid" = xyes; then :
|
|
|
b9abc1 |
+ cat >>confdefs.h <<_ACEOF
|
|
|
b9abc1 |
+#define HAVE_GSS_INQUIRE_SEC_CONTEXT_BY_OID 1
|
|
|
b9abc1 |
+_ACEOF
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
+fi
|
|
|
b9abc1 |
+done
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
+ if test "$ac_cv_func_gss_inquire_sec_context_by_oid" = no ; then
|
|
|
b9abc1 |
+ if test "$ac_cv_header_gssapi_gssapi_ext_h" = "yes"; then
|
|
|
b9abc1 |
+ ac_fn_c_check_decl "$LINENO" "gss_inquire_sec_context_by_oid" "ac_cv_have_decl_gss_inquire_sec_context_by_oid" "
|
|
|
b9abc1 |
+ $ac_includes_default
|
|
|
b9abc1 |
+ #include <gssapi/gssapi_ext.h>
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
+"
|
|
|
b9abc1 |
+if test "x$ac_cv_have_decl_gss_inquire_sec_context_by_oid" = xyes; then :
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
+$as_echo "#define HAVE_GSS_INQUIRE_SEC_CONTEXT_BY_OID 1" >>confdefs.h
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
+fi
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
+ fi
|
|
|
b9abc1 |
+ fi
|
|
|
b9abc1 |
+ if test "$ac_cv_header_gssapi_gssapi_ext_h" = "yes"; then
|
|
|
b9abc1 |
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
|
|
b9abc1 |
+/* end confdefs.h. */
|
|
|
b9abc1 |
+#include <gssapi/gssapi_ext.h>
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
+_ACEOF
|
|
|
b9abc1 |
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
|
|
|
b9abc1 |
+ $EGREP "GSS_C_SEC_CONTEXT_SASL_SSF" >/dev/null 2>&1; then :
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
+$as_echo "#define HAVE_GSS_C_SEC_CONTEXT_SASL_SSF /**/" >>confdefs.h
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
+fi
|
|
|
b9abc1 |
+rm -f conftest*
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
+ fi
|
|
|
b9abc1 |
+
|
|
|
b9abc1 |
cmu_save_LIBS="$LIBS"
|
|
|
b9abc1 |
LIBS="$LIBS $GSSAPIBASE_LIBS"
|
|
|
b9abc1 |
{ $as_echo "$as_me:$LINENO: checking for SPNEGO support in GSSAPI libraries" >&5
|