Remove unused patches and nonexisting files in new release

This commit is contained in:
Jakub Jelen 2016-12-02 15:27:39 +01:00
parent edd601075d
commit a183144ba4
6 changed files with 11 additions and 1391 deletions

View File

@ -1,26 +0,0 @@
diff -up cyrus-sasl-04dd838b2922840c5033c7071e1132e9ac555411/m4/kerberos_v4.m4.krb4 cyrus-sasl-04dd838b2922840c5033c7071e1132e9ac555411/m4/kerberos_v4.m4
--- cyrus-sasl-04dd838b2922840c5033c7071e1132e9ac555411/m4/kerberos_v4.m4.krb4 2017-07-13 13:46:08.828825672 +0200
+++ cyrus-sasl-04dd838b2922840c5033c7071e1132e9ac555411/m4/kerberos_v4.m4 2017-07-13 13:46:16.709804677 +0200
@@ -102,7 +102,6 @@ AC_DEFUN([SASL_KERBEROS_V4_CHK], [
if test -n "${cyrus_cv_krbinclude}"; then
CPPFLAGS="$CPPFLAGS -I${cyrus_cv_krbinclude}"
fi
- LDFLAGS="$LDFLAGS -L$krb4/lib"
fi
if test "$with_des" != no; then
diff -up cyrus-sasl-04dd838b2922840c5033c7071e1132e9ac555411/plugins/kerberos4.c.krb4 cyrus-sasl-04dd838b2922840c5033c7071e1132e9ac555411/plugins/kerberos4.c
--- cyrus-sasl-04dd838b2922840c5033c7071e1132e9ac555411/plugins/kerberos4.c.krb4 2017-03-03 15:12:10.000000000 +0100
+++ cyrus-sasl-04dd838b2922840c5033c7071e1132e9ac555411/plugins/kerberos4.c 2017-07-13 13:46:08.829825670 +0200
@@ -49,11 +49,7 @@
#include <krb.h>
#ifdef WITH_DES
-# ifdef WITH_SSL_DES
-# include <openssl/des.h>
-# else
# include <des.h>
-# endif /* WITH_SSL_DES */
#endif /* WITH_DES */
#ifdef WIN32

View File

@ -1,139 +0,0 @@
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, &params->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, &params->props,
+ oparams);
+ }
/* Switch to ssf negotiation */
text->state = SASL_GSSAPI_STATE_SSFCAP;

View File

@ -1,699 +0,0 @@
From 4a64c00dba4d35cadc71242f9f81336f46f72009 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Fri, 4 Dec 2015 17:59:26 +0100
Subject: [PATCH] GSSAPI: Use per-connection mutex where possible
Original patch from Alexander Bokovoy <abokovoy@redhat.com>
---
plugins/gssapi.c | 225 +++++++++++++++++++++++++++++++------------------------
1 file changed, 126 insertions(+), 99 deletions(-)
diff --git a/plugins/gssapi.c b/plugins/gssapi.c
index 60cc38c..50e1217 100644
--- a/plugins/gssapi.c
+++ b/plugins/gssapi.c
@@ -126,20 +126,29 @@ extern gss_OID gss_nt_service_name;
*/
#ifdef GSS_USE_MUTEXES
-#define GSS_LOCK_MUTEX(utils) \
- if(((sasl_utils_t *)(utils))->mutex_lock(gss_mutex) != 0) { \
+#define GSS_LOCK_MUTEX_EXT(utils, mutex) \
+ if(((sasl_utils_t *)(utils))->mutex_lock(mutex) != 0) { \
return SASL_FAIL; \
}
-#define GSS_UNLOCK_MUTEX(utils) \
- if(((sasl_utils_t *)(utils))->mutex_unlock(gss_mutex) != 0) { \
+#define GSS_UNLOCK_MUTEX_EXT(utils, mutex) \
+ if(((sasl_utils_t *)(utils))->mutex_unlock(mutex) != 0) { \
return SASL_FAIL; \
}
+#define GSS_LOCK_MUTEX(utils) GSS_LOCK_MUTEX_EXT(utils, gss_mutex)
+#define GSS_UNLOCK_MUTEX(utils) GSS_UNLOCK_MUTEX_EXT(utils, gss_mutex)
+
+#define GSS_LOCK_MUTEX_CTX(utils, ctx) GSS_LOCK_MUTEX_EXT(utils, (ctx)->ctx_mutex)
+#define GSS_UNLOCK_MUTEX_CTX(utils, ctx) GSS_UNLOCK_MUTEX_EXT(utils, (ctx)->ctx_mutex)
+
+
static void *gss_mutex = NULL;
#else
#define GSS_LOCK_MUTEX(utils)
#define GSS_UNLOCK_MUTEX(utils)
+#define GSS_LOCK_MUTEX_CTX(utils, ctx)
+#define GSS_UNLOCK_MUTEX_CTX(utils, ctx)
#endif
typedef struct context {
@@ -176,6 +185,7 @@ typedef struct context {
char *authid; /* hold the authid between steps - server */
const char *user; /* hold the userid between steps - client */
+ void *ctx_mutex; /* A per-context mutex */
} context_t;
enum {
@@ -355,7 +365,7 @@ sasl_gss_encode(void *context, const struct iovec *invec, unsigned numiov,
output_token->value = NULL;
output_token->length = 0;
- GSS_LOCK_MUTEX(text->utils);
+ GSS_LOCK_MUTEX_CTX(text->utils, text);
maj_stat = gss_wrap (&min_stat,
text->gss_ctx,
privacy,
@@ -363,14 +373,14 @@ sasl_gss_encode(void *context, const struct iovec *invec, unsigned numiov,
input_token,
NULL,
output_token);
- GSS_UNLOCK_MUTEX(text->utils);
+ GSS_UNLOCK_MUTEX_CTX(text->utils, text);
if (GSS_ERROR(maj_stat)) {
sasl_gss_seterror(text->utils, maj_stat, min_stat);
if (output_token->value) {
- GSS_LOCK_MUTEX(text->utils);
+ GSS_LOCK_MUTEX_CTX(text->utils, text);
gss_release_buffer(&min_stat, output_token);
- GSS_UNLOCK_MUTEX(text->utils);
+ GSS_UNLOCK_MUTEX_CTX(text->utils, text);
}
return SASL_FAIL;
}
@@ -384,9 +394,9 @@ sasl_gss_encode(void *context, const struct iovec *invec, unsigned numiov,
output_token->length + 4);
if (ret != SASL_OK) {
- GSS_LOCK_MUTEX(text->utils);
+ GSS_LOCK_MUTEX_CTX(text->utils, text);
gss_release_buffer(&min_stat, output_token);
- GSS_UNLOCK_MUTEX(text->utils);
+ GSS_UNLOCK_MUTEX_CTX(text->utils, text);
return ret;
}
@@ -407,9 +417,9 @@ sasl_gss_encode(void *context, const struct iovec *invec, unsigned numiov,
*output = text->encode_buf;
if (output_token->value) {
- GSS_LOCK_MUTEX(text->utils);
+ GSS_LOCK_MUTEX_CTX(text->utils, text);
gss_release_buffer(&min_stat, output_token);
- GSS_UNLOCK_MUTEX(text->utils);
+ GSS_UNLOCK_MUTEX_CTX(text->utils, text);
}
return SASL_OK;
@@ -455,21 +465,21 @@ gssapi_decode_packet(void *context,
output_token->value = NULL;
output_token->length = 0;
- GSS_LOCK_MUTEX(text->utils);
+ GSS_LOCK_MUTEX_CTX(text->utils, text);
maj_stat = gss_unwrap (&min_stat,
text->gss_ctx,
input_token,
output_token,
NULL,
NULL);
- GSS_UNLOCK_MUTEX(text->utils);
+ GSS_UNLOCK_MUTEX_CTX(text->utils, text);
if (GSS_ERROR(maj_stat)) {
sasl_gss_seterror(text->utils,maj_stat,min_stat);
if (output_token->value) {
- GSS_LOCK_MUTEX(text->utils);
+ GSS_LOCK_MUTEX_CTX(text->utils, text);
gss_release_buffer(&min_stat, output_token);
- GSS_UNLOCK_MUTEX(text->utils);
+ GSS_UNLOCK_MUTEX_CTX(text->utils, text);
}
return SASL_FAIL;
}
@@ -484,17 +494,17 @@ gssapi_decode_packet(void *context,
&text->decode_once_buf_len,
*outputlen);
if (result != SASL_OK) {
- GSS_LOCK_MUTEX(text->utils);
+ GSS_LOCK_MUTEX_CTX(text->utils, text);
gss_release_buffer(&min_stat, output_token);
- GSS_UNLOCK_MUTEX(text->utils);
+ GSS_UNLOCK_MUTEX_CTX(text->utils, text);
return result;
}
*output = text->decode_once_buf;
memcpy(*output, output_token->value, *outputlen);
}
- GSS_LOCK_MUTEX(text->utils);
+ GSS_LOCK_MUTEX_CTX(text->utils, text);
gss_release_buffer(&min_stat, output_token);
- GSS_UNLOCK_MUTEX(text->utils);
+ GSS_UNLOCK_MUTEX_CTX(text->utils, text);
}
return SASL_OK;
@@ -525,7 +535,14 @@ static context_t *sasl_gss_new_context(const sasl_utils_t *utils)
memset(ret,0,sizeof(context_t));
ret->utils = utils;
-
+#ifdef GSS_USE_MUTEXES
+ ret->ctx_mutex = utils->mutex_alloc();
+ if (!ret->ctx_mutex) {
+ utils->free(ret);
+ return NULL;
+ }
+#endif
+
return ret;
}
@@ -535,7 +552,11 @@ static int sasl_gss_free_context_contents(context_t *text)
if (!text) return SASL_OK;
- GSS_LOCK_MUTEX(text->utils);
+#ifdef GSS_USE_MUTEXES
+ if (text->ctx_mutex) {
+ GSS_LOCK_MUTEX_CTX(text->utils, text);
+ }
+#endif
if (text->gss_ctx != GSS_C_NO_CONTEXT) {
maj_stat = gss_delete_sec_context(&min_stat,&text->gss_ctx,
@@ -563,8 +584,6 @@ static int sasl_gss_free_context_contents(context_t *text)
text->client_creds = GSS_C_NO_CREDENTIAL;
}
- GSS_UNLOCK_MUTEX(text->utils);
-
if (text->out_buf) {
text->utils->free(text->out_buf);
text->out_buf = NULL;
@@ -598,6 +617,14 @@ static int sasl_gss_free_context_contents(context_t *text)
text->authid = NULL;
}
+#ifdef GSS_USE_MUTEXES
+ if (text->ctx_mutex) {
+ GSS_UNLOCK_MUTEX_CTX(text->utils, text);
+ text->utils->mutex_free(text->ctx_mutex);
+ text->ctx_mutex = NULL;
+ }
+#endif
+
return SASL_OK;
}
@@ -692,12 +719,12 @@ gssapi_server_mech_authneg(context_t *text,
}
sprintf(name_token.value,"%s@%s", params->service, params->serverFQDN);
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
maj_stat = gss_import_name (&min_stat,
&name_token,
GSS_C_NT_HOSTBASED_SERVICE,
&text->server_name);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
params->utils->free(name_token.value);
name_token.value = NULL;
@@ -709,15 +736,15 @@ gssapi_server_mech_authneg(context_t *text,
}
if ( text->server_creds != GSS_C_NO_CREDENTIAL) {
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
maj_stat = gss_release_cred(&min_stat, &text->server_creds);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
text->server_creds = GSS_C_NO_CREDENTIAL;
}
/* If caller didn't provide creds already */
if ( server_creds == GSS_C_NO_CREDENTIAL) {
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
maj_stat = gss_acquire_cred(&min_stat,
text->server_name,
GSS_C_INDEFINITE,
@@ -726,7 +753,7 @@ gssapi_server_mech_authneg(context_t *text,
&text->server_creds,
NULL,
NULL);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
if (GSS_ERROR(maj_stat)) {
sasl_gss_seterror(text->utils, maj_stat, min_stat);
@@ -743,7 +770,7 @@ gssapi_server_mech_authneg(context_t *text,
}
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
maj_stat =
gss_accept_sec_context(&min_stat,
&(text->gss_ctx),
@@ -756,15 +783,15 @@ gssapi_server_mech_authneg(context_t *text,
&out_flags,
NULL, /* context validity period */
&(text->client_creds));
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
if (GSS_ERROR(maj_stat)) {
sasl_gss_log(text->utils, maj_stat, min_stat);
text->utils->seterror(text->utils->conn, SASL_NOLOG, "GSSAPI Failure: gss_accept_sec_context");
if (output_token->value) {
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
gss_release_buffer(&min_stat, output_token);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
}
sasl_gss_free_context_contents(text);
return SASL_BADAUTH;
@@ -778,18 +805,18 @@ gssapi_server_mech_authneg(context_t *text,
ret = _plug_buf_alloc(text->utils, &(text->out_buf),
&(text->out_buf_len), *serveroutlen);
if(ret != SASL_OK) {
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
gss_release_buffer(&min_stat, output_token);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
return ret;
}
memcpy(text->out_buf, output_token->value, *serveroutlen);
*serverout = text->out_buf;
}
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
gss_release_buffer(&min_stat, output_token);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
} else {
/* No output token, send an empty string */
*serverout = GSSAPI_BLANK_STRING;
@@ -832,12 +859,12 @@ gssapi_server_mech_authneg(context_t *text,
/* continue with authentication */
}
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
maj_stat = gss_canonicalize_name(&min_stat,
text->client_name,
mech_type,
&client_name_MN);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
if (GSS_ERROR(maj_stat)) {
SETERROR(text->utils, "GSSAPI Failure: gss_canonicalize_name");
@@ -848,12 +875,12 @@ gssapi_server_mech_authneg(context_t *text,
name_token.value = NULL;
name_without_realm.value = NULL;
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
maj_stat = gss_display_name (&min_stat,
client_name_MN,
&name_token,
NULL);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
if (GSS_ERROR(maj_stat)) {
SETERROR(text->utils, "GSSAPI Failure: gss_display_name");
@@ -883,7 +910,7 @@ gssapi_server_mech_authneg(context_t *text,
name_without_realm.length = strlen( (char *) name_without_realm.value );
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
maj_stat = gss_import_name (&min_stat,
&name_without_realm,
/* Solaris 8/9 gss_import_name doesn't accept GSS_C_NULL_OID here,
@@ -894,7 +921,7 @@ gssapi_server_mech_authneg(context_t *text,
GSS_C_NULL_OID,
#endif
&without);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
if (GSS_ERROR(maj_stat)) {
SETERROR(text->utils, "GSSAPI Failure: gss_import_name");
@@ -903,12 +930,12 @@ gssapi_server_mech_authneg(context_t *text,
goto cleanup;
}
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
maj_stat = gss_compare_name(&min_stat,
client_name_MN,
without,
&equal);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
if (GSS_ERROR(maj_stat)) {
SETERROR(text->utils, "GSSAPI Failure: gss_compare_name");
@@ -1059,7 +1086,7 @@ gssapi_server_mech_ssfcap(context_t *text,
real_input_token.value = (void *)sasldata;
real_input_token.length = 4;
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
maj_stat = gss_wrap(&min_stat,
text->gss_ctx,
0, /* Just integrity checking here */
@@ -1067,14 +1094,14 @@ gssapi_server_mech_ssfcap(context_t *text,
input_token,
NULL,
output_token);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
if (GSS_ERROR(maj_stat)) {
sasl_gss_seterror(text->utils, maj_stat, min_stat);
if (output_token->value) {
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
gss_release_buffer(&min_stat, output_token);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
}
sasl_gss_free_context_contents(text);
return SASL_FAIL;
@@ -1088,18 +1115,18 @@ gssapi_server_mech_ssfcap(context_t *text,
ret = _plug_buf_alloc(text->utils, &(text->out_buf),
&(text->out_buf_len), *serveroutlen);
if(ret != SASL_OK) {
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
gss_release_buffer(&min_stat, output_token);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
return ret;
}
memcpy(text->out_buf, output_token->value, *serveroutlen);
*serverout = text->out_buf;
}
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
gss_release_buffer(&min_stat, output_token);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
}
/* Wait for ssf request and authid */
@@ -1130,14 +1157,14 @@ gssapi_server_mech_ssfreq(context_t *text,
real_input_token.value = (void *)clientin;
real_input_token.length = clientinlen;
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
maj_stat = gss_unwrap(&min_stat,
text->gss_ctx,
input_token,
output_token,
NULL,
NULL);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
if (GSS_ERROR(maj_stat)) {
sasl_gss_seterror(text->utils, maj_stat, min_stat);
@@ -1148,9 +1175,9 @@ gssapi_server_mech_ssfreq(context_t *text,
if (output_token->length < 4) {
SETERROR(text->utils,
"token too short");
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
gss_release_buffer(&min_stat, output_token);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
sasl_gss_free_context_contents(text);
return SASL_FAIL;
}
@@ -1181,9 +1208,9 @@ gssapi_server_mech_ssfreq(context_t *text,
/* Mark that we attempted negotiation */
oparams->mech_ssf = 2;
if (output_token->value) {
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
gss_release_buffer(&min_stat, output_token);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
}
sasl_gss_free_context_contents(text);
return SASL_FAIL;
@@ -1227,9 +1254,9 @@ gssapi_server_mech_ssfreq(context_t *text,
}
}
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
gss_release_buffer(&min_stat, output_token);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
text->state = SASL_GSSAPI_STATE_AUTHENTICATED;
@@ -1553,12 +1580,12 @@ static int gssapi_client_mech_step(void *conn_context,
sprintf(name_token.value,"%s@%s", params->service, params->serverFQDN);
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
maj_stat = gss_import_name (&min_stat,
&name_token,
GSS_C_NT_HOSTBASED_SERVICE,
&text->server_name);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
params->utils->free(name_token.value);
name_token.value = NULL;
@@ -1582,9 +1609,9 @@ static int gssapi_client_mech_step(void *conn_context,
* and no input from the server. However, thanks to Imap,
* which discards our first output, this happens all the time.
* Throw away the context and try again. */
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
maj_stat = gss_delete_sec_context (&min_stat,&text->gss_ctx,GSS_C_NO_BUFFER);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
text->gss_ctx = GSS_C_NO_CONTEXT;
}
@@ -1606,7 +1633,7 @@ static int gssapi_client_mech_step(void *conn_context,
req_flags = req_flags | GSS_C_DELEG_FLAG;
}
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
maj_stat = gss_init_sec_context(&min_stat,
client_creds, /* GSS_C_NO_CREDENTIAL */
&text->gss_ctx,
@@ -1620,14 +1647,14 @@ static int gssapi_client_mech_step(void *conn_context,
output_token,
&out_req_flags,
NULL);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
if (GSS_ERROR(maj_stat)) {
sasl_gss_seterror(text->utils, maj_stat, min_stat);
if (output_token->value) {
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
gss_release_buffer(&min_stat, output_token);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
}
sasl_gss_free_context_contents(text);
return SASL_FAIL;
@@ -1658,22 +1685,22 @@ static int gssapi_client_mech_step(void *conn_context,
ret = _plug_buf_alloc(text->utils, &(text->out_buf),
&(text->out_buf_len), *clientoutlen);
if(ret != SASL_OK) {
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
gss_release_buffer(&min_stat, output_token);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
return ret;
}
memcpy(text->out_buf, output_token->value, *clientoutlen);
*clientout = text->out_buf;
}
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
gss_release_buffer(&min_stat, output_token);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
}
if (maj_stat == GSS_S_COMPLETE) {
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
maj_stat = gss_inquire_context(&min_stat,
text->gss_ctx,
&text->client_name,
@@ -1684,7 +1711,7 @@ static int gssapi_client_mech_step(void *conn_context,
NULL, /* flags */
NULL, /* local init */
NULL); /* open */
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
if (GSS_ERROR(maj_stat)) {
sasl_gss_seterror(text->utils, maj_stat, min_stat);
@@ -1693,18 +1720,18 @@ static int gssapi_client_mech_step(void *conn_context,
}
name_token.length = 0;
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
maj_stat = gss_display_name(&min_stat,
text->client_name,
&name_token,
NULL);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
if (GSS_ERROR(maj_stat)) {
if (name_token.value) {
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
gss_release_buffer(&min_stat, &name_token);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
}
SETERROR(text->utils, "GSSAPI Failure");
sasl_gss_free_context_contents(text);
@@ -1725,9 +1752,9 @@ static int gssapi_client_mech_step(void *conn_context,
SASL_CU_AUTHID | SASL_CU_AUTHZID,
oparams);
}
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
gss_release_buffer(&min_stat, &name_token);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
if (ret != SASL_OK) return ret;
@@ -1753,32 +1780,32 @@ static int gssapi_client_mech_step(void *conn_context,
real_input_token.value = (void *) serverin;
real_input_token.length = serverinlen;
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
maj_stat = gss_unwrap(&min_stat,
text->gss_ctx,
input_token,
output_token,
NULL,
NULL);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
if (GSS_ERROR(maj_stat)) {
sasl_gss_seterror(text->utils, maj_stat, min_stat);
- sasl_gss_free_context_contents(text);
if (output_token->value) {
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
gss_release_buffer(&min_stat, output_token);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
}
+ sasl_gss_free_context_contents(text);
return SASL_FAIL;
}
if (output_token->length != 4) {
SETERROR(text->utils,
(output_token->length < 4) ? "token too short" : "token too long");
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
gss_release_buffer(&min_stat, output_token);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
sasl_gss_free_context_contents(text);
return SASL_FAIL;
}
@@ -1879,9 +1906,9 @@ static int gssapi_client_mech_step(void *conn_context,
}
}
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
gss_release_buffer(&min_stat, output_token);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
/* oparams->user is always set, due to canon_user requirements.
* Make sure the client actually requested it though, by checking
@@ -1927,7 +1954,7 @@ static int gssapi_client_mech_step(void *conn_context,
}
((unsigned char *)input_token->value)[0] = mychoice;
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
maj_stat = gss_wrap (&min_stat,
text->gss_ctx,
0, /* Just integrity checking here */
@@ -1935,7 +1962,7 @@ static int gssapi_client_mech_step(void *conn_context,
input_token,
NULL,
output_token);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
params->utils->free(input_token->value);
input_token->value = NULL;
@@ -1943,9 +1970,9 @@ static int gssapi_client_mech_step(void *conn_context,
if (GSS_ERROR(maj_stat)) {
sasl_gss_seterror(text->utils, maj_stat, min_stat);
if (output_token->value) {
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
gss_release_buffer(&min_stat, output_token);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
}
sasl_gss_free_context_contents(text);
return SASL_FAIL;
@@ -1961,18 +1988,18 @@ static int gssapi_client_mech_step(void *conn_context,
&(text->out_buf_len),
*clientoutlen);
if (ret != SASL_OK) {
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
gss_release_buffer(&min_stat, output_token);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
return ret;
}
memcpy(text->out_buf, output_token->value, *clientoutlen);
*clientout = text->out_buf;
}
- GSS_LOCK_MUTEX(params->utils);
+ GSS_LOCK_MUTEX_CTX(params->utils, text);
gss_release_buffer(&min_stat, output_token);
- GSS_UNLOCK_MUTEX(params->utils);
+ GSS_UNLOCK_MUTEX_CTX(params->utils, text);
}

View File

@ -1,33 +0,0 @@
diff --git a/saslauthd/saslauthd.mdoc b/saslauthd/saslauthd.mdoc
index 37c6f6e..5b635ab 100644
--- a/saslauthd/saslauthd.mdoc
+++ b/saslauthd/saslauthd.mdoc
@@ -44,7 +44,27 @@ multi-user mode. When running against a protected authentication
database (e.g. the
.Li shadow
mechanism),
-it must be run as the superuser.
+it must be run as the superuser. Otherwise it is recommended to run
+daemon unprivileged as saslauth:saslauth. You can do so by following
+these steps:
+.Bl -enum -compact
+.It
+create directory
+.Pa /etc/systemd/system/saslauthd.service.d/
+.It
+create file
+.Pa /etc/systemd/system/saslauthd.service.d/user.conf
+with content
+.Bd -literal
+[Service]
+User=saslauth
+Group=saslauth
+
+.Ed
+.It
+Reload systemd service file: run
+.Dq systemctl daemon-reload
+.El
.Ss Options
Options named by lower\-case letters configure the server itself.
Upper\-case options control the behavior of specific authentication

View File

@ -1,471 +0,0 @@
From 862b60c249c8a51095315062b22c0702a6500d80 Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Tue, 11 Apr 2017 18:31:46 -0400
Subject: [PATCH 1/3] Drop unused parameter from gssapi_spnego_ssf()
Signed-off-by: Simo Sorce <simo@redhat.com>
---
plugins/gssapi.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/plugins/gssapi.c b/plugins/gssapi.c
index 010c236..3050962 100644
--- a/plugins/gssapi.c
+++ b/plugins/gssapi.c
@@ -652,7 +652,7 @@ static void gssapi_common_mech_free(void *global_context __attribute__((unused))
* 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,
+static int gssapi_spnego_ssf(context_t *text,
sasl_security_properties_t *props,
sasl_out_params_t *oparams)
{
@@ -1019,7 +1019,7 @@ gssapi_server_mech_authneg(context_t *text,
text->state = SASL_GSSAPI_STATE_AUTHENTICATED;
ret = SASL_OK;
} else if (text->mech_type && text->mech_type == &gss_spnego_oid) {
- ret = gssapi_spnego_ssf(text, params->utils, &params->props, oparams);
+ ret = gssapi_spnego_ssf(text, &params->props, oparams);
} else {
/* Switch to ssf negotiation */
text->state = SASL_GSSAPI_STATE_SSFCAP;
@@ -1825,8 +1825,7 @@ static int gssapi_client_mech_step(void *conn_context,
return SASL_OK;
} else if (text->mech_type && text->mech_type == &gss_spnego_oid) {
oparams->doneflag = 1;
- return gssapi_spnego_ssf(text, params->utils, &params->props,
- oparams);
+ return gssapi_spnego_ssf(text, &params->props, oparams);
}
/* Switch to ssf negotiation */
From 72181257d77bda09afa7d0d640d322c4472f4833 Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Mon, 10 Apr 2017 18:35:10 -0400
Subject: [PATCH 2/3] Check return error from gss_wrap_size_limit()
The return error of this function is ignored and potentially
uninitialized values returned by this function are used.
Fix this by moving the function into a proper helper as it is used in an
identical way in 3 different places.
Signed-off-by: Simo Sorce <simo@redhat.com>
---
plugins/gssapi.c | 104 +++++++++++++++++++++++++++----------------------------
1 file changed, 51 insertions(+), 53 deletions(-)
diff --git a/plugins/gssapi.c b/plugins/gssapi.c
index 3050962..348debe 100644
--- a/plugins/gssapi.c
+++ b/plugins/gssapi.c
@@ -648,6 +648,32 @@ static void gssapi_common_mech_free(void *global_context __attribute__((unused))
#endif
}
+static int gssapi_wrap_sizes(context_t *text, sasl_out_params_t *oparams)
+{
+ OM_uint32 maj_stat = 0, min_stat = 0;
+ OM_uint32 max_input = 0;
+
+ maj_stat = gss_wrap_size_limit(&min_stat,
+ text->gss_ctx,
+ 1,
+ GSS_C_QOP_DEFAULT,
+ (OM_uint32)oparams->maxoutbuf,
+ &max_input);
+ if (maj_stat != GSS_S_COMPLETE) {
+ return SASL_FAIL;
+ }
+
+ 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;
+ }
+
+ 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
@@ -656,8 +682,7 @@ static int gssapi_spnego_ssf(context_t *text,
sasl_security_properties_t *props,
sasl_out_params_t *oparams)
{
- OM_uint32 maj_stat = 0, min_stat = 0;
- OM_uint32 max_input;
+ int ret;
if (text->qop & LAYER_CONFIDENTIALITY) {
oparams->encode = &gssapi_privacy_encode;
@@ -674,20 +699,10 @@ static int gssapi_spnego_ssf(context_t *text,
}
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;
- }
+ ret = gssapi_wrap_sizes(text, oparams);
+ if (ret != SASL_OK) {
+ return ret;
+ }
}
text->state = SASL_GSSAPI_STATE_AUTHENTICATED;
@@ -1208,7 +1223,6 @@ gssapi_server_mech_ssfreq(context_t *text,
gss_buffer_t input_token, output_token;
gss_buffer_desc real_input_token, real_output_token;
OM_uint32 maj_stat = 0, min_stat = 0;
- OM_uint32 max_input;
int layerchoice;
input_token = &real_input_token;
@@ -1297,27 +1311,20 @@ gssapi_server_mech_ssfreq(context_t *text,
(((unsigned char *) output_token->value)[2] << 8) |
(((unsigned char *) output_token->value)[3] << 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;
- }
- }
-
GSS_LOCK_MUTEX_CTX(params->utils, text);
gss_release_buffer(&min_stat, output_token);
GSS_UNLOCK_MUTEX_CTX(params->utils, text);
+ if (oparams->mech_ssf) {
+ int ret;
+
+ ret = gssapi_wrap_sizes(text, oparams);
+ if (ret != SASL_OK) {
+ sasl_gss_free_context_contents(text);
+ return ret;
+ }
+ }
+
text->state = SASL_GSSAPI_STATE_AUTHENTICATED;
/* used by layers */
@@ -1569,7 +1576,6 @@ static int gssapi_client_mech_step(void *conn_context,
gss_buffer_t input_token, output_token;
gss_buffer_desc real_input_token, real_output_token;
OM_uint32 maj_stat = 0, min_stat = 0;
- OM_uint32 max_input;
gss_buffer_desc name_token;
int ret;
OM_uint32 req_flags = 0, out_req_flags = 0;
@@ -1952,27 +1958,19 @@ static int gssapi_client_mech_step(void *conn_context,
(((unsigned char *) output_token->value)[2] << 8) |
(((unsigned char *) output_token->value)[3] << 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;
- }
- }
-
GSS_LOCK_MUTEX_CTX(params->utils, text);
gss_release_buffer(&min_stat, output_token);
GSS_UNLOCK_MUTEX_CTX(params->utils, text);
-
+
+ if (oparams->mech_ssf) {
+ int ret;
+
+ ret = gssapi_wrap_sizes(text, oparams);
+ if (ret != SASL_OK) {
+ sasl_gss_free_context_contents(text);
+ return ret;
+ }
+ }
/* oparams->user is always set, due to canon_user requirements.
* Make sure the client actually requested it though, by checking
* if our context was set.
From ff9f9caeb6db6d7513128fff9321f9bd445f58b7 Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Mon, 10 Apr 2017 19:54:19 -0400
Subject: [PATCH 3/3] 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>
---
m4/sasl2.m4 | 20 +++++++++++
plugins/gssapi.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++------
2 files changed, 111 insertions(+), 11 deletions(-)
diff --git a/cmulocal/sasl2.m4 b/cmulocal/sasl2.m4
index 66b291b..686c4bc 100644
--- a/cmulocal/sasl2.m4
+++ b/cmulocal/sasl2.m4
@@ -290,6 +290,26 @@ if test "$gssapi" != no; then
cmu_save_LIBS="$LIBS"
LIBS="$LIBS $GSSAPIBASE_LIBS"
+ AC_CHECK_FUNCS(gss_inquire_sec_context_by_oid)
+ if test "$ac_cv_func_gss_inquire_sec_context_by_oid" = no ; then
+ if test "$ac_cv_header_gssapi_gssapi_ext_h" = "yes"; then
+ AC_CHECK_DECL(gss_inquire_sec_context_by_oid,
+ [AC_DEFINE(HAVE_GSS_INQUIRE_SEC_CONTEXT_BY_OID,1,
+ [Define if your GSSAPI implementation defines gss_inquire_sec_context_by_oid])],,
+ [
+ AC_INCLUDES_DEFAULT
+ #include <gssapi/gssapi_ext.h>
+ ])
+ fi
+ fi
+ if test "$ac_cv_header_gssapi_gssapi_ext_h" = "yes"; then
+ AC_EGREP_HEADER(GSS_C_SEC_CONTEXT_SASL_SSF, gssapi/gssapi_ext.h,
+ [AC_DEFINE(HAVE_GSS_C_SEC_CONTEXT_SASL_SSF,,
+ [Define if your GSSAPI implementation defines GSS_C_SEC_CONTEXT_SASL_SSF])])
+ fi
+ cmu_save_LIBS="$LIBS"
+ LIBS="$LIBS $GSSAPIBASE_LIBS"
+
AC_MSG_CHECKING([for SPNEGO support in GSSAPI libraries])
AC_TRY_RUN([
#ifdef HAVE_GSSAPI_H
diff --git a/plugins/gssapi.c b/plugins/gssapi.c
index 348debe..5f554ce 100644
--- a/plugins/gssapi.c
+++ b/plugins/gssapi.c
@@ -51,7 +51,12 @@
#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 +103,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>
@@ -674,6 +686,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
@@ -687,7 +740,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;
@@ -1089,6 +1145,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;
@@ -1149,9 +1206,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;
}
@@ -1271,10 +1333,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,
@@ -1845,6 +1915,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;
@@ -1879,8 +1951,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;
@@ -1904,8 +1985,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;
@@ -1913,8 +1994,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) {

View File

@ -20,13 +20,15 @@ Source7: sasl-mechlist.c
Source8: sasl-checkpass.c
Source9: saslauthd.sysconfig
Source10: make-no-dlcompatorsrp-tarball.sh
# From upstream git, required for reconfigure after applying patches to configure.ac
# https://raw.githubusercontent.com/cyrusimap/cyrus-sasl/master/autogen.sh
Source11: autogen.sh
URL: http://asg.web.cmu.edu/sasl/sasl-library.html
Requires: %{name}-lib%{?_isa} = %{version}-%{release}
Patch11: cyrus-sasl-2.1.25-no_rpath.patch
Patch15: cyrus-sasl-2.1.20-saslauthd.conf-path.patch
Patch23: cyrus-sasl-2.1.23-man.patch
Patch24: cyrus-sasl-2.1.21-sizes.patch
Patch31: cyrus-sasl-2.1.22-kerberos4.patch
# removed due to #759334
#Patch38: cyrus-sasl-2.1.23-pam_rhosts.patch
# disable incorrect check for MkLinux
@ -35,16 +37,6 @@ Patch47: cyrus-sasl-2.1.26-ppc.patch
# revert upstream commit 080e51c7fa0421eb2f0210d34cf0ac48a228b1e9 (#984079)
# https://bugzilla.cyrusimap.org/show_bug.cgi?id=3480
Patch50: cyrus-sasl-2.1.26-revert-upstream-080e51c7fa0421eb2f0210d34cf0ac48a228b1e9.patch
# Document ability to run saslauthd unprivileged (#1189203)
Patch55: cyrus-sasl-2.1.26-saslauthd-user.patch
# OpenSSL 1.1.0 support
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
# Use per-connection mutex where possible
Patch59: cyrus-sasl-2.1.26-gssapi-lock.patch
# Allow cyrus sasl to get the ssf from gssapi #429
Patch60: cyrus-sasl-2.1.26-ssf-from-gssapi.patch
Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: autoconf, automake, libtool, gdbm-devel, groff
@ -169,25 +161,22 @@ the GS2 authentication scheme.
%prep
%setup -q
chmod -x doc/*.html
chmod -x include/*.h
%setup -q -n cyrus-sasl-%{version}
%patch11 -p1 -b .no_rpath
%patch15 -p1 -b .path
%patch23 -p1 -b .man
%patch24 -p1 -b .sizes
%patch31 -p1 -b .krb4
#%patch47 -p1 -b .ppc
#%patch49 -p1 -b .md5global.h
%patch50 -p1 -b .gssapi
%patch55 -p1 -b .man-unprivileged
%patch57 -p1 -b .openssl110
%patch58 -p1 -b .spnego
%patch59 -p1 -b .mutex
%patch60 -p1 -b .ssf-gssapi
%build
# reconfigure
cp %{SOURCE11} ./
rm configure aclocal.m4 config/ltmain.sh Makefile.in
export NOCONFIGURE=yes
sh autogen.sh
# Find Kerberos.
krb5_prefix=`krb5-config --prefix`
if test x$krb5_prefix = x%{_prefix} ; then
@ -354,7 +343,7 @@ getent passwd %{username} >/dev/null || useradd -r -g %{username} -d %{homedir}
%files lib
%defattr(-,root,root)
%license COPYING
%doc AUTHORS NEWS README doc/*.html
%doc AUTHORS doc/html/*.html
%{_libdir}/libsasl*.so.*
%dir %{_sysconfdir}/sasl2
%dir %{_plugindir2}/
@ -401,7 +390,6 @@ getent passwd %{username} >/dev/null || useradd -r -g %{username} -d %{homedir}
%files devel
%defattr(-,root,root)
%doc doc/*.txt
%{_bindir}/sasl2-sample-client
%{_bindir}/sasl2-sample-server
%{_includedir}/*