cyrus-sasl/cyrus-sasl-2.1.27-Add-suppo...

96 lines
3.9 KiB
Diff

Backport of part of Upstream PR#603 minimal part needed for interop
From 0e722dd3266d5ebd0f889462cc23856fde3d21ed Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Thu, 19 Sep 2019 15:58:04 -0400
Subject: [PATCH] Add support for setting max ssf 0 to GSS-SPNEGO
This is needed to interop with Windows within a TLS channel.
Signed-off-by: Simo Sorce <simo@redhat.com>
---
m4/sasl2.m4 | 13 +++++++++++++
plugins/gssapi.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 57 insertions(+), 1 deletion(-)
diff --git a/m4/sasl2.m4 b/m4/sasl2.m4
index 17f5d081..60306943 100644
--- a/m4/sasl2.m4
+++ b/m4/sasl2.m4
@@ -287,6 +287,19 @@ if test "$gssapi" != no; then
AC_CHECK_FUNCS(gss_oid_equal)
LIBS="$cmu_save_LIBS"
+ cmu_save_LIBS="$LIBS"
+ LIBS="$LIBS $GSSAPIBASE_LIBS"
+ if test "$ac_cv_header_gssapi_gssapi_krb5_h" = "yes"; then
+ AC_CHECK_DECL(GSS_KRB5_CRED_NO_CI_FLAGS_X,
+ [AC_DEFINE(HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X,1,
+ [Define if your GSSAPI implementation supports GSS_KRB5_CRED_NO_CI_FLAGS_X])],,
+ [
+ AC_INCLUDES_DEFAULT
+ #include <gssapi/gssapi_krb5.h>
+ ])
+ fi
+ LIBS="$cmu_save_LIBS"
+
cmu_save_LIBS="$LIBS"
LIBS="$LIBS $GSSAPIBASE_LIBS"
AC_CHECK_FUNCS(gss_get_name_attribute)
diff --git a/plugins/gssapi.c b/plugins/gssapi.c
index 46de7d48..cca6cc0a 100644
--- a/plugins/gssapi.c
+++ b/plugins/gssapi.c
@@ -2123,7 +2123,50 @@ static int gssapi_client_mech_step(void *conn_context,
/* We want to try for privacy */
req_flags |= GSS_C_CONF_FLAG;
}
- }
+#ifdef HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X
+ /* The krb5 mechanism automatically adds INTEG and CONF flags even when
+ * not specified, this has the effect of rendering explicit requests
+ * of no confidentiality and integrity via setting maxssf 0 moot.
+ * However to interoperate with Windows machines it needs to be
+ * possible to unset these flags as Windows machines refuse to allow
+ * two layers (say TLS and GSSAPI) to both provide these services.
+ * So if we do not suppress these flags a SASL/GSS-SPNEGO negotiation
+ * over, say, LDAPS will fail against Windows Servers */
+ } else if (params->props.max_ssf == 0) {
+ gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER;
+ if (client_creds == GSS_C_NO_CREDENTIAL) {
+ gss_OID_set_desc mechs = { 0 };
+ gss_OID_set desired_mechs = GSS_C_NO_OID_SET;
+ if (text->mech_type != GSS_C_NO_OID) {
+ mechs.count = 1;
+ mechs.elements = text->mech_type;
+ desired_mechs = &mechs;
+ }
+
+ maj_stat = gss_acquire_cred(&min_stat, GSS_C_NO_NAME,
+ GSS_C_INDEFINITE, desired_mechs,
+ GSS_C_INITIATE,
+ &text->client_creds, NULL, NULL);
+ if (GSS_ERROR(maj_stat)) {
+ sasl_gss_seterror(text->utils, maj_stat, min_stat);
+ sasl_gss_free_context_contents(text);
+ return SASL_FAIL;
+ }
+ client_creds = text->client_creds;
+ }
+
+ maj_stat = gss_set_cred_option(&min_stat, &client_creds,
+ (gss_OID)GSS_KRB5_CRED_NO_CI_FLAGS_X,
+ &empty_buffer);
+ if (GSS_ERROR(maj_stat)) {
+ sasl_gss_seterror(text->utils, maj_stat, min_stat);
+ sasl_gss_free_context_contents(text);
+ return SASL_FAIL;
+ }
+#endif
+ }
+
+
if (params->props.security_flags & SASL_SEC_PASS_CREDENTIALS) {
req_flags = req_flags | GSS_C_DELEG_FLAG;