diff --git a/.cyrus-sasl.metadata b/.cyrus-sasl.metadata new file mode 100644 index 0000000..82b591b --- /dev/null +++ b/.cyrus-sasl.metadata @@ -0,0 +1 @@ +c9e6848d9cc6f9588e0e7a75423f9a3aed3f10db SOURCES/cyrus-sasl-2.1.27-nodlcompatorsrp.tar.gz diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..07c8f97 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/cyrus-sasl-2.1.27-nodlcompatorsrp.tar.gz diff --git a/SOURCES/0001-CVE-2022-24407-Escape-password-for-SQL-insert-update.patch b/SOURCES/0001-CVE-2022-24407-Escape-password-for-SQL-insert-update.patch new file mode 100644 index 0000000..a430d65 --- /dev/null +++ b/SOURCES/0001-CVE-2022-24407-Escape-password-for-SQL-insert-update.patch @@ -0,0 +1,82 @@ +From 37f2e0f0658d78a1496dc277f402f8b577ce6aae Mon Sep 17 00:00:00 2001 +From: Klaus Espenlaub +Date: Tue, 8 Feb 2022 20:34:40 +0000 +Subject: [PATCH] CVE-2022-24407 Escape password for SQL insert/update + commands. + +Signed-off-by: Klaus Espenlaub +--- + plugins/sql.c | 26 +++++++++++++++++++++++--- + 1 file changed, 23 insertions(+), 3 deletions(-) + +diff --git a/plugins/sql.c b/plugins/sql.c +index 31b54a78..6ac81c2f 100644 +--- a/plugins/sql.c ++++ b/plugins/sql.c +@@ -1151,6 +1151,7 @@ static int sql_auxprop_store(void *glob_context, + char *statement = NULL; + char *escap_userid = NULL; + char *escap_realm = NULL; ++ char *escap_passwd = NULL; + const char *cmd; + + sql_settings_t *settings; +@@ -1222,6 +1223,11 @@ static int sql_auxprop_store(void *glob_context, + "Unable to begin transaction\n"); + } + for (cur = to_store; ret == SASL_OK && cur->name; cur++) { ++ /* Free the buffer, current content is from previous loop. */ ++ if (escap_passwd) { ++ sparams->utils->free(escap_passwd); ++ escap_passwd = NULL; ++ } + + if (cur->name[0] == '*') { + continue; +@@ -1243,19 +1249,32 @@ static int sql_auxprop_store(void *glob_context, + } + sparams->utils->free(statement); + ++ if (cur->values[0]) { ++ escap_passwd = (char *)sparams->utils->malloc(strlen(cur->values[0])*2+1); ++ if (!escap_passwd) { ++ ret = SASL_NOMEM; ++ break; ++ } ++ settings->sql_engine->sql_escape_str(escap_passwd, cur->values[0]); ++ } ++ + /* create a statement that we will use */ + statement = sql_create_statement(cmd, cur->name, escap_userid, + escap_realm, +- cur->values && cur->values[0] ? +- cur->values[0] : SQL_NULL_VALUE, ++ escap_passwd ? ++ escap_passwd : SQL_NULL_VALUE, + sparams->utils); ++ if (!statement) { ++ ret = SASL_NOMEM; ++ break; ++ } + + { + char *log_statement = + sql_create_statement(cmd, cur->name, + escap_userid, + escap_realm, +- cur->values && cur->values[0] ? ++ escap_passwd ? + "" : SQL_NULL_VALUE, + sparams->utils); + sparams->utils->log(sparams->utils->conn, SASL_LOG_DEBUG, +@@ -1288,6 +1307,7 @@ static int sql_auxprop_store(void *glob_context, + done: + if (escap_userid) sparams->utils->free(escap_userid); + if (escap_realm) sparams->utils->free(escap_realm); ++ if (escap_passwd) sparams->utils->free(escap_passwd); + if (conn) settings->sql_engine->sql_close(conn); + if (userid) sparams->utils->free(userid); + if (realm) sparams->utils->free(realm); +-- +2.25.1 + diff --git a/SOURCES/autogen.sh b/SOURCES/autogen.sh new file mode 100644 index 0000000..38e3be2 --- /dev/null +++ b/SOURCES/autogen.sh @@ -0,0 +1,37 @@ +#!/bin/sh +# Run this to generate all the initial makefiles, etc. +test -n "$srcdir" || srcdir=`dirname "$0"` +test -n "$srcdir" || srcdir=. + +olddir=`pwd` + +cd $srcdir + +(test -f configure.ac) || { + echo "*** ERROR: Directory "\`$srcdir\'" does not look like the top-level project directory ***" + exit 1 +} + +PKG_NAME=`autoconf --trace 'AC_INIT:$1' configure.ac` + +if [ "$#" = 0 -a "x$NOCONFIGURE" = "x" ]; then + echo "*** WARNING: I am going to run \`configure' with no arguments." >&2 + echo "*** If you wish to pass any to it, please specify them on the" >&2 + echo "*** \`$0\' command line." >&2 + echo "" >&2 +fi + +aclocal --install || exit 1 +autoreconf --verbose --force --install -Wno-portability || exit 1 + +cd $olddir +if [ "$NOCONFIGURE" = "" ]; then + $srcdir/configure "$@" || exit 1 + + if [ "$1" = "--help" ]; then exit 0 else + echo "Now type \`make\' to compile $PKG_NAME" || exit 1 + fi +else + echo "Skipping configure process." +fi + diff --git a/SOURCES/cyrus-sasl-2.1.20-saslauthd.conf-path.patch b/SOURCES/cyrus-sasl-2.1.20-saslauthd.conf-path.patch new file mode 100644 index 0000000..1e414ff --- /dev/null +++ b/SOURCES/cyrus-sasl-2.1.20-saslauthd.conf-path.patch @@ -0,0 +1,26 @@ +diff -up cyrus-sasl-2.1.27/saslauthd/saslauthd.mdoc.path cyrus-sasl-2.1.27/saslauthd/saslauthd.mdoc +--- cyrus-sasl-2.1.27/saslauthd/saslauthd.mdoc.path 2015-10-15 15:44:43.000000000 +0200 ++++ cyrus-sasl-2.1.27/saslauthd/saslauthd.mdoc 2015-11-20 15:05:30.421377527 +0100 +@@ -221,7 +221,7 @@ instead. + .Em (All platforms that support OpenLDAP 2.0 or higher) + .Pp + Authenticate against an ldap server. The ldap configuration parameters are +-read from /usr/local/etc/saslauthd.conf. The location of this file can be ++read from /etc/saslauthd.conf. The location of this file can be + changed with the -O parameter. See the LDAP_SASLAUTHD file included with the + distribution for the list of available parameters. + .It Li sia +@@ -251,10 +251,10 @@ these ticket files can cause serious per + servers. (Kerberos + was never intended to be used in this manner, anyway.) + .Sh FILES +-.Bl -tag -width "/var/run/saslauthd/mux" +-.It Pa /var/run/saslauthd/mux ++.Bl -tag -width "/run/saslauthd/mux" ++.It Pa /run/saslauthd/mux + The default communications socket. +-.It Pa /usr/local/etc/saslauthd.conf ++.It Pa /etc/saslauthd.conf + The default configuration file for ldap support. + .El + .Sh SEE ALSO diff --git a/SOURCES/cyrus-sasl-2.1.21-sizes.patch b/SOURCES/cyrus-sasl-2.1.21-sizes.patch new file mode 100644 index 0000000..6373924 --- /dev/null +++ b/SOURCES/cyrus-sasl-2.1.21-sizes.patch @@ -0,0 +1,119 @@ +diff -up cyrus-sasl-2.1.27/configure.ac.sizes cyrus-sasl-2.1.27/configure.ac +--- cyrus-sasl-2.1.27/configure.ac.sizes 2015-11-18 09:46:24.000000000 +0100 ++++ cyrus-sasl-2.1.27/configure.ac 2015-11-20 15:11:20.474588247 +0100 +@@ -1312,6 +1312,10 @@ AC_HEADER_STDC + 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_TYPES([long long, int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t],,,[ ++#ifdef HAVE_INTTYPES_H ++#include ++#endif]) + + IPv6_CHECK_SS_FAMILY() + IPv6_CHECK_SA_LEN() +diff -up cyrus-sasl-2.1.27/include/makemd5.c.sizes cyrus-sasl-2.1.27/include/makemd5.c +--- cyrus-sasl-2.1.27/include/makemd5.c.sizes 2015-10-15 15:44:43.000000000 +0200 ++++ cyrus-sasl-2.1.27/include/makemd5.c 2015-11-20 15:11:20.477588240 +0100 +@@ -82,12 +82,19 @@ + */ + + ++#ifdef HAVE_CONFIG_H ++#include "../config.h" ++#endif + + #include + #include + #include + #include + ++#ifdef HAVE_INTTYPES_H ++#include ++#endif ++ + + static void + my_strupr(char *s) +@@ -122,6 +129,18 @@ my_strupr(char *s) + static void + try_signed(FILE *f, int len) + { ++#ifdef HAVE_INT8_T ++ BITSIZE(int8_t); ++#endif ++#ifdef HAVE_INT16_T ++ BITSIZE(int16_t); ++#endif ++#ifdef HAVE_INT32_T ++ BITSIZE(int32_t); ++#endif ++#ifdef HAVE_INT64_T ++ BITSIZE(int64_t); ++#endif + BITSIZE(signed char); + BITSIZE(short); + BITSIZE(int); +@@ -135,6 +154,18 @@ try_signed(FILE *f, int len) + static void + try_unsigned(FILE *f, int len) + { ++#ifdef HAVE_UINT8_T ++ BITSIZE(uint8_t); ++#endif ++#ifdef HAVE_UINT16_T ++ BITSIZE(uint16_t); ++#endif ++#ifdef HAVE_UINT32_T ++ BITSIZE(uint32_t); ++#endif ++#ifdef HAVE_UINT64_T ++ BITSIZE(uint64_t); ++#endif + BITSIZE(unsigned char); + BITSIZE(unsigned short); + BITSIZE(unsigned int); +@@ -165,6 +196,11 @@ static int print_pre(FILE *f) + "/* POINTER defines a generic pointer type */\n" + "typedef unsigned char *POINTER;\n" + "\n" ++#ifdef HAVE_INTTYPES_H ++ "/* We try to define integer types for our use */\n" ++ "#include \n" ++ "\n" ++#endif + ); + return 1; + } +@@ -212,31 +248,15 @@ int main(int argc, char **argv) + + print_pre(f); + +-#ifndef HAVE_INT8_T + try_signed (f, 8); +-#endif /* HAVE_INT8_T */ +-#ifndef HAVE_INT16_T + try_signed (f, 16); +-#endif /* HAVE_INT16_T */ +-#ifndef HAVE_INT32_T + try_signed (f, 32); +-#endif /* HAVE_INT32_T */ +-#ifndef HAVE_INT64_T + try_signed (f, 64); +-#endif /* HAVE_INT64_T */ + +-#ifndef HAVE_U_INT8_T + try_unsigned (f, 8); +-#endif /* HAVE_INT8_T */ +-#ifndef HAVE_U_INT16_T + try_unsigned (f, 16); +-#endif /* HAVE_U_INT16_T */ +-#ifndef HAVE_U_INT32_T + try_unsigned (f, 32); +-#endif /* HAVE_U_INT32_T */ +-#ifndef HAVE_U_INT64_T + try_unsigned (f, 64); +-#endif /* HAVE_U_INT64_T */ + + print_post(f); + diff --git a/SOURCES/cyrus-sasl-2.1.23-man.patch b/SOURCES/cyrus-sasl-2.1.23-man.patch new file mode 100644 index 0000000..21c63cd --- /dev/null +++ b/SOURCES/cyrus-sasl-2.1.23-man.patch @@ -0,0 +1,24 @@ +diff -up cyrus-sasl-2.1.26/saslauthd/testsaslauthd.8.man cyrus-sasl-2.1.26/saslauthd/testsaslauthd.8 +--- cyrus-sasl-2.1.26/saslauthd/testsaslauthd.8.man 2013-09-03 15:25:26.818042047 +0200 ++++ cyrus-sasl-2.1.26/saslauthd/testsaslauthd.8 2013-09-03 15:25:26.818042047 +0200 +@@ -0,0 +1,20 @@ ++.\" Hey, EMACS: -*- nroff -*- ++.TH TESTSASLAUTHD 8 "14 October 2006" ++.SH NAME ++testsaslauthd \- test utility for the SASL authentication server ++.SH SYNOPSIS ++.B testsaslauthd ++.RI "[ " \(hyr " " realm " ] [ " \(hys " " servicename " ] [ " \(hyf " " socket " " path " ] [ " \(hyR " " repeatnum " ]" ++.SH DESCRIPTION ++This manual page documents briefly the ++.B testsaslauthd ++command. ++.PP ++.SH SEE ALSO ++.BR saslauthd (8). ++.br ++.SH AUTHOR ++testsaslauthd was written by Carnegie Mellon University. ++.PP ++This manual page was written by Roberto C. Sanchez , ++for the Debian project (but may be used by others). diff --git a/SOURCES/cyrus-sasl-2.1.25-no_rpath.patch b/SOURCES/cyrus-sasl-2.1.25-no_rpath.patch new file mode 100644 index 0000000..3ff180c --- /dev/null +++ b/SOURCES/cyrus-sasl-2.1.25-no_rpath.patch @@ -0,0 +1,20 @@ +diff -up cyrus-sasl-2.1.25/m4/cyrus.m4.no_rpath cyrus-sasl-2.1.25/m4/cyrus.m4 +--- cyrus-sasl-2.1.25/m4/cyrus.m4.no_rpath 2010-01-22 16:12:01.000000000 +0100 ++++ cyrus-sasl-2.1.25/m4/cyrus.m4 2012-12-06 14:59:47.956102057 +0100 +@@ -32,14 +32,5 @@ AC_DEFUN([CMU_ADD_LIBPATH_TO], [ + dnl runpath initialization + AC_DEFUN([CMU_GUESS_RUNPATH_SWITCH], [ + # CMU GUESS RUNPATH SWITCH +- AC_CACHE_CHECK(for runpath switch, andrew_cv_runpath_switch, [ +- # first, try -R +- SAVE_LDFLAGS="${LDFLAGS}" +- LDFLAGS="-R /usr/lib" +- AC_TRY_LINK([],[],[andrew_cv_runpath_switch="-R"], [ +- LDFLAGS="-Wl,-rpath,/usr/lib" +- AC_TRY_LINK([],[],[andrew_cv_runpath_switch="-Wl,-rpath,"], +- [andrew_cv_runpath_switch="none"]) +- ]) +- LDFLAGS="${SAVE_LDFLAGS}" +- ])]) ++ andrew_runpath_switch="none" ++ ]) diff --git a/SOURCES/cyrus-sasl-2.1.26-md5global.patch b/SOURCES/cyrus-sasl-2.1.26-md5global.patch new file mode 100644 index 0000000..605c8ec --- /dev/null +++ b/SOURCES/cyrus-sasl-2.1.26-md5global.patch @@ -0,0 +1,24 @@ +diff -up cyrus-sasl-2.1.27/include/Makefile.am.md5global.h cyrus-sasl-2.1.27/include/Makefile.am +--- cyrus-sasl-2.1.27/include/Makefile.am.md5global.h 2018-05-17 13:33:49.588368350 +0200 ++++ cyrus-sasl-2.1.27/include/Makefile.am 2018-05-17 13:38:19.377316869 +0200 +@@ -49,20 +49,7 @@ saslinclude_HEADERS = hmac-md5.h md5.h m + + noinst_PROGRAMS = makemd5 + +-makemd5_SOURCES = makemd5.c +- +-makemd5$(BUILD_EXEEXT) $(makemd5_OBJECTS): CC=$(CC_FOR_BUILD) +-makemd5$(BUILD_EXEEXT) $(makemd5_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD) +-makemd5$(BUILD_EXEEXT): LDFLAGS=$(LDFLAGS_FOR_BUILD) +- +-md5global.h: makemd5$(BUILD_EXEEXT) Makefile +- -rm -f $@ +- ./$< $@ +- +-BUILT_SOURCES = md5global.h +- + EXTRA_DIST = NTMakefile +-DISTCLEANFILES = md5global.h + + if MACOSX + framedir = /Library/Frameworks/SASL2.framework diff --git a/SOURCES/cyrus-sasl-2.1.27-Add-Channel-Binding-support-for-GSSAPI-GSS-SPNEGO.patch b/SOURCES/cyrus-sasl-2.1.27-Add-Channel-Binding-support-for-GSSAPI-GSS-SPNEGO.patch new file mode 100644 index 0000000..242b436 --- /dev/null +++ b/SOURCES/cyrus-sasl-2.1.27-Add-Channel-Binding-support-for-GSSAPI-GSS-SPNEGO.patch @@ -0,0 +1,444 @@ +From aa8b6b2275fd14ba2cca3d2339ae61c7e7ddfa70 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Tue, 5 May 2020 14:08:48 -0400 +Subject: [PATCH] Add Channel Binding support for GSSAPI/GSS-SPNEGO + +Backport of commit ids: +829a6ed086432e26dafa9d1dcf892aef4c42cfbd +944bd8a6205f840b105206ef83e8f6b9dff0138e + +Signed-off-by: Simo Sorce +--- + 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(-) + +diff --git a/plugins/gssapi.c b/plugins/gssapi.c +index ff663da..5d900c5 100644 +--- a/plugins/gssapi.c ++++ b/plugins/gssapi.c +@@ -830,7 +830,9 @@ gssapi_server_mech_authneg(context_t *text, + gss_buffer_desc name_without_realm; + gss_name_t client_name_MN = NULL, without = NULL; + gss_OID mech_type; +- ++ gss_channel_bindings_t bindings = GSS_C_NO_CHANNEL_BINDINGS; ++ struct gss_channel_bindings_struct cb = {0}; ++ + input_token = &real_input_token; + output_token = &real_output_token; + output_token->value = NULL; output_token->length = 0; +@@ -902,6 +904,12 @@ gssapi_server_mech_authneg(context_t *text, + real_input_token.length = clientinlen; + } + ++ if (params->cbinding != NULL) { ++ cb.application_data.length = params->cbinding->len; ++ cb.application_data.value = params->cbinding->data; ++ bindings = &cb; ++ } ++ + + GSS_LOCK_MUTEX_CTX(params->utils, text); + maj_stat = +@@ -909,7 +917,7 @@ gssapi_server_mech_authneg(context_t *text, + &(text->gss_ctx), + server_creds, + input_token, +- GSS_C_NO_CHANNEL_BINDINGS, ++ bindings, + &text->client_name, + &mech_type, + output_token, +@@ -1505,7 +1513,8 @@ static sasl_server_plug_t gssapi_server_plugins[] = + | SASL_SEC_PASS_CREDENTIALS, + SASL_FEAT_WANT_CLIENT_FIRST + | SASL_FEAT_ALLOWS_PROXY +- | SASL_FEAT_DONTUSE_USERPASSWD, /* features */ ++ | SASL_FEAT_DONTUSE_USERPASSWD ++ | SASL_FEAT_CHANNEL_BINDING, /* features */ + NULL, /* glob_context */ + &gssapi_server_mech_new, /* mech_new */ + &gssapi_server_mech_step, /* mech_step */ +@@ -1529,6 +1538,7 @@ static sasl_server_plug_t gssapi_server_plugins[] = + SASL_FEAT_WANT_CLIENT_FIRST + | SASL_FEAT_ALLOWS_PROXY + | SASL_FEAT_DONTUSE_USERPASSWD ++ | SASL_FEAT_CHANNEL_BINDING + | SASL_FEAT_SUPPORTS_HTTP, /* features */ + &gss_spnego_oid, /* glob_context */ + &gssapi_server_mech_new, /* mech_new */ +@@ -1662,6 +1672,8 @@ static int gssapi_client_mech_step(void *conn_context, + input_token->value = NULL; + input_token->length = 0; + gss_cred_id_t client_creds = (gss_cred_id_t)params->gss_creds; ++ gss_channel_bindings_t bindings = GSS_C_NO_CHANNEL_BINDINGS; ++ struct gss_channel_bindings_struct cb = {0}; + + if (clientout) + *clientout = NULL; +@@ -1777,6 +1789,12 @@ static int gssapi_client_mech_step(void *conn_context, + req_flags = req_flags | GSS_C_DELEG_FLAG; + } + ++ if (params->cbinding != NULL) { ++ cb.application_data.length = params->cbinding->len; ++ cb.application_data.value = params->cbinding->data; ++ bindings = &cb; ++ } ++ + GSS_LOCK_MUTEX_CTX(params->utils, text); + maj_stat = gss_init_sec_context(&min_stat, + client_creds, /* GSS_C_NO_CREDENTIAL */ +@@ -1785,7 +1803,7 @@ static int gssapi_client_mech_step(void *conn_context, + text->mech_type, + req_flags, + 0, +- GSS_C_NO_CHANNEL_BINDINGS, ++ bindings, + input_token, + NULL, + output_token, +@@ -2190,7 +2208,8 @@ static sasl_client_plug_t gssapi_client_plugins[] = + | SASL_SEC_PASS_CREDENTIALS, /* security_flags */ + SASL_FEAT_NEEDSERVERFQDN + | SASL_FEAT_WANT_CLIENT_FIRST +- | SASL_FEAT_ALLOWS_PROXY, /* features */ ++ | SASL_FEAT_ALLOWS_PROXY ++ | SASL_FEAT_CHANNEL_BINDING, /* features */ + gssapi_required_prompts, /* required_prompts */ + GSS_C_NO_OID, /* glob_context */ + &gssapi_client_mech_new, /* mech_new */ +@@ -2213,6 +2232,7 @@ static sasl_client_plug_t gssapi_client_plugins[] = + SASL_FEAT_NEEDSERVERFQDN + | SASL_FEAT_WANT_CLIENT_FIRST + | SASL_FEAT_ALLOWS_PROXY ++ | SASL_FEAT_CHANNEL_BINDING + | SASL_FEAT_SUPPORTS_HTTP, /* features */ + gssapi_required_prompts, /* required_prompts */ + &gss_spnego_oid, /* glob_context */ +diff --git a/tests/runtests.py b/tests/runtests.py +index f645adf..fc9cf24 100755 +--- a/tests/runtests.py ++++ b/tests/runtests.py +@@ -1,6 +1,7 @@ + #!/usr/bin/python3 + + import argparse ++import base64 + import os + import shutil + import signal +@@ -126,14 +127,7 @@ def setup_kdc(testdir, env): + + return kdc, env + +- +-def gssapi_tests(testdir): +- """ SASL/GSSAPI Tests """ +- env = setup_socket_wrappers(testdir) +- kdc, kenv = setup_kdc(testdir, env) +- #print("KDC: {}, ENV: {}".format(kdc, kenv)) +- kenv['KRB5_TRACE'] = os.path.join(testdir, 'trace.log') +- ++def gssapi_basic_test(kenv): + try: + srv = subprocess.Popen(["../tests/t_gssapi_srv"], + stdout=subprocess.PIPE, +@@ -155,11 +149,94 @@ def gssapi_tests(testdir): + srv.returncode, srv.stderr.read().decode('utf-8'))) + except Exception as e: + print("FAIL: {}".format(e)) ++ return ++ ++ print("PASS: CLI({}) SRV({})".format( ++ cli.stdout.read().decode('utf-8').strip(), ++ srv.stdout.read().decode('utf-8').strip())) ++ ++def gssapi_channel_binding_test(kenv): ++ try: ++ bindings = base64.b64encode("MATCHING CBS".encode('utf-8')) ++ srv = subprocess.Popen(["../tests/t_gssapi_srv", "-c", bindings], ++ 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", "-c", bindings], ++ 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 + + print("PASS: CLI({}) SRV({})".format( + cli.stdout.read().decode('utf-8').strip(), + srv.stdout.read().decode('utf-8').strip())) + ++def gssapi_channel_binding_mismatch_test(kenv): ++ result = "FAIL" ++ try: ++ bindings = base64.b64encode("SRV CBS".encode('utf-8')) ++ srv = subprocess.Popen(["../tests/t_gssapi_srv", "-c", bindings], ++ stdout=subprocess.PIPE, ++ stderr=subprocess.PIPE, env=kenv) ++ 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", "-c", bindings], ++ 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: ++ 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())) ++ ++def gssapi_tests(testdir): ++ """ SASL/GSSAPI Tests """ ++ env = setup_socket_wrappers(testdir) ++ kdc, kenv = setup_kdc(testdir, env) ++ #print("KDC: {}, ENV: {}".format(kdc, kenv)) ++ kenv['KRB5_TRACE'] = os.path.join(testdir, 'trace.log') ++ ++ print('GSSAPI BASIC:') ++ print(' ', end='') ++ gssapi_basic_test(kenv) ++ ++ print('GSSAPI CHANNEL BINDING:') ++ print(' ', end='') ++ gssapi_channel_binding_test(kenv) ++ ++ print('GSSAPI CHANNEL BINDING MISMTACH:') ++ print(' ', end='') ++ gssapi_channel_binding_mismatch_test(kenv) ++ + os.killpg(kdc.pid, signal.SIGTERM) + + +diff --git a/tests/t_common.c b/tests/t_common.c +index 7168b2f..478e6a1 100644 +--- a/tests/t_common.c ++++ b/tests/t_common.c +@@ -1,4 +1,5 @@ +-/* TBD, add (C) */ ++/* Copyright (C) Simo Sorce ++ * See COPYING file for License */ + + #include + +@@ -13,9 +14,6 @@ void send_string(int sd, const char *s, unsigned int l) + { + ssize_t ret; + +-fprintf(stderr, "s:%u ", l); +-fflush(stderr); +- + ret = send(sd, &l, sizeof(l), 0); + if (ret != sizeof(l)) s_error("send size", ret, sizeof(l), errno); + +@@ -34,8 +32,6 @@ void recv_string(int sd, char *buf, unsigned int *buflen) + if (ret != sizeof(l)) s_error("recv size", ret, sizeof(l), errno); + + if (l == 0) { +-fprintf(stderr, "r:0 "); +-fflush(stderr); + *buflen = 0; + return; + } +@@ -45,8 +41,6 @@ fflush(stderr); + ret = recv(sd, buf, l, 0); + if (ret != l) s_error("recv data", ret, l, errno); + +-fprintf(stderr, "r:%ld ", ret); +-fflush(stderr); + *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 +--- a/tests/t_common.h ++++ b/tests/t_common.h +@@ -1,4 +1,5 @@ +-/* TBD, add (C) */ ++/* Copyright (C) Simo Sorce ++ * See COPYING file for License */ + + #include "config.h" + +@@ -7,9 +8,11 @@ + #include + + #include ++#include + + 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 +--- a/tests/t_gssapi_cli.c ++++ b/tests/t_gssapi_cli.c +@@ -1,4 +1,5 @@ +-/* TBD, add (C) */ ++/* Copyright (C) Simo Sorce ++ * See COPYING file for License */ + + #include "t_common.h" + +@@ -13,6 +14,7 @@ + + #include + #include ++#include + + 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 +--- a/tests/t_gssapi_srv.c ++++ b/tests/t_gssapi_srv.c +@@ -1,4 +1,5 @@ +-/* TBD, add (C) */ ++/* Copyright (C) Simo Sorce ++ * See COPYING file for License */ + + #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 + diff --git a/SOURCES/cyrus-sasl-2.1.27-Add-basic-test-infrastructure.patch b/SOURCES/cyrus-sasl-2.1.27-Add-basic-test-infrastructure.patch new file mode 100644 index 0000000..2f6a35c --- /dev/null +++ b/SOURCES/cyrus-sasl-2.1.27-Add-basic-test-infrastructure.patch @@ -0,0 +1,641 @@ +From 82e299e970461c153a036bb1fbc84e808f926e12 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Tue, 5 May 2020 14:06:57 -0400 +Subject: [PATCH] Add basic test infrastructure + +First test is for SASL/GSSAPI + +Backport of upstream commit id: +18ff41d5d18f61c2ded7235dad1d9618aa84784b + +Signed-off-by: Simo Sorce +--- + Makefile.am | 2 +- + configure.ac | 3 +- + tests/Makefile.am | 79 +++++++++++++++++++ + tests/runtests.py | 179 +++++++++++++++++++++++++++++++++++++++++++ + tests/t_common.c | 68 ++++++++++++++++ + tests/t_common.h | 15 ++++ + tests/t_gssapi_cli.c | 95 +++++++++++++++++++++++ + tests/t_gssapi_srv.c | 111 +++++++++++++++++++++++++++ + 8 files changed, 550 insertions(+), 2 deletions(-) + create mode 100644 tests/Makefile.am + create mode 100755 tests/runtests.py + create mode 100644 tests/t_common.c + create mode 100644 tests/t_common.h + create mode 100644 tests/t_gssapi_cli.c + create mode 100644 tests/t_gssapi_srv.c + +diff --git a/Makefile.am b/Makefile.am +index 83dae6f..fc24509 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -70,7 +70,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 + 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 +--- 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) ++pwcheck/Makefile ++tests/Makefile) + + AC_MSG_NOTICE([ + +diff --git a/tests/Makefile.am b/tests/Makefile.am +new file mode 100644 +index 0000000..1edf010 +--- /dev/null ++++ b/tests/Makefile.am +@@ -0,0 +1,79 @@ ++# Makefile.am -- automake input for cyrus-sasl tests ++# Simo Sorce ++# ++################################################################ ++# Copyright (c) 2000 Carnegie Mellon University. All rights reserved. ++# ++# Redistribution and use in source and binary forms, with or without ++# modification, are permitted provided that the following conditions ++# are met: ++# ++# 1. Redistributions of source code must retain the above copyright ++# notice, this list of conditions and the following disclaimer. ++# ++# 2. Redistributions in binary form must reproduce the above copyright ++# notice, this list of conditions and the following disclaimer in ++# the documentation and/or other materials provided with the ++# distribution. ++# ++# 3. The name "Carnegie Mellon University" must not be used to ++# endorse or promote products derived from this software without ++# prior written permission. For permission or any other legal ++# details, please contact ++# Office of Technology Transfer ++# Carnegie Mellon University ++# 5000 Forbes Avenue ++# Pittsburgh, PA 15213-3890 ++# (412) 268-4387, fax: (412) 268-7395 ++# tech-transfer@andrew.cmu.edu ++# ++# 4. Redistributions of any form whatsoever must retain the following ++# acknowledgment: ++# "This product includes software developed by Computing Services ++# at Carnegie Mellon University (http://www.cmu.edu/computing/)." ++# ++# CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO ++# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ++# AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE ++# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN ++# AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING ++# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++# ++################################################################ ++ ++AM_CPPFLAGS=-I$(top_srcdir)/include -DPLUGINDIR='"${top_srcdir}/plugins/.libs"' ++ ++COMMON_LDADD = ../lib/libsasl2.la $(GSSAPIBASE_LIBS) $(GSSAPI_LIBS) $(LIB_SOCKET) ++ ++t_gssapi_cli_SOURCES = \ ++ t_common.c \ ++ t_gssapi_cli.c ++ ++t_gssapi_cli_LDADD = $(COMMON_LDADD) ++ ++t_gssapi_srv_SOURCES = \ ++ t_common.c \ ++ t_gssapi_srv.c ++ ++t_gssapi_srv_LDADD = $(COMMON_LDADD) ++ ++check_PROGRAMS = \ ++ t_gssapi_cli \ ++ t_gssapi_srv \ ++ $(NULL) ++ ++noinst_PROGRAMS = $(check_PROGRAMS) ++ ++EXTRA_DIST = \ ++ runtests.py \ ++ $(NULL) ++ ++all: $(check_PROGRAMS) ++ ++check: ++if MACOSX ++# skip Mac OSX for now ++else ++ $(srcdir)/runtests.py $(CHECKARGS) ++endif +diff --git a/tests/runtests.py b/tests/runtests.py +new file mode 100755 +index 0000000..f645adf +--- /dev/null ++++ b/tests/runtests.py +@@ -0,0 +1,179 @@ ++#!/usr/bin/python3 ++ ++import argparse ++import os ++import shutil ++import signal ++import subprocess ++import time ++from string import Template ++ ++ ++def setup_socket_wrappers(testdir): ++ """ Try to set up socket wrappers """ ++ wrapdir = os.path.join(testdir, 'w') ++ os.makedirs(wrapdir) ++ ++ wrappers = subprocess.Popen(['pkg-config', '--exists', 'socket_wrapper']) ++ wrappers.wait() ++ if wrappers.returncode != 0: ++ raise Exception('Socket Wrappers not available') ++ ++ wrappers = subprocess.Popen(['pkg-config', '--exists', 'nss_wrapper']) ++ wrappers.wait() ++ if wrappers.returncode != 0: ++ raise Exception('NSS Wrappers not available') ++ ++ hosts = os.path.join(wrapdir, 'hosts') ++ with open(hosts, 'w+') as conffile: ++ conffile.write('127.0.0.9 host.realm.test') ++ ++ return {'LD_PRELOAD': 'libsocket_wrapper.so libnss_wrapper.so', ++ 'SOCKET_WRAPPER_DIR': wrapdir, ++ 'SOCKET_WRAPPER_DEFAULT_IFACE': '9', ++ 'NSS_WRAPPER_HOSTNAME': 'host.realm.test', ++ 'NSS_WRAPPER_HOSTS': hosts} ++ ++ ++KERBEROS_CONF = ''' ++[libdefaults] ++ default_realm = REALM.TEST ++ dns_lookup_realm = false ++ dns_lookup_kdc = false ++ rdns = false ++ ticket_lifetime = 24h ++ forwardable = yes ++ default_ccache_name = FILE://${TESTDIR}/ccache ++ udp_preference_limit = 1 ++ ++[domain_realm] ++ .realm.test = REALM.TEST ++ realm.test = REALM.TEST ++ ++[realms] ++ REALM.TEST = { ++ kdc = 127.0.0.9 ++ admin_server = 127.0.0.9 ++ acl_file = ${TESTDIR}/kadm.acl ++ dict_file = /usr/share/dict/words ++ admin_keytab = ${TESTDIR}/kadm.keytab ++ database_name = ${TESTDIR}/kdc.db ++ key_stash_file = ${TESTDIR}/kdc.stash ++ } ++ ++[kdcdefaults] ++ kdc_ports = 88 ++ kdc_tcp_ports = 88 ++ ++[logging] ++ kdc = FILE:${TESTDIR}/kdc.log ++ admin_server = FILE:${TESTDIR}/kadm.log ++ default = FILE:${TESTDIR}/krb5.log ++''' ++ ++ ++def setup_kdc(testdir, env): ++ """ Setup KDC and start process """ ++ krbconf = os.path.join(testdir, 'krb.conf') ++ env['KRB5_CONFIG'] = krbconf ++ ++ kenv = {'KRB5_KDC_PROFILE': krbconf, ++ 'PATH': '/sbin:/bin:/usr/sbin:/usr/bin'} ++ kenv.update(env) ++ ++ # KDC/KRB5 CONFIG ++ templ = Template(KERBEROS_CONF) ++ text = templ.substitute({'TESTDIR': testdir}) ++ with open(krbconf, 'w+') as conffile: ++ conffile.write(text) ++ ++ testlog = os.path.join(testdir, 'kdc.log') ++ log = open(testlog, 'a') ++ ++ subprocess.check_call([ ++ "kdb5_util", "create", ++ "-r", "REALM.TEST", "-s", "-P", "password" ++ ], stdout=log, stderr=log, env=kenv, timeout=5) ++ ++ kdc = subprocess.Popen(['krb5kdc', '-n'], env=kenv, preexec_fn=os.setsid) ++ time.sleep(5) ++ ++ # Add a user and genrate a keytab ++ keytab = os.path.join(testdir, "user.keytab") ++ subprocess.check_call([ ++ "kadmin.local", "-q", ++ "addprinc -randkey user" ++ ], stdout=log, stderr=log, env=kenv, timeout=5) ++ ++ subprocess.check_call([ ++ "kadmin.local", "-q", ++ "ktadd -k {} user".format(keytab) ++ ], stdout=log, stderr=log, env=kenv, timeout=5) ++ env['KRB5_CLIENT_KTNAME'] = keytab ++ ++ # Add a service and genrate a keytab ++ keytab = os.path.join(testdir, "test.keytab") ++ subprocess.check_call([ ++ "kadmin.local", "-q", ++ "addprinc -randkey test/host.realm.test" ++ ], stdout=log, stderr=log, env=kenv, timeout=5) ++ ++ subprocess.check_call([ ++ "kadmin.local", "-q", ++ "ktadd -k {} test/host.realm.test".format(keytab) ++ ], stdout=log, stderr=log, env=kenv, timeout=5) ++ env['KRB5_KTNAME'] = keytab ++ ++ return kdc, env ++ ++ ++def gssapi_tests(testdir): ++ """ SASL/GSSAPI Tests """ ++ env = setup_socket_wrappers(testdir) ++ kdc, kenv = setup_kdc(testdir, env) ++ #print("KDC: {}, ENV: {}".format(kdc, kenv)) ++ kenv['KRB5_TRACE'] = os.path.join(testdir, 'trace.log') ++ ++ try: ++ srv = subprocess.Popen(["../tests/t_gssapi_srv"], ++ 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"], ++ 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)) ++ ++ print("PASS: CLI({}) SRV({})".format( ++ cli.stdout.read().decode('utf-8').strip(), ++ srv.stdout.read().decode('utf-8').strip())) ++ ++ os.killpg(kdc.pid, signal.SIGTERM) ++ ++ ++if __name__ == "__main__": ++ ++ P = argparse.ArgumentParser(description='Cyrus SASL Tests') ++ P.add_argument('--testdir', default=os.path.join(os.getcwd(), '.tests'), ++ help="Directory for running tests") ++ A = vars(P.parse_args()) ++ ++ T = A['testdir'] ++ ++ if os.path.exists(T): ++ shutil.rmtree(T) ++ os.makedirs(T) ++ ++ gssapi_tests(T) +diff --git a/tests/t_common.c b/tests/t_common.c +new file mode 100644 +index 0000000..7168b2f +--- /dev/null ++++ b/tests/t_common.c +@@ -0,0 +1,68 @@ ++/* TBD, add (C) */ ++ ++#include ++ ++void s_error(const char *hdr, ssize_t ret, ssize_t len, int err) ++{ ++ fprintf(stderr, "%s l:%ld/%ld [%d] %s", ++ hdr, ret, len, err, strerror(err)); ++ exit(-1); ++} ++ ++void send_string(int sd, const char *s, unsigned int l) ++{ ++ ssize_t ret; ++ ++fprintf(stderr, "s:%u ", l); ++fflush(stderr); ++ ++ ret = send(sd, &l, sizeof(l), 0); ++ if (ret != sizeof(l)) s_error("send size", ret, sizeof(l), errno); ++ ++ if (l == 0) return; ++ ++ ret = send(sd, s, l, 0); ++ if (ret != l) s_error("send data", ret, l, errno); ++} ++ ++void recv_string(int sd, char *buf, unsigned int *buflen) ++{ ++ unsigned int l; ++ ssize_t ret; ++ ++ ret = recv(sd, &l, sizeof(l), MSG_WAITALL); ++ if (ret != sizeof(l)) s_error("recv size", ret, sizeof(l), errno); ++ ++ if (l == 0) { ++fprintf(stderr, "r:0 "); ++fflush(stderr); ++ *buflen = 0; ++ return; ++ } ++ ++ if (*buflen < l) s_error("recv len", l, *buflen, E2BIG); ++ ++ ret = recv(sd, buf, l, 0); ++ if (ret != l) s_error("recv data", ret, l, errno); ++ ++fprintf(stderr, "r:%ld ", ret); ++fflush(stderr); ++ *buflen = ret; ++} ++ ++void saslerr(int why, const char *what) ++{ ++ fprintf(stderr, "%s: %s", what, sasl_errstring(why, NULL, NULL)); ++} ++ ++int getpath(void *context __attribute__((unused)), const char **path) ++{ ++ if (! path) { ++ return SASL_BADPARAM; ++ } ++ ++ *path = PLUGINDIR; ++ return SASL_OK; ++} ++ ++ +diff --git a/tests/t_common.h b/tests/t_common.h +new file mode 100644 +index 0000000..4ee1976 +--- /dev/null ++++ b/tests/t_common.h +@@ -0,0 +1,15 @@ ++/* TBD, add (C) */ ++ ++#include "config.h" ++ ++#include ++#include ++#include ++ ++#include ++ ++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); +diff --git a/tests/t_gssapi_cli.c b/tests/t_gssapi_cli.c +new file mode 100644 +index 0000000..c833c05 +--- /dev/null ++++ b/tests/t_gssapi_cli.c +@@ -0,0 +1,95 @@ ++/* TBD, add (C) */ ++ ++#include "t_common.h" ++ ++#include ++#include ++#include ++#include ++ ++#ifdef HAVE_UNISTD_H ++#include ++#endif ++ ++#include ++#include ++ ++static int setup_socket(void) ++{ ++ struct sockaddr_in addr; ++ int sock, ret; ++ ++ sock = socket(AF_INET, SOCK_STREAM, 0); ++ if (sock < 0) s_error("socket", 0, 0, errno); ++ ++ addr.sin_family = AF_INET; ++ addr.sin_addr.s_addr = inet_addr("127.0.0.9"); ++ addr.sin_port = htons(9000); ++ ++ ret = connect(sock, (struct sockaddr *)&addr, sizeof(addr)); ++ if (ret != 0) s_error("connect", 0, 0, errno); ++ ++ return sock; ++} ++ ++int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused))) ++{ ++ sasl_callback_t callbacks[2] = {}; ++ char buf[8192]; ++ const char *chosenmech; ++ sasl_conn_t *conn; ++ const char *data; ++ unsigned int len; ++ int sd; ++ int r; ++ ++ /* 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].context = NULL; ++ ++ r = sasl_client_init(callbacks); ++ if (r != SASL_OK) exit(-1); ++ ++ r = sasl_client_new("test", "host.realm.test", NULL, NULL, NULL, 0, &conn); ++ if (r != SASL_OK) { ++ saslerr(r, "allocating connection state"); ++ exit(-1); ++ } ++ ++ r = sasl_client_start(conn, "GSSAPI", 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); ++ } ++ ++ sd = setup_socket(); ++ ++ while (r == SASL_CONTINUE) { ++ send_string(sd, data, len); ++ 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); ++ } ++ } ++ ++ if (r != SASL_OK) exit(-1); ++ ++ if (len > 0) { ++ send_string(sd, data, len); ++ } ++ ++ fprintf(stdout, "DONE\n"); ++ fflush(stdout); ++ return 0; ++} ++ +diff --git a/tests/t_gssapi_srv.c b/tests/t_gssapi_srv.c +new file mode 100644 +index 0000000..29f538d +--- /dev/null ++++ b/tests/t_gssapi_srv.c +@@ -0,0 +1,111 @@ ++/* TBD, add (C) */ ++ ++#include "t_common.h" ++ ++#include ++#include ++#include ++#include ++ ++#ifdef HAVE_UNISTD_H ++#include ++#endif ++ ++#include ++#include ++ ++static int setup_socket(void) ++{ ++ struct sockaddr_in addr; ++ int sock, ret, sd; ++ ++ sock = socket(AF_INET, SOCK_STREAM, 0); ++ if (sock < 0) s_error("socket", 0, 0, errno); ++ ++ addr.sin_family = AF_INET; ++ addr.sin_addr.s_addr = inet_addr("127.0.0.9"); ++ addr.sin_port = htons(9000); ++ ++ ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr)); ++ if (ret != 0) s_error("bind", 0, 0, errno); ++ ++ ret = listen(sock, 1); ++ if (ret != 0) s_error("listen", 0, 0, errno); ++ ++ /* signal we are ready */ ++ fprintf(stdout, "READY\n"); ++ fflush(stdout); ++ ++ /* block until the client connects */ ++ sd = accept(sock, NULL, NULL); ++ if (sd < 0) s_error("accept", 0, 0, errno); ++ ++ close(sock); ++ return sd; ++} ++ ++int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused))) ++{ ++ sasl_callback_t callbacks[2] = {}; ++ char buf[8192]; ++ sasl_conn_t *conn; ++ const char *data; ++ unsigned int len; ++ int sd; ++ int r; ++ ++ /* 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].context = NULL; ++ ++ r = sasl_server_init(callbacks, "t_gssapi_srv"); ++ if (r != SASL_OK) exit(-1); ++ ++ r = sasl_server_new("test", "host.realm.test", NULL, NULL, NULL, ++ callbacks, 0, &conn); ++ if (r != SASL_OK) { ++ saslerr(r, "allocating connection state"); ++ exit(-1); ++ } ++ ++ sd = setup_socket(); ++ ++ len = 8192; ++ recv_string(sd, buf, &len); ++ ++ r = sasl_server_start(conn, "GSSAPI", 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); ++ } ++ ++ while (r == SASL_CONTINUE) { ++ send_string(sd, data, len); ++ 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); ++ } ++ ++ } ++ ++ if (r != SASL_OK) exit(-1); ++ ++ if (len > 0) { ++ send_string(sd, data, len); ++ } ++ ++ fprintf(stdout, "DONE\n"); ++ fflush(stdout); ++ return 0; ++} ++ +-- +2.18.2 + diff --git a/SOURCES/cyrus-sasl-2.1.27-Add-basic-test-plain-auth.patch b/SOURCES/cyrus-sasl-2.1.27-Add-basic-test-plain-auth.patch new file mode 100644 index 0000000..35903d0 --- /dev/null +++ b/SOURCES/cyrus-sasl-2.1.27-Add-basic-test-plain-auth.patch @@ -0,0 +1,411 @@ +diff -Nru cyrus-sasl-2.1.27/tests/runtests.py cyrus-sasl-2.1.27-beldmit/tests/runtests.py +--- cyrus-sasl-2.1.27/tests/runtests.py 2020-12-23 14:31:35.564537485 +0100 ++++ cyrus-sasl-2.1.27-beldmit/tests/runtests.py 2020-12-23 14:30:46.933219377 +0100 +@@ -313,6 +313,99 @@ + + return err + ++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 1 ++ ++ print("PASS: PLAIN CLI({}) SRV({})".format( ++ cli.stdout.read().decode('utf-8').strip(), ++ srv.stdout.read().decode('utf-8').strip())) ++ return 0 ++ ++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 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 plain_tests(testdir): ++ err = 0 ++ sasldbfile, sasldbenv = setup_plain(testdir) ++ #print("DB file: {}, ENV: {}".format(sasldbfile, sasldbenv)) ++ print('SASLDB PLAIN:') ++ print(' ', end='') ++ err += plain_test(sasldbfile, sasldbenv) ++ ++ print('SASLDB PLAIN PASSWORD MISMATCH:') ++ print(' ', end='') ++ err += plain_mismatch_test(sasldbfile, sasldbenv) ++ ++ return err + + if __name__ == "__main__": + +@@ -329,5 +422,9 @@ + + err = gssapi_tests(T) + if err != 0: +- print('{} test(s) FAILED'.format(err)) ++ print('{} GSSAPI test(s) FAILED'.format(err)) ++ ++ err = plain_tests(T) ++ if err != 0: ++ print('{} PLAIN test(s) FAILED'.format(err)) + sys.exit(-1) +diff -Nru cyrus-sasl-2.1.27/tests/t_gssapi_cli.c cyrus-sasl-2.1.27-beldmit/tests/t_gssapi_cli.c +--- cyrus-sasl-2.1.27/tests/t_gssapi_cli.c 2020-12-23 14:31:35.564537485 +0100 ++++ cyrus-sasl-2.1.27-beldmit/tests/t_gssapi_cli.c 2021-01-06 11:26:15.460662537 +0100 +@@ -16,6 +16,8 @@ + #include + #include + ++const char *testpass = NULL; ++ + static int setup_socket(void) + { + struct sockaddr_in addr; +@@ -34,9 +36,60 @@ + 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; +@@ -49,8 +102,9 @@ + const char *sasl_mech = "GSSAPI"; + bool spnego = false; + bool zeromaxssf = false; ++ bool plain = false; + +- while ((c = getopt(argc, argv, "c:zN")) != EOF) { ++ while ((c = getopt(argc, argv, "c:zNP:")) != EOF) { + switch (c) { + case 'c': + parse_cb(&cb, cb_buf, 256, optarg); +@@ -61,6 +115,10 @@ + case 'N': + spnego = true; + break; ++ case 'P': ++ plain = true; ++ testpass = optarg; ++ break; + default: + break; + } +@@ -73,6 +131,12 @@ + 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; + + r = sasl_client_init(callbacks); + if (r != SASL_OK) exit(-1); +@@ -91,6 +155,16 @@ + sasl_mech = "GSS-SPNEGO"; + } + ++ 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; ++ } ++ + if (zeromaxssf) { + /* set all security properties to 0 including maxssf */ + sasl_security_properties_t secprops = { 0 }; +@@ -99,9 +173,9 @@ + + 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(); +@@ -111,11 +185,11 @@ + len = 8192; + recv_string(sd, buf, &len, false); + +- 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 -Nru cyrus-sasl-2.1.27/tests/t_gssapi_srv.c cyrus-sasl-2.1.27-beldmit/tests/t_gssapi_srv.c +--- cyrus-sasl-2.1.27/tests/t_gssapi_srv.c 2020-12-23 14:31:35.565537492 +0100 ++++ cyrus-sasl-2.1.27-beldmit/tests/t_gssapi_srv.c 2021-01-06 11:27:48.373257373 +0100 +@@ -1,4 +1,5 @@ +-/* Copyright (C) Simo Sorce ++/* Copyright (C) Simo Sorce , ++ * Dmitry Belyavskiy + * See COPYING file for License */ + + #include "t_common.h" +@@ -15,6 +16,10 @@ + #include + #include + ++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 @@ + 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; +@@ -59,8 +93,9 @@ + const char *sasl_mech = "GSSAPI"; + bool spnego = false; + bool zeromaxssf = false; ++ bool plain = false; + +- while ((c = getopt(argc, argv, "c:zN")) != EOF) { ++ while ((c = getopt(argc, argv, "c:zNP:")) != EOF) { + switch (c) { + case 'c': + parse_cb(&cb, cb_buf, 256, optarg); +@@ -71,6 +106,10 @@ + case 'N': + spnego = true; + break; ++ case 'P': ++ plain = true; ++ sasldb_path = optarg; ++ break; + default: + break; + } +@@ -81,9 +120,12 @@ + 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); +@@ -103,6 +145,10 @@ + sasl_mech = "GSS-SPNEGO"; + } + ++ if (plain) { ++ sasl_mech = "PLAIN"; ++ } ++ + if (zeromaxssf) { + /* set all security properties to 0 including maxssf */ + sasl_security_properties_t secprops = { 0 }; +@@ -116,9 +162,9 @@ + + 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) { +@@ -126,12 +172,12 @@ + len = 8192; + recv_string(sd, buf, &len, true); + +- 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); ++ } + } + + if (r != SASL_OK) exit(-1); diff --git a/SOURCES/cyrus-sasl-2.1.27-Add-support-for-setting-max-ssf-0-to-GSS-SPNEGO.patch b/SOURCES/cyrus-sasl-2.1.27-Add-support-for-setting-max-ssf-0-to-GSS-SPNEGO.patch new file mode 100644 index 0000000..c8c4a79 --- /dev/null +++ b/SOURCES/cyrus-sasl-2.1.27-Add-support-for-setting-max-ssf-0-to-GSS-SPNEGO.patch @@ -0,0 +1,435 @@ +From 49e965f41257a0ed299c58a7cf1c120ddf944aaa Mon Sep 17 00:00:00 2001 +From: Simo Sorce +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 +--- + 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 ++ ]) ++ 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 ++#include + #include + #include + +@@ -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 + diff --git a/SOURCES/cyrus-sasl-2.1.27-Emit-debug-log-only-in-case-of-errors.patch b/SOURCES/cyrus-sasl-2.1.27-Emit-debug-log-only-in-case-of-errors.patch new file mode 100644 index 0000000..d5e1334 --- /dev/null +++ b/SOURCES/cyrus-sasl-2.1.27-Emit-debug-log-only-in-case-of-errors.patch @@ -0,0 +1,42 @@ +From ec070b2e83a4ee698c08d6d68c205aea4d90b0bb Mon Sep 17 00:00:00 2001 +From: Simo Sorce +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 +--- + 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 + diff --git a/SOURCES/cyrus-sasl-2.1.27-Migration-from-BerkeleyDB.patch b/SOURCES/cyrus-sasl-2.1.27-Migration-from-BerkeleyDB.patch new file mode 100644 index 0000000..cc999e5 --- /dev/null +++ b/SOURCES/cyrus-sasl-2.1.27-Migration-from-BerkeleyDB.patch @@ -0,0 +1,569 @@ +diff -up cyrus-sasl-2.1.27/configure.ac.frombdb cyrus-sasl-2.1.27/configure.ac +--- cyrus-sasl-2.1.27/configure.ac.frombdb 2021-06-04 13:02:07.790112263 +0200 ++++ cyrus-sasl-2.1.27/configure.ac 2021-06-04 13:02:07.798112327 +0200 +@@ -1091,6 +1091,9 @@ AC_SUBST(SASL_STATIC_SRCS) + AC_SUBST(SASL_STATIC_OBJS) + AC_SUBST(SASL_STATIC_LIBS) + ++CYRUS_BERKELEY_DB_STATIC_LIB() ++AC_SUBST(BDB_STATIC_LIBADD) ++ + AC_ARG_WITH(plugindir, [ --with-plugindir=DIR set the directory where plugins will + be found [[LIBDIR/sasl2]] ], + plugindir=$withval, +diff -up cyrus-sasl-2.1.27/m4/berkdb.m4.frombdb cyrus-sasl-2.1.27/m4/berkdb.m4 +--- cyrus-sasl-2.1.27/m4/berkdb.m4.frombdb 2016-01-29 18:35:35.000000000 +0100 ++++ cyrus-sasl-2.1.27/m4/berkdb.m4 2021-06-04 13:02:07.798112327 +0200 +@@ -286,3 +286,10 @@ AC_DEFUN([CYRUS_BERKELEY_DB_CHK], + + CPPFLAGS=$cmu_save_CPPFLAGS + ]) ++ ++AC_DEFUN([CYRUS_BERKELEY_DB_STATIC_LIB], ++[ ++BDB_STATIC_LIBADD="/dev/null -lpthread" ++AC_CHECK_FILE([/usr/lib64/libdb-5.3.a],[BDB_STATIC_LIBADD="/usr/lib64/libdb-5.3.a -lpthread "],[]) ++AC_CHECK_FILE([/usr/lib/libdb-5.3.a],[BDB_STATIC_LIBADD="/usr/lib/libdb-5.3.a -lpthread"],[]) ++]) +diff -up cyrus-sasl-2.1.27/m4/sasldb.m4.frombdb cyrus-sasl-2.1.27/m4/sasldb.m4 +--- cyrus-sasl-2.1.27/m4/sasldb.m4.frombdb 2017-07-13 20:45:19.000000000 +0200 ++++ cyrus-sasl-2.1.27/m4/sasldb.m4 2021-06-04 13:02:07.798112327 +0200 +@@ -111,7 +111,7 @@ AC_MSG_RESULT($dblib) + SASL_DB_BACKEND="db_${dblib}.lo" + SASL_DB_BACKEND_STATIC="db_${dblib}.o allockey.o" + SASL_DB_BACKEND_STATIC_SRCS="\$(top_srcdir)/sasldb/db_${dblib}.c \$(top_srcdir)/sasldb/allockey.c" +-SASL_DB_UTILS="saslpasswd2 sasldblistusers2" ++SASL_DB_UTILS="cyrusbdb2current saslpasswd2 sasldblistusers2" + SASL_DB_MANS="saslpasswd2.8 sasldblistusers2.8" + + case "$dblib" in +diff -up cyrus-sasl-2.1.27/sasldb/db_gdbm.c.frombdb cyrus-sasl-2.1.27/sasldb/db_gdbm.c +--- cyrus-sasl-2.1.27/sasldb/db_gdbm.c.frombdb 2017-07-13 14:34:03.000000000 +0200 ++++ cyrus-sasl-2.1.27/sasldb/db_gdbm.c 2021-06-04 13:04:24.098206887 +0200 +@@ -67,6 +67,7 @@ int _sasldb_getdata(const sasl_utils_t * + void *cntxt; + sasl_getopt_t *getopt; + const char *path = SASL_DB_PATH; ++ int fetch_errno = 0; + + if (!utils) return SASL_BADPARAM; + if (!authid || !propName || !realm || !out || !max_out) { +@@ -99,6 +100,9 @@ int _sasldb_getdata(const sasl_utils_t * + } + db = gdbm_open((char *)path, 0, GDBM_READER, S_IRUSR | S_IWUSR, NULL); + if (! db) { ++ utils->log(conn, SASL_LOG_ERR, ++ "SASL error opening password file. " ++ "Have you performed the migration from db2 using cyrusbdb2current?\n"); + utils->seterror(cntxt, 0, "Could not open %s: gdbm_errno=%d", + path, gdbm_errno); + result = SASL_FAIL; +@@ -107,9 +111,10 @@ int _sasldb_getdata(const sasl_utils_t * + gkey.dptr = key; + gkey.dsize = key_len; + gvalue = gdbm_fetch(db, gkey); ++ fetch_errno = gdbm_errno; + gdbm_close(db); + if (! gvalue.dptr) { +- if (gdbm_errno == GDBM_ITEM_NOT_FOUND) { ++ if (fetch_errno == GDBM_ITEM_NOT_FOUND) { + utils->seterror(conn, SASL_NOLOG, + "user: %s@%s property: %s not found in %s", + authid, realm, propName, path); +@@ -186,7 +191,8 @@ int _sasldb_putdata(const sasl_utils_t * + if (! db) { + utils->log(conn, SASL_LOG_ERR, + "SASL error opening password file. " +- "Do you have write permissions?\n"); ++ "Do you have write permissions?\n" ++ "Have you performed the migration from db2 using cyrusbdb2current?\n"); + utils->seterror(conn, 0, "Could not open %s for write: gdbm_errno=%d", + path, gdbm_errno); + result = SASL_FAIL; +@@ -298,6 +304,9 @@ sasldb_handle _sasldb_getkeyhandle(const + db = gdbm_open((char *)path, 0, GDBM_READER, S_IRUSR | S_IWUSR, NULL); + + if(!db) { ++ utils->log(conn, SASL_LOG_ERR, ++ "SASL error opening password file. " ++ "Have you performed the migration from db2 using cyrusbdb2current?\n"); + utils->seterror(conn, 0, "Could not open %s: gdbm_errno=%d", + path, gdbm_errno); + return NULL; +diff -up cyrus-sasl-2.1.27/utils/cyrusbdb2current.8.frombdb cyrus-sasl-2.1.27/utils/cyrusbdb2current.8 +--- cyrus-sasl-2.1.27/utils/cyrusbdb2current.8.frombdb 2021-06-04 13:02:07.798112327 +0200 ++++ cyrus-sasl-2.1.27/utils/cyrusbdb2current.8 2021-06-04 13:02:07.798112327 +0200 +@@ -0,0 +1,159 @@ ++.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40) ++.\" ++.\" Standard preamble: ++.\" ======================================================================== ++.de Sp \" Vertical space (when we can't use .PP) ++.if t .sp .5v ++.if n .sp ++.. ++.de Vb \" Begin verbatim text ++.ft CW ++.nf ++.ne \\$1 ++.. ++.de Ve \" End verbatim text ++.ft R ++.fi ++.. ++.\" Set up some character translations and predefined strings. \*(-- will ++.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left ++.\" double quote, and \*(R" will give a right double quote. \*(C+ will ++.\" give a nicer C++. Capital omega is used to do unbreakable dashes and ++.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, ++.\" nothing in troff, for use with C<>. ++.tr \(*W- ++.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' ++.ie n \{\ ++. ds -- \(*W- ++. ds PI pi ++. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch ++. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch ++. ds L" "" ++. ds R" "" ++. ds C` "" ++. ds C' "" ++'br\} ++.el\{\ ++. ds -- \|\(em\| ++. ds PI \(*p ++. ds L" `` ++. ds R" '' ++. ds C` ++. ds C' ++'br\} ++.\" ++.\" Escape single quotes in literal strings from groff's Unicode transform. ++.ie \n(.g .ds Aq \(aq ++.el .ds Aq ' ++.\" ++.\" If the F register is >0, we'll generate index entries on stderr for ++.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index ++.\" entries marked with X<> in POD. Of course, you'll have to process the ++.\" output yourself in some meaningful fashion. ++.\" ++.\" Avoid warning from groff about undefined register 'F'. ++.de IX ++.. ++.nr rF 0 ++.if \n(.g .if rF .nr rF 1 ++.if (\n(rF:(\n(.g==0)) \{\ ++. if \nF \{\ ++. de IX ++. tm Index:\\$1\t\\n%\t"\\$2" ++.. ++. if !\nF==2 \{\ ++. nr % 0 ++. nr F 2 ++. \} ++. \} ++.\} ++.rr rF ++.\" ++.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). ++.\" Fear. Run. Save yourself. No user-serviceable parts. ++. \" fudge factors for nroff and troff ++.if n \{\ ++. ds #H 0 ++. ds #V .8m ++. ds #F .3m ++. ds #[ \f1 ++. ds #] \fP ++.\} ++.if t \{\ ++. ds #H ((1u-(\\\\n(.fu%2u))*.13m) ++. ds #V .6m ++. ds #F 0 ++. ds #[ \& ++. ds #] \& ++.\} ++. \" simple accents for nroff and troff ++.if n \{\ ++. ds ' \& ++. ds ` \& ++. ds ^ \& ++. ds , \& ++. ds ~ ~ ++. ds / ++.\} ++.if t \{\ ++. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" ++. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' ++. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' ++. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' ++. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' ++. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' ++.\} ++. \" troff and (daisy-wheel) nroff accents ++.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' ++.ds 8 \h'\*(#H'\(*b\h'-\*(#H' ++.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] ++.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' ++.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' ++.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] ++.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] ++.ds ae a\h'-(\w'a'u*4/10)'e ++.ds Ae A\h'-(\w'A'u*4/10)'E ++. \" corrections for vroff ++.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' ++.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' ++. \" for low resolution devices (crt and lpr) ++.if \n(.H>23 .if \n(.V>19 \ ++\{\ ++. ds : e ++. ds 8 ss ++. ds o a ++. ds d- d\h'-1'\(ga ++. ds D- D\h'-1'\(hy ++. ds th \o'bp' ++. ds Th \o'LP' ++. ds ae ae ++. ds Ae AE ++.\} ++.rm #[ #] #H #V #F C ++.\" ======================================================================== ++.\" ++.IX Title "CYRUSBDB2CURRENT 1" ++.TH CYRUSBDB2CURRENT 1 "2021-04-28" "perl v5.30.3" "User Contributed Perl Documentation" ++.\" For nroff, turn off justification. Always turn off hyphenation; it makes ++.\" way too many mistakes in technical documents. ++.if n .ad l ++.nh ++.SH "NAME" ++cyrusbdb2current \- command\-line utility converting the SASLDB database from ++BerkeleyDB to the database format currently used bys sasldb. ++.SH "SYNOPSIS" ++.IX Header "SYNOPSIS" ++cyrusbdb2current ++.SH "DESCRIPTION" ++.IX Header "DESCRIPTION" ++\&\fBcyrusbdb2current\fR converts the current sasldb database from BerkeleyDB format to the ++currently used database format. It is \fB\s-1STRONGLY RECOMMENDED\s0\fR to make a backup ++of the current database before the conversion. ++.PP ++We expect that the old path is \fB/etc/sasldb2\fR and the new one is ++\&\fB/etc/sasl2/sasldb2\fR ++.SH "SEE ALSO" ++.IX Header "SEE ALSO" ++\&\fBsaslpasswd2\fR\|(8) ++.PP ++rfc4422 \- Simple Authentication and Security Layer (\s-1SASL\s0) +diff -up cyrus-sasl-2.1.27/utils/cyrusbdb2current.c.frombdb cyrus-sasl-2.1.27/utils/cyrusbdb2current.c +--- cyrus-sasl-2.1.27/utils/cyrusbdb2current.c.frombdb 2021-06-04 13:02:07.798112327 +0200 ++++ cyrus-sasl-2.1.27/utils/cyrusbdb2current.c 2021-06-04 13:02:07.798112327 +0200 +@@ -0,0 +1,282 @@ ++#include ++ ++#include ++#include ++ ++#include ++#include ++#include "../sasldb/sasldb.h" ++ ++/* Cheating to make the utils work out right */ ++extern const sasl_utils_t *sasl_global_utils; ++sasl_conn_t *globalconn; ++ ++typedef void *listcb_t(const char *, const char *, const char *, ++ const char *, unsigned); ++ ++void listusers_cb(const char *authid, const char *realm, ++ const char *propName, const char *secret, ++ unsigned seclen) ++{ ++ if (!authid || !propName || !realm) { ++ fprintf(stderr,"userlist callback has bad param"); ++ return; ++ } ++ ++ /* the entries that just say the mechanism exists */ ++ if (strlen(authid)==0) return; ++ ++ printf("Converting: %s@%s (%s)...",authid,realm,propName); ++ ++ _sasldb_putdata(sasl_global_utils, globalconn, ++ authid, realm, propName, ++ secret, seclen); ++ ++ printf("ok\n"); ++} ++ ++/* ++ * List all users in database ++ */ ++ ++#include ++ ++#define DB_VERSION_FULL ((DB_VERSION_MAJOR << 24) | (DB_VERSION_MINOR << 16) | DB_VERSION_PATCH) ++/* ++ * Open the database ++ * ++ */ ++static int berkeleydb_open(const char *path,DB **mbdb) ++{ ++ int ret; ++ ++#if DB_VERSION_FULL < 0x03000000 ++ ret = db_open(path, DB_HASH, DB_CREATE, 0664, NULL, NULL, mbdb); ++#else /* DB_VERSION_FULL < 0x03000000 */ ++ ret = db_create(mbdb, NULL, 0); ++ if (ret == 0 && *mbdb != NULL) ++ { ++#if DB_VERSION_FULL >= 0x04010000 ++ ret = (*mbdb)->open(*mbdb, NULL, path, NULL, DB_HASH, DB_CREATE, 0664); ++#else ++ ret = (*mbdb)->open(*mbdb, path, NULL, DB_HASH, DB_CREATE, 0664); ++#endif ++ if (ret != 0) ++ { ++ (void) (*mbdb)->close(*mbdb, 0); ++ *mbdb = NULL; ++ } ++ } ++#endif /* DB_VERSION_FULL < 0x03000000 */ ++ ++ if (ret != 0) { ++ fprintf(stderr,"Error opening password file %s\n", path); ++ return SASL_FAIL; ++ } ++ ++ return SASL_OK; ++} ++ ++/* ++ * Close the database ++ * ++ */ ++ ++static void berkeleydb_close(DB *mbdb) ++{ ++ int ret; ++ ++ ret = mbdb->close(mbdb, 0); ++ if (ret!=0) { ++ fprintf(stderr,"error closing sasldb: %s", ++ db_strerror(ret)); ++ } ++} ++ ++int listusers(const char *path, listcb_t *cb) ++{ ++ int result; ++ DB *mbdb = NULL; ++ DBC *cursor; ++ DBT key, data; ++ ++ /* open the db */ ++ result=berkeleydb_open(path, &mbdb); ++ if (result!=SASL_OK) goto cleanup; ++ ++ /* make cursor */ ++#if DB_VERSION_FULL < 0x03060000 ++ result = mbdb->cursor(mbdb, NULL,&cursor); ++#else ++ result = mbdb->cursor(mbdb, NULL,&cursor, 0); ++#endif /* DB_VERSION_FULL < 0x03060000 */ ++ ++ if (result!=0) { ++ fprintf(stderr,"Making cursor failure: %s\n",db_strerror(result)); ++ result = SASL_FAIL; ++ goto cleanup; ++ } ++ ++ memset(&key,0, sizeof(key)); ++ memset(&data,0,sizeof(data)); ++ ++ /* loop thru */ ++ result = cursor->c_get(cursor, &key, &data, ++ DB_FIRST); ++ ++ while (result != DB_NOTFOUND) ++ { ++ char *authid; ++ char *realm; ++ char *tmp; ++ unsigned int len; ++ char prop[1024]; ++ int numnulls = 0; ++ unsigned int lup; ++ ++ /* make sure there are exactly 2 null's */ ++ for (lup=0;lupc_get(cursor, &key, &data, DB_NEXT); ++ continue; ++ } ++ ++ authid = key.data; ++ realm = authid + strlen(authid)+1; ++ tmp = realm + strlen(realm)+1; ++ len = key.size - (tmp - authid); ++ ++ /* make sure we have enough space of prop */ ++ if (len >=sizeof(prop)) { ++ fprintf(stderr,"warning: absurdly long prop name\n"); ++ result = cursor->c_get(cursor, &key, &data, DB_NEXT); ++ continue; ++ } ++ ++ memcpy(prop, tmp, key.size - (tmp - ((char *)key.data))); ++ prop[key.size - (tmp - ((char *)key.data))] = '\0'; ++ ++ if (*authid) { ++ /* don't check return values */ ++ cb(authid,realm,prop,data.data,data.size); ++ } ++ ++ result = cursor->c_get(cursor, &key, &data, DB_NEXT); ++ } ++ ++ if (result != DB_NOTFOUND) { ++ fprintf(stderr,"failure: %s\n",db_strerror(result)); ++ result = SASL_FAIL; ++ goto cleanup; ++ } ++ ++ result = cursor->c_close(cursor); ++ if (result != 0) { ++ result = SASL_FAIL; ++ goto cleanup; ++ } ++ ++ result = SASL_OK; ++ ++ cleanup: ++ ++ if (mbdb != NULL) berkeleydb_close(mbdb); ++ return result; ++} ++ ++ ++char *db = NULL, *db_new=NULL; ++ ++int good_getopt(void *context __attribute__((unused)), ++ const char *plugin_name __attribute__((unused)), ++ const char *option, ++ const char **result, ++ unsigned *len) ++{ ++ if (db_new && !strcmp(option, "sasldb_path")) { ++ *result = db_new; ++ if (len) ++ *len = strlen(db_new); ++ return SASL_OK; ++ } ++ ++ return SASL_FAIL; ++} ++ ++static struct sasl_callback goodsasl_cb[] = { ++ { SASL_CB_GETOPT, (int (*)(void))&good_getopt, NULL }, ++ { SASL_CB_LIST_END, NULL, NULL } ++}; ++ ++int main(int argc, char **argv) ++{ ++ int result; ++ FILE *f; ++ ++ if (argc != 3) { ++ fprintf(stderr, "Usage: cyrusbdb2current old_sasldb new_sasldb\n"); ++ fprintf(stderr, "old_sasldb is presumably /etc/sasldb2\n"); ++ fprintf(stderr, "new_sasldb is presumably /etc/sasl2/sasldb2\n"); ++ return 1; ++ } ++ ++ db = argv[1]; ++ db_new = argv[2]; ++ ++ if (strcmp(db, db_new) == 0) { ++ fprintf(stderr, "Old and new files should be different\n"); ++ return 1; ++ } ++ ++ ++ f = fopen(db_new, "rb"); ++ if (f != NULL) { ++ fprintf(stderr, "The specified target file %s already exists\n", db_new); ++ fclose(f); ++ return 1; ++ } ++ ++ result = sasl_server_init(goodsasl_cb, "dbconverter"); ++ if (result != SASL_OK) { ++ fprintf(stderr, "couldn't init saslv2\n"); ++ return 1; ++ } ++ ++ result = sasl_server_new("sasldb", ++ "localhost", ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ 0, ++ &globalconn); ++ if (result != SASL_OK) { ++ fprintf(stderr, "couldn't create globalconn\n"); ++ return 1; ++ } ++ ++ if(_sasl_check_db(sasl_global_utils,globalconn) != SASL_OK) { ++ fprintf(stderr, "target DB %s is not OK\n", db_new); ++ return 1; ++ } ++ ++ printf("\nThis program will take the sasldb file specified on the\n" ++ "command line and convert it to a new sasldb specified\n" ++ "on the command line. It is STRONGLY RECOMMENDED that you\n" ++ "backup sasldb before allowing this program to run\n\n" ++ "We are going to convert %s and our output will be in %s\n\n" ++ "Press return to continue\n", db, db_new); ++ ++ getchar(); ++ ++ listusers(db, (listcb_t *) &listusers_cb); ++ ++ sasl_dispose(&globalconn); ++ sasl_done(); ++ ++ exit(0); ++} +diff -up cyrus-sasl-2.1.27/utils/Makefile.am.frombdb cyrus-sasl-2.1.27/utils/Makefile.am +--- cyrus-sasl-2.1.27/utils/Makefile.am.frombdb 2018-10-05 16:40:16.000000000 +0200 ++++ cyrus-sasl-2.1.27/utils/Makefile.am 2021-06-04 13:02:07.798112327 +0200 +@@ -46,14 +46,14 @@ all_sasl_libs = ../lib/libsasl2.la $(SAS + all_sasl_static_libs = ../lib/.libs/libsasl2.a $(SASL_DB_LIB) $(LIB_SOCKET) $(GSSAPIBASE_LIBS) $(GSSAPI_LIBS) $(SASL_KRB_LIB) $(LIB_DES) $(PLAIN_LIBS) $(SRP_LIBS) $(LIB_MYSQL) $(LIB_PGSQL) $(LIB_SQLITE) + + sbin_PROGRAMS = @SASL_DB_UTILS@ @SMTPTEST_PROGRAM@ pluginviewer +-EXTRA_PROGRAMS = saslpasswd2 sasldblistusers2 testsuite testsuitestatic smtptest pluginviewer ++EXTRA_PROGRAMS = saslpasswd2 sasldblistusers2 testsuite testsuitestatic smtptest pluginviewer cyrusbdb2current + + noinst_PROGRAMS = dbconverter-2 + + if NO_SASL_DB_MANS + man_MANS = + else +-man_MANS = saslpasswd2.8 sasldblistusers2.8 pluginviewer.8 ++man_MANS = saslpasswd2.8 sasldblistusers2.8 pluginviewer.8 cyrusbdb2current.8 + endif + + saslpasswd2_LDADD = ../sasldb/libsasldb.la $(all_sasl_libs) +@@ -63,6 +63,7 @@ sasldblistusers2_SOURCES = sasldblistuse + dbconverter_2_LDADD = ../sasldb/libsasldb.la $(all_sasl_libs) + pluginviewer_LDADD = $(all_sasl_libs) + pluginviewer_SOURCES = pluginviewer.c ++cyrusbdb2current_LDADD = ../sasldb/libsasldb.la @BDB_STATIC_LIBADD@ $(all_sasl_libs) + + testsuite_LDADD = $(all_sasl_libs) @DMALLOC_LIBS@ + diff --git a/SOURCES/cyrus-sasl-2.1.27-coverity.patch b/SOURCES/cyrus-sasl-2.1.27-coverity.patch new file mode 100644 index 0000000..871ea10 --- /dev/null +++ b/SOURCES/cyrus-sasl-2.1.27-coverity.patch @@ -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; + } + diff --git a/SOURCES/cyrus-sasl-2.1.27-cumulative-digestmd5.patch b/SOURCES/cyrus-sasl-2.1.27-cumulative-digestmd5.patch new file mode 100644 index 0000000..d61130f --- /dev/null +++ b/SOURCES/cyrus-sasl-2.1.27-cumulative-digestmd5.patch @@ -0,0 +1,544 @@ +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 ++# include ++#endif ++ + #ifdef WIN32 + # include + #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,139 @@ + + 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 + ++#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]) + { ++ const EVP_CIPHER *cipher; + EVP_CIPHER_CTX *ctx; + int rc; + +- ctx = EVP_CIPHER_CTX_new(); +- if (ctx == NULL) return SASL_NOMEM; ++#if OPENSSL_VERSION_NUMBER >= 0x30000000L ++ 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 ++ 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 (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,188 +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); +- if(text->cipher_dec_context) text->utils->free(text->cipher_dec_context); +-} +- +-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; ++ } + } + } + diff --git a/SOURCES/cyrus-sasl-2.1.27-cumulative-ossl3.patch b/SOURCES/cyrus-sasl-2.1.27-cumulative-ossl3.patch new file mode 100644 index 0000000..10b57cc --- /dev/null +++ b/SOURCES/cyrus-sasl-2.1.27-cumulative-ossl3.patch @@ -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 + #include ++#if OPENSSL_VERSION_NUMBER < 0x30000000L + #include ++#endif + + /***************************** Common Section *****************************/ + +@@ -267,6 +271,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-1] 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 */ diff --git a/SOURCES/cyrus-sasl-2.1.27-fix-for-autoconf270.patch b/SOURCES/cyrus-sasl-2.1.27-fix-for-autoconf270.patch new file mode 100644 index 0000000..3c6e7be --- /dev/null +++ b/SOURCES/cyrus-sasl-2.1.27-fix-for-autoconf270.patch @@ -0,0 +1,74 @@ +From 3b0149cf3d235247b051b7cb7663bc3dadbb999b Mon Sep 17 00:00:00 2001 +From: Pavel Raiskup +Date: Thu, 1 Apr 2021 17:17:52 +0200 +Subject: [PATCH] configure.ac: avoid side-effects in AC_CACHE_VAL + +In the COMMANDS-TO-SET-IT argument, per Autoconf docs: +https://www.gnu.org/software/autoconf/manual/autoconf-2.63/html_node/Caching-Results.html +--- + configure.ac | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/configure.ac b/configure.ac +index a106d35e..d333496d 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -220,11 +220,14 @@ void foo() { int i=0;} + int main() { void *self, *ptr1, *ptr2; self=dlopen(NULL,RTLD_LAZY); + if(self) { ptr1=dlsym(self,"foo"); ptr2=dlsym(self,"_foo"); + if(ptr1 && !ptr2) exit(0); } exit(1); } +-], [sasl_cv_dlsym_adds_uscore=yes], sasl_cv_dlsym_adds_uscore=no +- AC_DEFINE(DLSYM_NEEDS_UNDERSCORE, [], [Do we need a leading _ for dlsym?]), ++], [sasl_cv_dlsym_adds_uscore=yes], sasl_cv_dlsym_adds_uscore=no, + AC_MSG_WARN(cross-compiler, we'll do our best))) + LIBS="$cmu_save_LIBS" + AC_MSG_RESULT($sasl_cv_dlsym_adds_uscore) ++ ++ if test "$sasl_cv_dlsym_adds_uscore" = no; then ++ AC_DEFINE(DLSYM_NEEDS_UNDERSCORE, [], [Do we need a leading _ for dlsym?]) ++ fi + fi + fi + +From d3bcaf62f6213e7635e9c4a574f39a831e333980 Mon Sep 17 00:00:00 2001 +From: Pavel Raiskup +Date: Thu, 1 Apr 2021 17:26:28 +0200 +Subject: [PATCH] configure.ac: properly quote macro arguments + +Autoconf 2.70+ is more picky about the quotation (even though with +previous versions the arguments should have been quoted, too). When we +don't quote macros inside the AC_CACHE_VAL macro - some of the Autoconf +initialization is wrongly ordered in ./configure script and we keep +seeing bugs like: + + ./configure: line 2165: ac_fn_c_try_run: command not found + +Original report: https://bugzilla.redhat.com/1943013 +--- + configure.ac | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/configure.ac b/configure.ac +index d333496d..7281cba0 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -213,15 +213,16 @@ if test $sasl_cv_uscore = yes; then + AC_MSG_CHECKING(whether dlsym adds the underscore for us) + cmu_save_LIBS="$LIBS" + LIBS="$LIBS $SASL_DL_LIB" +- AC_CACHE_VAL(sasl_cv_dlsym_adds_uscore,AC_TRY_RUN( [ ++ AC_CACHE_VAL([sasl_cv_dlsym_adds_uscore], ++ [AC_TRY_RUN([ + #include + #include + void foo() { int i=0;} + int main() { void *self, *ptr1, *ptr2; self=dlopen(NULL,RTLD_LAZY); + if(self) { ptr1=dlsym(self,"foo"); ptr2=dlsym(self,"_foo"); + if(ptr1 && !ptr2) exit(0); } exit(1); } +-], [sasl_cv_dlsym_adds_uscore=yes], sasl_cv_dlsym_adds_uscore=no, +- AC_MSG_WARN(cross-compiler, we'll do our best))) ++], [sasl_cv_dlsym_adds_uscore=yes], [sasl_cv_dlsym_adds_uscore=no], ++ [AC_MSG_WARN(cross-compiler, we'll do our best)])]) + LIBS="$cmu_save_LIBS" + AC_MSG_RESULT($sasl_cv_dlsym_adds_uscore) + diff --git a/SOURCES/cyrus-sasl-2.1.27-nostrncpy.patch b/SOURCES/cyrus-sasl-2.1.27-nostrncpy.patch new file mode 100644 index 0000000..d009047 --- /dev/null +++ b/SOURCES/cyrus-sasl-2.1.27-nostrncpy.patch @@ -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)); diff --git a/SOURCES/cyrus-sasl-cve-2019-19906.patch b/SOURCES/cyrus-sasl-cve-2019-19906.patch new file mode 100644 index 0000000..acdf682 --- /dev/null +++ b/SOURCES/cyrus-sasl-cve-2019-19906.patch @@ -0,0 +1,25 @@ +From dcc9f51cbd4ed622cfb0f9b1c141eb2ffe3b12f1 Mon Sep 17 00:00:00 2001 +From: Quanah Gibson-Mount +Date: Tue, 18 Feb 2020 19:05:12 +0000 +Subject: [PATCH] Fix #587 + +Off by one error in common.c, CVE-2019-19906. + +Thanks to Stephan Zeisberg for reporting +--- + lib/common.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/common.c b/lib/common.c +index bc3bf1df..9969d6aa 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; + diff --git a/SOURCES/cyrus-sasl-pr559-RC4-openssl.patch b/SOURCES/cyrus-sasl-pr559-RC4-openssl.patch new file mode 100644 index 0000000..f884423 --- /dev/null +++ b/SOURCES/cyrus-sasl-pr559-RC4-openssl.patch @@ -0,0 +1,156 @@ +From 8aa9ae816ddf66921b4a8a0f422517e6f2e55ac6 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Wed, 27 Mar 2019 14:29:08 -0400 +Subject: [PATCH] Use Openssl RC4 when available + +Signed-off-by: Simo Sorce +--- + 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 +@@ -1103,13 +1103,12 @@ AC_ARG_WITH(configdir, [ --with-configdir=DIR set the directory where confi + configdir='${plugindir}:${sysconfdir}/sasl2') + 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 ++ ++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[] = diff --git a/SOURCES/make-no-dlcompatorsrp-tarball.sh b/SOURCES/make-no-dlcompatorsrp-tarball.sh new file mode 100755 index 0000000..e58dc3b --- /dev/null +++ b/SOURCES/make-no-dlcompatorsrp-tarball.sh @@ -0,0 +1,41 @@ +#!/bin/bash -e +# +# See https://github.com/cyrusimap/cyrus-sasl/releases for unmodified sources. +# + +tmppath=`mktemp -d ${TMPDIR:-/tmp}/make-no-dlcompat-tarball-XXXXXX` +if test -z "$tmppath" ; then + echo Error creating temporary directory. + exit 1 +fi +trap "rm -fr $tmppath" EXIT + +initialdir=`pwd` + +for tarball in ${initialdir}/cyrus-sasl-*.tar.{gz,bz2} ; do + if ! test -s "$tarball" ; then + continue + fi + rm -fr $tmppath/* + pushd $tmppath > /dev/null + case "$tarball" in + *nodlcompat*) + : Do nothing. + ;; + *.gz) + gzip -dc "$tarball" | tar xf - + rm -fr cyrus-sasl-*/dlcompat* + rm -fr cyrus-sasl-*/plugins/srp* + tar cf - * | gzip -9c > \ + $initialdir/`basename $tarball .tar.gz`-nodlcompatorsrp.tar.gz + ;; + *.bz2) + bzip2 -dc "$tarball" | tar xf - + rm -fr cyrus-sasl-*/dlcompat* + rm -fr cyrus-sasl-*/plugins/srp* + tar cf - * | bzip2 -9c > \ + $initialdir/`basename $tarball .tar.bz2`-nodlcompatorsrp.tar.bz2 + ;; + esac + popd > /dev/null +done diff --git a/SOURCES/sasl-mechlist.c b/SOURCES/sasl-mechlist.c new file mode 100644 index 0000000..680e983 --- /dev/null +++ b/SOURCES/sasl-mechlist.c @@ -0,0 +1,99 @@ +#include +#include +#include +#include + +#include "sasl.h" + +static int +my_getopt(void *context, const char *plugin_name, + const char *option, const char **result, unsigned *len) +{ + if (result) { + *result = NULL; +#if 0 + fprintf(stderr, "Getopt plugin=%s%s%s/option=%s%s%s -> ", + plugin_name ? "\"" : "", + plugin_name ? plugin_name : "(null)", + plugin_name ? "\"" : "", + option ? "\"" : "", + option ? option : "(null)", + option ? "\"" : ""); + fprintf(stderr, "'%s'.\n", *result ? *result : ""); +#endif + } + if (len) { + *len = 0; + } + return 0; +} + +int +main(int argc, char **argv) +{ + int ret, i; + const char *mechs, **globals; + sasl_callback_t callbacks[] = { + {SASL_CB_GETOPT, my_getopt, NULL}, + {SASL_CB_LIST_END}, + }; + sasl_conn_t *connection; + char hostname[512]; + + if ((argc > 1) && (argv[1][0] == '-')) { + fprintf(stderr, "Usage: %s [appname [hostname] ]\n", argv[0]); + return 0; + } + + ret = sasl_server_init(callbacks, argc > 1 ? argv[1] : "sasl-mechlist"); + if (ret != SASL_OK) { + fprintf(stderr, "Error in sasl_server_init(): %s\n", + sasl_errstring(ret, NULL, NULL)); + } + + connection = NULL; + strcpy(hostname, "localhost"); + gethostname(hostname, sizeof(hostname)); + ret = sasl_server_new(argc > 2 ? argv[2] : "host", + hostname, + NULL, + NULL, + NULL, + callbacks, + 0, + &connection); + if (ret != SASL_OK) { + fprintf(stderr, "Error in sasl_server_new(): %s\n", + sasl_errstring(ret, NULL, NULL)); + } + + ret = sasl_listmech(connection, + getenv("USER") ? getenv("USER") : "root", + "Available mechanisms: ", + ",", + "\n", + &mechs, + NULL, + NULL); + if (ret != SASL_OK) { + fprintf(stderr, "Error in sasl_listmechs(): %s\n", + sasl_errstring(ret, NULL, NULL)); + } else { + fprintf(stdout, "%s", mechs); + } + + globals = sasl_global_listmech(); + for (i = 0; (globals != NULL) && (globals[i] != NULL); i++) { + if (i == 0) { + fprintf(stdout, "Library supports: "); + } + fprintf(stdout, "%s", globals[i]); + if (globals[i + 1] != NULL) { + fprintf(stdout, ","); + } else { + fprintf(stdout, "\n"); + } + } + + return 0; +} diff --git a/SOURCES/saslauthd.service b/SOURCES/saslauthd.service new file mode 100644 index 0000000..c7c7eca --- /dev/null +++ b/SOURCES/saslauthd.service @@ -0,0 +1,12 @@ +[Unit] +Description=SASL authentication daemon. + +[Service] +Type=forking +PIDFile=/run/saslauthd/saslauthd.pid +EnvironmentFile=/etc/sysconfig/saslauthd +ExecStart=/usr/sbin/saslauthd -m $SOCKETDIR -a $MECH $FLAGS +RuntimeDirectory=saslauthd + +[Install] +WantedBy=multi-user.target diff --git a/SOURCES/saslauthd.sysconfig b/SOURCES/saslauthd.sysconfig new file mode 100644 index 0000000..5413c36 --- /dev/null +++ b/SOURCES/saslauthd.sysconfig @@ -0,0 +1,11 @@ +# Directory in which to place saslauthd's listening socket, pid file, and so +# on. This directory must already exist. +SOCKETDIR=/run/saslauthd + +# Mechanism to use when checking passwords. Run "saslauthd -v" to get a list +# of which mechanism your installation was compiled with the ablity to use. +MECH=pam + +# Additional flags to pass to saslauthd on the command line. See saslauthd(8) +# for the list of accepted flags. +FLAGS= diff --git a/SPECS/cyrus-sasl.spec b/SPECS/cyrus-sasl.spec new file mode 100644 index 0000000..6b3cff7 --- /dev/null +++ b/SPECS/cyrus-sasl.spec @@ -0,0 +1,1209 @@ +%global username saslauth +%global hint Saslauthd user +%global homedir /run/saslauthd + +%global _plugindir2 %{_libdir}/sasl2 +%global bootstrap_cyrus_sasl 0 +%global gdbm_db_file /etc/sasl2/sasldb2 + +Summary: The Cyrus SASL library +Name: cyrus-sasl +Version: 2.1.27 +Release: 20%{?dist} +License: BSD with advertising +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 +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 + +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 +Patch60: cyrus-sasl-pr559-RC4-openssl.patch + +Patch100: cyrus-sasl-cve-2019-19906.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 +Patch103: cyrus-sasl-2.1.27-Add-support-for-setting-max-ssf-0-to-GSS-SPNEGO.patch +Patch104: cyrus-sasl-2.1.27-Emit-debug-log-only-in-case-of-errors.patch +Patch105: cyrus-sasl-2.1.27-fix-for-autoconf270.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-Add-basic-test-plain-auth.patch +#Migration tool should be removed from RHEL10 +Patch108: cyrus-sasl-2.1.27-Migration-from-BerkeleyDB.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 + +Patch900: 0001-CVE-2022-24407-Escape-password-for-SQL-insert-update.patch + +BuildRequires: autoconf, automake, libtool, gdbm-devel, groff +BuildRequires: krb5-devel >= 1.19, 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 migration from BerkeleyDB +#should be removed from RHEL10 +BuildRequires: libdb-devel-static +#build reqs for make check +BuildRequires: python3 nss_wrapper socket_wrapper krb5-server +%{?systemd_requires} + +Requires: %{name}-lib = %{version}-%{release} +Requires: systemd + +#Requires/Provides related to the saslauthd user creation +Requires: /sbin/nologin +Requires(pre): /usr/sbin/useradd /usr/sbin/groupadd +Requires(postun): /usr/sbin/userdel /usr/sbin/groupdel +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 = %{version}-%{release} +Requires: %{name} = %{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. + +%package ntlm +Requires: %{name}-lib%{?_isa} = %{version}-%{release} +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} +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 +%patch60 -p1 -b .openssl_rc4 +%patch100 -p1 -b .cve_2019_19906 +%patch101 -p1 -b .tests +%patch102 -p1 -b .gssapi_cbs +%patch103 -p1 -b .maxssf0 +%patch104 -p1 -b .nolog +%patch105 -p1 -b .autoconf270 +%patch106 -p1 -b .nostrncpy +%patch107 -p1 -b .plaintests +%patch108 -p1 -b .frombdb +%patch500 -p1 -b .coverity +%patch501 -p1 -b .digestmd5 +%patch502 -p1 -b .ossl3 +%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 + +CFLAGS="$RPM_OPT_FLAGS $CFLAGS $CPPFLAGS -fPIC -pie -Wl,-z,relro -Wl,-z,now"; export CFLAGS + +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 \ + --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 +#Migration tool should be removed from RHEL10 +mv $RPM_BUILD_ROOT%{_sbindir}/cyrusbdb2current $RPM_BUILD_ROOT%{_bindir}/cyrusbdb2current +./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}/ + +# 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 + +%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 /run/saslauthd + +%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 +%{_bindir}/cyrusbdb2current + +%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 ntlm +%{_plugindir2}/*ntlm*.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 +* Thu Feb 23 2022 Simo Sorce - 2.1.27-6 +- Fix for CVE-2022-24407 +- Resolves: rhbz#2055848 + +* Mon Feb 9 2022 Simo Sorce - 2.1.27-19 +- Fix a memleak in one of the OpenSSL 3 compat patches + found by covscan + +* Mon Feb 7 2022 Simo Sorce - 2.1.27-18 +- Update OpenSSL 3 related compatibility patch backports + +* Mon Aug 09 2021 Mohan Boddu - 2.1.27-17 +- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags + Related: rhbz#1991688 + +* Wed Jul 28 2021 Simo Sorce - 2.1.27-16 +- Rebuild to pass gating after fixing rhbz#1983928 + +* Wed Jul 28 2021 Florian Weimer - 2.1.27-15 +- Rebuild to pick up OpenSSL 3.0 Beta ABI (#1984097) + +* Mon Jul 19 2021 Simo Sorce - 2.1.27-14 +- Fix crashs on missing legacy algorithms + Resolves: rhbz#1974354 + +* Wed Jun 16 2021 Mohan Boddu - 2.1.27-13 +- Rebuilt for RHEL 9 BETA for openssl 3.0 + Related: rhbz#1971065 + +* Fri Jun 04 2021 Dmitry Belyavskiy - 2.1.27-12 +- Incorporate the upstream gdbm specific patch from + https://github.com/cyrusimap/cyrus-sasl/pull/554 +- Resolves rhbz#1947971 + +* Wed Apr 28 2021 Dmitry Belyavskiy - 2.1.27-11 +- Set default sasldb database to GDBM instead of BerkeleyDB +- Add the migration tool from BerkeleyDB +- Add some PLAIN auth tests +- Resolves rhbz#1947971 + +* Thu Apr 15 2021 Mohan Boddu - 2.1.27-10 +- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937 + +* Mon Apr 12 2021 Dmitry Belyavskiy - 2.1.27-9 +- Coverity-related fixes (#1938700) + +* Mon Feb 08 2021 Pavel Raiskup - 2.1.27-8 +- rebuild for libpq ABI fix rhbz#1908268 + +* Tue Jan 26 2021 Fedora Release Engineering - 2.1.27-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Mon Jul 27 2020 Fedora Release Engineering - 2.1.27-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Thu May 7 2020 Simo Sorce - 2.1.27-5 +- Backport GSSAPI Channel Bindings support +- Add support for setting maxssf=0 in GSS-SPNEGO +- Reduce excessive GSSAPI plugin logging + +* Thu Mar 19 2020 Simo Sorce - 2.1.27-4 +- Fix CVE 2019 19906 + +* Tue Jan 28 2020 Fedora Release Engineering - 2.1.27-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Wed Jul 24 2019 Fedora Release Engineering - 2.1.27-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* 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 + +* Thu Jan 31 2019 Fedora Release Engineering - 2.1.27-0.6rc7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Mon Jan 14 2019 Björn Esser - 2.1.27-0.5rc7 +- Rebuilt for libcrypt.so.2 (#1666033) + +* Sun Oct 14 2018 Peter Robinson 2.1.27-0.4rc7 +- Clean up remanents of sys-v, spec cleanups + +* Thu Jul 12 2018 Fedora Release Engineering - 2.1.27-0.3rc7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Thu May 17 2018 Jakub Jelen - 2.1.27-0.2rc7 +- Avoid multilib conflicts between devel subpackages (#1577675) + +* Mon Mar 05 2018 Jakub Jelen - 2.1.27-0.1rc7 +- New upstream (pre-)release +- Import LDFLAGS from redhat-rpm-config (#1548437) + +* Wed Feb 07 2018 Fedora Release Engineering - 2.1.26-37 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Sat Jan 20 2018 Björn Esser - 2.1.26-36 +- Rebuilt for switch to libxcrypt + +* Mon Oct 23 2017 Jakub Jelen - 2.1.26-35 +- Use mariadb-connector-c-devel instead of mysql-devel (#1493620) + +* Wed Aug 02 2017 Fedora Release Engineering - 2.1.26-34 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 2.1.26-33 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Wed Apr 19 2017 Jakub Jelen - 2.1.26-32 +- Add missing patch for separate mutexes per connection in GSSAPI + +* Tue Apr 18 2017 Jakub Jelen - 2.1.26-31 +- Allow cyrus sasl to get the ssf from gssapi + +* Wed Apr 12 2017 Petr Šabata - 2.1.26-30 +- Removing the obsolete scriptlet /sbin/service dependency + +* Tue Mar 07 2017 Jakub Jelen - 2.1.26-29 +- Fix GSS SPNEGO support (#1421663) + +* Fri Feb 10 2017 Fedora Release Engineering - 2.1.26-28 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Mon Nov 07 2016 Jakub Jelen - 2.1.26-27 +- Add support for OpenSSL 1.1.0 + +* Wed Feb 03 2016 Fedora Release Engineering - 2.1.26-26.2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Thu Jul 16 2015 Jakub Jelen 2.1.26-25.2 +- Revert tmpfiles.d and use new systemd feature RuntimeDirectory + +* Wed Jun 17 2015 Fedora Release Engineering - 2.1.26-24 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Fri May 29 2015 Jakub Jelen 2.1.26-23 +- Add ability to handle logging in gssapi plugin (#1187097) + +* Mon Mar 16 2015 Jakub Jelen 2.1.26-22 +- Rever "Do not leak memory in plugin_common.c ..." due the breakage of svn (#1202364) + +* Thu Mar 12 2015 Jakub Jelen 2.1.26-21 +- Add and Document ability to run saslauthd as non-root user, fix tpmfiles ownership (#1189203) +- Do not leak memory in sample server (#852755) +- Do not leak memory in plugin_common.c for password callback (#1191183) +- Cleanup spec file: tmpfiles.d macros and tab/space + +* Wed Feb 04 2015 Petr Lautrbach 2.1.26-20 +- Change the ownership of /run/saslauth to saslauth:saslauth (#1189203) + +* Sat Aug 16 2014 Fedora Release Engineering - 2.1.26-19 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Fri Jul 11 2014 Tom Callaway - 2.1.26-18 +- fix license handling + +* Sat Jun 07 2014 Fedora Release Engineering - 2.1.26-17 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Sun Jan 19 2014 Ville Skyttä - 2.1.26-16 +- Don't order service after syslog.target. + +* Fri Nov 15 2013 Petr Lautrbach 2.1.26-15 +- Treat SCRAM-SHA-1/DIGEST-MD5 as more secure than PLAIN (#970718) +- improve configuration error message + +* Fri Nov 01 2013 Petr Lautrbach 2.1.26-14 +- revert upstream commit 080e51c7fa0421eb2f0210d34cf0ac48a228b1e9 (#984079) + +* Tue Oct 15 2013 Karsten Hopp 2.1.26-13 +- add ppc64p7 subarch support in config.sub (Fedora only) + +* Mon Sep 09 2013 Petr Lautrbach 2.1.26-12 +- build with RPM_OPT_FLAGS (#1005535) + +* Tue Sep 03 2013 Petr Lautrbach 2.1.26-11 +- fix hardening for /usr/sbin/saslauthd +- add testsaslauthd.8 man page to the package +- use static md5global.h file + +* Sat Aug 03 2013 Fedora Release Engineering - 2.1.26-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Mon Jun 24 2013 Petr Lautrbach 2.1.26-9 +- detect gsskrb5_register_acceptor_identity macro (#976538) + +* Tue Jun 04 2013 Karsten Hopp 2.1.26-8 +- disable incorrect check for MkLinux to allow building with shared libraries on PPC + +* Tue May 21 2013 Petr Lautrbach 2.1.26-7 +- fix the spec file in order to build the cyrus-sasl-sql plugin + with support for PostgreSQL and MySQL + +* Thu Feb 21 2013 Petr Lautrbach 2.1.26-6 +- don't include system sasl2 library needed for rebuilds after rebase + +* Mon Feb 11 2013 Petr Lautrbach 2.1.26-5 +- enable full relro and PIE compiler flags for saslauthd + +* Fri Feb 01 2013 Petr Lautrbach 2.1.26-4 +- fix library symlinks + +* Thu Jan 31 2013 Rex Dieter 2.1.26-3 +- actually apply size_t patch (#906519) + +* Thu Jan 31 2013 Rex Dieter 2.1.26-2 +- sasl.h: +#include for missing size_t type (#906519) +- tighten subpkg deps via %%?_isa + +* Thu Dec 20 2012 Petr Lautrbach 2.1.26-1 +- update to 2.1.26 +- fix segfaults in sasl_gss_encode (#886140) + +* Mon Dec 10 2012 Petr Lautrbach 2.1.25-2 +- always use the current external Berkeley DB when linking + +* Fri Dec 07 2012 Petr Lautrbach 2.1.25-1 +- update to 2.1.25 +- add cyrus-sasl-scram and cyrus-sasl-gs2 packages + +* Fri Sep 14 2012 Petr Lautrbach 2.1.23-36 +- replace scriptlets with systemd macros (#856666) + +* Wed Jul 18 2012 Fedora Release Engineering - 2.1.23-35 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Tue Jul 17 2012 Petr Lautrbach 2.1.23-34 +- move /etc/tmpfiles.d/saslauthd.conf to /usr/lib/tmpfiles.d/saslauthd.conf (#840193) + +* Wed Jun 20 2012 Petr Lautrbach 2.1.23-33 +- properly deal with crypt() returning NULL (#816250) +- use fixed gid 76 for saslauth + +* Mon Apr 16 2012 Jindrich Novy 2.1.23-32 +- re-enable libdb support and utilities + +* Wed Apr 04 2012 Jindrich Novy 2.1.23-31 +- temporarily disable libdb support to resolve cyrus-sasl + chicken and egg build problem against libdb + +* Tue Apr 03 2012 Jindrich Novy 2.1.23-30 +- rebuild against new libdb + +* Wed Feb 08 2012 Petr Lautrbach 2.1.23-29 +- Change saslauth user homedir to /run/saslauthd (#752889) +- Change all /var/run/ to /run/ +- DAEMONOPTS are not supported any more in systemd units + +* Mon Jan 09 2012 Jeroen van Meeuwen - 2.1.23-28 +- Ship with sasl_pwcheck_method: alwaystrue + +* Mon Dec 12 2011 Petr Lautrbach 2.1.23-27 +- remove support for logging of the remote host via PAM (#759334) +- fix systemd files (#750436) + +* Wed Aug 10 2011 Jan F. Chadima - 2.1.23-26 +- Add partial relro support for libraries + +* Mon Jul 25 2011 Jan F. Chadima - 2.1.23-25 +- Add support for berkeley db 5 + +* Wed Jun 29 2011 Jan F. Chadima - 2.1.23-23 +- Migrate the package to full native systemd unit files, according to the Fedora + packaging guidelines. + +* Wed Jun 1 2011 Jan F. Chadima - 2.1.23-22 +- repair rimap support (more packets in response) + +* Wed May 25 2011 Jan F. Chadima - 2.1.23-21 +- repair ntlm support + +* Mon May 23 2011 Jan F. Chadima - 2.1.23-20 +- add logging of the remote host via PAM + +* Thu Apr 28 2011 Jan F. Chadima - 2.1.23-19 +- temporarilly revert systemd units + +* Tue Apr 26 2011 Jan F. Chadima - 2.1.23-18 +- update scriptlets + +* Fri Apr 22 2011 Jan F. Chadima - 2.1.23-17 +- Add systemd units + +* Wed Mar 23 2011 Tomas Mraz - 2.1.23-16 +- Rebuilt with new mysqlclient + +* Fri Feb 25 2011 Jan F. Chadima - 2.1.23-15 +- set correct license tag +- add ghost to /var/run/saslauthd + +* Tue Feb 08 2011 Fedora Release Engineering - 2.1.23-14 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Fri Apr 9 2010 Jan F. Chadima - 2.1.23-13 +- Add /etc/tmpfiles.d element (#662734) + +* Fri Apr 9 2010 Jan F. Chadima - 2.1.23-12 +- Update init script to impeach pid file + +* Thu Mar 11 2010 Jan F. Chadima - 2.1.23-11 +- Update pre post preun and postun scripts (#572399) + +* Wed Mar 10 2010 Jan F. Chadima - 2.1.23-10 +- Rewrite spec file, make corect CFLAGS, CPPFLAGS and LDFLAGS + +* Mon Feb 22 2010 Jan F. Chadima - 2.1.23-9 +- solve race condition (#566875) + +* Wed Feb 17 2010 Stepan Kasal - 2.1.23-8 +- improve m4 quoting to fix saslauthd/configure (#566088) +- call autotools in build, not in prep + +* Fri Feb 5 2010 Jan F. Chadima - 2.1.23-7 +- Add man page to testtcpauthd (#526189) + +* Fri Oct 16 2009 Jan F. Chadima - 2.1.23-6 +- Create the saslauth user according to fedora packaging guide + +* Thu Sep 24 2009 Jan F. Chadima - 2.1.23-5 +- Repair initscript to make condrestart working properly (#522103) + +* Wed Sep 23 2009 Jan F. Chadima - 2.1.23-3 +- Add possibility to run the saslauth without root privilegies (#185614) + +* Fri Aug 21 2009 Tomas Mraz - 2.1.23-2 +- rebuilt with new openssl + +* Fri Aug 7 2009 Jan F. Chadima - 2.1.23-1 +- update to 2.1.23 + +* Fri Jul 24 2009 Fedora Release Engineering - 2.1.22-25 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Mon May 11 2009 Jan F. Chadima - 2.1.22-24 +- repair sasl_encode64 nul termination (#487251) + +* Thu Apr 16 2009 Robert Scheck - 2.1.22-23 +- Don't build the krb4 plugin as krb5 1.7 will drop it (#225974 #c6) + +* Tue Feb 24 2009 Fedora Release Engineering - 2.1.22-22 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Fri Feb 6 2009 Tomas Mraz - 2.1.22-21 +- fix build with gcc-4.4 + +* Fri Jan 23 2009 Tomas Mraz - 2.1.22-20 +- set LDAP_OPT_TIMEOUT (#326452) +- provide LSB compatible init script (#246900) + +* Fri Sep 26 2008 Tomas Mraz - 2.1.22-19 +- always use the current external db4 when linking, + thanks to Dan Horak for the original patch (#464098) + +* Wed Sep 10 2008 Tomas Mraz - 2.1.22-18 +- fix most critical build warnings (#433583) +- use external db4 + +* Fri Aug 29 2008 Tomas Mraz - 2.1.22-17 +- always link against the internal db4 (#459163) +- rediff patches for no fuzz + +* Wed Jul 9 2008 Tomas Mraz - 2.1.22-16 +- update internal db4 (#449737) + +* Tue Jul 1 2008 Tomas Mraz - 2.1.22-15 +- drop reload from initscript help (#448154) +- fix hang in rimap auth method (#438533) +- build the krb4 plugin (#154675) + +* Fri May 23 2008 Dennis Gilmore - 2.1.22-14 +- make it so that bootstrap actually works + +* Thu May 22 2008 Tom "spot" Callaway - 2.1.22-13.1 +- minor release bump for sparc rebuild + +* Tue Feb 19 2008 Fedora Release Engineering - 2.1.22-13 +- Autorebuild for GCC 4.3 + +* Thu Feb 14 2008 Steve Conklin - 2.1.22-12 +- rebuild for gcc4.3 + +* Fri Jan 25 2008 Steve Conklin - 2.1.22-11 +- Cleanup after merge review bz #225673 +- no longer mark /etc/rc.d/init.d/saslauthd as config file +- removed -x permissions on include files +- added devel package dependency on cyrus-sasl +- removed some remaining .la files that were being delivered + +* Wed Dec 05 2007 Release Engineering - 2.1.22-10 + - Rebuild for deps + +* Wed Nov 7 2007 Steve Conklin - 2.1.22-9 +- Fixed a typo in the spec file + +* Wed Nov 7 2007 Steve Conklin - 2.1.22-8 +- Removed srp plugin source and added dist to NVR + +* Tue Sep 18 2007 Steve Conklin 2.1.22-7 +- use db4 version 4.6.19 bz#249737 + +* Mon Feb 26 2007 Nalin Dahyabhai 2.1.22-6 +- install config files and init scripts using -p +- pull in patch to build with current automake (#229010, Jacek Konieczny + and Robert Scheck) +- remove prereq on ldconfig, RPM should pick it up based on the -libs + scriptlets +- pull in patch to correctly detect gsskrb5_register_acceptor_identity + (#200892, Mirko Streckenbach) +- move sasldb auxprop modules into the -lib subpackage, so that we'll pick + it up for multilib systems + +* Thu Feb 22 2007 Nalin Dahyabhai +- pull CVS fix for not tripping over extra commas in digest-md5 + challenges (#229640) + +* Fri Feb 16 2007 Nalin Dahyabhai +- remove static build, which is no longer a useful option because not all of + our dependencies are available as static libraries +- drop patches which were needed to keep static builds going +- drop gssapi-generic patch due to lack of interest +- update the bundled copy of db to 4.5.20 (#229012) +- drop dbconverter-2, as we haven't bundled v1 libraries since FC4 + +* Tue Dec 5 2006 Nalin Dahyabhai 2.1.22-5 +- rebuild +- add 'authentication' or 'auxprop' to summaries for plugin packages to + better indicate what the plugin provides +- switch from automake 1.9 to automake 1.7 + +* Fri Sep 29 2006 Nalin Dahyabhai 2.1.22-4 +- rebuild without 'dlcompat' bits (#206119) + +* Mon Jul 17 2006 Nalin Dahyabhai 2.1.22-3 +- rebuild + +* Tue Jun 20 2006 Nalin Dahyabhai 2.1.22-2 +- fix a typo in sasl_client_start(3) (#196066) + +* Mon May 22 2006 Nalin Dahyabhai 2.1.22-1 +- update to 2.1.22, adding pluginviewer to %%{_sbindir} + +* Tue May 16 2006 Nalin Dahyabhai 2.1.21-12 +- add conditionalized build dependency on openldap-devel (#191855) +- patch md5global.h to be the same on all architectures + +* Thu Apr 27 2006 Nalin Dahyabhai 2.1.21-11 +- add unapplied patch which makes the DIGEST-MD5 plugin omit the realm + argument when the environment has $CYRUS_SASL_DIGEST_MD5_OMIT_REALM set to a + non-zero value, for testing purposes +- add missing buildrequires on zlib-devel (#190113) + +* Mon Feb 20 2006 Nalin Dahyabhai 2.1.21-10 +- add missing buildrequires on gdbm-devel (Karsten Hopp) + +* Fri Feb 10 2006 Jesse Keating - 2.1.21-9.2 +- bump again for double-long bug on ppc(64) + +* Tue Feb 07 2006 Jesse Keating - 2.1.21-9.1 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Mon Dec 19 2005 Nalin Dahyabhai 2.1.21-9 +- use --as-needed to avoid linking dbconverter-2 with SQL libraries, which + it doesn't use because it manipulates files directly (#173321) + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Mon Nov 14 2005 Nalin Dahyabhai 2.1.21-8 +- rebuild with new OpenLDAP, overriding the version checks to assume that + 2.3.11 is acceptable +- remove a lingering patch for 1.x which we no longer use + +* Sat Nov 12 2005 Tom Lane 2.1.21-7 +- Rebuild due to mysql update. + +* Tue Nov 8 2005 Tomas Mraz 2.1.21-6 +- rebuilt with new openssl + +* Fri Sep 9 2005 Nalin Dahyabhai 2.1.21-5 +- add missing buildrequires: on groff (#163032) + +* Thu Sep 1 2005 Nalin Dahyabhai 2.1.21-4 +- move the ldapdb auxprop support into a subpackage (#167300) + (note: the ldap password check support in saslauthd doesn't use auxprop) + +* Tue Aug 30 2005 Nalin Dahyabhai 2.1.21-3 +- correct a use of uninitialized memory in the bundled libdb (Arjan van de Ven) + +* Mon Aug 29 2005 Nalin Dahyabhai 2.1.21-2 +- move the ANONYMOUS mech plugin to the -lib subpackage so that multilib + systems can use it without installing the main package +- build the static libraries without sql auxprop support + +* Mon Aug 29 2005 Nalin Dahyabhai 2.1.21-1 +- update to 2.1.21 +- turn off compilation of libsasl v1 (finally) +- explicitly disable sqlite to avoid the build warning +- change the default mechanism which is set for saslauthd from "shadow" to + "pam" (#159194) +- split the shared library up from saslauthd so that multilib systems don't + have to pull in every dependency of saslauthd for the compat arch (#166749) + +* Wed Apr 13 2005 Nalin Dahyabhai 2.1.20-5 +- rebuild with new deps + +* Tue Mar 1 2005 Nalin Dahyabhai 2.1.20-4 +- rebuild with new deps + +* Thu Nov 11 2004 Jeff Johnson 2.1.20-3 +- rebuild against db-4.3.21. + +* Thu Nov 11 2004 Nalin Dahyabhai 2.1.20-2 +- build with mysql-devel instead of mysqlclient10 + +* Mon Nov 1 2004 Nalin Dahyabhai 2.1.20-1 +- build with mysqlclient10 instead of mysql-devel + +* Wed Oct 27 2004 Nalin Dahyabhai 2.1.20-0 +- update to 2.1.20, including the fix for CAN-2004-0884 + +* Tue Oct 5 2004 Nalin Dahyabhai 2.1.19-3 +- use notting's fix for incorrect patch for CAN-2004-0884 for 1.5.28 + +* Tue Oct 5 2004 Nalin Dahyabhai 2.1.19-2 +- don't trust the environment in setuid/setgid contexts (CAN-2004-0884, #134660) + +* Thu Aug 19 2004 Nalin Dahyabhai 2.1.19-1 +- rebuild (the 2.1.19 changelog for fixing a buffer overflow referred to a CVS + revision between 2.1.18 and 2.1.19) + +* Mon Jul 19 2004 Nalin Dahyabhai 2.1.19-0 +- update to 2.1.19, maybe for update + +* Tue Jun 15 2004 Elliot Lee +- rebuilt + +* Mon Jun 7 2004 Nalin Dahyabhai 2.1.18-4 +- enable sql auxprop support in a subpackage +- include LDAP_SASLAUTHD documentation file (#124830) + +* Fri Jun 4 2004 Nalin Dahyabhai +- turn on ntlm in a subpackage + +* Thu May 13 2004 Thomas Woerner 2.1.18-3 +- removed rpath + +* Tue Mar 16 2004 Nalin Dahyabhai 2.1.18-2 +- turn on building of libsasl v1 again + +* Fri Mar 12 2004 Nalin Dahyabhai 2.1.18-1 +- update to 2.1.18 +- saslauthd's ldap code is no longer marked experimental, so we build it + +* Mon Mar 8 2004 Nalin Dahyabhai 2.1.17-4 +- rebuild + +* Tue Mar 02 2004 Elliot Lee +- rebuilt + +* Fri Feb 13 2004 Elliot Lee +- rebuilt + +* Tue Feb 3 2004 Nalin Dahyabhai 2.1.17-2 +- include default /etc/sysconfig/saslauthd configuration file for the init + script (#114868) + +* Thu Jan 29 2004 Nalin Dahyabhai +- drop saslauthd_version patch for libsasl2 + +* Thu Jan 29 2004 Nalin Dahyabhai +- add a saslauthd_version option to libsasl's saslauthd client and teach it to + do the right thing +- enable the saslauthd client code in libsasl version 1 (it's still going away!) +- add saslauthd1-checkpass/saslauthd2-checkpass for testing the above change + +* Wed Jan 7 2004 Nalin Dahyabhai 2.1.17-1 +- forcibly disable otp and sql plugins at compile-time + +* Fri Dec 19 2003 Nalin Dahyabhai +- update to 2.1.17, forcing the gssapi plugin to be shared now, as before +- use a bundled libdb (#112215) +- build static-with-all-plugins and normal-shared libsasl versions +- add sasl2-{shared,static}-mechlist for very basic sanity checking +- make inclusion of sasl1 stuffs conditional, because it's so going away + +* Sat Dec 13 2003 Jeff Johnson 2.1.15-7 +- rebuild against db-4.2.52. + +* Thu Oct 23 2003 Nalin Dahyabhai 2.1.15-6 +- use /dev/urandom instead of /dev/random for SASL2 (docs indicate that this is + safe if you aren't using OTP or SRP, and we build neither); SASL1 appears to + use it to seed the libc RNG only (#103378) + +* Mon Oct 20 2003 Nalin Dahyabhai +- obey RPM_OPT_FLAGS again when krb5_prefix != %%{_prefix} + +* Fri Oct 17 2003 Nalin Dahyabhai 2.1.15-5 +- install saslauthd's mdoc page instead of the pre-formatted man page, which + would get formatted again + +* Thu Sep 25 2003 Jeff Johnson 2.1.15-5 +- rebuild against db-4.2.42. + +* Mon Sep 15 2003 Nalin Dahyabhai +- include testsaslauthd +- note in the README that the saslauthd protocol is different for v1 and v2, + so v1's clients can't talk to the v2 server + +* Thu Aug 21 2003 Nalin Dahyabhai 2.1.15-4 +- rebuild + +* Thu Aug 21 2003 Nalin Dahyabhai 2.1.15-3 +- add logic to build with gssapi libs in either /usr or /usr/kerberos + +* Mon Jul 21 2003 Nalin Dahyabhai 2.1.15-2 +- rebuild + +* Tue Jul 15 2003 Nalin Dahyabhai 2.1.15-1 +- update to 2.1.15 + +* Mon Jul 14 2003 Nalin Dahyabhai 2.1.14-1 +- update to 2.1.14 + +* Wed Jun 04 2003 Elliot Lee +- rebuilt + +* Fri May 9 2003 Nalin Dahyabhai 2.1.13-3 +- change -m argument to saslauthd to be a directory instead of a path + +* Thu May 8 2003 Nalin Dahyabhai 2.1.13-2 +- link libsasl2 with -lpthread to ensure that the sasldb plug-in can always + be loaded + +* Tue Apr 29 2003 Nalin Dahyabhai 2.1.13-1 +- update to 2.1.13 + +* Wed Jan 22 2003 Tim Powers +- rebuilt + +* Tue Jan 7 2003 Nalin Dahyabhai 2.1.10-3 +- rebuild + +* Thu Dec 12 2002 Nalin Dahyabhai +- consider either des_cbc_encrypt or DES_cbc_encrypt to be sufficient when + searching for a DES implementation in libcrypto +- pull in CPPFLAGS and LDFLAGS from openssl's pkg-config data, if it exists + +* Mon Dec 9 2002 Nalin Dahyabhai 2.1.10-2 +- rebuild + +* Mon Dec 9 2002 Nalin Dahyabhai 2.1.10-1 +- update to 2.1.10, fixing buffer overflows in libsasl2 noted by Timo Sirainen + +* Tue Nov 12 2002 Tim Powers 2.1.7-5 +- remove files from $RPM_BUILD_ROOT that we don't intend to include + +* Wed Oct 9 2002 Nalin Dahyabhai 2.1.7-4 +- update to SASLv1 to final 1.5.28 + +* Fri Sep 13 2002 Nalin Dahyabhai 2.1.7-3 +- rebuild, overriding sasldir when running make so that on multilib systems + applications will be able to load modules for the right arch + +* Mon Sep 2 2002 Nalin Dahyabhai 2.1.7-2 +- include dbconverter-2 (#68741) + +* Fri Aug 9 2002 Nalin Dahyabhai 2.1.7-1 +- update to 2.1.7, fixing a race condition in digest-md5 + +* Wed Jul 17 2002 Nalin Dahyabhai 2.1.6-1 +- update to 2.1.6 and 1.5.28 + +* Fri Jun 21 2002 Tim Powers +- automated rebuild + +* Thu Jun 13 2002 Nalin Dahyabhai 2.1.5-1 +- update to 2.1.5 + +* Mon Jun 10 2002 Nalin Dahyabhai 2.1.4-1 +- update to 2.1.4 + +* Sun May 26 2002 Tim Powers +- automated rebuild + +* Thu May 16 2002 Nalin Dahyabhai 2.1.2-1 +- modify to build with db 4.x + +* Thu Apr 18 2002 Nalin Dahyabhai +- update cyrus-sasl 2 to 2.1.2 +- change buildreq to db3-devel + +* Tue Feb 12 2002 Nalin Dahyabhai 2.1.1-3 +- suppress output to stdout/stderr in %%postun + +* Sun Feb 10 2002 Nalin Dahyabhai 2.1.1-2 +- configure sasldb2 to use berkeley DB instead of gdbm + +* Wed Feb 6 2002 Nalin Dahyabhai 2.1.1-1 +- update to 2.1.1 + +* Thu Jan 31 2002 Nalin Dahyabhai 2.1.0-1 +- marge 1.5.24 back in, making a note that it should be removed at some + point in the future + +* Wed Jan 30 2002 Nalin Dahyabhai +- update to 2.1.0, which is designed to be installed in parallel with cyrus sasl + 1.x, so fork the package and rename it to cyrus-sasl2 +- add the sasldb auxprop plugin to the main package +- add disabled-by-default saslauthd init script +- move the .la files for plugins into their respective packages -- they're + needed by the library + +* Wed Jan 23 2002 Nalin Dahyabhai 1.5.24-24 +- free ride through the build system + +* Fri Nov 2 2001 Nalin Dahyabhai 1.5.24-23 +- patch to fix possible syslog format-string vulnerability + +* Mon Oct 29 2001 Nalin Dahyabhai 1.5.24-22 +- add pam-devel as a buildprereq + +* Wed Aug 29 2001 Nalin Dahyabhai 1.5.24-21 +- include sample programs in the -devel subpackage, prefixing their names + with "sasl-" to reduce future potential naming conflicts + +* Tue Aug 14 2001 Nalin Dahyabhai 1.5.24-20 +- build without -ggdb + +* Fri Aug 3 2001 Nalin Dahyabhai +- add gdbm-devel as a build dependency (#44990) +- split off CRAM-MD5 and DIGEST-MD5 into a subpackage of their own (#43079, + and dialogs with David L. Parsley) + +* Fri Apr 27 2001 Nalin Dahyabhai +- split out the PLAIN and LOGIN mechanisms into their own package (this allows + an administrator to disable them by simply removing the package) + +* Fri Jan 19 2001 Nalin Dahyabhai +- rebuild in new environment + +* Wed Dec 6 2000 Nalin Dahyabhai +- fix gssapi-over-tls + +* Fri Oct 27 2000 Nalin Dahyabhai +- enable static libraries, but always build with -fPIC + +* Wed Oct 25 2000 Nalin Dahyabhai +- make sure the version of 1.5.24 in the package matches the masters (#18968) + +* Mon Oct 9 2000 Nalin Dahyabhai +- re-add the libsasl.so symlink to the -devel package (oops) + +* Fri Oct 6 2000 Nalin Dahyabhai +- move .so files for modules to their respective packages -- they're not -devel + links meant for use by ld anyway + +* Thu Oct 5 2000 Nalin Dahyabhai +- split off -devel subpackage +- add a -gssapi subpackage for the gssapi plugins + +* Wed Aug 16 2000 Nalin Dahyabhai +- fix the summary text + +* Sun Aug 13 2000 Nalin Dahyabhai +- re-enable arcfour and CRAM + +* Fri Aug 4 2000 Nalin Dahyabhai +- force use of gdbm for database files to avoid DB migration weirdness +- enable login mechanism +- disable gssapi until it can coexist peacefully with non-gssapi setups +- actually do a make in the build section (#15410) + +* Fri Jul 21 2000 Nalin Dahyabhai +- update to 1.5.24 + +* Wed Jul 12 2000 Prospector +- automatic rebuild + +* Tue Jun 27 2000 Nalin Dahyabhai +- rebuild in new environment (release 3) + +* Mon Jun 19 2000 Nalin Dahyabhai +- don't muck with syslogd in post +- remove patch for db-3.0 wackiness, no longer needed + +* Thu Jun 8 2000 Nalin Dahyabhai +- FHS cleanup +- don't strip anything by default + +* Fri Feb 11 2000 Tim Powers +- fixed man pages not being gzipped + +* Tue Nov 16 1999 Tim Powers +- incorporated changes from Mads Kiilerich +- release number is 1, not mk1 + +* Wed Nov 10 1999 Mads Kiilerich +- updated to sasl 1.5.11 +- configure --disable-krb4 --without-rc4 --disable-cram + because of missing libraries and pine having cram as default... +- handle changing libsasl.so versions + +* Mon Aug 30 1999 Tim Powers +- changed group + +* Fri Aug 13 1999 Tim Powers +- first build for Powertools