Compare commits

...

No commits in common. "c8" and "c10s" have entirely different histories.
c8 ... c10s

38 changed files with 2855 additions and 1262 deletions

View File

@ -1 +0,0 @@
c9e6848d9cc6f9588e0e7a75423f9a3aed3f10db SOURCES/cyrus-sasl-2.1.27-nodlcompatorsrp.tar.gz

7
.gitignore vendored
View File

@ -1 +1,6 @@
SOURCES/cyrus-sasl-2.1.27-nodlcompatorsrp.tar.gz
cyrus-sasl-2.1.23-nodlcompatorsrp.tar.gz
/cyrus-sasl-2.1.25-nodlcompatorsrp.tar.gz
/cyrus-sasl-2.1.26-nodlcompatorsrp.tar.gz
/cyrus-sasl-2.1.27-rc7-nodlcompatorsrp.tar.gz
/cyrus-sasl-2.1.27-nodlcompatorsrp.tar.gz
/cyrus-sasl-2.1.28-nodlcompatorsrp.tar.gz

View File

@ -1,435 +0,0 @@
From 49e965f41257a0ed299c58a7cf1c120ddf944aaa Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Tue, 5 May 2020 14:51:36 -0400
Subject: [PATCH] Add support for setting max ssf 0 to GSS-SPNEGO
Bacport form this proposed PR (still open at bacport time):
https://github.com/cyrusimap/cyrus-sasl/pull/603
Signed-off-by: Simo Sorce <simo@redhat.com>
---
m4/sasl2.m4 | 13 +++++++
plugins/gssapi.c | 44 ++++++++++++++++++++-
tests/runtests.py | 91 ++++++++++++++++++++++++++++++++++++++++----
tests/t_common.c | 13 ++++---
tests/t_common.h | 3 +-
tests/t_gssapi_cli.c | 25 ++++++++++--
tests/t_gssapi_srv.c | 28 +++++++++++---
7 files changed, 194 insertions(+), 23 deletions(-)
diff --git a/m4/sasl2.m4 b/m4/sasl2.m4
index 56e0504..6effe99 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 5d900c5..7480316 100644
--- a/plugins/gssapi.c
+++ b/plugins/gssapi.c
@@ -1783,7 +1783,49 @@ 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;
diff --git a/tests/runtests.py b/tests/runtests.py
index fc9cf24..4106401 100755
--- a/tests/runtests.py
+++ b/tests/runtests.py
@@ -6,6 +6,7 @@ import os
import shutil
import signal
import subprocess
+import sys
import time
from string import Template
@@ -149,11 +150,12 @@ def gssapi_basic_test(kenv):
srv.returncode, srv.stderr.read().decode('utf-8')))
except Exception as e:
print("FAIL: {}".format(e))
- return
+ return 1
print("PASS: CLI({}) SRV({})".format(
cli.stdout.read().decode('utf-8').strip(),
srv.stdout.read().decode('utf-8').strip()))
+ return 0
def gssapi_channel_binding_test(kenv):
try:
@@ -178,11 +180,12 @@ def gssapi_channel_binding_test(kenv):
srv.returncode, srv.stderr.read().decode('utf-8')))
except Exception as e:
print("FAIL: {}".format(e))
- return
+ return 1
print("PASS: CLI({}) SRV({})".format(
cli.stdout.read().decode('utf-8').strip(),
srv.stdout.read().decode('utf-8').strip()))
+ return 0
def gssapi_channel_binding_mismatch_test(kenv):
result = "FAIL"
@@ -212,11 +215,70 @@ def gssapi_channel_binding_mismatch_test(kenv):
cli.returncode, cli_err, srv.returncode, srv_err))
except Exception as e:
print("{}: {}".format(result, e))
- return
+ return 0
print("FAIL: This test should fail [CLI({}) SRV({})]".format(
cli.stdout.read().decode('utf-8').strip(),
srv.stdout.read().decode('utf-8').strip()))
+ return 1
+
+def gss_spnego_basic_test(kenv):
+ try:
+ srv = subprocess.Popen(["../tests/t_gssapi_srv", "-N"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=kenv)
+ srv.stdout.readline() # Wait for srv to say it is ready
+ cli = subprocess.Popen(["../tests/t_gssapi_cli", "-N"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=kenv)
+ try:
+ cli.wait(timeout=5)
+ srv.wait(timeout=5)
+ except Exception as e:
+ print("Failed on {}".format(e));
+ cli.kill()
+ srv.kill()
+ if cli.returncode != 0 or srv.returncode != 0:
+ raise Exception("CLI ({}): {} --> SRV ({}): {}".format(
+ cli.returncode, cli.stderr.read().decode('utf-8'),
+ srv.returncode, srv.stderr.read().decode('utf-8')))
+ except Exception as e:
+ print("FAIL: {}".format(e))
+ return 1
+
+ print("PASS: CLI({}) SRV({})".format(
+ cli.stdout.read().decode('utf-8').strip(),
+ srv.stdout.read().decode('utf-8').strip()))
+ return 0
+
+def gss_spnego_zeromaxssf_test(kenv):
+ try:
+ srv = subprocess.Popen(["../tests/t_gssapi_srv", "-N", "-z"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=kenv)
+ srv.stdout.readline() # Wait for srv to say it is ready
+ cli = subprocess.Popen(["../tests/t_gssapi_cli", "-N", "-z"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=kenv)
+ try:
+ cli.wait(timeout=5)
+ srv.wait(timeout=5)
+ except Exception as e:
+ print("Failed on {}".format(e));
+ cli.kill()
+ srv.kill()
+ if cli.returncode != 0 or srv.returncode != 0:
+ raise Exception("CLI ({}): {} --> SRV ({}): {}".format(
+ cli.returncode, cli.stderr.read().decode('utf-8'),
+ srv.returncode, srv.stderr.read().decode('utf-8')))
+ except Exception as e:
+ print("FAIL: {}".format(e))
+ return 1
+
+ print("PASS: CLI({}) SRV({})".format(
+ cli.stdout.read().decode('utf-8').strip(),
+ srv.stdout.read().decode('utf-8').strip()))
+ return 0
def gssapi_tests(testdir):
""" SASL/GSSAPI Tests """
@@ -225,20 +287,32 @@ def gssapi_tests(testdir):
#print("KDC: {}, ENV: {}".format(kdc, kenv))
kenv['KRB5_TRACE'] = os.path.join(testdir, 'trace.log')
+ err = 0
+
print('GSSAPI BASIC:')
print(' ', end='')
- gssapi_basic_test(kenv)
+ err += gssapi_basic_test(kenv)
print('GSSAPI CHANNEL BINDING:')
print(' ', end='')
- gssapi_channel_binding_test(kenv)
+ err += gssapi_channel_binding_test(kenv)
print('GSSAPI CHANNEL BINDING MISMTACH:')
print(' ', end='')
- gssapi_channel_binding_mismatch_test(kenv)
+ err += gssapi_channel_binding_mismatch_test(kenv)
+
+ print('GSS-SPNEGO BASIC:')
+ print(' ', end='')
+ err += gss_spnego_basic_test(kenv)
+
+ print('GSS-SPNEGO 0 MAXSSF:')
+ print(' ', end='')
+ err += gss_spnego_zeromaxssf_test(kenv)
os.killpg(kdc.pid, signal.SIGTERM)
+ return err
+
if __name__ == "__main__":
@@ -253,4 +327,7 @@ if __name__ == "__main__":
shutil.rmtree(T)
os.makedirs(T)
- gssapi_tests(T)
+ err = gssapi_tests(T)
+ if err != 0:
+ print('{} test(s) FAILED'.format(err))
+ sys.exit(-1)
diff --git a/tests/t_common.c b/tests/t_common.c
index 478e6a1..f56098e 100644
--- a/tests/t_common.c
+++ b/tests/t_common.c
@@ -23,20 +23,21 @@ void send_string(int sd, const char *s, unsigned int l)
if (ret != l) s_error("send data", ret, l, errno);
}
-void recv_string(int sd, char *buf, unsigned int *buflen)
+void recv_string(int sd, char *buf, unsigned int *buflen, bool allow_eof)
{
+ unsigned int bufsize = *buflen;
unsigned int l;
ssize_t ret;
+ *buflen = 0;
+
ret = recv(sd, &l, sizeof(l), MSG_WAITALL);
+ if (allow_eof && ret == 0) return;
if (ret != sizeof(l)) s_error("recv size", ret, sizeof(l), errno);
- if (l == 0) {
- *buflen = 0;
- return;
- }
+ if (l == 0) return;
- if (*buflen < l) s_error("recv len", l, *buflen, E2BIG);
+ if (bufsize < l) s_error("recv len", l, bufsize, E2BIG);
ret = recv(sd, buf, l, 0);
if (ret != l) s_error("recv data", ret, l, errno);
diff --git a/tests/t_common.h b/tests/t_common.h
index a10def1..be24a53 100644
--- a/tests/t_common.h
+++ b/tests/t_common.h
@@ -4,6 +4,7 @@
#include "config.h"
#include <errno.h>
+#include <stdbool.h>
#include <stdio.h>
#include <sys/socket.h>
@@ -12,7 +13,7 @@
void s_error(const char *hdr, ssize_t ret, ssize_t len, int err);
void send_string(int sd, const char *s, unsigned int l);
-void recv_string(int sd, char *buf, unsigned int *buflen);
+void recv_string(int sd, char *buf, unsigned int *buflen, bool allow_eof);
void saslerr(int why, const char *what);
int getpath(void *context __attribute__((unused)), const char **path);
void parse_cb(sasl_channel_binding_t *cb, char *buf, unsigned max, char *in);
diff --git a/tests/t_gssapi_cli.c b/tests/t_gssapi_cli.c
index a44a3f5..d9eafe1 100644
--- a/tests/t_gssapi_cli.c
+++ b/tests/t_gssapi_cli.c
@@ -46,12 +46,21 @@ int main(int argc, char *argv[])
char cb_buf[256];
int sd;
int c, r;
+ const char *sasl_mech = "GSSAPI";
+ bool spnego = false;
+ bool zeromaxssf = false;
- while ((c = getopt(argc, argv, "c:")) != EOF) {
+ while ((c = getopt(argc, argv, "c:zN")) != EOF) {
switch (c) {
case 'c':
parse_cb(&cb, cb_buf, 256, optarg);
break;
+ case 'z':
+ zeromaxssf = true;
+ break;
+ case 'N':
+ spnego = true;
+ break;
default:
break;
}
@@ -78,7 +87,17 @@ int main(int argc, char *argv[])
sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb);
}
- r = sasl_client_start(conn, "GSSAPI", NULL, &data, &len, &chosenmech);
+ if (spnego) {
+ sasl_mech = "GSS-SPNEGO";
+ }
+
+ if (zeromaxssf) {
+ /* set all security properties to 0 including maxssf */
+ sasl_security_properties_t secprops = { 0 };
+ sasl_setprop(conn, SASL_SEC_PROPS, &secprops);
+ }
+
+ r = sasl_client_start(conn, sasl_mech, NULL, &data, &len, &chosenmech);
if (r != SASL_OK && r != SASL_CONTINUE) {
saslerr(r, "starting SASL negotiation");
printf("\n%s\n", sasl_errdetail(conn));
@@ -90,7 +109,7 @@ int main(int argc, char *argv[])
while (r == SASL_CONTINUE) {
send_string(sd, data, len);
len = 8192;
- recv_string(sd, buf, &len);
+ recv_string(sd, buf, &len, false);
r = sasl_client_step(conn, buf, len, NULL, &data, &len);
if (r != SASL_OK && r != SASL_CONTINUE) {
diff --git a/tests/t_gssapi_srv.c b/tests/t_gssapi_srv.c
index ef1217f..448a218 100644
--- a/tests/t_gssapi_srv.c
+++ b/tests/t_gssapi_srv.c
@@ -56,12 +56,21 @@ int main(int argc, char *argv[])
unsigned char cb_buf[256];
int sd;
int c, r;
+ const char *sasl_mech = "GSSAPI";
+ bool spnego = false;
+ bool zeromaxssf = false;
- while ((c = getopt(argc, argv, "c:")) != EOF) {
+ while ((c = getopt(argc, argv, "c:zN")) != EOF) {
switch (c) {
case 'c':
parse_cb(&cb, cb_buf, 256, optarg);
break;
+ case 'z':
+ zeromaxssf = true;
+ break;
+ case 'N':
+ spnego = true;
+ break;
default:
break;
}
@@ -90,12 +99,22 @@ int main(int argc, char *argv[])
sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb);
}
+ if (spnego) {
+ sasl_mech = "GSS-SPNEGO";
+ }
+
+ if (zeromaxssf) {
+ /* set all security properties to 0 including maxssf */
+ sasl_security_properties_t secprops = { 0 };
+ sasl_setprop(conn, SASL_SEC_PROPS, &secprops);
+ }
+
sd = setup_socket();
len = 8192;
- recv_string(sd, buf, &len);
+ recv_string(sd, buf, &len, false);
- r = sasl_server_start(conn, "GSSAPI", buf, len, &data, &len);
+ r = sasl_server_start(conn, sasl_mech, buf, len, &data, &len);
if (r != SASL_OK && r != SASL_CONTINUE) {
saslerr(r, "starting SASL negotiation");
printf("\n%s\n", sasl_errdetail(conn));
@@ -105,7 +124,7 @@ int main(int argc, char *argv[])
while (r == SASL_CONTINUE) {
send_string(sd, data, len);
len = 8192;
- recv_string(sd, buf, &len);
+ recv_string(sd, buf, &len, true);
r = sasl_server_step(conn, buf, len, &data, &len);
if (r != SASL_OK && r != SASL_CONTINUE) {
@@ -113,7 +132,6 @@ int main(int argc, char *argv[])
printf("\n%s\n", sasl_errdetail(conn));
exit(-1);
}
-
}
if (r != SASL_OK) exit(-1);
--
2.18.2

View File

@ -1,29 +0,0 @@
From bcb6c06ec17728f7c9c492dc257b1e541a6830da Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Tue, 5 May 2020 14:41:06 -0400
Subject: [PATCH] CVE-2019-19906
Backport of commit id:
dcc9f51cbd4ed622cfb0f9b1c141eb2ffe3b12f1
Signed-off-by: Simo Sorce <simo@redhat.com>
---
lib/common.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/common.c b/lib/common.c
index bc3bf1d..9969d6a 100644
--- a/lib/common.c
+++ b/lib/common.c
@@ -190,7 +190,7 @@ int _sasl_add_string(char **out, size_t *alloclen,
if (add==NULL) add = "(null)";
- addlen=strlen(add); /* only compute once */
+ addlen=strlen(add)+1; /* only compute once */
if (_buf_alloc(out, alloclen, (*outlen)+addlen)!=SASL_OK)
return SASL_NOMEM;
--
2.18.2

View File

@ -1,42 +0,0 @@
From ec070b2e83a4ee698c08d6d68c205aea4d90b0bb Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Tue, 5 May 2020 14:31:10 -0400
Subject: [PATCH] Emit debug log only in case of errors
Backport of commit id:
ccc5e547d4b40ee2b182a9945f8f6cc10b4fdf48
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 7480316..6bcd78e 100644
--- a/plugins/gssapi.c
+++ b/plugins/gssapi.c
@@ -1444,9 +1444,6 @@ gssapi_server_mech_step(void *conn_context,
if (text == NULL) return SASL_BADPROT;
- params->utils->log(params->utils->conn, SASL_LOG_DEBUG,
- "GSSAPI server step %d\n", text->state);
-
switch (text->state) {
case SASL_GSSAPI_STATE_AUTHNEG:
@@ -1496,8 +1493,10 @@ gssapi_server_mech_step(void *conn_context,
}
oparams->doneflag = 1;
+ } else {
+ params->utils->log(params->utils->conn, SASL_LOG_DEBUG,
+ "GSSAPI server step failed: %d\n", text->state);
}
-
return ret;
}
--
2.18.2

View File

@ -1,155 +0,0 @@
From 8aa9ae816ddf66921b4a8a0f422517e6f2e55ac6 Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Wed, 27 Mar 2019 14:29:08 -0400
Subject: [PATCH] Use Openssl RC4 when available
Signed-off-by: Simo Sorce <simo@redhat.com>
---
configure.ac | 5 +--
plugins/digestmd5.c | 107 +++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 108 insertions(+), 4 deletions(-)
diff --git a/configure.ac b/configure.ac
index 388f5d02..cfdee4a2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1102,12 +1102,11 @@ AC_ARG_WITH(configdir, [ --with-configdir=DIR set the directory where confi
AC_SUBST(configdir)
-dnl look for rc4 libraries. we accept the CMU one or one from openSSL
-AC_ARG_WITH(rc4, [ --with-rc4 use internal rc4 routines [[yes]] ],
+AC_ARG_WITH(rc4, [ --with-rc4 use rc4 routines [[yes]] ],
with_rc4=$withval,
with_rc4=yes)
if test "$with_rc4" != no; then
- AC_DEFINE(WITH_RC4,[],[Use internal RC4 implementation?])
+ AC_DEFINE(WITH_RC4,[],[Use RC4])
fi
building_for_macosx=no
diff --git a/plugins/digestmd5.c b/plugins/digestmd5.c
index df35093d..c6b54317 100644
--- a/plugins/digestmd5.c
+++ b/plugins/digestmd5.c
@@ -1117,6 +1117,111 @@ static void free_des(context_t *text)
#endif /* WITH_DES */
#ifdef WITH_RC4
+#ifdef HAVE_OPENSSL
+#include <openssl/evp.h>
+
+static void free_rc4(context_t *text)
+{
+ if (text->cipher_enc_context) {
+ EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *)text->cipher_enc_context);
+ text->cipher_enc_context = NULL;
+ }
+ if (text->cipher_dec_context) {
+ EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *)text->cipher_dec_context);
+ text->cipher_dec_context = NULL;
+ }
+}
+
+static int init_rc4(context_t *text,
+ unsigned char enckey[16],
+ unsigned char deckey[16])
+{
+ EVP_CIPHER_CTX *ctx;
+ int rc;
+
+ ctx = EVP_CIPHER_CTX_new();
+ if (ctx == NULL) return SASL_NOMEM;
+
+ rc = EVP_EncryptInit_ex(ctx, EVP_rc4(), NULL, enckey, NULL);
+ if (rc != 1) return SASL_FAIL;
+
+ text->cipher_enc_context = (void *)ctx;
+
+ ctx = EVP_CIPHER_CTX_new();
+ if (ctx == NULL) return SASL_NOMEM;
+
+ rc = EVP_DecryptInit_ex(ctx, EVP_rc4(), NULL, deckey, NULL);
+ if (rc != 1) return SASL_FAIL;
+
+ text->cipher_dec_context = (void *)ctx;
+
+ return SASL_OK;
+}
+
+static int dec_rc4(context_t *text,
+ const char *input,
+ unsigned inputlen,
+ unsigned char digest[16] __attribute__((unused)),
+ char *output,
+ unsigned *outputlen)
+{
+ int len;
+ int rc;
+
+ /* decrypt the text part & HMAC */
+ rc = EVP_DecryptUpdate((EVP_CIPHER_CTX *)text->cipher_dec_context,
+ (unsigned char *)output, &len,
+ (const unsigned char *)input, inputlen);
+ if (rc != 1) return SASL_FAIL;
+
+ *outputlen = len;
+
+ rc = EVP_DecryptFinal_ex((EVP_CIPHER_CTX *)text->cipher_dec_context,
+ (unsigned char *)output + len, &len);
+ if (rc != 1) return SASL_FAIL;
+
+ *outputlen += len;
+
+ /* subtract the HMAC to get the text length */
+ *outputlen -= 10;
+
+ return SASL_OK;
+}
+
+static int enc_rc4(context_t *text,
+ const char *input,
+ unsigned inputlen,
+ unsigned char digest[16],
+ char *output,
+ unsigned *outputlen)
+{
+ int len;
+ int rc;
+ /* encrypt the text part */
+ rc = EVP_EncryptUpdate((EVP_CIPHER_CTX *)text->cipher_enc_context,
+ (unsigned char *)output, &len,
+ (const unsigned char *)input, inputlen);
+ if (rc != 1) return SASL_FAIL;
+
+ *outputlen = len;
+
+ /* encrypt the `MAC part */
+ rc = EVP_EncryptUpdate((EVP_CIPHER_CTX *)text->cipher_enc_context,
+ (unsigned char *)output + *outputlen, &len,
+ digest, 10);
+ if (rc != 1) return SASL_FAIL;
+
+ *outputlen += len;
+
+ rc = EVP_EncryptFinal_ex((EVP_CIPHER_CTX *)text->cipher_enc_context,
+ (unsigned char *)output + *outputlen, &len);
+ if (rc != 1) return SASL_FAIL;
+
+ *outputlen += len;
+
+ return SASL_OK;
+}
+#else
/* quick generic implementation of RC4 */
struct rc4_context_s {
unsigned char sbox[256];
@@ -1296,7 +1401,7 @@ static int enc_rc4(context_t *text,
return SASL_OK;
}
-
+#endif /* HAVE_OPENSSL */
#endif /* WITH_RC4 */
struct digest_cipher available_ciphers[] =

View File

@ -1,448 +1,74 @@
%global username saslauth
%global hint Saslauthd user
%global homedir /run/saslauthd
* Tue Oct 12 2021 Simo Sorce <simo@redhat.com> - 2.1.27-16
- Fix rpath patch
- Resolves: rhbz#2012172
%global _plugindir2 %{_libdir}/sasl2
%global bootstrap_cyrus_sasl 0
* Wed Oct 6 2021 Simo Sorce <simo@redhat.com> - 2.1.27-15
- More openssl 3 compatibility and digestmd5 updates.
Summary: The Cyrus SASL library
Name: cyrus-sasl
Version: 2.1.27
Release: 6%{?dist}
License: BSD with advertising
Group: System Environment/Libraries
# Source0 originally comes from https://www.cyrusimap.org/releases/;
# make-no-dlcompatorsrp-tarball.sh removes the "dlcompat" subdirectory and builds a
# new tarball.
Source0: cyrus-sasl-%{version}-nodlcompatorsrp.tar.gz
Source5: saslauthd.service
Source7: sasl-mechlist.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: https://www.cyrusimap.org/sasl/
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
Patch49: cyrus-sasl-2.1.26-md5global.patch
Patch60: cyrus-sasl-pr559-RC4-openssl.patch
Patch830: cyrus-sasl-2.1.27-CVE-2019-19906.patch
Patch831: cyrus-sasl-2.1.27-Add-basic-test-infrastructure.patch
Patch832: cyrus-sasl-2.1.27-Add-Channel-Binding-support-for-GSSAPI-GSS-SPNEGO.patch
Patch833: cyrus-sasl-2.1.27-Add-support-for-setting-max-ssf-0-to-GSS-SPNEGO.patch
Patch834: cyrus-sasl-2.1.27-Emit-debug-log-only-in-case-of-errors.patch
* Tue Sep 14 2021 Sahana Prasad <sahana@redhat.com> - 2.1.27-14
- Rebuilt with OpenSSL 3.0.0
Patch900: 0001-CVE-2022-24407-Escape-password-for-SQL-insert-update.patch
* Tue Aug 10 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 2.1.27-13
- Preserve GDBM error to correctly deal with GDBM sasldb
- Related: rhbz#1952926
Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: autoconf, automake, libtool, gdbm-devel, groff
BuildRequires: krb5-devel >= 1.2.2, openssl-devel, pam-devel, pkgconfig
BuildRequires: mariadb-connector-c-devel, postgresql-devel, zlib-devel
BuildRequires: libdb-devel
%if ! %{bootstrap_cyrus_sasl}
BuildRequires: openldap-devel
%endif
#build reqs for make check
BuildRequires: python36 nss_wrapper socket_wrapper krb5-server
%{?systemd_requires}
Requires(post): chkconfig
Requires(pre): /usr/sbin/useradd /usr/sbin/groupadd
Requires(postun): /usr/sbin/userdel /usr/sbin/groupdel
Requires: /sbin/nologin
Requires: systemd >= 211
Provides: user(%username)
Provides: group(%username)
* Wed Jul 21 2021 Fedora Release Engineering <releng@fedoraproject.org> - 2.1.27-12
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
* Mon May 03 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 2.1.27-11
- Fix some coverity issues
- Set default sasldb database to GDBM instead of BerkeleyDB
- Add the migration tool from BerkeleyDB
- Add some PLAIN auth tests
%description
The %{name} package contains the Cyrus implementation of SASL.
SASL is the Simple Authentication and Security Layer, a method for
adding authentication support to connection-based protocols.
* Tue Apr 06 2021 Simo Sorce <simo@redhat.com> - 2.1.27-10
- Fix issues with autoconf 2.70+
%package lib
Group: System Environment/Libraries
Summary: Shared libraries needed by applications which use Cyrus SASL
* Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 2.1.27-9
- Rebuilt for updated systemd-rpm-macros
See https://pagure.io/fesco/issue/2583.
%description lib
The %{name}-lib package contains shared libraries which are needed by
applications which use the Cyrus SASL library.
* Mon Feb 08 2021 Pavel Raiskup <praiskup@redhat.com> - 2.1.27-8
- rebuild for libpq ABI fix rhbz#1908268
%package devel
Requires: %{name}-lib%{?_isa} = %{version}-%{release}
Requires: %{name}%{?_isa} = %{version}-%{release}
Requires: pkgconfig
Group: Development/Libraries
Summary: Files needed for developing applications with Cyrus SASL
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 2.1.27-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
%description devel
The %{name}-devel package contains files needed for developing and
compiling applications which use the Cyrus SASL library.
* Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 2.1.27-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
%package gssapi
Requires: %{name}-lib%{?_isa} = %{version}-%{release}
Group: System Environment/Libraries
Summary: GSSAPI authentication support for Cyrus SASL
%description gssapi
The %{name}-gssapi package contains the Cyrus SASL plugins which
support GSSAPI authentication. GSSAPI is commonly used for Kerberos
authentication.
%package plain
Requires: %{name}-lib%{?_isa} = %{version}-%{release}
Group: System Environment/Libraries
Summary: PLAIN and LOGIN authentication support for Cyrus SASL
%description plain
The %{name}-plain package contains the Cyrus SASL plugins which support
PLAIN and LOGIN authentication schemes.
%package md5
Requires: %{name}-lib%{?_isa} = %{version}-%{release}
Group: System Environment/Libraries
Summary: CRAM-MD5 and DIGEST-MD5 authentication support for Cyrus SASL
%description md5
The %{name}-md5 package contains the Cyrus SASL plugins which support
CRAM-MD5 and DIGEST-MD5 authentication schemes.
%package ntlm
Requires: %{name}-lib%{?_isa} = %{version}-%{release}
Group: System Environment/Libraries
Summary: NTLM authentication support for Cyrus SASL
%description ntlm
The %{name}-ntlm package contains the Cyrus SASL plugin which supports
the NTLM authentication scheme.
# This would more appropriately be named cyrus-sasl-auxprop-sql.
%package sql
Requires: %{name}-lib%{?_isa} = %{version}-%{release}
Group: System Environment/Libraries
Summary: SQL auxprop support for Cyrus SASL
%description sql
The %{name}-sql package contains the Cyrus SASL plugin which supports
using a RDBMS for storing shared secrets.
%if ! %{bootstrap_cyrus_sasl}
# This was *almost* named cyrus-sasl-auxprop-ldapdb, but that's a lot of typing.
%package ldap
Requires: %{name}-lib%{?_isa} = %{version}-%{release}
Group: System Environment/Libraries
Summary: LDAP auxprop support for Cyrus SASL
%description ldap
The %{name}-ldap package contains the Cyrus SASL plugin which supports using
a directory server, accessed using LDAP, for storing shared secrets.
%endif
%package scram
Requires: %{name}-lib%{?_isa} = %{version}-%{release}
Group: System Environment/Libraries
Summary: SCRAM auxprop support for Cyrus SASL
%description scram
The %{name}-scram package contains the Cyrus SASL plugin which supports
the SCRAM authentication scheme.
%package gs2
Requires: %{name}-lib%{?_isa} = %{version}-%{release}
Group: System Environment/Libraries
Summary: GS2 support for Cyrus SASL
%description gs2
The %{name}-gs2 package contains the Cyrus SASL plugin which supports
the GS2 authentication scheme.
###
%prep
%setup -q -n cyrus-sasl-%{version}
%patch11 -p1 -b .no_rpath
%patch15 -p1 -b .path
%patch23 -p1 -b .man
%patch24 -p1 -b .sizes
%patch49 -p1 -b .md5global.h
%patch60 -p1 -b .openssl_rc4
%patch830 -p1 -b .CVE-2019-19906
%patch831 -p1 -b .tests
%patch832 -p1 -b .gssapi_cbs
%patch833 -p1 -b .maxssf0
%patch834 -p1 -b .nolog
%patch900 -p1 -b .CVE-2022-24407
%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
krb5_prefix=
else
CPPFLAGS="-I${krb5_prefix}/include $CPPFLAGS"; export CPPFLAGS
LDFLAGS="-L${krb5_prefix}/%{_lib} $LDFLAGS"; export LDFLAGS
fi
# Find OpenSSL.
LIBS="-lcrypt"; export LIBS
if pkg-config openssl ; then
CPPFLAGS="`pkg-config --cflags-only-I openssl` $CPPFLAGS"; export CPPFLAGS
LDFLAGS="`pkg-config --libs-only-L openssl` $LDFLAGS"; export LDFLAGS
fi
# Find the MySQL libraries used needed by the SQL auxprop plugin.
INC_DIR="`mysql_config --include`"
if test x"$INC_DIR" != "x-I%{_includedir}"; then
CPPFLAGS="$INC_DIR $CPPFLAGS"; export CPPFLAGS
fi
LIB_DIR="`mysql_config --libs | sed -e 's,-[^L][^ ]*,,g' -e 's,^ *,,' -e 's, *$,,' -e 's, *, ,g'`"
if test x"$LIB_DIR" != "x-L%{_libdir}"; then
LDFLAGS="$LIB_DIR $LDFLAGS"; export LDFLAGS
fi
# Find the PostgreSQL libraries used needed by the SQL auxprop plugin.
INC_DIR="-I`pg_config --includedir`"
if test x"$INC_DIR" != "x-I%{_includedir}"; then
CPPFLAGS="$INC_DIR $CPPFLAGS"; export CPPFLAGS
fi
LIB_DIR="-L`pg_config --libdir`"
if test x"$LIB_DIR" != "x-L%{_libdir}"; then
LDFLAGS="$LIB_DIR $LDFLAGS"; export LDFLAGS
fi
# Patch config.sub to support ppc64p7 subarch (Fedora specific)
# This is similar to what the config.sub from automake has
for i in `find . -name config.sub`; do
perl -pi -e "s/ppc64-\*/ppc64-\* \| ppc64p7-\*/" $i
done
CFLAGS="$RPM_OPT_FLAGS $CFLAGS $CPPFLAGS -fPIC -pie -Wl,-z,relro -Wl,-z,now"; export CFLAGS
LDFLAGS="$LDFLAGS -pie -Wl,-z,now"; export LDFLAGS
echo "$CFLAGS"
echo "$CPPFLAGS"
echo "$LDFLAGS"
%configure \
--enable-shared --disable-static \
--disable-java \
--with-plugindir=%{_plugindir2} \
--with-configdir=%{_plugindir2}:%{_sysconfdir}/sasl2 \
--disable-krb4 \
--enable-gssapi${krb5_prefix:+=${krb5_prefix}} \
--with-gss_impl=mit \
--with-rc4 \
--with-dblib=berkeley \
--with-bdb=db \
--with-saslauthd=/run/saslauthd --without-pwcheck \
%if ! %{bootstrap_cyrus_sasl}
--with-ldap \
%endif
--with-devrandom=/dev/urandom \
--enable-anon \
--enable-cram \
--enable-digest \
--enable-ntlm \
--enable-plain \
--enable-login \
--enable-alwaystrue \
--enable-httpform \
--disable-otp \
%if ! %{bootstrap_cyrus_sasl}
--enable-ldapdb \
%endif
--enable-sql --with-mysql=yes --with-pgsql=yes \
--without-sqlite \
"$@"
# --enable-auth-sasldb -- EXPERIMENTAL
make sasldir=%{_plugindir2}
make -C saslauthd testsaslauthd
make -C sample
# Build a small program to list the available mechanisms, because I need it.
pushd lib
../libtool --mode=link %{__cc} -o sasl2-shared-mechlist -I../include $CFLAGS %{SOURCE7} $LDFLAGS ./libsasl2.la
%install
test "$RPM_BUILD_ROOT" != "/" && rm -rf $RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT sasldir=%{_plugindir2}
make install DESTDIR=$RPM_BUILD_ROOT sasldir=%{_plugindir2} -C plugins
install -m755 -d $RPM_BUILD_ROOT%{_bindir}
./libtool --mode=install \
install -m755 sample/client $RPM_BUILD_ROOT%{_bindir}/sasl2-sample-client
./libtool --mode=install \
install -m755 sample/server $RPM_BUILD_ROOT%{_bindir}/sasl2-sample-server
./libtool --mode=install \
install -m755 saslauthd/testsaslauthd $RPM_BUILD_ROOT%{_sbindir}/testsaslauthd
# Install the saslauthd mdoc page in the expected location. Sure, it's not
# really a man page, but groff seems to be able to cope with it.
install -m755 -d $RPM_BUILD_ROOT%{_mandir}/man8/
install -m644 -p saslauthd/saslauthd.mdoc $RPM_BUILD_ROOT%{_mandir}/man8/saslauthd.8
install -m644 -p saslauthd/testsaslauthd.8 $RPM_BUILD_ROOT%{_mandir}/man8/testsaslauthd.8
# Install the init script for saslauthd and the init script's config file.
install -m755 -d $RPM_BUILD_ROOT/etc/rc.d/init.d $RPM_BUILD_ROOT/etc/sysconfig
install -d -m755 $RPM_BUILD_ROOT/%{_unitdir}
install -m644 -p %{SOURCE5} $RPM_BUILD_ROOT/%{_unitdir}/saslauthd.service
install -m644 -p %{SOURCE9} $RPM_BUILD_ROOT/etc/sysconfig/saslauthd
# Install the config dirs if they're not already there.
install -m755 -d $RPM_BUILD_ROOT/%{_sysconfdir}/sasl2
install -m755 -d $RPM_BUILD_ROOT/%{_plugindir2}
# Provide an easy way to query the list of available mechanisms.
./libtool --mode=install \
install -m755 lib/sasl2-shared-mechlist $RPM_BUILD_ROOT/%{_sbindir}/
# Remove unpackaged files from the buildroot.
rm -f $RPM_BUILD_ROOT%{_libdir}/sasl2/libotp.*
rm -f $RPM_BUILD_ROOT%{_libdir}/sasl2/*.a
rm -f $RPM_BUILD_ROOT%{_libdir}/sasl2/*.la
rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
rm -f $RPM_BUILD_ROOT%{_mandir}/cat8/saslauthd.8
%check
make check %{?_smp_mflags}
%pre
getent group %{username} >/dev/null || groupadd -g 76 -r %{username}
getent passwd %{username} >/dev/null || useradd -r -g %{username} -d %{homedir} -s /sbin/nologin -c "%{hint}" %{username}
%post
%systemd_post saslauthd.service
%preun
%systemd_preun saslauthd.service
%postun
%systemd_postun_with_restart saslauthd.service
%triggerun -n cyrus-sasl -- cyrus-sasl < 2.1.23-32
/usr/bin/systemd-sysv-convert --save saslauthd >/dev/null 2>&1 || :
/sbin/chkconfig --del saslauthd >/dev/null 2>&1 || :
/bin/systemctl try-restart saslauthd.service >/dev/null 2>&1 || :
%post lib -p /sbin/ldconfig
%postun lib -p /sbin/ldconfig
%files
%defattr(-,root,root)
%doc saslauthd/LDAP_SASLAUTHD
%{_mandir}/man8/*
%{_sbindir}/pluginviewer
%{_sbindir}/saslauthd
%{_sbindir}/testsaslauthd
%config(noreplace) /etc/sysconfig/saslauthd
%{_unitdir}/saslauthd.service
%ghost /run/saslauthd
%files lib
%defattr(-,root,root)
%license COPYING
%doc AUTHORS doc/html/*.html
%{_libdir}/libsasl*.so.*
%dir %{_sysconfdir}/sasl2
%dir %{_plugindir2}/
%{_plugindir2}/*anonymous*.so*
%{_plugindir2}/*sasldb*.so*
%{_sbindir}/saslpasswd2
%{_sbindir}/sasldblistusers2
%files plain
%defattr(-,root,root)
%{_plugindir2}/*plain*.so*
%{_plugindir2}/*login*.so*
%if ! %{bootstrap_cyrus_sasl}
%files ldap
%defattr(-,root,root)
%{_plugindir2}/*ldapdb*.so*
%endif
%files md5
%defattr(-,root,root)
%{_plugindir2}/*crammd5*.so*
%{_plugindir2}/*digestmd5*.so*
%files ntlm
%defattr(-,root,root)
%{_plugindir2}/*ntlm*.so*
%files sql
%defattr(-,root,root)
%{_plugindir2}/*sql*.so*
%files gssapi
%defattr(-,root,root)
%{_plugindir2}/*gssapi*.so*
%files scram
%defattr(-,root,root)
%{_plugindir2}/libscram.so*
%files gs2
%defattr(-,root,root)
%{_plugindir2}/libgs2.so*
%files devel
%defattr(-,root,root)
%{_bindir}/sasl2-sample-client
%{_bindir}/sasl2-sample-server
%{_includedir}/*
%{_libdir}/libsasl*.*so
%{_libdir}/pkgconfig/*.pc
%{_mandir}/man3/*
%{_sbindir}/sasl2-shared-mechlist
%changelog
* Thu Feb 17 2022 Simo Sorce <simo@redhat.com> - 2.1.27-6
- Fix for CVE-2022-24407
- Resolves: rhbz#2055846
* Tue May 5 2020 Simo Sorce <simo@redhat.com> - 2.1.27-5
- Reduce excessive GSSAPI plugin logging
- Resolves: rhbz#1274734
* Tue May 5 2020 Simo Sorce <simo@redhat.com> - 2.1.27-4
- Add support for setting maxssf=0 in GSS-SPNEGO
- Resolves: rhbz#1822133
* Tue May 5 2020 Simo Sorce <simo@redhat.com> - 2.1.27-3
* Thu May 7 2020 Simo Sorce <simo@redhat.com> - 2.1.27-5
- Backport GSSAPI Channel Bindings support
- Resolves: rhbz#1817054
- Add support for setting maxssf=0 in GSS-SPNEGO
- Reduce excessive GSSAPI plugin logging
* Tue May 5 2020 Simo Sorce <simo@redhat.com> - 2.1.27-2
- Backport fix for CVE-2019-19906
- Resolves: rhbz#1804036
* Thu Mar 19 2020 Simo Sorce - 2.1.27-4
- Fix CVE 2019 19906
* Fri Jun 14 2019 Simo Sorce <simo@redhat.com> - 2.1.27-1
- Rc7 to final source
- Resovles bz#1618744
* Tue Jan 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 2.1.27-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Thu Jun 13 2019 Simo Sorce <simo@redhat.com> - 2.1.27-0.4rc7
- Add patch form Upstream PR559 to use RC4 implementation from OpenSSL
- Resolves bz#1618744
- Fix multilib issue bz#1663120
* Wed Jul 24 2019 Fedora Release Engineering <releng@fedoraproject.org> - 2.1.27-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Mon Jul 30 2018 Florian Weimer <fweimer@redhat.com> - 2.1.27-0.3rc7
- Rebuild with fixed binutils
* Thu Jun 13 2019 Simo Sorce - 2.1.27-1
- Update to final 2.1.27 sources
- Also add patch to use OpenSSL RC4, currently proposed as PR 559
* Wed Jul 25 2018 Petr Kubat <pkubat@redhat.com> - 2.1.27-0.2rc7
- Rebuilt for gdbm
* Thu Jan 31 2019 Fedora Release Engineering <releng@fedoraproject.org> - 2.1.27-0.6rc7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Mon Jan 14 2019 Björn Esser <besser82@fedoraproject.org> - 2.1.27-0.5rc7
- Rebuilt for libcrypt.so.2 (#1666033)
* Sun Oct 14 2018 Peter Robinson <pbrobinson@fedoraproject.org> 2.1.27-0.4rc7
- Clean up remanents of sys-v, spec cleanups
* Thu Jul 12 2018 Fedora Release Engineering <releng@fedoraproject.org> - 2.1.27-0.3rc7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Thu May 17 2018 Jakub Jelen <jjelen@redhat.com> - 2.1.27-0.2rc7
- Avoid multilib conflicts between devel subpackages (#1577675)
* Mon Mar 05 2018 Jakub Jelen <jjelen@redhat.com> - 2.1.27-0.1rc7
- New upstream (pre-)release

View File

@ -0,0 +1,22 @@
--- a/sasldb/db_berkeley.c
+++ b/sasldb/db_berkeley.c
@@ -100,7 +100,7 @@ static int berkeleydb_open(const sasl_ut
ret = db_create(mbdb, NULL, 0);
if (ret == 0 && *mbdb != NULL)
{
-#if DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1
+#if (DB_VERSION_MAJOR > 4) || ((DB_VERSION_MAJOR == 4) && (DB_VERSION_MINOR >= 1))
ret = (*mbdb)->open(*mbdb, NULL, path, NULL, DB_HASH, flags, 0660);
#else
ret = (*mbdb)->open(*mbdb, path, NULL, DB_HASH, flags, 0660);
--- a/utils/dbconverter-2.c
+++ b/utils/dbconverter-2.c
@@ -214,7 +214,7 @@ static int berkeleydb_open(const char *p
ret = db_create(mbdb, NULL, 0);
if (ret == 0 && *mbdb != NULL)
{
-#if DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1
+#if (DB_VERSION_MAJOR > 4) || ((DB_VERSION_MAJOR == 4) && (DB_VERSION_MINOR >= 1))
ret = (*mbdb)->open(*mbdb, NULL, path, NULL, DB_HASH, DB_CREATE, 0664);
#else
ret = (*mbdb)->open(*mbdb, path, NULL, DB_HASH, DB_CREATE, 0664);

View File

@ -0,0 +1,16 @@
diff -up cyrus-sasl-2.1.23/lib/common.c.race cyrus-sasl-2.1.23/lib/common.c
--- cyrus-sasl-2.1.23/lib/common.c.race 2010-02-22 09:57:28.000000000 +0100
+++ cyrus-sasl-2.1.23/lib/common.c 2010-02-22 09:59:30.000000000 +0100
@@ -794,7 +794,11 @@ void sasl_dispose(sasl_conn_t **pconn)
if (result!=SASL_OK) return;
/* *pconn might have become NULL by now */
- if (! (*pconn)) return;
+ if (! (*pconn))
+ {
+ sasl_MUTEX_UNLOCK(free_mutex);
+ return;
+ }
(*pconn)->destroy_conn(*pconn);
sasl_FREE(*pconn);

View File

@ -0,0 +1,70 @@
diff -up cyrus-sasl-2.1.23/saslauthd/auth_rimap.c.rimap2 cyrus-sasl-2.1.23/saslauthd/auth_rimap.c
--- cyrus-sasl-2.1.23/saslauthd/auth_rimap.c.rimap2 2011-06-01 05:54:13.339252378 +0200
+++ cyrus-sasl-2.1.23/saslauthd/auth_rimap.c 2011-06-01 05:54:39.626252337 +0200
@@ -1,3 +1,4 @@
+
/* MODULE: auth_rimap */
/* COPYRIGHT
@@ -368,6 +369,30 @@ auth_rimap (
alarm(NETWORK_IO_TIMEOUT);
rc = read(s, rbuf, sizeof(rbuf));
alarm(0);
+ if ( rc>0 ) {
+ /* check if there is more to read */
+ fd_set perm;
+ int fds, ret;
+ struct timeval timeout;
+
+ FD_ZERO(&perm);
+ FD_SET(s, &perm);
+ fds = s +1;
+
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+ while( select (fds, &perm, NULL, NULL, &timeout ) >0 ) {
+ if ( FD_ISSET(s, &perm) ) {
+ ret = read(s, rbuf+rc, sizeof(rbuf)-rc);
+ if ( ret<0 ) {
+ rc = ret;
+ break;
+ } else {
+ rc += ret;
+ }
+ }
+ }
+ }
if (rc == -1) {
syslog(LOG_WARNING, "auth_rimap: read (banner): %m");
(void) close(s);
@@ -457,6 +482,30 @@ auth_rimap (
alarm(NETWORK_IO_TIMEOUT);
rc = read(s, rbuf, sizeof(rbuf));
alarm(0);
+ if ( rc>0 ) {
+ /* check if there is more to read */
+ fd_set perm;
+ int fds, ret;
+ struct timeval timeout;
+
+ FD_ZERO(&perm);
+ FD_SET(s, &perm);
+ fds = s +1;
+
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+ while( select (fds, &perm, NULL, NULL, &timeout ) >0 ) {
+ if ( FD_ISSET(s, &perm) ) {
+ ret = read(s, rbuf+rc, sizeof(rbuf)-rc);
+ if ( ret<0 ) {
+ rc = ret;
+ break;
+ } else {
+ rc += ret;
+ }
+ }
+ }
+ }
(void) close(s); /* we're done with the remote */
if (rc == -1) {
syslog(LOG_WARNING, "auth_rimap: read (response): %m");

View File

@ -16,5 +16,5 @@ diff -up cyrus-sasl-2.1.25/m4/cyrus.m4.no_rpath cyrus-sasl-2.1.25/m4/cyrus.m4
- ])
- LDFLAGS="${SAVE_LDFLAGS}"
- ])])
+ andrew_runpath_switch="none"
+ andrew_cv_runpath_switch="none"
+ ])

View File

@ -1,24 +1,24 @@
From aa8b6b2275fd14ba2cca3d2339ae61c7e7ddfa70 Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Tue, 5 May 2020 14:08:48 -0400
Subject: [PATCH] Add Channel Binding support for GSSAPI/GSS-SPNEGO
Backport of commit ids (minor inline mods to make them apply):
975edbb69070eba6b035f08776de771a129cfb57
ea8eb892e44129ac3890298da91c868d5592ed20
Backport of commit ids:
829a6ed086432e26dafa9d1dcf892aef4c42cfbd
944bd8a6205f840b105206ef83e8f6b9dff0138e
From 975edbb69070eba6b035f08776de771a129cfb57 Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Fri, 20 Mar 2020 14:51:04 -0400
Subject: [PATCH] Add Channel Binding support for GSSAPI/GSS-SPNEGO
Signed-off-by: Simo Sorce <simo@redhat.com>
---
plugins/gssapi.c | 30 +++++++++++---
tests/runtests.py | 93 ++++++++++++++++++++++++++++++++++++++++----
tests/t_common.c | 24 ++++++++----
tests/t_common.h | 5 ++-
tests/t_gssapi_cli.c | 24 ++++++++++--
tests/t_gssapi_srv.c | 24 ++++++++++--
6 files changed, 172 insertions(+), 28 deletions(-)
tests/t_common.c | 14 +++++++
tests/t_common.h | 2 +
tests/t_gssapi_cli.c | 21 +++++++++-
tests/t_gssapi_srv.c | 21 +++++++++-
6 files changed, 164 insertions(+), 17 deletions(-)
diff --git a/plugins/gssapi.c b/plugins/gssapi.c
index ff663da..5d900c5 100644
index ff663da7..5d900c5e 100644
--- a/plugins/gssapi.c
+++ b/plugins/gssapi.c
@@ -830,7 +830,9 @@ gssapi_server_mech_authneg(context_t *text,
@ -122,7 +122,7 @@ index ff663da..5d900c5 100644
gssapi_required_prompts, /* required_prompts */
&gss_spnego_oid, /* glob_context */
diff --git a/tests/runtests.py b/tests/runtests.py
index f645adf..fc9cf24 100755
index f645adf4..fc9cf244 100755
--- a/tests/runtests.py
+++ b/tests/runtests.py
@@ -1,6 +1,7 @@
@ -245,7 +245,163 @@ index f645adf..fc9cf24 100755
diff --git a/tests/t_common.c b/tests/t_common.c
index 7168b2f..478e6a1 100644
index 7168b2f1..87875b48 100644
--- a/tests/t_common.c
+++ b/tests/t_common.c
@@ -65,4 +65,18 @@ int getpath(void *context __attribute__((unused)), const char **path)
return SASL_OK;
}
+void parse_cb(sasl_channel_binding_t *cb, char *buf, unsigned max, char *in)
+{
+ unsigned len;
+ int r;
+ r = sasl_decode64(in, strlen(in), buf, max, &len);
+ if (r != SASL_OK) {
+ saslerr(r, "failed to parse channel bindings");
+ exit(-1);
+ }
+ cb->name = "TEST BINDINGS";
+ cb->critical = 0;
+ cb->data = (unsigned char *)buf;
+ cb->len = len;
+}
diff --git a/tests/t_common.h b/tests/t_common.h
index 4ee1976c..0d08d8ba 100644
--- a/tests/t_common.h
+++ b/tests/t_common.h
@@ -7,9 +7,11 @@
#include <sys/socket.h>
#include <sasl.h>
+#include <saslutil.h>
void s_error(const char *hdr, ssize_t ret, ssize_t len, int err);
void send_string(int sd, const char *s, unsigned int l);
void recv_string(int sd, char *buf, unsigned int *buflen);
void saslerr(int why, const char *what);
int getpath(void *context __attribute__((unused)), const char **path);
+void parse_cb(sasl_channel_binding_t *cb, char *buf, unsigned max, char *in);
diff --git a/tests/t_gssapi_cli.c b/tests/t_gssapi_cli.c
index c833c055..6b5664eb 100644
--- a/tests/t_gssapi_cli.c
+++ b/tests/t_gssapi_cli.c
@@ -13,6 +13,7 @@
#include <arpa/inet.h>
#include <saslplug.h>
+#include <saslutil.h>
static int setup_socket(void)
{
@@ -32,7 +33,7 @@ static int setup_socket(void)
return sock;
}
-int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
+int main(int argc, char *argv[])
{
sasl_callback_t callbacks[2] = {};
char buf[8192];
@@ -40,8 +41,20 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
sasl_conn_t *conn;
const char *data;
unsigned int len;
+ sasl_channel_binding_t cb = {0};
+ char cb_buf[256];
int sd;
- int r;
+ int c, r;
+
+ while ((c = getopt(argc, argv, "c:")) != EOF) {
+ switch (c) {
+ case 'c':
+ parse_cb(&cb, cb_buf, 256, optarg);
+ break;
+ default:
+ break;
+ }
+ }
/* initialize the sasl library */
callbacks[0].id = SASL_CB_GETPATH;
@@ -60,6 +73,10 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
exit(-1);
}
+ if (cb.name) {
+ sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb);
+ }
+
r = sasl_client_start(conn, "GSSAPI", NULL, &data, &len, &chosenmech);
if (r != SASL_OK && r != SASL_CONTINUE) {
saslerr(r, "starting SASL negotiation");
diff --git a/tests/t_gssapi_srv.c b/tests/t_gssapi_srv.c
index 29f538dd..3a8a5d44 100644
--- a/tests/t_gssapi_srv.c
+++ b/tests/t_gssapi_srv.c
@@ -44,15 +44,28 @@ static int setup_socket(void)
return sd;
}
-int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
+int main(int argc, char *argv[])
{
sasl_callback_t callbacks[2] = {};
char buf[8192];
sasl_conn_t *conn;
const char *data;
unsigned int len;
+ sasl_channel_binding_t cb = {0};
+ unsigned char cb_buf[256];
int sd;
- int r;
+ int c, r;
+
+ while ((c = getopt(argc, argv, "c:")) != EOF) {
+ switch (c) {
+ case 'c':
+ parse_cb(&cb, cb_buf, 256, optarg);
+ break;
+ default:
+ break;
+ }
+ }
+
/* initialize the sasl library */
callbacks[0].id = SASL_CB_GETPATH;
@@ -72,6 +85,10 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
exit(-1);
}
+ if (cb.name) {
+ sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb);
+ }
+
sd = setup_socket();
len = 8192;
From ea8eb892e44129ac3890298da91c868d5592ed20 Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Fri, 20 Mar 2020 14:52:15 -0400
Subject: [PATCH] Fixup minor issues in previous PR.
Remove spurious debugging code, this was left in by mistake.
Add C notices, this was omitted by mistake.
Signed-off-by: Simo Sorce <simo@redhat.com>
---
tests/t_common.c | 10 ++--------
tests/t_common.h | 3 ++-
tests/t_gssapi_cli.c | 3 ++-
tests/t_gssapi_srv.c | 3 ++-
4 files changed, 8 insertions(+), 11 deletions(-)
diff --git a/tests/t_common.c b/tests/t_common.c
index 87875b48..478e6a1f 100644
--- a/tests/t_common.c
+++ b/tests/t_common.c
@@ -1,4 +1,5 @@
@ -283,27 +439,8 @@ index 7168b2f..478e6a1 100644
*buflen = ret;
}
@@ -65,4 +59,18 @@ int getpath(void *context __attribute__((unused)), const char **path)
return SASL_OK;
}
+void parse_cb(sasl_channel_binding_t *cb, char *buf, unsigned max, char *in)
+{
+ unsigned len;
+ int r;
+ r = sasl_decode64(in, strlen(in), buf, max, &len);
+ if (r != SASL_OK) {
+ saslerr(r, "failed to parse channel bindings");
+ exit(-1);
+ }
+ cb->name = "TEST BINDINGS";
+ cb->critical = 0;
+ cb->data = (unsigned char *)buf;
+ cb->len = len;
+}
diff --git a/tests/t_common.h b/tests/t_common.h
index 4ee1976..a10def1 100644
index 0d08d8ba..a10def17 100644
--- a/tests/t_common.h
+++ b/tests/t_common.h
@@ -1,4 +1,5 @@
@ -313,20 +450,8 @@ index 4ee1976..a10def1 100644
#include "config.h"
@@ -7,9 +8,11 @@
#include <sys/socket.h>
#include <sasl.h>
+#include <saslutil.h>
void s_error(const char *hdr, ssize_t ret, ssize_t len, int err);
void send_string(int sd, const char *s, unsigned int l);
void recv_string(int sd, char *buf, unsigned int *buflen);
void saslerr(int why, const char *what);
int getpath(void *context __attribute__((unused)), const char **path);
+void parse_cb(sasl_channel_binding_t *cb, char *buf, unsigned max, char *in);
diff --git a/tests/t_gssapi_cli.c b/tests/t_gssapi_cli.c
index c833c05..a44a3f5 100644
index 6b5664eb..a44a3f58 100644
--- a/tests/t_gssapi_cli.c
+++ b/tests/t_gssapi_cli.c
@@ -1,4 +1,5 @@
@ -336,58 +461,8 @@ index c833c05..a44a3f5 100644
#include "t_common.h"
@@ -13,6 +14,7 @@
#include <arpa/inet.h>
#include <saslplug.h>
+#include <saslutil.h>
static int setup_socket(void)
{
@@ -32,7 +34,7 @@ static int setup_socket(void)
return sock;
}
-int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
+int main(int argc, char *argv[])
{
sasl_callback_t callbacks[2] = {};
char buf[8192];
@@ -40,8 +42,20 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
sasl_conn_t *conn;
const char *data;
unsigned int len;
+ sasl_channel_binding_t cb = {0};
+ char cb_buf[256];
int sd;
- int r;
+ int c, r;
+
+ while ((c = getopt(argc, argv, "c:")) != EOF) {
+ switch (c) {
+ case 'c':
+ parse_cb(&cb, cb_buf, 256, optarg);
+ break;
+ default:
+ break;
+ }
+ }
/* initialize the sasl library */
callbacks[0].id = SASL_CB_GETPATH;
@@ -60,6 +74,10 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
exit(-1);
}
+ if (cb.name) {
+ sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb);
+ }
+
r = sasl_client_start(conn, "GSSAPI", NULL, &data, &len, &chosenmech);
if (r != SASL_OK && r != SASL_CONTINUE) {
saslerr(r, "starting SASL negotiation");
diff --git a/tests/t_gssapi_srv.c b/tests/t_gssapi_srv.c
index 29f538d..ef1217f 100644
index 3a8a5d44..ef1217f6 100644
--- a/tests/t_gssapi_srv.c
+++ b/tests/t_gssapi_srv.c
@@ -1,4 +1,5 @@
@ -397,48 +472,4 @@ index 29f538d..ef1217f 100644
#include "t_common.h"
@@ -44,15 +45,28 @@ static int setup_socket(void)
return sd;
}
-int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
+int main(int argc, char *argv[])
{
sasl_callback_t callbacks[2] = {};
char buf[8192];
sasl_conn_t *conn;
const char *data;
unsigned int len;
+ sasl_channel_binding_t cb = {0};
+ unsigned char cb_buf[256];
int sd;
- int r;
+ int c, r;
+
+ while ((c = getopt(argc, argv, "c:")) != EOF) {
+ switch (c) {
+ case 'c':
+ parse_cb(&cb, cb_buf, 256, optarg);
+ break;
+ default:
+ break;
+ }
+ }
+
/* initialize the sasl library */
callbacks[0].id = SASL_CB_GETPATH;
@@ -72,6 +86,10 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
exit(-1);
}
+ if (cb.name) {
+ sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb);
+ }
+
sd = setup_socket();
len = 8192;
--
2.18.2

View File

@ -1,14 +1,16 @@
From 82e299e970461c153a036bb1fbc84e808f926e12 Mon Sep 17 00:00:00 2001
Backport of 18ff41d5d18f61c2ded7235dad1d9618aa84784b with minor inline mods to
make it apply.
From 18ff41d5d18f61c2ded7235dad1d9618aa84784b Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Tue, 5 May 2020 14:06:57 -0400
Date: Sat, 14 Mar 2020 10:50:19 -0400
Subject: [PATCH] Add basic test infrastructure
First test is for SASL/GSSAPI
Backport of upstream commit id:
18ff41d5d18f61c2ded7235dad1d9618aa84784b
Signed-off-by: Simo Sorce <simo@redhat.com>
:x
---
Makefile.am | 2 +-
configure.ac | 3 +-
@ -18,7 +20,7 @@ Signed-off-by: Simo Sorce <simo@redhat.com>
tests/t_common.h | 15 ++++
tests/t_gssapi_cli.c | 95 +++++++++++++++++++++++
tests/t_gssapi_srv.c | 111 +++++++++++++++++++++++++++
8 files changed, 550 insertions(+), 2 deletions(-)
10 files changed, 559 insertions(+), 4 deletions(-)
create mode 100644 tests/Makefile.am
create mode 100755 tests/runtests.py
create mode 100644 tests/t_common.c
@ -27,35 +29,36 @@ Signed-off-by: Simo Sorce <simo@redhat.com>
create mode 100644 tests/t_gssapi_srv.c
diff --git a/Makefile.am b/Makefile.am
index 83dae6f..fc24509 100644
index f7d3b22e..102e2a3e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -70,7 +70,7 @@ else
@@ -65,7 +65,7 @@ else
INSTALLOSX =
endif
-SUBDIRS=include sasldb common lib plugins utils $(PWC) $(SAM) $(JAV) $(SAD)
+SUBDIRS=include sasldb common lib plugins utils $(PWC) $(SAM) $(JAV) $(SAD) tests
-SUBDIRS=include sasldb common lib plugins utils $(PWC) $(SAM) $(SAD)
+SUBDIRS=include sasldb common lib plugins utils $(PWC) $(SAM) $(SAD) tests
EXTRA_DIST=config doc docsrc win32 mac dlcompat-20010505 NTMakefile \
INSTALL.TXT libsasl2.pc.in
diff --git a/configure.ac b/configure.ac
index ca5936a..c1d2182 100644
index 3610671b..dd7908a3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1575,7 +1575,8 @@ java/javax/Makefile
java/javax/security/Makefile
java/javax/security/auth/Makefile
java/javax/security/auth/callback/Makefile
-pwcheck/Makefile)
@@ -1516,8 +1516,9 @@ plugins/Makefile
lib/Makefile
utils/Makefile
sample/Makefile
-pwcheck/Makefile])
+pwcheck/Makefile
+tests/Makefile)
+tests/Makefile])
AC_OUTPUT
AC_MSG_NOTICE([
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644
index 0000000..1edf010
index 00000000..1edf010a
--- /dev/null
+++ b/tests/Makefile.am
@@ -0,0 +1,79 @@
@ -140,7 +143,7 @@ index 0000000..1edf010
+endif
diff --git a/tests/runtests.py b/tests/runtests.py
new file mode 100755
index 0000000..f645adf
index 00000000..f645adf4
--- /dev/null
+++ b/tests/runtests.py
@@ -0,0 +1,179 @@
@ -325,7 +328,7 @@ index 0000000..f645adf
+ gssapi_tests(T)
diff --git a/tests/t_common.c b/tests/t_common.c
new file mode 100644
index 0000000..7168b2f
index 00000000..7168b2f1
--- /dev/null
+++ b/tests/t_common.c
@@ -0,0 +1,68 @@
@ -399,7 +402,7 @@ index 0000000..7168b2f
+
diff --git a/tests/t_common.h b/tests/t_common.h
new file mode 100644
index 0000000..4ee1976
index 00000000..4ee1976c
--- /dev/null
+++ b/tests/t_common.h
@@ -0,0 +1,15 @@
@ -420,7 +423,7 @@ index 0000000..4ee1976
+int getpath(void *context __attribute__((unused)), const char **path);
diff --git a/tests/t_gssapi_cli.c b/tests/t_gssapi_cli.c
new file mode 100644
index 0000000..c833c05
index 00000000..c833c055
--- /dev/null
+++ b/tests/t_gssapi_cli.c
@@ -0,0 +1,95 @@
@ -521,7 +524,7 @@ index 0000000..c833c05
+
diff --git a/tests/t_gssapi_srv.c b/tests/t_gssapi_srv.c
new file mode 100644
index 0000000..29f538d
index 00000000..29f538dd
--- /dev/null
+++ b/tests/t_gssapi_srv.c
@@ -0,0 +1,111 @@
@ -636,6 +639,4 @@ index 0000000..29f538d
+ return 0;
+}
+
--
2.18.2

View File

@ -0,0 +1,95 @@
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;

View File

@ -0,0 +1,56 @@
diff -up cyrus-sasl-2.1.27/include/makemd5.c.coverity cyrus-sasl-2.1.27/include/makemd5.c
--- cyrus-sasl-2.1.27/include/makemd5.c.coverity 2021-04-12 15:10:25.421431535 +0200
+++ cyrus-sasl-2.1.27/include/makemd5.c 2021-04-12 15:56:46.752827737 +0200
@@ -107,7 +107,6 @@ my_strupr(char *s)
}
}
-
#define BITSIZE(TYPE) \
{ \
int b = 0; TYPE x = 1, zero = 0; char *pre = "U"; \
@@ -129,6 +128,8 @@ my_strupr(char *s)
static void
try_signed(FILE *f, int len)
{
+/* Local macros for not-installed program. No coverity/compiler issues! */
+#pragma GCC diagnostic ignored "-Wformat-overflow"
#ifdef HAVE_INT8_T
BITSIZE(int8_t);
#endif
@@ -149,6 +150,7 @@ try_signed(FILE *f, int len)
BITSIZE(long long);
#endif
fprintf(f, "/* There is no %d bit type */\n", len);
+#pragma GCC pop
}
static void
diff -up cyrus-sasl-2.1.27/saslauthd/lak.c.coverity cyrus-sasl-2.1.27/saslauthd/lak.c
--- cyrus-sasl-2.1.27/saslauthd/lak.c.coverity 2018-11-08 18:29:57.000000000 +0100
+++ cyrus-sasl-2.1.27/saslauthd/lak.c 2021-04-12 15:10:25.433431630 +0200
@@ -337,9 +337,9 @@ static int lak_config_read(
EMPTY(conf->group_search_base) )
strlcpy(conf->group_search_base, conf->search_base, LAK_DN_LEN);
- fclose(infile);
+ fclose(infile);
- return LAK_OK;
+ return LAK_OK;
}
static int lak_config_int(
diff -up cyrus-sasl-2.1.27/saslauthd/saslauthd-main.c.coverity cyrus-sasl-2.1.27/saslauthd/saslauthd-main.c
--- cyrus-sasl-2.1.27/saslauthd/saslauthd-main.c.coverity 2018-01-19 15:13:40.000000000 +0100
+++ cyrus-sasl-2.1.27/saslauthd/saslauthd-main.c 2021-04-12 15:10:25.433431630 +0200
@@ -833,7 +833,8 @@ void detach_tty() {
}
logger(L_INFO, L_FUNC, "master pid is: %lu", (unsigned long)master_pid);
-
+ /* null_fd expected to be more than 2, so it is closed after dups, no leaks occur */
+ /* coverity[leaked_handle : FALSE]*/
return;
}

View File

@ -0,0 +1,554 @@
diff -uPr cyrus-sasl-2.1.27/plugins/digestmd5.c cyrus-sasl-2.1.27.digestmd5/plugins/digestmd5.c
--- cyrus-sasl-2.1.27/plugins/digestmd5.c 2021-09-30 17:13:06.573093526 -0400
+++ cyrus-sasl-2.1.27.digestmd5/plugins/digestmd5.c 2021-09-30 17:26:31.818378442 -0400
@@ -80,6 +80,12 @@
# endif
#endif /* WITH_DES */
+/* legacy provider with openssl 3.0 */
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+# include <openssl/provider.h>
+# include <openssl/crypto.h>
+#endif
+
#ifdef WIN32
# include <winsock2.h>
#else /* Unix */
@@ -170,6 +176,12 @@
typedef struct cipher_context cipher_context_t;
+typedef struct crypto_context {
+ void *libctx;
+ cipher_context_t *enc_ctx;
+ cipher_context_t *dec_ctx;
+} crypto_context_t;
+
/* cached auth info used for fast reauth */
typedef struct reauth_entry {
char *authid;
@@ -254,12 +266,12 @@
decode_context_t decode_context;
/* if privacy mode is used use these functions for encode and decode */
+ char *cipher_name;
cipher_function_t *cipher_enc;
cipher_function_t *cipher_dec;
cipher_init_t *cipher_init;
cipher_free_t *cipher_free;
- struct cipher_context *cipher_enc_context;
- struct cipher_context *cipher_dec_context;
+ crypto_context_t crypto;
} context_t;
struct digest_cipher {
@@ -888,7 +900,7 @@
char *output,
unsigned *outputlen)
{
- des_context_t *c = (des_context_t *) text->cipher_dec_context;
+ des_context_t *c = (des_context_t *) text->crypto.dec_ctx;
int padding, p;
des_ede2_cbc_encrypt((void *) input,
@@ -925,7 +937,7 @@
char *output,
unsigned *outputlen)
{
- des_context_t *c = (des_context_t *) text->cipher_enc_context;
+ des_context_t *c = (des_context_t *) text->crypto.enc_ctx;
int len;
int paddinglen;
@@ -973,7 +985,7 @@
return SASL_FAIL;
memcpy(c->ivec, ((char *) enckey) + 8, 8);
- text->cipher_enc_context = (cipher_context_t *) c;
+ text->crypto.enc_ctx = (cipher_context_t *) c;
/* setup dec context */
c++;
@@ -987,7 +999,7 @@
memcpy(c->ivec, ((char *) deckey) + 8, 8);
- text->cipher_dec_context = (cipher_context_t *) c;
+ text->crypto.dec_ctx = (cipher_context_t *) c;
return SASL_OK;
}
@@ -1006,7 +1018,7 @@
char *output,
unsigned *outputlen)
{
- des_context_t *c = (des_context_t *) text->cipher_dec_context;
+ des_context_t *c = (des_context_t *) text->crypto.dec_ctx;
int p, padding = 0;
des_cbc_encrypt((void *) input,
@@ -1046,7 +1058,7 @@
char *output,
unsigned *outputlen)
{
- des_context_t *c = (des_context_t *) text->cipher_enc_context;
+ des_context_t *c = (des_context_t *) text->crypto.enc_ctx;
int len;
int paddinglen;
@@ -1093,7 +1105,7 @@
memcpy(c->ivec, ((char *) enckey) + 8, 8);
- text->cipher_enc_context = (cipher_context_t *) c;
+ text->crypto.enc_ctx = (cipher_context_t *) c;
/* setup dec context */
c++;
@@ -1102,60 +1114,143 @@
memcpy(c->ivec, ((char *) deckey) + 8, 8);
- text->cipher_dec_context = (cipher_context_t *) c;
+ text->crypto.dec_ctx = (cipher_context_t *) c;
return SASL_OK;
}
static void free_des(context_t *text)
{
- /* free des contextss. only cipher_enc_context needs to be free'd,
- since cipher_dec_context was allocated at the same time. */
- if (text->cipher_enc_context) text->utils->free(text->cipher_enc_context);
+ /* free des contextss. only enc_ctx needs to be free'd,
+ since dec_cxt was allocated at the same time. */
+ if (text->crypto.enc_ctx) {
+ text->utils->free(text->crypto.enc_ctx);
+ }
}
#endif /* WITH_DES */
#ifdef WITH_RC4
-#ifdef HAVE_OPENSSL
#include <openssl/evp.h>
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+typedef struct ossl3_library_context {
+ OSSL_LIB_CTX *libctx;
+ OSSL_PROVIDER *legacy_provider;
+ OSSL_PROVIDER *default_provider;
+} ossl3_context_t;
+
+static int init_ossl3_ctx(context_t *text)
+{
+ ossl3_context_t *ctx = text->utils->malloc(sizeof(ossl3_context_t));
+ if (!ctx) return SASL_NOMEM;
+
+ ctx->libctx = OSSL_LIB_CTX_new();
+ if (!ctx->libctx) {
+ text->utils->free(ctx);
+ return SASL_FAIL;
+ }
+
+ /* Load both legacy and default provider as both may be needed */
+ /* if they fail keep going and an error will be raised when we try to
+ * fetch the cipher later */
+ ctx->legacy_provider = OSSL_PROVIDER_load(ctx->libctx, "legacy");
+ ctx->default_provider = OSSL_PROVIDER_load(ctx->libctx, "default");
+ text->crypto.libctx = (void *)ctx;
+
+ return SASL_OK;
+}
+
+static void free_ossl3_ctx(context_t *text)
+{
+ ossl3_context_t *ctx;
+
+ if (!text->crypto.libctx) return;
+
+ ctx = (ossl3_context_t *)text->crypto.libctx;
+
+ if (ctx->legacy_provider) OSSL_PROVIDER_unload(ctx->legacy_provider);
+ if (ctx->default_provider) OSSL_PROVIDER_unload(ctx->default_provider);
+ if (ctx->libctx) OSSL_LIB_CTX_free(ctx->libctx);
+
+ text->utils->free(ctx);
+ text->crypto.libctx = NULL;
+}
+#endif
+
static void free_rc4(context_t *text)
{
- if (text->cipher_enc_context) {
- EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *)text->cipher_enc_context);
- text->cipher_enc_context = NULL;
- }
- if (text->cipher_dec_context) {
- EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *)text->cipher_dec_context);
- text->cipher_dec_context = NULL;
+ if (text->crypto.enc_ctx) {
+ EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *)text->crypto.enc_ctx);
+ text->crypto.enc_ctx = NULL;
+ }
+ if (text->crypto.dec_ctx) {
+ EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *)text->crypto.dec_ctx);
+ text->crypto.dec_ctx = NULL;
}
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ free_ossl3_ctx(text);
+#endif
}
static int init_rc4(context_t *text,
unsigned char enckey[16],
unsigned char deckey[16])
{
EVP_CIPHER_CTX *ctx;
int rc;
- ctx = EVP_CIPHER_CTX_new();
- if (ctx == NULL) return SASL_NOMEM;
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ EVP_CIPHER *cipher;
+ ossl3_context_t *ossl3_ctx;
- rc = EVP_EncryptInit_ex(ctx, EVP_rc4(), NULL, enckey, NULL);
- if (rc != 1) return SASL_FAIL;
+ rc = init_ossl3_ctx(text);
+ if (rc != SASL_OK) return rc;
+
+ ossl3_ctx = (ossl3_context_t *)text->crypto.libctx;
+ cipher = EVP_CIPHER_fetch(ossl3_ctx->libctx, "RC4", "");
+#else
+ const EVP_CIPHER *cipher;
+ cipher = EVP_rc4();
+#endif
- text->cipher_enc_context = (void *)ctx;
ctx = EVP_CIPHER_CTX_new();
- if (ctx == NULL) return SASL_NOMEM;
+ if (ctx == NULL) {
+ rc = SASL_NOMEM;
+ goto done;
+ }
- rc = EVP_DecryptInit_ex(ctx, EVP_rc4(), NULL, deckey, NULL);
- if (rc != 1) return SASL_FAIL;
+ rc = EVP_EncryptInit_ex(ctx, cipher, NULL, enckey, NULL);
+ if (rc != 1) {
+ rc = SASL_FAIL;
+ goto done;
+ }
+ text->crypto.enc_ctx = (void *)ctx;
- text->cipher_dec_context = (void *)ctx;
+ ctx = EVP_CIPHER_CTX_new();
+ if (ctx == NULL) {
+ rc = SASL_NOMEM;
+ goto done;
+ }
- return SASL_OK;
+ rc = EVP_DecryptInit_ex(ctx, cipher, NULL, deckey, NULL);
+ if (rc != 1) {
+ rc = SASL_FAIL;
+ goto done;
+ }
+ text->crypto.dec_ctx = (void *)ctx;
+
+ rc = SASL_OK;
+
+done:
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ EVP_CIPHER_free(cipher);
+#endif
+ if (rc != SASL_OK) {
+ free_rc4(text);
+ }
+ return rc;
}
static int dec_rc4(context_t *text,
@@ -1169,14 +1260,14 @@
int rc;
/* decrypt the text part & HMAC */
- rc = EVP_DecryptUpdate((EVP_CIPHER_CTX *)text->cipher_dec_context,
+ rc = EVP_DecryptUpdate((EVP_CIPHER_CTX *)text->crypto.dec_ctx,
(unsigned char *)output, &len,
(const unsigned char *)input, inputlen);
if (rc != 1) return SASL_FAIL;
*outputlen = len;
- rc = EVP_DecryptFinal_ex((EVP_CIPHER_CTX *)text->cipher_dec_context,
+ rc = EVP_DecryptFinal_ex((EVP_CIPHER_CTX *)text->crypto.dec_ctx,
(unsigned char *)output + len, &len);
if (rc != 1) return SASL_FAIL;
@@ -1198,7 +1289,7 @@
int len;
int rc;
/* encrypt the text part */
- rc = EVP_EncryptUpdate((EVP_CIPHER_CTX *)text->cipher_enc_context,
+ rc = EVP_EncryptUpdate((EVP_CIPHER_CTX *)text->crypto.enc_ctx,
(unsigned char *)output, &len,
(const unsigned char *)input, inputlen);
if (rc != 1) return SASL_FAIL;
@@ -1206,14 +1297,14 @@
*outputlen = len;
/* encrypt the `MAC part */
- rc = EVP_EncryptUpdate((EVP_CIPHER_CTX *)text->cipher_enc_context,
+ rc = EVP_EncryptUpdate((EVP_CIPHER_CTX *)text->crypto.enc_ctx,
(unsigned char *)output + *outputlen, &len,
digest, 10);
if (rc != 1) return SASL_FAIL;
*outputlen += len;
- rc = EVP_EncryptFinal_ex((EVP_CIPHER_CTX *)text->cipher_enc_context,
+ rc = EVP_EncryptFinal_ex((EVP_CIPHER_CTX *)text->crypto.enc_ctx,
(unsigned char *)output + *outputlen, &len);
if (rc != 1) return SASL_FAIL;
@@ -1221,194 +1312,11 @@
return SASL_OK;
}
-#else
-/* quick generic implementation of RC4 */
-struct rc4_context_s {
- unsigned char sbox[256];
- int i, j;
-};
-
-typedef struct rc4_context_s rc4_context_t;
-
-static void rc4_init(rc4_context_t *text,
- const unsigned char *key,
- unsigned keylen)
-{
- int i, j;
-
- /* fill in linearly s0=0 s1=1... */
- for (i=0;i<256;i++)
- text->sbox[i]=i;
-
- j=0;
- for (i = 0; i < 256; i++) {
- unsigned char tmp;
- /* j = (j + Si + Ki) mod 256 */
- j = (j + text->sbox[i] + key[i % keylen]) % 256;
-
- /* swap Si and Sj */
- tmp = text->sbox[i];
- text->sbox[i] = text->sbox[j];
- text->sbox[j] = tmp;
- }
-
- /* counters initialized to 0 */
- text->i = 0;
- text->j = 0;
-}
-
-static void rc4_encrypt(rc4_context_t *text,
- const char *input,
- char *output,
- unsigned len)
-{
- int tmp;
- int i = text->i;
- int j = text->j;
- int t;
- int K;
- const char *input_end = input + len;
-
- while (input < input_end) {
- i = (i + 1) % 256;
-
- j = (j + text->sbox[i]) % 256;
-
- /* swap Si and Sj */
- tmp = text->sbox[i];
- text->sbox[i] = text->sbox[j];
- text->sbox[j] = tmp;
-
- t = (text->sbox[i] + text->sbox[j]) % 256;
-
- K = text->sbox[t];
-
- /* byte K is Xor'ed with plaintext */
- *output++ = *input++ ^ K;
- }
-
- text->i = i;
- text->j = j;
-}
-
-static void rc4_decrypt(rc4_context_t *text,
- const char *input,
- char *output,
- unsigned len)
-{
- int tmp;
- int i = text->i;
- int j = text->j;
- int t;
- int K;
- const char *input_end = input + len;
-
- while (input < input_end) {
- i = (i + 1) % 256;
-
- j = (j + text->sbox[i]) % 256;
-
- /* swap Si and Sj */
- tmp = text->sbox[i];
- text->sbox[i] = text->sbox[j];
- text->sbox[j] = tmp;
-
- t = (text->sbox[i] + text->sbox[j]) % 256;
-
- K = text->sbox[t];
-
- /* byte K is Xor'ed with plaintext */
- *output++ = *input++ ^ K;
- }
-
- text->i = i;
- text->j = j;
-}
-
-static void free_rc4(context_t *text)
-{
- /* free rc4 context structures */
-
- if (text->cipher_enc_context) {
- text->utils->free(text->cipher_enc_context);
- text->cipher_enc_context = NULL;
- }
- if (text->cipher_dec_context) {
- text->utils->free(text->cipher_dec_context);
- text->cipher_dec_context = NULL;
- }
-}
-
-static int init_rc4(context_t *text,
- unsigned char enckey[16],
- unsigned char deckey[16])
-{
- /* allocate rc4 context structures */
- text->cipher_enc_context=
- (cipher_context_t *) text->utils->malloc(sizeof(rc4_context_t));
- if (text->cipher_enc_context == NULL) return SASL_NOMEM;
-
- text->cipher_dec_context=
- (cipher_context_t *) text->utils->malloc(sizeof(rc4_context_t));
- if (text->cipher_dec_context == NULL) return SASL_NOMEM;
-
- /* initialize them */
- rc4_init((rc4_context_t *) text->cipher_enc_context,
- (const unsigned char *) enckey, 16);
- rc4_init((rc4_context_t *) text->cipher_dec_context,
- (const unsigned char *) deckey, 16);
-
- return SASL_OK;
-}
-
-static int dec_rc4(context_t *text,
- const char *input,
- unsigned inputlen,
- unsigned char digest[16] __attribute__((unused)),
- char *output,
- unsigned *outputlen)
-{
- /* decrypt the text part & HMAC */
- rc4_decrypt((rc4_context_t *) text->cipher_dec_context,
- input, output, inputlen);
-
- /* no padding so we just subtract the HMAC to get the text length */
- *outputlen = inputlen - 10;
-
- return SASL_OK;
-}
-
-static int enc_rc4(context_t *text,
- const char *input,
- unsigned inputlen,
- unsigned char digest[16],
- char *output,
- unsigned *outputlen)
-{
- /* pad is zero */
- *outputlen = inputlen+10;
-
- /* encrypt the text part */
- rc4_encrypt((rc4_context_t *) text->cipher_enc_context,
- input,
- output,
- inputlen);
-
- /* encrypt the HMAC part */
- rc4_encrypt((rc4_context_t *) text->cipher_enc_context,
- (const char *) digest,
- (output)+inputlen, 10);
-
- return SASL_OK;
-}
-#endif /* HAVE_OPENSSL */
#endif /* WITH_RC4 */
struct digest_cipher available_ciphers[] =
{
#ifdef WITH_RC4
- { "rc4-40", 40, 5, 0x01, &enc_rc4, &dec_rc4, &init_rc4, &free_rc4 },
- { "rc4-56", 56, 7, 0x02, &enc_rc4, &dec_rc4, &init_rc4, &free_rc4 },
{ "rc4", 128, 16, 0x04, &enc_rc4, &dec_rc4, &init_rc4, &free_rc4 },
#endif
#ifdef WITH_DES
@@ -2815,6 +2729,7 @@
}
if (cptr->name) {
+ text->cipher_name = cptr->name;
text->cipher_enc = cptr->cipher_enc;
text->cipher_dec = cptr->cipher_dec;
text->cipher_init = cptr->cipher_init;
@@ -2958,7 +2873,10 @@
if (text->cipher_init) {
if (text->cipher_init(text, enckey, deckey) != SASL_OK) {
sparams->utils->seterror(sparams->utils->conn, 0,
- "couldn't init cipher");
+ "couldn't init cipher '%s'",
+ text->cipher_name);
+ result = SASL_FAIL;
+ goto FreeAllMem;
}
}
}
@@ -3509,6 +3427,7 @@
oparams->mech_ssf = ctext->cipher->ssf;
nbits = ctext->cipher->n;
+ text->cipher_name = ctext->cipher->name;
text->cipher_enc = ctext->cipher->cipher_enc;
text->cipher_dec = ctext->cipher->cipher_dec;
text->cipher_free = ctext->cipher->cipher_free;
@@ -3733,7 +3652,13 @@
/* initialize cipher if need be */
if (text->cipher_init) {
- text->cipher_init(text, enckey, deckey);
+ if (text->cipher_init(text, enckey, deckey) != SASL_OK) {
+ params->utils->seterror(params->utils->conn, 0,
+ "internal error: failed to init cipher '%s'",
+ text->cipher_name);
+ result = SASL_FAIL;
+ goto FreeAllocatedMem;
+ }
}
}

View File

@ -0,0 +1,109 @@
diff -uPr cyrus-sasl-2.1.27/configure.ac cyrus-sasl-2.1.27.ossl3/configure.ac
--- cyrus-sasl-2.1.27/configure.ac 2021-10-06 11:29:53.274375206 -0400
+++ cyrus-sasl-2.1.27.ossl3/configure.ac 2021-10-06 11:31:19.966726775 -0400
@@ -1115,7 +1115,11 @@
with_rc4=yes)
if test "$with_rc4" != no; then
- AC_DEFINE(WITH_RC4,[],[Use RC4])
+ if test "$with_openssl" = no; then
+ AC_WARN([OpenSSL not found -- RC4 will be disabled])
+ else
+ AC_DEFINE(WITH_RC4,[],[Use RC4])
+ fi
fi
building_for_macosx=no
diff -uPr cyrus-sasl-2.1.27/plugins/scram.c cyrus-sasl-2.1.27.ossl3/plugins/scram.c
--- cyrus-sasl-2.1.27/plugins/scram.c 2018-11-08 12:29:57.000000000 -0500
+++ cyrus-sasl-2.1.27.ossl3/plugins/scram.c 2021-10-06 11:31:04.407484201 -0400
@@ -65,7 +65,9 @@
#include <openssl/sha.h>
#include <openssl/evp.h>
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
#include <openssl/hmac.h>
+#endif
/***************************** Common Section *****************************/
@@ -291,6 +293,32 @@
}
#endif
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+
+/* Decalre as void given functions never use the result */
+void *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
+ const unsigned char *data, size_t data_len,
+ unsigned char *md, unsigned int *md_len)
+{
+ const char *digest;
+ size_t digest_size;
+ size_t out_len;
+ void *ret = NULL;
+
+ digest = EVP_MD_get0_name(evp_md);
+ if (digest == NULL) {
+ return NULL;
+ }
+ digest_size = EVP_MD_size(evp_md);
+
+ ret = EVP_Q_mac(NULL, "hmac", NULL, digest, NULL, key, key_len,
+ data, data_len, md, digest_size, &out_len);
+ if (ret != NULL) {
+ *md_len = (unsigned int)out_len;
+ }
+ return ret;
+}
+#endif
/* The result variable need to point to a buffer big enough for the [SHA-*] hash */
static void
diff -uPr cyrus-sasl-2.1.27/saslauthd/lak.c cyrus-sasl-2.1.27.ossl3/saslauthd/lak.c
--- cyrus-sasl-2.1.27/saslauthd/lak.c 2022-01-09 11:30:50.000000000 -0400
+++ cyrus-sasl-2.1.27.ossl3/saslauthd/lak.c 2022-01-09 11:30:50.000000001 -0400
@@ -1806,18 +1806,36 @@
return rc;
}
- EVP_DigestInit(mdctx, md);
- EVP_DigestUpdate(mdctx, passwd, strlen(passwd));
+ rc = EVP_DigestInit(mdctx, md);
+ if (rc != 1) {
+ rc = LAK_FAIL;
+ goto done;
+ }
+ rc = EVP_DigestUpdate(mdctx, passwd, strlen(passwd));
+ if (rc != 1) {
+ rc = LAK_FAIL;
+ goto done;
+ }
if (hrock->salted) {
- EVP_DigestUpdate(mdctx, &cred[EVP_MD_size(md)],
- clen - EVP_MD_size(md));
+ rc = EVP_DigestUpdate(mdctx, &cred[EVP_MD_size(md)],
+ clen - EVP_MD_size(md));
+ if (rc != 1) {
+ rc = LAK_FAIL;
+ goto done;
+ }
+ }
+ rc = EVP_DigestFinal(mdctx, digest, NULL);
+ if (rc != 1) {
+ rc = LAK_FAIL;
+ goto done;
}
- EVP_DigestFinal(mdctx, digest, NULL);
- EVP_MD_CTX_free(mdctx);
rc = memcmp((char *)cred, (char *)digest, EVP_MD_size(md));
+ rc = rc ? LAK_INVALID_PASSWORD : LAK_OK;
+done:
+ EVP_MD_CTX_free(mdctx);
free(cred);
- return rc ? LAK_INVALID_PASSWORD : LAK_OK;
+ return rc;
}
#endif /* HAVE_OPENSSL */

View File

@ -0,0 +1,761 @@
From 10ac4d4822023b24734acde3c07186937ad52813 Mon Sep 17 00:00:00 2001
From: Dmitry Belyavskiy <beldmit@gmail.com>
Date: Wed, 6 Jan 2021 12:38:46 +0100
Subject: [PATCH] Some basic PLAIN auth tests
Signed-off-by: Dmitry Belyavskiy <beldmit@gmail.com>
---
tests/runtests.py | 91 +++++++++++++++++++++++++++++++++++++++++
tests/t_gssapi_cli.c | 97 +++++++++++++++++++++++++++++++++++++++-----
tests/t_gssapi_srv.c | 78 +++++++++++++++++++++++++++--------
3 files changed, 239 insertions(+), 27 deletions(-)
diff --git a/tests/runtests.py b/tests/runtests.py
index fc9cf244..513ed3ff 100755
--- a/tests/runtests.py
+++ b/tests/runtests.py
@@ -239,6 +239,96 @@ def gssapi_tests(testdir):
os.killpg(kdc.pid, signal.SIGTERM)
+def setup_plain(testdir):
+ """ Create sasldb file """
+ sasldbfile = os.path.join(testdir, 'testsasldb.db')
+
+ sasldbenv = {'SASL_PATH': os.path.join(testdir, '../../plugins/.libs'),
+ 'LD_LIBRARY_PATH' : os.path.join(testdir, '../../lib/.libs')}
+
+ passwdprog = os.path.join(testdir, '../../utils/saslpasswd2')
+
+ echo = subprocess.Popen(('echo', '1234567'), stdout=subprocess.PIPE)
+ subprocess.check_call([
+ passwdprog, "-f", sasldbfile, "-c", "test",
+ "-u", "host.realm.test", "-p"
+ ], stdin=echo.stdout, env=sasldbenv, timeout=5)
+
+ return (sasldbfile, sasldbenv)
+
+def plain_test(sasldbfile, sasldbenv):
+ try:
+ srv = subprocess.Popen(["../tests/t_gssapi_srv", "-P", sasldbfile],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=sasldbenv)
+ srv.stdout.readline() # Wait for srv to say it is ready
+ cli = subprocess.Popen(["../tests/t_gssapi_cli", "-P", "1234567"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=sasldbenv)
+ try:
+ cli.wait(timeout=5)
+ srv.wait(timeout=5)
+ except Exception as e:
+ print("Failed on {}".format(e));
+ cli.kill()
+ srv.kill()
+ if cli.returncode != 0 or srv.returncode != 0:
+ raise Exception("CLI ({}): {} --> SRV ({}): {}".format(
+ cli.returncode, cli.stderr.read().decode('utf-8'),
+ srv.returncode, srv.stderr.read().decode('utf-8')))
+ except Exception as e:
+ print("FAIL: {}".format(e))
+ return
+
+ print("PASS: PLAIN CLI({}) SRV({})".format(
+ cli.stdout.read().decode('utf-8').strip(),
+ srv.stdout.read().decode('utf-8').strip()))
+ return
+
+def plain_mismatch_test(sasldbfile, sasldbenv):
+ result = "FAIL"
+ try:
+ srv = subprocess.Popen(["../tests/t_gssapi_srv", "-P", sasldbfile],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=sasldbenv)
+ srv.stdout.readline() # Wait for srv to say it is ready
+ bindings = base64.b64encode("CLI CBS".encode('utf-8'))
+ cli = subprocess.Popen(["../tests/t_gssapi_cli", "-P", "12345678"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=sasldbenv)
+ try:
+ cli.wait(timeout=5)
+ srv.wait(timeout=5)
+ except Exception as e:
+ print("Failed on {}".format(e));
+ cli.kill()
+ srv.kill()
+ if cli.returncode != 0 or srv.returncode != 0:
+ cli_err = cli.stderr.read().decode('utf-8').strip()
+ srv_err = srv.stderr.read().decode('utf-8').strip()
+ if "authentication failure" in srv_err:
+ result = "PASS"
+ raise Exception("CLI ({}): {} --> SRV ({}): {}".format(
+ cli.returncode, cli_err, srv.returncode, srv_err))
+ except Exception as e:
+ print("{}: {}".format(result, e))
+ return
+
+ print("FAIL: This test should fail [CLI({}) SRV({})]".format(
+ cli.stdout.read().decode('utf-8').strip(),
+ srv.stdout.read().decode('utf-8').strip()))
+ return
+
+def plain_tests(testdir):
+ sasldbfile, sasldbenv = setup_plain(testdir)
+ #print("DB file: {}, ENV: {}".format(sasldbfile, sasldbenv))
+ print('SASLDB PLAIN:')
+ print(' ', end='')
+ plain_test(sasldbfile, sasldbenv)
+
+ print('SASLDB PLAIN PASSWORD MISMATCH:')
+ print(' ', end='')
+ plain_mismatch_test(sasldbfile, sasldbenv)
if __name__ == "__main__":
@@ -254,3 +344,4 @@ def gssapi_tests(testdir):
os.makedirs(T)
gssapi_tests(T)
+ plain_tests(T)
diff --git a/tests/t_gssapi_cli.c b/tests/t_gssapi_cli.c
index a44a3f58..20d22070 100644
--- a/tests/t_gssapi_cli.c
+++ b/tests/t_gssapi_cli.c
@@ -16,6 +16,8 @@
#include <saslplug.h>
#include <saslutil.h>
+const char *testpass = NULL;
+
static int setup_socket(void)
{
struct sockaddr_in addr;
@@ -34,9 +36,60 @@ static int setup_socket(void)
return sock;
}
+static int get_user(void *context __attribute__((unused)),
+ int id,
+ const char **result,
+ unsigned *len)
+{
+ const char *testuser = "test@host.realm.test";
+
+ if (! result)
+ return SASL_BADPARAM;
+
+ switch (id) {
+ case SASL_CB_USER:
+ case SASL_CB_AUTHNAME:
+ *result = testuser;
+ break;
+ default:
+ return SASL_BADPARAM;
+ }
+
+ if (len) *len = strlen(*result);
+
+ return SASL_OK;
+}
+
+static int get_pass(sasl_conn_t *conn __attribute__((unused)),
+ void *context __attribute__((unused)),
+ int id,
+ sasl_secret_t **psecret)
+{
+ size_t len;
+ static sasl_secret_t *x;
+
+ /* paranoia check */
+ if (! conn || ! psecret || id != SASL_CB_PASS)
+ return SASL_BADPARAM;
+
+ len = strlen(testpass);
+
+ x = (sasl_secret_t *) realloc(x, sizeof(sasl_secret_t) + len);
+
+ if (!x) {
+ return SASL_NOMEM;
+ }
+
+ x->len = len;
+ strcpy((char *)x->data, testpass);
+
+ *psecret = x;
+ return SASL_OK;
+}
+
int main(int argc, char *argv[])
{
- sasl_callback_t callbacks[2] = {};
+ sasl_callback_t callbacks[4] = {};
char buf[8192];
const char *chosenmech;
sasl_conn_t *conn;
@@ -46,12 +99,18 @@ int main(int argc, char *argv[])
char cb_buf[256];
int sd;
int c, r;
+ const char *sasl_mech = "GSSAPI";
+ int plain = 0;
- while ((c = getopt(argc, argv, "c:")) != EOF) {
+ while ((c = getopt(argc, argv, "c:P:")) != EOF) {
switch (c) {
case 'c':
parse_cb(&cb, cb_buf, 256, optarg);
break;
+ case 'P':
+ plain = 1;
+ testpass = optarg;
+ break;
default:
break;
}
@@ -64,6 +123,22 @@ int main(int argc, char *argv[])
callbacks[1].id = SASL_CB_LIST_END;
callbacks[1].proc = NULL;
callbacks[1].context = NULL;
+ callbacks[2].id = SASL_CB_LIST_END;
+ callbacks[2].proc = NULL;
+ callbacks[2].context = NULL;
+ callbacks[3].id = SASL_CB_LIST_END;
+ callbacks[3].proc = NULL;
+ callbacks[3].context = NULL;
+
+ if (plain) {
+ sasl_mech = "PLAIN";
+
+ callbacks[1].id = SASL_CB_AUTHNAME;
+ callbacks[1].proc = (sasl_callback_ft)&get_user;
+
+ callbacks[2].id = SASL_CB_PASS;
+ callbacks[2].proc = (sasl_callback_ft)&get_pass;
+ }
r = sasl_client_init(callbacks);
if (r != SASL_OK) exit(-1);
@@ -78,11 +153,11 @@ int main(int argc, char *argv[])
sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb);
}
- r = sasl_client_start(conn, "GSSAPI", NULL, &data, &len, &chosenmech);
+ r = sasl_client_start(conn, sasl_mech, NULL, &data, &len, &chosenmech);
if (r != SASL_OK && r != SASL_CONTINUE) {
- saslerr(r, "starting SASL negotiation");
- printf("\n%s\n", sasl_errdetail(conn));
- exit(-1);
+ saslerr(r, "starting SASL negotiation");
+ printf("\n%s\n", sasl_errdetail(conn));
+ exit(-1);
}
sd = setup_socket();
@@ -92,11 +167,11 @@ int main(int argc, char *argv[])
len = 8192;
recv_string(sd, buf, &len);
- r = sasl_client_step(conn, buf, len, NULL, &data, &len);
- if (r != SASL_OK && r != SASL_CONTINUE) {
- saslerr(r, "performing SASL negotiation");
- printf("\n%s\n", sasl_errdetail(conn));
- exit(-1);
+ r = sasl_client_step(conn, buf, len, NULL, &data, &len);
+ if (r != SASL_OK && r != SASL_CONTINUE) {
+ saslerr(r, "performing SASL negotiation");
+ printf("\n%s\n", sasl_errdetail(conn));
+ exit(-1);
}
}
diff --git a/tests/t_gssapi_srv.c b/tests/t_gssapi_srv.c
index ef1217f6..430cad65 100644
--- a/tests/t_gssapi_srv.c
+++ b/tests/t_gssapi_srv.c
@@ -1,4 +1,5 @@
-/* Copyright (C) Simo Sorce <simo@redhat.com>
+/* Copyright (C) Simo Sorce <simo@redhat.com>,
+ * Dmitry Belyavskiy <dbelyavs@redhat.com>
* See COPYING file for License */
#include "t_common.h"
@@ -15,6 +16,10 @@
#include <arpa/inet.h>
#include <saslplug.h>
+const char *sasldb_path = NULL,
+ *auxprop_plugin = "sasldb",
+ *pwcheck_method = "auxprop-hashed";
+
static int setup_socket(void)
{
struct sockaddr_in addr;
@@ -45,9 +50,38 @@ static int setup_socket(void)
return sd;
}
+static int test_getopt(void *context __attribute__((unused)),
+ const char *plugin_name __attribute__((unused)),
+ const char *option,
+ const char **result,
+ unsigned *len)
+{
+ if (sasldb_path && !strcmp(option, "sasldb_path")) {
+ *result = sasldb_path;
+ if (len)
+ *len = (unsigned) strlen(sasldb_path);
+ return SASL_OK;
+ }
+
+ if (sasldb_path && !strcmp(option, "auxprop_plugin")) {
+ *result = auxprop_plugin;
+ if (len)
+ *len = (unsigned) strlen(auxprop_plugin);
+ return SASL_OK;
+ }
+
+ if (sasldb_path && !strcmp(option, "pwcheck_method")) {
+ *result = pwcheck_method;
+ if (len)
+ *len = (unsigned) strlen(pwcheck_method);
+ return SASL_OK;
+ }
+ return SASL_FAIL;
+}
+
int main(int argc, char *argv[])
{
- sasl_callback_t callbacks[2] = {};
+ sasl_callback_t callbacks[3] = {};
char buf[8192];
sasl_conn_t *conn;
const char *data;
@@ -56,25 +90,33 @@ int main(int argc, char *argv[])
unsigned char cb_buf[256];
int sd;
int c, r;
+ const char *sasl_mech = "GSSAPI";
+ int plain = 0;
- while ((c = getopt(argc, argv, "c:")) != EOF) {
+ while ((c = getopt(argc, argv, "c:P:")) != EOF) {
switch (c) {
case 'c':
parse_cb(&cb, cb_buf, 256, optarg);
break;
+ case 'P':
+ plain = 1;
+ sasldb_path = optarg;
+ break;
default:
break;
}
}
-
/* initialize the sasl library */
callbacks[0].id = SASL_CB_GETPATH;
callbacks[0].proc = (sasl_callback_ft)&getpath;
callbacks[0].context = NULL;
- callbacks[1].id = SASL_CB_LIST_END;
- callbacks[1].proc = NULL;
+ callbacks[1].id = SASL_CB_GETOPT;
+ callbacks[1].proc = (sasl_callback_ft)&test_getopt;
callbacks[1].context = NULL;
+ callbacks[2].id = SASL_CB_LIST_END;
+ callbacks[2].proc = NULL;
+ callbacks[2].context = NULL;
r = sasl_server_init(callbacks, "t_gssapi_srv");
if (r != SASL_OK) exit(-1);
@@ -90,16 +132,20 @@ int main(int argc, char *argv[])
sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb);
}
+ if (plain) {
+ sasl_mech = "PLAIN";
+ }
+
sd = setup_socket();
len = 8192;
recv_string(sd, buf, &len);
- r = sasl_server_start(conn, "GSSAPI", buf, len, &data, &len);
+ r = sasl_server_start(conn, sasl_mech, buf, len, &data, &len);
if (r != SASL_OK && r != SASL_CONTINUE) {
- saslerr(r, "starting SASL negotiation");
- printf("\n%s\n", sasl_errdetail(conn));
- exit(-1);
+ saslerr(r, "starting SASL negotiation");
+ printf("\n%s\n", sasl_errdetail(conn));
+ exit(-1);
}
while (r == SASL_CONTINUE) {
@@ -107,12 +153,12 @@ int main(int argc, char *argv[])
len = 8192;
recv_string(sd, buf, &len);
- r = sasl_server_step(conn, buf, len, &data, &len);
- if (r != SASL_OK && r != SASL_CONTINUE) {
- saslerr(r, "performing SASL negotiation");
- printf("\n%s\n", sasl_errdetail(conn));
- exit(-1);
- }
+ r = sasl_server_step(conn, buf, len, &data, &len);
+ if (r != SASL_OK && r != SASL_CONTINUE) {
+ saslerr(r, "performing SASL negotiation");
+ printf("\n%s\n", sasl_errdetail(conn));
+ exit(-1);
+ }
}
From d95b0afef1289194148090874799428e9e4f4cff Mon Sep 17 00:00:00 2001
From: Simo Sorce <idra@samba.org>
Date: Wed, 15 Apr 2020 11:57:17 -0400
Subject: [PATCH] Test GSS-SPNEGO as well
Signed-off-by: Simo Sorce <simo@redhat.com>
---
tests/runtests.py | 91 ++++++++++++++++++++++++++++++++++++++++----
tests/t_common.c | 13 ++++---
tests/t_common.h | 3 +-
tests/t_gssapi_cli.c | 22 ++++++++++-
tests/t_gssapi_srv.c | 25 ++++++++++--
5 files changed, 134 insertions(+), 20 deletions(-)
diff --git a/tests/runtests.py b/tests/runtests.py
index 513ed3ff..7be60745 100755
--- a/tests/runtests.py
+++ b/tests/runtests.py
@@ -6,6 +6,7 @@
import shutil
import signal
import subprocess
+import sys
import time
from string import Template
@@ -149,11 +150,12 @@ def gssapi_basic_test(kenv):
srv.returncode, srv.stderr.read().decode('utf-8')))
except Exception as e:
print("FAIL: {}".format(e))
- return
+ return 1
print("PASS: CLI({}) SRV({})".format(
cli.stdout.read().decode('utf-8').strip(),
srv.stdout.read().decode('utf-8').strip()))
+ return 0
def gssapi_channel_binding_test(kenv):
try:
@@ -178,11 +180,12 @@ def gssapi_channel_binding_test(kenv):
srv.returncode, srv.stderr.read().decode('utf-8')))
except Exception as e:
print("FAIL: {}".format(e))
- return
+ return 1
print("PASS: CLI({}) SRV({})".format(
cli.stdout.read().decode('utf-8').strip(),
srv.stdout.read().decode('utf-8').strip()))
+ return 0
def gssapi_channel_binding_mismatch_test(kenv):
result = "FAIL"
@@ -212,11 +215,70 @@ def gssapi_channel_binding_mismatch_test(kenv):
cli.returncode, cli_err, srv.returncode, srv_err))
except Exception as e:
print("{}: {}".format(result, e))
- return
+ return 0
print("FAIL: This test should fail [CLI({}) SRV({})]".format(
cli.stdout.read().decode('utf-8').strip(),
srv.stdout.read().decode('utf-8').strip()))
+ return 1
+
+def gss_spnego_basic_test(kenv):
+ try:
+ srv = subprocess.Popen(["../tests/t_gssapi_srv", "-N"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=kenv)
+ srv.stdout.readline() # Wait for srv to say it is ready
+ cli = subprocess.Popen(["../tests/t_gssapi_cli", "-N"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=kenv)
+ try:
+ cli.wait(timeout=5)
+ srv.wait(timeout=5)
+ except Exception as e:
+ print("Failed on {}".format(e));
+ cli.kill()
+ srv.kill()
+ if cli.returncode != 0 or srv.returncode != 0:
+ raise Exception("CLI ({}): {} --> SRV ({}): {}".format(
+ cli.returncode, cli.stderr.read().decode('utf-8'),
+ srv.returncode, srv.stderr.read().decode('utf-8')))
+ except Exception as e:
+ print("FAIL: {}".format(e))
+ return 1
+
+ print("PASS: CLI({}) SRV({})".format(
+ cli.stdout.read().decode('utf-8').strip(),
+ srv.stdout.read().decode('utf-8').strip()))
+ return 0
+
+def gss_spnego_zeromaxssf_test(kenv):
+ try:
+ srv = subprocess.Popen(["../tests/t_gssapi_srv", "-N", "-z"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=kenv)
+ srv.stdout.readline() # Wait for srv to say it is ready
+ cli = subprocess.Popen(["../tests/t_gssapi_cli", "-N", "-z"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=kenv)
+ try:
+ cli.wait(timeout=5)
+ srv.wait(timeout=5)
+ except Exception as e:
+ print("Failed on {}".format(e));
+ cli.kill()
+ srv.kill()
+ if cli.returncode != 0 or srv.returncode != 0:
+ raise Exception("CLI ({}): {} --> SRV ({}): {}".format(
+ cli.returncode, cli.stderr.read().decode('utf-8'),
+ srv.returncode, srv.stderr.read().decode('utf-8')))
+ except Exception as e:
+ print("FAIL: {}".format(e))
+ return 1
+
+ print("PASS: CLI({}) SRV({})".format(
+ cli.stdout.read().decode('utf-8').strip(),
+ srv.stdout.read().decode('utf-8').strip()))
+ return 0
def gssapi_tests(testdir):
""" SASL/GSSAPI Tests """
@@ -225,19 +287,30 @@ def gssapi_tests(testdir):
#print("KDC: {}, ENV: {}".format(kdc, kenv))
kenv['KRB5_TRACE'] = os.path.join(testdir, 'trace.log')
+ err = 0
+
print('GSSAPI BASIC:')
print(' ', end='')
- gssapi_basic_test(kenv)
+ err += gssapi_basic_test(kenv)
print('GSSAPI CHANNEL BINDING:')
print(' ', end='')
- gssapi_channel_binding_test(kenv)
+ err += gssapi_channel_binding_test(kenv)
print('GSSAPI CHANNEL BINDING MISMTACH:')
print(' ', end='')
- gssapi_channel_binding_mismatch_test(kenv)
+ err += gssapi_channel_binding_mismatch_test(kenv)
+
+ print('GSS-SPNEGO BASIC:')
+ print(' ', end='')
+ err += gss_spnego_basic_test(kenv)
+
+ print('GSS-SPNEGO 0 MAXSSF:')
+ print(' ', end='')
+ err += gss_spnego_zeromaxssf_test(kenv)
os.killpg(kdc.pid, signal.SIGTERM)
+ return err
def setup_plain(testdir):
""" Create sasldb file """
@@ -343,5 +416,9 @@ def plain_tests(testdir):
shutil.rmtree(T)
os.makedirs(T)
- gssapi_tests(T)
plain_tests(T)
+
+ err = gssapi_tests(T)
+ if err != 0:
+ print('{} test(s) FAILED'.format(err))
+ sys.exit(-1)
diff --git a/tests/t_common.c b/tests/t_common.c
index 478e6a1f..f56098ef 100644
--- a/tests/t_common.c
+++ b/tests/t_common.c
@@ -23,20 +23,21 @@ void send_string(int sd, const char *s, unsigned int l)
if (ret != l) s_error("send data", ret, l, errno);
}
-void recv_string(int sd, char *buf, unsigned int *buflen)
+void recv_string(int sd, char *buf, unsigned int *buflen, bool allow_eof)
{
+ unsigned int bufsize = *buflen;
unsigned int l;
ssize_t ret;
+ *buflen = 0;
+
ret = recv(sd, &l, sizeof(l), MSG_WAITALL);
+ if (allow_eof && ret == 0) return;
if (ret != sizeof(l)) s_error("recv size", ret, sizeof(l), errno);
- if (l == 0) {
- *buflen = 0;
- return;
- }
+ if (l == 0) return;
- if (*buflen < l) s_error("recv len", l, *buflen, E2BIG);
+ if (bufsize < l) s_error("recv len", l, bufsize, E2BIG);
ret = recv(sd, buf, l, 0);
if (ret != l) s_error("recv data", ret, l, errno);
diff --git a/tests/t_common.h b/tests/t_common.h
index a10def17..be24a53d 100644
--- a/tests/t_common.h
+++ b/tests/t_common.h
@@ -4,6 +4,7 @@
#include "config.h"
#include <errno.h>
+#include <stdbool.h>
#include <stdio.h>
#include <sys/socket.h>
@@ -12,7 +13,7 @@
void s_error(const char *hdr, ssize_t ret, ssize_t len, int err);
void send_string(int sd, const char *s, unsigned int l);
-void recv_string(int sd, char *buf, unsigned int *buflen);
+void recv_string(int sd, char *buf, unsigned int *buflen, bool allow_eof);
void saslerr(int why, const char *what);
int getpath(void *context __attribute__((unused)), const char **path);
void parse_cb(sasl_channel_binding_t *cb, char *buf, unsigned max, char *in);
diff --git a/tests/t_gssapi_cli.c b/tests/t_gssapi_cli.c
index 20d22070..b1dd6ce0 100644
--- a/tests/t_gssapi_cli.c
+++ b/tests/t_gssapi_cli.c
@@ -101,8 +101,10 @@ int main(int argc, char *argv[])
int c, r;
const char *sasl_mech = "GSSAPI";
int plain = 0;
+ bool spnego = false;
+ bool zeromaxssf = false;
- while ((c = getopt(argc, argv, "c:P:")) != EOF) {
+ while ((c = getopt(argc, argv, "c:P:zN")) != EOF) {
switch (c) {
case 'c':
parse_cb(&cb, cb_buf, 256, optarg);
@@ -111,6 +113,12 @@ int main(int argc, char *argv[])
plain = 1;
testpass = optarg;
break;
+ case 'z':
+ zeromaxssf = true;
+ break;
+ case 'N':
+ spnego = true;
+ break;
default:
break;
}
@@ -153,6 +161,16 @@ int main(int argc, char *argv[])
sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb);
}
+ if (spnego) {
+ sasl_mech = "GSS-SPNEGO";
+ }
+
+ if (zeromaxssf) {
+ /* set all security properties to 0 including maxssf */
+ sasl_security_properties_t secprops = { 0 };
+ sasl_setprop(conn, SASL_SEC_PROPS, &secprops);
+ }
+
r = sasl_client_start(conn, sasl_mech, NULL, &data, &len, &chosenmech);
if (r != SASL_OK && r != SASL_CONTINUE) {
saslerr(r, "starting SASL negotiation");
@@ -165,7 +183,7 @@ int main(int argc, char *argv[])
while (r == SASL_CONTINUE) {
send_string(sd, data, len);
len = 8192;
- recv_string(sd, buf, &len);
+ recv_string(sd, buf, &len, false);
r = sasl_client_step(conn, buf, len, NULL, &data, &len);
if (r != SASL_OK && r != SASL_CONTINUE) {
diff --git a/tests/t_gssapi_srv.c b/tests/t_gssapi_srv.c
index 430cad65..0adbd12f 100644
--- a/tests/t_gssapi_srv.c
+++ b/tests/t_gssapi_srv.c
@@ -92,8 +92,10 @@ int main(int argc, char *argv[])
int c, r;
const char *sasl_mech = "GSSAPI";
int plain = 0;
+ bool spnego = false;
+ bool zeromaxssf = false;
- while ((c = getopt(argc, argv, "c:P:")) != EOF) {
+ while ((c = getopt(argc, argv, "c:P:zN")) != EOF) {
switch (c) {
case 'c':
parse_cb(&cb, cb_buf, 256, optarg);
@@ -102,6 +104,12 @@ int main(int argc, char *argv[])
plain = 1;
sasldb_path = optarg;
break;
+ case 'z':
+ zeromaxssf = true;
+ break;
+ case 'N':
+ spnego = true;
+ break;
default:
break;
}
@@ -136,10 +144,20 @@ int main(int argc, char *argv[])
sasl_mech = "PLAIN";
}
+ if (spnego) {
+ sasl_mech = "GSS-SPNEGO";
+ }
+
+ if (zeromaxssf) {
+ /* set all security properties to 0 including maxssf */
+ sasl_security_properties_t secprops = { 0 };
+ sasl_setprop(conn, SASL_SEC_PROPS, &secprops);
+ }
+
sd = setup_socket();
len = 8192;
- recv_string(sd, buf, &len);
+ recv_string(sd, buf, &len, false);
r = sasl_server_start(conn, sasl_mech, buf, len, &data, &len);
if (r != SASL_OK && r != SASL_CONTINUE) {
@@ -151,7 +169,7 @@ int main(int argc, char *argv[])
while (r == SASL_CONTINUE) {
send_string(sd, data, len);
len = 8192;
- recv_string(sd, buf, &len);
+ recv_string(sd, buf, &len, true);
r = sasl_server_step(conn, buf, len, &data, &len);
if (r != SASL_OK && r != SASL_CONTINUE) {
@@ -159,7 +177,6 @@ int main(int argc, char *argv[])
printf("\n%s\n", sasl_errdetail(conn));
exit(-1);
}
-
}
if (r != SASL_OK) exit(-1);

View File

@ -0,0 +1,51 @@
diff --git a/plugins/gssapi.c b/plugins/gssapi.c
index 5d900c5e..4688bb9a 100644
--- a/plugins/gssapi.c
+++ b/plugins/gssapi.c
@@ -1567,7 +1567,6 @@ int gssapiv2_server_plug_init(
{
#ifdef HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY
const char *keytab = NULL;
- char keytab_path[1024];
unsigned int rl;
#endif
@@ -1589,15 +1588,7 @@ int gssapiv2_server_plug_init(
return SASL_FAIL;
}
- if(strlen(keytab) > 1024) {
- utils->log(NULL, SASL_LOG_ERR,
- "path to keytab is > 1024 characters");
- return SASL_BUFOVER;
- }
-
- strncpy(keytab_path, keytab, 1024);
-
- gsskrb5_register_acceptor_identity(keytab_path);
+ gsskrb5_register_acceptor_identity(keytab);
}
#endif
diff --git a/plugins/ntlm.c b/plugins/ntlm.c
index aeb3ac34..8a7d9065 100644
--- a/plugins/ntlm.c
+++ b/plugins/ntlm.c
@@ -375,10 +375,15 @@ static unsigned char *P16_lm(unsigned char *P16, sasl_secret_t *passwd,
unsigned *buflen __attribute__((unused)),
int *result)
{
- char P14[14];
+ char P14[14] = { 0 };
+ int Plen;
unsigned char S8[] = { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
- strncpy(P14, (const char *) passwd->data, sizeof(P14));
+ Plen = sizeof(P14);
+ if (passwd->len < Plen) {
+ Plen = passwd->len;
+ }
+ memcpy(P14, (const char *) passwd->data, Plen);
ucase(P14, sizeof(P14));
E(P16, (unsigned char *) P14, sizeof(P14), S8, sizeof(S8));

View File

@ -0,0 +1,83 @@
From 5703f2a26b0a183079beb7f1b176a3c24ede7309 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Wed, 15 May 2024 14:17:46 -0400
Subject: [PATCH] Fix some issues uncovered by a static analyzer
A few possible overruns and a memory leak.
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
---
lib/common.c | 13 +++++++------
saslauthd/auth_krb5.c | 1 +
saslauthd/testsaslauthd.c | 6 +++---
3 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/lib/common.c b/lib/common.c
index 6c5496a2..b9c8bf50 100644
--- a/lib/common.c
+++ b/lib/common.c
@@ -2395,18 +2395,19 @@ int _sasl_ipfromstring(const char *addr,
/* Parse the address */
for (i = 0; addr[i] != '\0' && addr[i] != ';'; i++) {
- if (i >= NI_MAXHOST)
+ if (i >= NI_MAXHOST - 1)
return SASL_BADPARAM;
hbuf[i] = addr[i];
}
hbuf[i] = '\0';
- if (addr[i] == ';')
+ if (addr[i] == ';') {
i++;
- /* XXX: Do we need this check? */
- for (j = i; addr[j] != '\0'; j++)
- if (!isdigit((int)(addr[j])))
- return SASL_BADPARAM;
+ /* XXX: Do we need this check? */
+ for (j = i; addr[j] != '\0'; j++)
+ if (!isdigit((int)(addr[j])))
+ return SASL_BADPARAM;
+ }
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
diff --git a/saslauthd/auth_krb5.c b/saslauthd/auth_krb5.c
index c7cceeec..7750b55e 100644
--- a/saslauthd/auth_krb5.c
+++ b/saslauthd/auth_krb5.c
@@ -203,6 +203,7 @@ auth_krb5 (
if (form_principal_name(user, service, realm, principalbuf, sizeof (principalbuf))) {
syslog(LOG_ERR, "auth_krb5: form_principal_name");
+ krb5_free_context(context);
return strdup("NO saslauthd principal name error");
}
diff --git a/saslauthd/testsaslauthd.c b/saslauthd/testsaslauthd.c
index 8a0e4d9c..9267c43d 100644
--- a/saslauthd/testsaslauthd.c
+++ b/saslauthd/testsaslauthd.c
@@ -70,8 +70,8 @@ int flags = LOG_USE_STDERR;
*/
int retry_read(int fd, void *inbuf, unsigned nbyte)
{
- int n;
- int nread = 0;
+ ssize_t n;
+ size_t nread = 0;
char *buf = (char *)inbuf;
if (nbyte == 0) return 0;
@@ -233,7 +233,7 @@ static int saslauthd_verify_password(const char *saslauthd_path,
return -1;
}
- count = (int)sizeof(response) < count ? sizeof(response) : count;
+ count = (int)sizeof(response) <= count ? sizeof(response) - 1: count;
if (retry_read(s, response, count) < count) {
close(s);
fprintf(stderr,"read failed\n");
--
2.45.0

View File

@ -0,0 +1,53 @@
From 266f0acf7f5e029afbb3e263437039e50cd6c262 Mon Sep 17 00:00:00 2001
From: Sam James <sam@gentoo.org>
Date: Wed, 23 Feb 2022 00:45:15 +0000
Subject: Fix <time.h> check
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We're conditionally including based on HAVE_TIME_H in a bunch of places,
but we're not actually checking for time.h, so that's never going to be defined.
While at it, add in a missing include in the cram plugin.
This fixes a bunch of implicit declaration warnings:
```
* cyrus-sasl-2.1.28/lib/saslutil.c:280:3: warning: implicit declaration of function time [-Wimplicit-function-declaration]
* cyrus-sasl-2.1.28/lib/saslutil.c:364:41: warning: implicit declaration of function clock [-Wimplicit-function-declaration]
* cyrus-sasl-2.1.28/plugins/cram.c:132:7: warning: implicit declaration of function time [-Wimplicit-function-declaration]
* cyrus-sasl-2.1.28/lib/saslutil.c:280:3: warning: implicit declaration of function time [-Wimplicit-function-declaration]
* cyrus-sasl-2.1.28/lib/saslutil.c:364:41: warning: implicit declaration of function clock [-Wimplicit-function-declaration]
* cyrus-sasl-2.1.28/plugins/cram.c:132:7: warning: implicit declaration of function time [-Wimplicit-function-declaration]
```
Signed-off-by: Sam James <sam@gentoo.org>
[Edited to apply to Fedora - DJ]
diff -rup a/configure.ac b/configure.ac
--- a/configure.ac 2023-04-20 00:31:33.578596460 -0400
+++ b/configure.ac 2023-04-20 01:17:40.877579628 -0400
@@ -1239,6 +1239,7 @@ AC_CHECK_HEADERS_ONCE([sys/time.h])
AC_HEADER_DIRENT
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS(crypt.h des.h dlfcn.h fcntl.h limits.h malloc.h paths.h strings.h sys/file.h sys/time.h syslog.h unistd.h inttypes.h sys/uio.h sys/param.h sysexits.h stdarg.h varargs.h krb5.h)
+AC_CHECK_HEADERS(crypt.h des.h dlfcn.h fcntl.h limits.h malloc.h paths.h strings.h sys/file.h sys/time.h syslog.h time.h unistd.h inttypes.h sys/uio.h sys/param.h sysexits.h stdarg.h varargs.h krb5.h)
AC_CHECK_TYPES([long long, int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t],,,[
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
Only in b: configure.ac.orig
Only in b: configure.ac.rej
diff -rup a/plugins/cram.c b/plugins/cram.c
--- a/plugins/cram.c 2022-02-18 16:50:42.000000000 -0500
+++ b/plugins/cram.c 2023-04-20 01:20:12.228312652 -0400
@@ -53,6 +53,10 @@
#endif
#include <fcntl.h>
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
#include <sasl.h>
#include <saslplug.h>
#include <saslutil.h>

378
cyrus-sasl.spec Normal file
View File

@ -0,0 +1,378 @@
%global username saslauth
%global _plugindir2 %{_libdir}/sasl2
%global bootstrap_cyrus_sasl 0
Summary: The Cyrus SASL library
Name: cyrus-sasl
Version: 2.1.28
Release: %autorelease
License: BSD-Attribution-HPND-disclaimer
URL: https://www.cyrusimap.org/sasl/
# Source0 originally comes from https://www.cyrusimap.org/releases/;
# make-no-dlcompatorsrp-tarball.sh removes the "dlcompat" subdirectory and builds a
# new tarball.
Source0: cyrus-sasl-%{version}-nodlcompatorsrp.tar.gz
Source3: saslauth.sysusers
Source5: saslauthd.service
Source7: sasl-mechlist.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
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
# The 64 bit *INT8 type is not used anywhere and other types match
Patch49: cyrus-sasl-2.1.26-md5global.patch
Patch101: cyrus-sasl-2.1.27-Add-basic-test-infrastructure.patch
Patch102: cyrus-sasl-2.1.27-Add-Channel-Binding-support-for-GSSAPI-GSS-SPNEGO.patch
#https://github.com/simo5/cyrus-sasl/commit/ebd2387f06c84c7f9aac3167ec041bb01e5c6e48
Patch106: cyrus-sasl-2.1.27-nostrncpy.patch
# Upstream PR: https://github.com/cyrusimap/cyrus-sasl/pull/635
Patch107: cyrus-sasl-2.1.27-more-tests.patch
Patch108: cyrus-sasl-2.1.27-Add-support-for-setting-max-ssf-0-to-GSS-SPNEGO.patch
Patch500: cyrus-sasl-2.1.27-coverity.patch
Patch501: cyrus-sasl-2.1.27-cumulative-digestmd5.patch
Patch502: cyrus-sasl-2.1.27-cumulative-ossl3.patch
Patch503: cyrus-sasl-2.1.28-SAST.patch
Patch599: cyrus-sasl-2.1.28-fedora-c99.patch
BuildRequires: autoconf, automake, libtool, gdbm-devel, groff
BuildRequires: krb5-devel >= 1.2.2, openssl-devel, pam-devel, pkgconfig
BuildRequires: mariadb-connector-c-devel, libpq-devel, zlib-devel
%if ! %{bootstrap_cyrus_sasl}
BuildRequires: openldap-devel
%endif
#build reqs for make check
BuildRequires: python3 nss_wrapper socket_wrapper krb5-server
BuildRequires: make
Requires(pre): /usr/sbin/useradd /usr/sbin/groupadd
Requires(postun): /usr/sbin/userdel /usr/sbin/groupdel
Requires: /sbin/nologin
Provides: user(%username)
Provides: group(%username)
%description
The %{name} package contains the Cyrus implementation of SASL.
SASL is the Simple Authentication and Security Layer, a method for
adding authentication support to connection-based protocols.
%package lib
Summary: Shared libraries needed by applications which use Cyrus SASL
%description lib
The %{name}-lib package contains shared libraries which are needed by
applications which use the Cyrus SASL library.
%package devel
Requires: %{name}-lib%{?_isa} = %{version}-%{release}
Requires: %{name}%{?_isa} = %{version}-%{release}
Requires: pkgconfig
Summary: Files needed for developing applications with Cyrus SASL
%description devel
The %{name}-devel package contains files needed for developing and
compiling applications which use the Cyrus SASL library.
%package gssapi
Requires: %{name}-lib%{?_isa} = %{version}-%{release}
Summary: GSSAPI authentication support for Cyrus SASL
%description gssapi
The %{name}-gssapi package contains the Cyrus SASL plugins which
support GSSAPI authentication. GSSAPI is commonly used for Kerberos
authentication.
%package plain
Requires: %{name}-lib%{?_isa} = %{version}-%{release}
Summary: PLAIN and LOGIN authentication support for Cyrus SASL
%description plain
The %{name}-plain package contains the Cyrus SASL plugins which support
PLAIN and LOGIN authentication schemes.
%package md5
Requires: %{name}-lib%{?_isa} = %{version}-%{release}
Summary: CRAM-MD5 and DIGEST-MD5 authentication support for Cyrus SASL
%description md5
The %{name}-md5 package contains the Cyrus SASL plugins which support
CRAM-MD5 and DIGEST-MD5 authentication schemes.
# This would more appropriately be named cyrus-sasl-auxprop-sql.
%package sql
Requires: %{name}-lib%{?_isa} = %{version}-%{release}
Summary: SQL auxprop support for Cyrus SASL
%description sql
The %{name}-sql package contains the Cyrus SASL plugin which supports
using a RDBMS for storing shared secrets.
%if ! %{bootstrap_cyrus_sasl}
# This was *almost* named cyrus-sasl-auxprop-ldapdb, but that's a lot of typing.
%package ldap
Requires: %{name}-lib%{?_isa} = %{version}-%{release}
Summary: LDAP auxprop support for Cyrus SASL
%description ldap
The %{name}-ldap package contains the Cyrus SASL plugin which supports using
a directory server, accessed using LDAP, for storing shared secrets.
%endif
%package scram
Requires: %{name}-lib%{?_isa} = %{version}-%{release}
Summary: SCRAM auxprop support for Cyrus SASL
%description scram
The %{name}-scram package contains the Cyrus SASL plugin which supports
the SCRAM authentication scheme.
%package gs2
Requires: %{name}-lib%{?_isa} = %{version}-%{release}
Summary: GS2 support for Cyrus SASL
%description gs2
The %{name}-gs2 package contains the Cyrus SASL plugin which supports
the GS2 authentication scheme.
###
%prep
%setup -q -n cyrus-sasl-%{version}
%patch11 -p1 -b .no_rpath
%patch15 -p1 -b .path
%patch23 -p1 -b .man
%patch24 -p1 -b .sizes
%patch49 -p1 -b .md5global.h
%patch101 -p1 -b .tests
%patch102 -p1 -b .gssapi_cbs
%patch106 -p1 -b .nostrncpy
%patch107 -p1 -b .moretests
%patch108 -p1 -b .maxssf0
%patch500 -p1 -b .coverity
%patch501 -p1 -b .digestmd5
%patch502 -p1 -b .ossl3
%patch503 -p1 -b .sast
%patch599 -p1 -b .c99
%build
# reconfigure
cp %{SOURCE11} ./
rm configure aclocal.m4 config/ltmain.sh Makefile.in
export NOCONFIGURE=yes
sh autogen.sh
%set_build_flags
# Find Kerberos.
krb5_prefix=`krb5-config --prefix`
if test x$krb5_prefix = x%{_prefix} ; then
krb5_prefix=
else
CPPFLAGS="-I${krb5_prefix}/include $CPPFLAGS"; export CPPFLAGS
LDFLAGS="-L${krb5_prefix}/%{_lib} $LDFLAGS"; export LDFLAGS
fi
# Find OpenSSL.
LIBS="-lcrypt"; export LIBS
if pkg-config openssl ; then
CPPFLAGS="`pkg-config --cflags-only-I openssl` $CPPFLAGS"; export CPPFLAGS
LDFLAGS="`pkg-config --libs-only-L openssl` $LDFLAGS"; export LDFLAGS
fi
# Find the MySQL libraries used needed by the SQL auxprop plugin.
INC_DIR="`mysql_config --include`"
if test x"$INC_DIR" != "x-I%{_includedir}"; then
CPPFLAGS="$INC_DIR $CPPFLAGS"; export CPPFLAGS
fi
LIB_DIR="`mysql_config --libs | sed -e 's,-[^L][^ ]*,,g' -e 's,^ *,,' -e 's, *$,,' -e 's, *, ,g'`"
if test x"$LIB_DIR" != "x-L%{_libdir}"; then
LDFLAGS="$LIB_DIR $LDFLAGS"; export LDFLAGS
fi
# Find the PostgreSQL libraries used needed by the SQL auxprop plugin.
INC_DIR="-I`pg_config --includedir`"
if test x"$INC_DIR" != "x-I%{_includedir}"; then
CPPFLAGS="$INC_DIR $CPPFLAGS"; export CPPFLAGS
fi
LIB_DIR="-L`pg_config --libdir`"
if test x"$LIB_DIR" != "x-L%{_libdir}"; then
LDFLAGS="$LIB_DIR $LDFLAGS"; export LDFLAGS
fi
# run "make check" against the built library rather than the one in buildroot
LDFLAGS="-Wl,--enable-new-dtags $LDFLAGS"; export LDFLAGS
echo "$CFLAGS"
echo "$CPPFLAGS"
echo "$LDFLAGS"
%configure \
--enable-shared --disable-static \
--disable-java \
--with-plugindir=%{_plugindir2} \
--with-configdir=%{_plugindir2}:%{_sysconfdir}/sasl2 \
--disable-krb4 \
--enable-gssapi${krb5_prefix:+=${krb5_prefix}} \
--with-gss_impl=mit \
--with-rc4 \
--with-dblib=gdbm \
--with-dbpath=%{gdbm_db_file} \
--with-saslauthd=/run/saslauthd --without-pwcheck \
%if ! %{bootstrap_cyrus_sasl}
--with-ldap \
%endif
--with-devrandom=/dev/urandom \
--enable-anon \
--enable-cram \
--enable-digest \
--disable-ntlm \
--enable-plain \
--enable-login \
--enable-alwaystrue \
--enable-httpform \
--disable-otp \
%if ! %{bootstrap_cyrus_sasl}
--enable-ldapdb \
%endif
--enable-sql --with-mysql=yes --with-pgsql=yes \
--without-sqlite \
--enable-auth-sasldb \
"$@"
make sasldir=%{_plugindir2}
make -C saslauthd testsaslauthd
make -C sample
# Build a small program to list the available mechanisms, because I need it.
pushd lib
../libtool --mode=link %{__cc} -o sasl2-shared-mechlist -I../include $CFLAGS %{SOURCE7} $LDFLAGS ./libsasl2.la
%install
test "$RPM_BUILD_ROOT" != "/" && rm -rf $RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT sasldir=%{_plugindir2}
make install DESTDIR=$RPM_BUILD_ROOT sasldir=%{_plugindir2} -C plugins
install -m755 -d $RPM_BUILD_ROOT%{_bindir}
./libtool --mode=install \
install -m755 sample/client $RPM_BUILD_ROOT%{_bindir}/sasl2-sample-client
./libtool --mode=install \
install -m755 sample/server $RPM_BUILD_ROOT%{_bindir}/sasl2-sample-server
./libtool --mode=install \
install -m755 saslauthd/testsaslauthd $RPM_BUILD_ROOT%{_sbindir}/testsaslauthd
# Install the saslauthd mdoc page in the expected location. Sure, it's not
# really a man page, but groff seems to be able to cope with it.
install -m755 -d $RPM_BUILD_ROOT%{_mandir}/man8/
install -m644 -p saslauthd/saslauthd.mdoc $RPM_BUILD_ROOT%{_mandir}/man8/saslauthd.8
install -m644 -p saslauthd/testsaslauthd.8 $RPM_BUILD_ROOT%{_mandir}/man8/testsaslauthd.8
# Install the systemd unit file for saslauthd and the config file.
install -d -m755 $RPM_BUILD_ROOT/%{_unitdir} $RPM_BUILD_ROOT/etc/sysconfig
install -m644 -p %{SOURCE5} $RPM_BUILD_ROOT/%{_unitdir}/saslauthd.service
install -m644 -p %{SOURCE9} $RPM_BUILD_ROOT/etc/sysconfig/saslauthd
# Install the config dirs if they're not already there.
install -m755 -d $RPM_BUILD_ROOT/%{_sysconfdir}/sasl2
install -m755 -d $RPM_BUILD_ROOT/%{_plugindir2}
# Provide an easy way to query the list of available mechanisms.
./libtool --mode=install \
install -m755 lib/sasl2-shared-mechlist $RPM_BUILD_ROOT/%{_sbindir}/
# Sysusers file
install -p -D -m 0644 %{SOURCE3} %{buildroot}%{_sysusersdir}/cyrus-sasl.conf
# Remove unpackaged files from the buildroot.
rm -f $RPM_BUILD_ROOT%{_libdir}/sasl2/libotp.*
rm -f $RPM_BUILD_ROOT%{_libdir}/sasl2/*.a
rm -f $RPM_BUILD_ROOT%{_libdir}/sasl2/*.la
rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
rm -f $RPM_BUILD_ROOT%{_mandir}/cat8/saslauthd.8
%check
make check %{?_smp_mflags}
%pre
%sysusers_create_compat %{SOURCE3}
%post
%systemd_post saslauthd.service
%preun
%systemd_preun saslauthd.service
%postun
%systemd_postun_with_restart saslauthd.service
%ldconfig_scriptlets lib
%files
%doc saslauthd/LDAP_SASLAUTHD
%{_mandir}/man8/*
%{_sbindir}/pluginviewer
%{_sbindir}/saslauthd
%{_sbindir}/testsaslauthd
%config(noreplace) /etc/sysconfig/saslauthd
%{_unitdir}/saslauthd.service
%ghost %attr(755,root,root) /run/saslauthd
%{_sysusersdir}/cyrus-sasl.conf
%files lib
%license COPYING
%doc AUTHORS doc/html/*.html
%{_libdir}/libsasl*.so.*
%dir %{_sysconfdir}/sasl2
%dir %{_plugindir2}/
%{_plugindir2}/*anonymous*.so*
%{_plugindir2}/*sasldb*.so*
%{_sbindir}/saslpasswd2
%{_sbindir}/sasldblistusers2
%files plain
%{_plugindir2}/*plain*.so*
%{_plugindir2}/*login*.so*
%if ! %{bootstrap_cyrus_sasl}
%files ldap
%{_plugindir2}/*ldapdb*.so*
%endif
%files md5
%{_plugindir2}/*crammd5*.so*
%{_plugindir2}/*digestmd5*.so*
%files sql
%{_plugindir2}/*sql*.so*
%files gssapi
%{_plugindir2}/*gssapi*.so*
%files scram
%{_plugindir2}/libscram.so*
%files gs2
%{_plugindir2}/libgs2.so*
%files devel
%{_bindir}/sasl2-sample-client
%{_bindir}/sasl2-sample-server
%{_includedir}/*
%{_libdir}/libsasl*.*so
%{_libdir}/pkgconfig/*.pc
%{_mandir}/man3/*
%{_sbindir}/sasl2-shared-mechlist
%changelog
%autochangelog

View File

@ -1,6 +1,6 @@
#!/bin/bash -e
#
# See ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/ for unmodified sources.
# See https://github.com/cyrusimap/cyrus-sasl/releases for unmodified sources.
#
tmppath=`mktemp -d ${TMPDIR:-/tmp}/make-no-dlcompat-tarball-XXXXXX`

View File

@ -34,7 +34,7 @@ main(int argc, char **argv)
int ret, i;
const char *mechs, **globals;
sasl_callback_t callbacks[] = {
{SASL_CB_GETOPT, my_getopt, NULL},
{SASL_CB_GETOPT, (int (*)(void)) my_getopt, NULL},
{SASL_CB_LIST_END},
};
sasl_conn_t *connection;

4
saslauth.sysusers Normal file
View File

@ -0,0 +1,4 @@
#Type Name ID GECOS Home directory Shell
g saslauth 76
u saslauth - "Saslauthd user" /run/saslauthd /sbin/nologin
m saslauth saslauth

1
sources Normal file
View File

@ -0,0 +1 @@
SHA512 (cyrus-sasl-2.1.28-nodlcompatorsrp.tar.gz) = 9a80b363718774ac5b9b8b71c7eba7c48d760296542b4d545010ba4fc463d0da807fc8efd314381467e4c44b3b055082882f3ac03e8f829db2a543e271d70cbc

View File

@ -0,0 +1,69 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /CoreOS/cyrus-sasl/Sanity/sanity-ldapdb-plugin
# Description: The ldapdb auxprop plugin provides access to credentials stored in an LDAP server.
# Author: David Spurek <dspurek@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export TEST=/CoreOS/cyrus-sasl/Sanity/sanity-ldapdb-plugin
export TESTVERSION=1.0
BUILT_FILES=
FILES=$(METADATA) runtest.sh Makefile PURPOSE
.PHONY: all install download clean
run: $(FILES) build
./runtest.sh
build: $(BUILT_FILES)
test -x runtest.sh || chmod a+x runtest.sh
clean:
rm -f *~ $(BUILT_FILES)
include /usr/share/rhts/lib/rhts-make.include
$(METADATA): Makefile
@echo "Owner: David Spurek <dspurek@redhat.com>" > $(METADATA)
@echo "Name: $(TEST)" >> $(METADATA)
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
@echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "Description: The ldapdb auxprop plugin provides access to credentials stored in an LDAP server." >> $(METADATA)
@echo "Type: Sanity" >> $(METADATA)
@echo "TestTime: 15m" >> $(METADATA)
@echo "RunFor: cyrus-sasl" >> $(METADATA)
@echo "Requires: cyrus-sasl" >> $(METADATA)
@echo "Requires: cyrus-sasl-md5" >> $(METADATA)
@echo "Requires: cyrus-sasl-ldap" >> $(METADATA)
@echo "Requires: cyrus-sasl-plain cyrus-sasl-devel" >> $(METADATA)
@echo "Requires: expect" >> $(METADATA)
@echo "Requires: openldap-servers" >> $(METADATA)
@echo "Requires: openldap-clients" >> $(METADATA)
@echo "Priority: Normal" >> $(METADATA)
@echo "License: GPLv2" >> $(METADATA)
@echo "Confidential: no" >> $(METADATA)
@echo "Destructive: no" >> $(METADATA)
rhts-lint $(METADATA)

View File

@ -0,0 +1,3 @@
PURPOSE of /CoreOS/cyrus-sasl/Sanity/sanity-ldapdb-plugin
Description: The ldapdb auxprop plugin provides access to credentials stored in an LDAP server.
Author: David Spurek <dspurek@redhat.com>

View File

@ -0,0 +1,249 @@
#!/bin/bash
# vim: dict=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# runtest.sh of /CoreOS/cyrus-sasl/Sanity/sanity-ldapdb-plugin
# Description: The ldapdb auxprop plugin provides access to credentials stored in an LDAP server.
# Author: David Spurek <dspurek@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Include Beaker environment
. /usr/bin/rhts-environment.sh || exit 1
. /usr/share/beakerlib/beakerlib.sh || exit 1
PACKAGE="cyrus-sasl"
PACKAGES=( "cyrus-sasl" \
"cyrus-sasl-devel" \
"cyrus-sasl-ldap" \
"cyrus-sasl-plain" \
"expect" \
"pam" \
"openldap" \
"openldap-clients" \
"openldap-servers" \
"cyrus-sasl-md5" )
# else branch is also relevant for Fedora
if rlIsRHEL '<6'; then
SERVICE_LDAP=ldap
else
SERVICE_LDAP=slapd
fi
ldapdb_id="sasluser"
ldapdb_pw="x"
SASL_PASSWORD="x"
SASL_USER="test"
if [ "`uname -i`" = "i386" ]; then
LIBDIR=/usr/lib
else
LIBDIR=/usr/lib64
fi
rlIsRHEL 5 && [ "`uname -i`" = "ia64" ] && LIBDIR=/usr/lib
function slapd_conf {
cat >/etc/openldap/slapd.conf<<'EOF'
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/nis.schema
allow bind_v2
pidfile /var/run/openldap/slapd.pid
argsfile /var/run/openldap/slapd.args
database mdb
suffix "dc=my-domain,dc=com"
rootdn "uid=admin,dc=my-domain,dc=com"
rootpw x
directory /var/lib/ldap
password-hash {CLEARTEXT}
authz-policy to
authz-regexp
uid=(.*),cn=.*,cn=auth
"ldap:///dc=my-domain,dc=com??sub?(uid=$1)"
index objectClass eq,pres
index ou,cn,mail,surname,givenname eq,pres,sub
index uidNumber,gidNumber,loginShell eq,pres
index uid,memberUid eq,pres,sub
index nisMapName,nisMapEntry eq,pres,sub
access to * by * write
access to * by * read
access to * by * auth
EOF
return $?
}
function data_ldif {
cat >data.ldif<<EOF
dn: dc=my-domain,dc=com
objectclass: top
objectclass: domain
dc: my-domain
dn: ou=Admins,dc=my-domain,dc=com
objectclass: top
objectclass: organizationalUnit
ou: Admins
dn: uid=$ldapdb_id,ou=People,dc=my-domain,dc=com
objectClass: person
objectClass: inetOrgPerson
userPassword: $ldapdb_pw
uid: $ldapdb_id
cn: $ldapdb_id
sn: $ldapdb_id
authzTo: ldap:///ou=People,dc=my-domain,dc=com??sub?(&(objectclass=inetOrgPerson)(uid=*))
dn: ou=People,dc=my-domain,dc=com
objectclass: top
objectclass: organizationalUnit
ou: People
dn: uid=$SASL_USER,ou=People,dc=my-domain,dc=com
objectClass: person
objectClass: inetOrgPerson
userPassword: x
uid: $SASL_USER
cn: $SASL_USER
sn: $SASL_USER
EOF
return $?
}
function sasl_client {
expect <<EOF
set timeout 30
spawn sasl2-sample-client -p 8000 -s rcmd -m PLAIN localhost
expect {
timeout {exit 1}
eof {exit 2}
-nocase "please enter an authentication id:" { puts $1 ; send "$1\r"}
}
expect {
timeout {exit 3}
eof {exit 4}
-nocase "please enter an authorization id:" { puts $1 ; send "$1\r"}
}
expect {
timeout {exit 5}
eof {exit 6}
-nocase "Password:" { puts $2 ; send "$2\r"}
}
expect {
timeout {exit 8}
-nocase "successful authentication" { expect eof ; exit 0}
-nocase "authentication failed" {exit 9}
}
expect eof
exit 0
EOF
}
# ldapdb configuration for services, in this test for sasl2-sample-server
# configuration may be for smtpd.conf,imapd.conf instead of sample.conf
function smtpd_ldapdb {
cat >$LIBDIR/sasl2/sample.conf<<EOF
pwcheck_method: auxprop
auxprop_plugin: ldapdb
mech_list: PLAIN LOGIN CRAM-MD5 DIGEST-MD5
ldapdb_uri: ldap://localhost
ldapdb_id: $ldapdb_id
ldapdb_pw: $ldapdb_pw
ldapdb_mech: DIGEST-MD5
EOF
return $?
}
rlJournalStart
rlPhaseStartSetup
for P in ${PACKAGES[@]}; do rlCheckRpm $P || rlDie "Package $P is missing"; done
rlRun "TmpDir=\$(mktemp -d)" 0 "Creating tmp directory"
rlRun "pushd $TmpDir"
rlFileBackup --clean "$LIBDIR/sasl2/sample.conf"
rlFileBackup --clean "/etc/sasldb2"
rlRun "smtpd_ldapdb" 0
rlServiceStop $SERVICE_LDAP
# Back-up.
rlFileBackup --clean /var/run/openldap
rlFileBackup --clean /var/lib/ldap && rm -rf /var/lib/ldap/*
rlFileBackup --clean /etc/openldap/
rlRun "slapd_conf" 0
rlRun "cat /etc/openldap/slapd.conf" 0
if rlIsRHEL '>=6' || rlIsFedora '>=14'; then
rm -rf /etc/openldap/slapd.d/*
slaptest -f /etc/openldap/slapd.conf -F /etc/openldap/slapd.d/
fi
rlRun "data_ldif" 0
rlRun "slapadd -l data.ldif" 0
chown -R ldap:ldap /var/lib/ldap/* && chmod -R a+rx /etc/openldap/
rlRun "restorecon -vvRF /etc/openldap/"
rlRun "service $SERVICE_LDAP start && sleep 10" 0
rlPhaseEnd
rlPhaseStartTest
rlRun "ldapsearch -LLL -H ldap://localhost -s base -b '' -x supportedSASLMechanisms" 0
rlRun "ldapsearch -H ldap://localhost -x -b 'dc=my-domain,dc=com' '(objectclass=*)'" 0 "Check ldap entries without SASL"
# this two ldapwhoami commands may be used for testing purposes
# rlRun "ldapwhoami -U $ldapdb_id -Y digest-md5" 0
# rlRun "ldapwhoami -U $ldapdb_id -X u:test@localhost -Y digest-md5" 0
# sasl sample server uses ldap sasluser as sasl bind id
# then try search user passed to sample client in ldap database
rlRun "sasl2-sample-server -p 8000 -s rcmd -m PLAIN &>sample_server.log &" 0
SASL_PID=`pgrep -f "sasl2-sample-server -p 8000 -s rcmd -m PLAIN"`
rlRun "sasl_client $SASL_USER ${SASL_PASSWORD}" 0
rlRun "sasl_client baduser ${SASL_PASSWORD}" 9
rlRun "kill $SASL_PID" 0 ; sleep 5
rlRun "cat sample_server.log" 0
rlPhaseEnd
rlPhaseStartCleanup
rlRun "service $SERVICE_LDAP stop && sleep 10" 0
rlFileRestore
rlServiceRestore $SERVICE_LDAP
rlRun "popd"
rlRun "rm -r $TmpDir" 0 "Removing tmp directory"
rlPhaseEnd
rlJournalPrintText
rlJournalEnd

18
tests/tests.yml Normal file
View File

@ -0,0 +1,18 @@
---
# This first play always runs on the local staging system
- hosts: localhost
roles:
- role: standard-test-beakerlib
tags:
- classic
tests:
- sanity-ldapdb-plugin
required_packages:
- cyrus-sasl
- cyrus-sasl-md5
- cyrus-sasl-ldap
- cyrus-sasl-plain
- cyrus-sasl-devel
- expect
- openldap-servers
- openldap-clients