diff --git a/.cyrus-sasl.metadata b/.cyrus-sasl.metadata deleted file mode 100644 index 82b591b..0000000 --- a/.cyrus-sasl.metadata +++ /dev/null @@ -1 +0,0 @@ -c9e6848d9cc6f9588e0e7a75423f9a3aed3f10db SOURCES/cyrus-sasl-2.1.27-nodlcompatorsrp.tar.gz diff --git a/.gitignore b/.gitignore index 07c8f97..8d7e0eb 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/cyrus-sasl-2.1.27-nodlcompatorsrp.tar.gz +cyrus-sasl-2.1.28-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 deleted file mode 100644 index a430d65..0000000 --- a/SOURCES/0001-CVE-2022-24407-Escape-password-for-SQL-insert-update.patch +++ /dev/null @@ -1,82 +0,0 @@ -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/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 deleted file mode 100644 index c8c4a79..0000000 --- a/SOURCES/cyrus-sasl-2.1.27-Add-support-for-setting-max-ssf-0-to-GSS-SPNEGO.patch +++ /dev/null @@ -1,435 +0,0 @@ -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-CVE-2019-19906.patch b/SOURCES/cyrus-sasl-2.1.27-CVE-2019-19906.patch deleted file mode 100644 index ad278aa..0000000 --- a/SOURCES/cyrus-sasl-2.1.27-CVE-2019-19906.patch +++ /dev/null @@ -1,29 +0,0 @@ -From bcb6c06ec17728f7c9c492dc257b1e541a6830da Mon Sep 17 00:00:00 2001 -From: Simo Sorce -Date: Tue, 5 May 2020 14:41:06 -0400 -Subject: [PATCH] CVE-2019-19906 - -Backport of commit id: -dcc9f51cbd4ed622cfb0f9b1c141eb2ffe3b12f1 - -Signed-off-by: Simo Sorce ---- - lib/common.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/lib/common.c b/lib/common.c -index bc3bf1d..9969d6a 100644 ---- a/lib/common.c -+++ b/lib/common.c -@@ -190,7 +190,7 @@ int _sasl_add_string(char **out, size_t *alloclen, - - if (add==NULL) add = "(null)"; - -- addlen=strlen(add); /* only compute once */ -+ addlen=strlen(add)+1; /* only compute once */ - if (_buf_alloc(out, alloclen, (*outlen)+addlen)!=SASL_OK) - return SASL_NOMEM; - --- -2.18.2 - 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 deleted file mode 100644 index d5e1334..0000000 --- a/SOURCES/cyrus-sasl-2.1.27-Emit-debug-log-only-in-case-of-errors.patch +++ /dev/null @@ -1,42 +0,0 @@ -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-pr559-RC4-openssl.patch b/SOURCES/cyrus-sasl-pr559-RC4-openssl.patch deleted file mode 100644 index 1993639..0000000 --- a/SOURCES/cyrus-sasl-pr559-RC4-openssl.patch +++ /dev/null @@ -1,155 +0,0 @@ -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 -@@ -1102,12 +1102,11 @@ AC_ARG_WITH(configdir, [ --with-configdir=DIR set the directory where confi - AC_SUBST(configdir) - --dnl look for rc4 libraries. we accept the CMU one or one from openSSL --AC_ARG_WITH(rc4, [ --with-rc4 use internal rc4 routines [[yes]] ], -+AC_ARG_WITH(rc4, [ --with-rc4 use rc4 routines [[yes]] ], - with_rc4=$withval, - with_rc4=yes) - - if test "$with_rc4" != no; then -- AC_DEFINE(WITH_RC4,[],[Use internal RC4 implementation?]) -+ AC_DEFINE(WITH_RC4,[],[Use RC4]) - fi - - building_for_macosx=no -diff --git a/plugins/digestmd5.c b/plugins/digestmd5.c -index df35093d..c6b54317 100644 ---- a/plugins/digestmd5.c -+++ b/plugins/digestmd5.c -@@ -1117,6 +1117,111 @@ static void free_des(context_t *text) - #endif /* WITH_DES */ - - #ifdef WITH_RC4 -+#ifdef HAVE_OPENSSL -+#include -+ -+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/autogen.sh b/autogen.sh similarity index 100% rename from SOURCES/autogen.sh rename to autogen.sh diff --git a/SOURCES/cyrus-sasl-2.1.20-saslauthd.conf-path.patch b/cyrus-sasl-2.1.20-saslauthd.conf-path.patch similarity index 100% rename from SOURCES/cyrus-sasl-2.1.20-saslauthd.conf-path.patch rename to cyrus-sasl-2.1.20-saslauthd.conf-path.patch diff --git a/SOURCES/cyrus-sasl-2.1.21-sizes.patch b/cyrus-sasl-2.1.21-sizes.patch similarity index 100% rename from SOURCES/cyrus-sasl-2.1.21-sizes.patch rename to cyrus-sasl-2.1.21-sizes.patch diff --git a/SOURCES/cyrus-sasl-2.1.23-man.patch b/cyrus-sasl-2.1.23-man.patch similarity index 100% rename from SOURCES/cyrus-sasl-2.1.23-man.patch rename to cyrus-sasl-2.1.23-man.patch diff --git a/SOURCES/cyrus-sasl-2.1.25-no_rpath.patch b/cyrus-sasl-2.1.25-no_rpath.patch similarity index 95% rename from SOURCES/cyrus-sasl-2.1.25-no_rpath.patch rename to cyrus-sasl-2.1.25-no_rpath.patch index 3ff180c..82e5aa7 100644 --- a/SOURCES/cyrus-sasl-2.1.25-no_rpath.patch +++ b/cyrus-sasl-2.1.25-no_rpath.patch @@ -16,5 +16,5 @@ diff -up cyrus-sasl-2.1.25/m4/cyrus.m4.no_rpath cyrus-sasl-2.1.25/m4/cyrus.m4 - ]) - LDFLAGS="${SAVE_LDFLAGS}" - ])]) -+ andrew_runpath_switch="none" ++ andrew_cv_runpath_switch="none" + ]) diff --git a/SOURCES/cyrus-sasl-2.1.26-md5global.patch b/cyrus-sasl-2.1.26-md5global.patch similarity index 100% rename from SOURCES/cyrus-sasl-2.1.26-md5global.patch rename to cyrus-sasl-2.1.26-md5global.patch diff --git a/SOURCES/cyrus-sasl-2.1.27-Add-Channel-Binding-support-for-GSSAPI-GSS-SPNEGO.patch b/cyrus-sasl-2.1.27-Add-Channel-Binding-support-for-GSSAPI-GSS-SPNEGO.patch similarity index 86% rename from SOURCES/cyrus-sasl-2.1.27-Add-Channel-Binding-support-for-GSSAPI-GSS-SPNEGO.patch rename to cyrus-sasl-2.1.27-Add-Channel-Binding-support-for-GSSAPI-GSS-SPNEGO.patch index 242b436..b95d8f1 100644 --- a/SOURCES/cyrus-sasl-2.1.27-Add-Channel-Binding-support-for-GSSAPI-GSS-SPNEGO.patch +++ b/cyrus-sasl-2.1.27-Add-Channel-Binding-support-for-GSSAPI-GSS-SPNEGO.patch @@ -1,24 +1,24 @@ -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 (minor inline mods to make them apply): +975edbb69070eba6b035f08776de771a129cfb57 +ea8eb892e44129ac3890298da91c868d5592ed20 -Backport of commit ids: -829a6ed086432e26dafa9d1dcf892aef4c42cfbd -944bd8a6205f840b105206ef83e8f6b9dff0138e +From 975edbb69070eba6b035f08776de771a129cfb57 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Fri, 20 Mar 2020 14:51:04 -0400 +Subject: [PATCH] Add Channel Binding support for GSSAPI/GSS-SPNEGO 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(-) + tests/t_common.c | 14 +++++++ + tests/t_common.h | 2 + + tests/t_gssapi_cli.c | 21 +++++++++- + tests/t_gssapi_srv.c | 21 +++++++++- + 6 files changed, 164 insertions(+), 17 deletions(-) diff --git a/plugins/gssapi.c b/plugins/gssapi.c -index ff663da..5d900c5 100644 +index ff663da7..5d900c5e 100644 --- a/plugins/gssapi.c +++ b/plugins/gssapi.c @@ -830,7 +830,9 @@ gssapi_server_mech_authneg(context_t *text, @@ -122,7 +122,7 @@ index ff663da..5d900c5 100644 gssapi_required_prompts, /* required_prompts */ &gss_spnego_oid, /* glob_context */ diff --git a/tests/runtests.py b/tests/runtests.py -index f645adf..fc9cf24 100755 +index f645adf4..fc9cf244 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -1,6 +1,7 @@ @@ -245,7 +245,163 @@ index f645adf..fc9cf24 100755 diff --git a/tests/t_common.c b/tests/t_common.c -index 7168b2f..478e6a1 100644 +index 7168b2f1..87875b48 100644 +--- a/tests/t_common.c ++++ b/tests/t_common.c +@@ -65,4 +65,18 @@ int getpath(void *context __attribute__((unused)), const char **path) + return SASL_OK; + } + ++void parse_cb(sasl_channel_binding_t *cb, char *buf, unsigned max, char *in) ++{ ++ unsigned len; ++ int r; + ++ r = sasl_decode64(in, strlen(in), buf, max, &len); ++ if (r != SASL_OK) { ++ saslerr(r, "failed to parse channel bindings"); ++ exit(-1); ++ } ++ cb->name = "TEST BINDINGS"; ++ cb->critical = 0; ++ cb->data = (unsigned char *)buf; ++ cb->len = len; ++} +diff --git a/tests/t_common.h b/tests/t_common.h +index 4ee1976c..0d08d8ba 100644 +--- a/tests/t_common.h ++++ b/tests/t_common.h +@@ -7,9 +7,11 @@ + #include + + #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 c833c055..6b5664eb 100644 +--- a/tests/t_gssapi_cli.c ++++ b/tests/t_gssapi_cli.c +@@ -13,6 +13,7 @@ + + #include + #include ++#include + + static int setup_socket(void) + { +@@ -32,7 +33,7 @@ static int setup_socket(void) + return sock; + } + +-int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused))) ++int main(int argc, char *argv[]) + { + sasl_callback_t callbacks[2] = {}; + char buf[8192]; +@@ -40,8 +41,20 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused))) + sasl_conn_t *conn; + const char *data; + unsigned int len; ++ sasl_channel_binding_t cb = {0}; ++ char cb_buf[256]; + int sd; +- int r; ++ int c, r; ++ ++ while ((c = getopt(argc, argv, "c:")) != EOF) { ++ switch (c) { ++ case 'c': ++ parse_cb(&cb, cb_buf, 256, optarg); ++ break; ++ default: ++ break; ++ } ++ } + + /* initialize the sasl library */ + callbacks[0].id = SASL_CB_GETPATH; +@@ -60,6 +73,10 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused))) + exit(-1); + } + ++ if (cb.name) { ++ sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb); ++ } ++ + r = sasl_client_start(conn, "GSSAPI", NULL, &data, &len, &chosenmech); + if (r != SASL_OK && r != SASL_CONTINUE) { + saslerr(r, "starting SASL negotiation"); +diff --git a/tests/t_gssapi_srv.c b/tests/t_gssapi_srv.c +index 29f538dd..3a8a5d44 100644 +--- a/tests/t_gssapi_srv.c ++++ b/tests/t_gssapi_srv.c +@@ -44,15 +44,28 @@ static int setup_socket(void) + return sd; + } + +-int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused))) ++int main(int argc, char *argv[]) + { + sasl_callback_t callbacks[2] = {}; + char buf[8192]; + sasl_conn_t *conn; + const char *data; + unsigned int len; ++ sasl_channel_binding_t cb = {0}; ++ unsigned char cb_buf[256]; + int sd; +- int r; ++ int c, r; ++ ++ while ((c = getopt(argc, argv, "c:")) != EOF) { ++ switch (c) { ++ case 'c': ++ parse_cb(&cb, cb_buf, 256, optarg); ++ break; ++ default: ++ break; ++ } ++ } ++ + + /* initialize the sasl library */ + callbacks[0].id = SASL_CB_GETPATH; +@@ -72,6 +85,10 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused))) + exit(-1); + } + ++ if (cb.name) { ++ sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb); ++ } ++ + sd = setup_socket(); + + len = 8192; + +From ea8eb892e44129ac3890298da91c868d5592ed20 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Fri, 20 Mar 2020 14:52:15 -0400 +Subject: [PATCH] Fixup minor issues in previous PR. + +Remove spurious debugging code, this was left in by mistake. +Add C notices, this was omitted by mistake. + +Signed-off-by: Simo Sorce +--- + tests/t_common.c | 10 ++-------- + tests/t_common.h | 3 ++- + tests/t_gssapi_cli.c | 3 ++- + tests/t_gssapi_srv.c | 3 ++- + 4 files changed, 8 insertions(+), 11 deletions(-) + +diff --git a/tests/t_common.c b/tests/t_common.c +index 87875b48..478e6a1f 100644 --- a/tests/t_common.c +++ b/tests/t_common.c @@ -1,4 +1,5 @@ @@ -283,27 +439,8 @@ index 7168b2f..478e6a1 100644 *buflen = ret; } -@@ -65,4 +59,18 @@ int getpath(void *context __attribute__((unused)), const char **path) - return SASL_OK; - } - -+void parse_cb(sasl_channel_binding_t *cb, char *buf, unsigned max, char *in) -+{ -+ unsigned len; -+ int r; - -+ r = sasl_decode64(in, strlen(in), buf, max, &len); -+ if (r != SASL_OK) { -+ saslerr(r, "failed to parse channel bindings"); -+ exit(-1); -+ } -+ cb->name = "TEST BINDINGS"; -+ cb->critical = 0; -+ cb->data = (unsigned char *)buf; -+ cb->len = len; -+} diff --git a/tests/t_common.h b/tests/t_common.h -index 4ee1976..a10def1 100644 +index 0d08d8ba..a10def17 100644 --- a/tests/t_common.h +++ b/tests/t_common.h @@ -1,4 +1,5 @@ @@ -313,20 +450,8 @@ index 4ee1976..a10def1 100644 #include "config.h" -@@ -7,9 +8,11 @@ - #include - - #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 +index 6b5664eb..a44a3f58 100644 --- a/tests/t_gssapi_cli.c +++ b/tests/t_gssapi_cli.c @@ -1,4 +1,5 @@ @@ -336,58 +461,8 @@ index c833c05..a44a3f5 100644 #include "t_common.h" -@@ -13,6 +14,7 @@ - - #include - #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 +index 3a8a5d44..ef1217f6 100644 --- a/tests/t_gssapi_srv.c +++ b/tests/t_gssapi_srv.c @@ -1,4 +1,5 @@ @@ -397,48 +472,4 @@ index 29f538d..ef1217f 100644 #include "t_common.h" -@@ -44,15 +45,28 @@ static int setup_socket(void) - return sd; - } - --int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused))) -+int main(int argc, char *argv[]) - { - sasl_callback_t callbacks[2] = {}; - char buf[8192]; - sasl_conn_t *conn; - const char *data; - unsigned int len; -+ sasl_channel_binding_t cb = {0}; -+ unsigned char cb_buf[256]; - int sd; -- int r; -+ int c, r; -+ -+ while ((c = getopt(argc, argv, "c:")) != EOF) { -+ switch (c) { -+ case 'c': -+ parse_cb(&cb, cb_buf, 256, optarg); -+ break; -+ default: -+ break; -+ } -+ } -+ - - /* initialize the sasl library */ - callbacks[0].id = SASL_CB_GETPATH; -@@ -72,6 +86,10 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused))) - exit(-1); - } - -+ if (cb.name) { -+ sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb); -+ } -+ - sd = setup_socket(); - - len = 8192; --- -2.18.2 diff --git a/SOURCES/cyrus-sasl-2.1.27-Add-basic-test-infrastructure.patch b/cyrus-sasl-2.1.27-Add-basic-test-infrastructure.patch similarity index 96% rename from SOURCES/cyrus-sasl-2.1.27-Add-basic-test-infrastructure.patch rename to cyrus-sasl-2.1.27-Add-basic-test-infrastructure.patch index 2f6a35c..171b309 100644 --- a/SOURCES/cyrus-sasl-2.1.27-Add-basic-test-infrastructure.patch +++ b/cyrus-sasl-2.1.27-Add-basic-test-infrastructure.patch @@ -1,14 +1,16 @@ -From 82e299e970461c153a036bb1fbc84e808f926e12 Mon Sep 17 00:00:00 2001 +Backport of 18ff41d5d18f61c2ded7235dad1d9618aa84784b with minor inline mods to +make it apply. + +From 18ff41d5d18f61c2ded7235dad1d9618aa84784b Mon Sep 17 00:00:00 2001 From: Simo Sorce -Date: Tue, 5 May 2020 14:06:57 -0400 +Date: Sat, 14 Mar 2020 10:50:19 -0400 Subject: [PATCH] Add basic test infrastructure First test is for SASL/GSSAPI -Backport of upstream commit id: -18ff41d5d18f61c2ded7235dad1d9618aa84784b - Signed-off-by: Simo Sorce + +:x --- Makefile.am | 2 +- configure.ac | 3 +- @@ -18,7 +20,7 @@ Signed-off-by: Simo Sorce tests/t_common.h | 15 ++++ tests/t_gssapi_cli.c | 95 +++++++++++++++++++++++ tests/t_gssapi_srv.c | 111 +++++++++++++++++++++++++++ - 8 files changed, 550 insertions(+), 2 deletions(-) + 10 files changed, 559 insertions(+), 4 deletions(-) create mode 100644 tests/Makefile.am create mode 100755 tests/runtests.py create mode 100644 tests/t_common.c @@ -27,35 +29,36 @@ Signed-off-by: Simo Sorce create mode 100644 tests/t_gssapi_srv.c diff --git a/Makefile.am b/Makefile.am -index 83dae6f..fc24509 100644 +index f7d3b22e..102e2a3e 100644 --- a/Makefile.am +++ b/Makefile.am -@@ -70,7 +70,7 @@ else +@@ -65,7 +65,7 @@ else INSTALLOSX = endif --SUBDIRS=include sasldb common lib plugins utils $(PWC) $(SAM) $(JAV) $(SAD) -+SUBDIRS=include sasldb common lib plugins utils $(PWC) $(SAM) $(JAV) $(SAD) tests +-SUBDIRS=include sasldb common lib plugins utils $(PWC) $(SAM) $(SAD) ++SUBDIRS=include sasldb common lib plugins utils $(PWC) $(SAM) $(SAD) tests EXTRA_DIST=config doc docsrc win32 mac dlcompat-20010505 NTMakefile \ INSTALL.TXT libsasl2.pc.in diff --git a/configure.ac b/configure.ac -index ca5936a..c1d2182 100644 +index 3610671b..dd7908a3 100644 --- a/configure.ac +++ b/configure.ac -@@ -1575,7 +1575,8 @@ java/javax/Makefile - java/javax/security/Makefile - java/javax/security/auth/Makefile - java/javax/security/auth/callback/Makefile --pwcheck/Makefile) +@@ -1516,8 +1516,9 @@ plugins/Makefile + lib/Makefile + utils/Makefile + sample/Makefile +-pwcheck/Makefile]) +pwcheck/Makefile -+tests/Makefile) ++tests/Makefile]) + AC_OUTPUT AC_MSG_NOTICE([ diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 -index 0000000..1edf010 +index 00000000..1edf010a --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,79 @@ @@ -140,7 +143,7 @@ index 0000000..1edf010 +endif diff --git a/tests/runtests.py b/tests/runtests.py new file mode 100755 -index 0000000..f645adf +index 00000000..f645adf4 --- /dev/null +++ b/tests/runtests.py @@ -0,0 +1,179 @@ @@ -325,7 +328,7 @@ index 0000000..f645adf + gssapi_tests(T) diff --git a/tests/t_common.c b/tests/t_common.c new file mode 100644 -index 0000000..7168b2f +index 00000000..7168b2f1 --- /dev/null +++ b/tests/t_common.c @@ -0,0 +1,68 @@ @@ -399,7 +402,7 @@ index 0000000..7168b2f + diff --git a/tests/t_common.h b/tests/t_common.h new file mode 100644 -index 0000000..4ee1976 +index 00000000..4ee1976c --- /dev/null +++ b/tests/t_common.h @@ -0,0 +1,15 @@ @@ -420,7 +423,7 @@ index 0000000..4ee1976 +int getpath(void *context __attribute__((unused)), const char **path); diff --git a/tests/t_gssapi_cli.c b/tests/t_gssapi_cli.c new file mode 100644 -index 0000000..c833c05 +index 00000000..c833c055 --- /dev/null +++ b/tests/t_gssapi_cli.c @@ -0,0 +1,95 @@ @@ -521,7 +524,7 @@ index 0000000..c833c05 + diff --git a/tests/t_gssapi_srv.c b/tests/t_gssapi_srv.c new file mode 100644 -index 0000000..29f538d +index 00000000..29f538dd --- /dev/null +++ b/tests/t_gssapi_srv.c @@ -0,0 +1,111 @@ @@ -636,6 +639,4 @@ index 0000000..29f538d + return 0; +} + --- -2.18.2 diff --git a/cyrus-sasl-2.1.27-Add-support-for-setting-max-ssf-0-to-GSS-SPNEGO.patch b/cyrus-sasl-2.1.27-Add-support-for-setting-max-ssf-0-to-GSS-SPNEGO.patch new file mode 100644 index 0000000..46f89ed --- /dev/null +++ b/cyrus-sasl-2.1.27-Add-support-for-setting-max-ssf-0-to-GSS-SPNEGO.patch @@ -0,0 +1,95 @@ +Backport of part of Upstream PR#603 minimal part needed for interop + +From 0e722dd3266d5ebd0f889462cc23856fde3d21ed Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Thu, 19 Sep 2019 15:58:04 -0400 +Subject: [PATCH] Add support for setting max ssf 0 to GSS-SPNEGO + +This is needed to interop with Windows within a TLS channel. + +Signed-off-by: Simo Sorce +--- + m4/sasl2.m4 | 13 +++++++++++++ + plugins/gssapi.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 57 insertions(+), 1 deletion(-) + +diff --git a/m4/sasl2.m4 b/m4/sasl2.m4 +index 17f5d081..60306943 100644 +--- a/m4/sasl2.m4 ++++ b/m4/sasl2.m4 +@@ -287,6 +287,19 @@ if test "$gssapi" != no; then + AC_CHECK_FUNCS(gss_oid_equal) + LIBS="$cmu_save_LIBS" + ++ cmu_save_LIBS="$LIBS" ++ LIBS="$LIBS $GSSAPIBASE_LIBS" ++ if test "$ac_cv_header_gssapi_gssapi_krb5_h" = "yes"; then ++ AC_CHECK_DECL(GSS_KRB5_CRED_NO_CI_FLAGS_X, ++ [AC_DEFINE(HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X,1, ++ [Define if your GSSAPI implementation supports GSS_KRB5_CRED_NO_CI_FLAGS_X])],, ++ [ ++ AC_INCLUDES_DEFAULT ++ #include ++ ]) ++ fi ++ LIBS="$cmu_save_LIBS" ++ + cmu_save_LIBS="$LIBS" + LIBS="$LIBS $GSSAPIBASE_LIBS" + AC_CHECK_FUNCS(gss_get_name_attribute) +diff --git a/plugins/gssapi.c b/plugins/gssapi.c +index 46de7d48..cca6cc0a 100644 +--- a/plugins/gssapi.c ++++ b/plugins/gssapi.c +@@ -2123,7 +2123,50 @@ static int gssapi_client_mech_step(void *conn_context, + /* We want to try for privacy */ + req_flags |= GSS_C_CONF_FLAG; + } +- } ++#ifdef HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X ++ /* The krb5 mechanism automatically adds INTEG and CONF flags even when ++ * not specified, this has the effect of rendering explicit requests ++ * of no confidentiality and integrity via setting maxssf 0 moot. ++ * However to interoperate with Windows machines it needs to be ++ * possible to unset these flags as Windows machines refuse to allow ++ * two layers (say TLS and GSSAPI) to both provide these services. ++ * So if we do not suppress these flags a SASL/GSS-SPNEGO negotiation ++ * over, say, LDAPS will fail against Windows Servers */ ++ } else if (params->props.max_ssf == 0) { ++ gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER; ++ if (client_creds == GSS_C_NO_CREDENTIAL) { ++ gss_OID_set_desc mechs = { 0 }; ++ gss_OID_set desired_mechs = GSS_C_NO_OID_SET; ++ if (text->mech_type != GSS_C_NO_OID) { ++ mechs.count = 1; ++ mechs.elements = text->mech_type; ++ desired_mechs = &mechs; ++ } ++ ++ maj_stat = gss_acquire_cred(&min_stat, GSS_C_NO_NAME, ++ GSS_C_INDEFINITE, desired_mechs, ++ GSS_C_INITIATE, ++ &text->client_creds, NULL, NULL); ++ if (GSS_ERROR(maj_stat)) { ++ sasl_gss_seterror(text->utils, maj_stat, min_stat); ++ sasl_gss_free_context_contents(text); ++ return SASL_FAIL; ++ } ++ client_creds = text->client_creds; ++ } ++ ++ maj_stat = gss_set_cred_option(&min_stat, &client_creds, ++ (gss_OID)GSS_KRB5_CRED_NO_CI_FLAGS_X, ++ &empty_buffer); ++ if (GSS_ERROR(maj_stat)) { ++ sasl_gss_seterror(text->utils, maj_stat, min_stat); ++ sasl_gss_free_context_contents(text); ++ return SASL_FAIL; ++ } ++#endif ++ } ++ ++ + + if (params->props.security_flags & SASL_SEC_PASS_CREDENTIALS) { + req_flags = req_flags | GSS_C_DELEG_FLAG; diff --git a/cyrus-sasl-2.1.27-coverity.patch b/cyrus-sasl-2.1.27-coverity.patch new file mode 100644 index 0000000..871ea10 --- /dev/null +++ b/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/cyrus-sasl-2.1.27-cumulative-digestmd5.patch b/cyrus-sasl-2.1.27-cumulative-digestmd5.patch new file mode 100644 index 0000000..c0df481 --- /dev/null +++ b/cyrus-sasl-2.1.27-cumulative-digestmd5.patch @@ -0,0 +1,554 @@ +diff -uPr cyrus-sasl-2.1.27/plugins/digestmd5.c cyrus-sasl-2.1.27.digestmd5/plugins/digestmd5.c +--- cyrus-sasl-2.1.27/plugins/digestmd5.c 2021-09-30 17:13:06.573093526 -0400 ++++ cyrus-sasl-2.1.27.digestmd5/plugins/digestmd5.c 2021-09-30 17:26:31.818378442 -0400 +@@ -80,6 +80,12 @@ + # endif + #endif /* WITH_DES */ + ++/* legacy provider with openssl 3.0 */ ++#if OPENSSL_VERSION_NUMBER >= 0x30000000L ++# include ++# 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,143 @@ + + memcpy(c->ivec, ((char *) deckey) + 8, 8); + +- text->cipher_dec_context = (cipher_context_t *) c; ++ text->crypto.dec_ctx = (cipher_context_t *) c; + + return SASL_OK; + } + + static void free_des(context_t *text) + { +- /* free des contextss. only cipher_enc_context needs to be free'd, +- since cipher_dec_context was allocated at the same time. */ +- if (text->cipher_enc_context) text->utils->free(text->cipher_enc_context); ++ /* free des contextss. only enc_ctx needs to be free'd, ++ since dec_cxt was allocated at the same time. */ ++ if (text->crypto.enc_ctx) { ++ text->utils->free(text->crypto.enc_ctx); ++ } + } + + #endif /* WITH_DES */ + + #ifdef WITH_RC4 +-#ifdef HAVE_OPENSSL + #include + ++#if OPENSSL_VERSION_NUMBER >= 0x30000000L ++typedef struct ossl3_library_context { ++ OSSL_LIB_CTX *libctx; ++ OSSL_PROVIDER *legacy_provider; ++ OSSL_PROVIDER *default_provider; ++} ossl3_context_t; ++ ++static int init_ossl3_ctx(context_t *text) ++{ ++ ossl3_context_t *ctx = text->utils->malloc(sizeof(ossl3_context_t)); ++ if (!ctx) return SASL_NOMEM; ++ ++ ctx->libctx = OSSL_LIB_CTX_new(); ++ if (!ctx->libctx) { ++ text->utils->free(ctx); ++ return SASL_FAIL; ++ } ++ ++ /* Load both legacy and default provider as both may be needed */ ++ /* if they fail keep going and an error will be raised when we try to ++ * fetch the cipher later */ ++ ctx->legacy_provider = OSSL_PROVIDER_load(ctx->libctx, "legacy"); ++ ctx->default_provider = OSSL_PROVIDER_load(ctx->libctx, "default"); ++ text->crypto.libctx = (void *)ctx; ++ ++ return SASL_OK; ++} ++ ++static void free_ossl3_ctx(context_t *text) ++{ ++ ossl3_context_t *ctx; ++ ++ if (!text->crypto.libctx) return; ++ ++ ctx = (ossl3_context_t *)text->crypto.libctx; ++ ++ if (ctx->legacy_provider) OSSL_PROVIDER_unload(ctx->legacy_provider); ++ if (ctx->default_provider) OSSL_PROVIDER_unload(ctx->default_provider); ++ if (ctx->libctx) OSSL_LIB_CTX_free(ctx->libctx); ++ ++ text->utils->free(ctx); ++ text->crypto.libctx = NULL; ++} ++#endif ++ + static void free_rc4(context_t *text) + { +- if (text->cipher_enc_context) { +- EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *)text->cipher_enc_context); +- text->cipher_enc_context = NULL; +- } +- if (text->cipher_dec_context) { +- EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *)text->cipher_dec_context); +- text->cipher_dec_context = NULL; ++ if (text->crypto.enc_ctx) { ++ EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *)text->crypto.enc_ctx); ++ text->crypto.enc_ctx = NULL; ++ } ++ if (text->crypto.dec_ctx) { ++ EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *)text->crypto.dec_ctx); ++ text->crypto.dec_ctx = NULL; + } ++#if OPENSSL_VERSION_NUMBER >= 0x30000000L ++ free_ossl3_ctx(text); ++#endif + } + + static int init_rc4(context_t *text, + unsigned char enckey[16], + unsigned char deckey[16]) + { + EVP_CIPHER_CTX *ctx; + int rc; + +- ctx = EVP_CIPHER_CTX_new(); +- if (ctx == NULL) return SASL_NOMEM; ++#if OPENSSL_VERSION_NUMBER >= 0x30000000L ++ EVP_CIPHER *cipher; ++ ossl3_context_t *ossl3_ctx; + +- rc = EVP_EncryptInit_ex(ctx, EVP_rc4(), NULL, enckey, NULL); +- if (rc != 1) return SASL_FAIL; ++ rc = init_ossl3_ctx(text); ++ if (rc != SASL_OK) return rc; ++ ++ ossl3_ctx = (ossl3_context_t *)text->crypto.libctx; ++ cipher = EVP_CIPHER_fetch(ossl3_ctx->libctx, "RC4", ""); ++#else ++ const EVP_CIPHER *cipher; ++ cipher = EVP_rc4(); ++#endif + +- text->cipher_enc_context = (void *)ctx; + + ctx = EVP_CIPHER_CTX_new(); +- if (ctx == NULL) return SASL_NOMEM; ++ if (ctx == NULL) { ++ rc = SASL_NOMEM; ++ goto done; ++ } + +- rc = EVP_DecryptInit_ex(ctx, EVP_rc4(), NULL, deckey, NULL); +- if (rc != 1) return SASL_FAIL; ++ rc = EVP_EncryptInit_ex(ctx, cipher, NULL, enckey, NULL); ++ if (rc != 1) { ++ rc = SASL_FAIL; ++ goto done; ++ } ++ text->crypto.enc_ctx = (void *)ctx; + +- text->cipher_dec_context = (void *)ctx; ++ ctx = EVP_CIPHER_CTX_new(); ++ if (ctx == NULL) { ++ rc = SASL_NOMEM; ++ goto done; ++ } + +- return SASL_OK; ++ rc = EVP_DecryptInit_ex(ctx, cipher, NULL, deckey, NULL); ++ if (rc != 1) { ++ rc = SASL_FAIL; ++ goto done; ++ } ++ text->crypto.dec_ctx = (void *)ctx; ++ ++ rc = SASL_OK; ++ ++done: ++#if OPENSSL_VERSION_NUMBER >= 0x30000000L ++ EVP_CIPHER_free(cipher); ++#endif ++ if (rc != SASL_OK) { ++ free_rc4(text); ++ } ++ return rc; + } + + static int dec_rc4(context_t *text, +@@ -1169,14 +1260,14 @@ + int rc; + + /* decrypt the text part & HMAC */ +- rc = EVP_DecryptUpdate((EVP_CIPHER_CTX *)text->cipher_dec_context, ++ rc = EVP_DecryptUpdate((EVP_CIPHER_CTX *)text->crypto.dec_ctx, + (unsigned char *)output, &len, + (const unsigned char *)input, inputlen); + if (rc != 1) return SASL_FAIL; + + *outputlen = len; + +- rc = EVP_DecryptFinal_ex((EVP_CIPHER_CTX *)text->cipher_dec_context, ++ rc = EVP_DecryptFinal_ex((EVP_CIPHER_CTX *)text->crypto.dec_ctx, + (unsigned char *)output + len, &len); + if (rc != 1) return SASL_FAIL; + +@@ -1198,7 +1289,7 @@ + int len; + int rc; + /* encrypt the text part */ +- rc = EVP_EncryptUpdate((EVP_CIPHER_CTX *)text->cipher_enc_context, ++ rc = EVP_EncryptUpdate((EVP_CIPHER_CTX *)text->crypto.enc_ctx, + (unsigned char *)output, &len, + (const unsigned char *)input, inputlen); + if (rc != 1) return SASL_FAIL; +@@ -1206,14 +1297,14 @@ + *outputlen = len; + + /* encrypt the `MAC part */ +- rc = EVP_EncryptUpdate((EVP_CIPHER_CTX *)text->cipher_enc_context, ++ rc = EVP_EncryptUpdate((EVP_CIPHER_CTX *)text->crypto.enc_ctx, + (unsigned char *)output + *outputlen, &len, + digest, 10); + if (rc != 1) return SASL_FAIL; + + *outputlen += len; + +- rc = EVP_EncryptFinal_ex((EVP_CIPHER_CTX *)text->cipher_enc_context, ++ rc = EVP_EncryptFinal_ex((EVP_CIPHER_CTX *)text->crypto.enc_ctx, + (unsigned char *)output + *outputlen, &len); + if (rc != 1) return SASL_FAIL; + +@@ -1221,194 +1312,11 @@ + + return SASL_OK; + } +-#else +-/* quick generic implementation of RC4 */ +-struct rc4_context_s { +- unsigned char sbox[256]; +- int i, j; +-}; +- +-typedef struct rc4_context_s rc4_context_t; +- +-static void rc4_init(rc4_context_t *text, +- const unsigned char *key, +- unsigned keylen) +-{ +- int i, j; +- +- /* fill in linearly s0=0 s1=1... */ +- for (i=0;i<256;i++) +- text->sbox[i]=i; +- +- j=0; +- for (i = 0; i < 256; i++) { +- unsigned char tmp; +- /* j = (j + Si + Ki) mod 256 */ +- j = (j + text->sbox[i] + key[i % keylen]) % 256; +- +- /* swap Si and Sj */ +- tmp = text->sbox[i]; +- text->sbox[i] = text->sbox[j]; +- text->sbox[j] = tmp; +- } +- +- /* counters initialized to 0 */ +- text->i = 0; +- text->j = 0; +-} +- +-static void rc4_encrypt(rc4_context_t *text, +- const char *input, +- char *output, +- unsigned len) +-{ +- int tmp; +- int i = text->i; +- int j = text->j; +- int t; +- int K; +- const char *input_end = input + len; +- +- while (input < input_end) { +- i = (i + 1) % 256; +- +- j = (j + text->sbox[i]) % 256; +- +- /* swap Si and Sj */ +- tmp = text->sbox[i]; +- text->sbox[i] = text->sbox[j]; +- text->sbox[j] = tmp; +- +- t = (text->sbox[i] + text->sbox[j]) % 256; +- +- K = text->sbox[t]; +- +- /* byte K is Xor'ed with plaintext */ +- *output++ = *input++ ^ K; +- } +- +- text->i = i; +- text->j = j; +-} +- +-static void rc4_decrypt(rc4_context_t *text, +- const char *input, +- char *output, +- unsigned len) +-{ +- int tmp; +- int i = text->i; +- int j = text->j; +- int t; +- int K; +- const char *input_end = input + len; +- +- while (input < input_end) { +- i = (i + 1) % 256; +- +- j = (j + text->sbox[i]) % 256; +- +- /* swap Si and Sj */ +- tmp = text->sbox[i]; +- text->sbox[i] = text->sbox[j]; +- text->sbox[j] = tmp; +- +- t = (text->sbox[i] + text->sbox[j]) % 256; +- +- K = text->sbox[t]; +- +- /* byte K is Xor'ed with plaintext */ +- *output++ = *input++ ^ K; +- } +- +- text->i = i; +- text->j = j; +-} +- +-static void free_rc4(context_t *text) +-{ +- /* free rc4 context structures */ +- +- if (text->cipher_enc_context) { +- text->utils->free(text->cipher_enc_context); +- text->cipher_enc_context = NULL; +- } +- if (text->cipher_dec_context) { +- text->utils->free(text->cipher_dec_context); +- text->cipher_dec_context = NULL; +- } +-} +- +-static int init_rc4(context_t *text, +- unsigned char enckey[16], +- unsigned char deckey[16]) +-{ +- /* allocate rc4 context structures */ +- text->cipher_enc_context= +- (cipher_context_t *) text->utils->malloc(sizeof(rc4_context_t)); +- if (text->cipher_enc_context == NULL) return SASL_NOMEM; +- +- text->cipher_dec_context= +- (cipher_context_t *) text->utils->malloc(sizeof(rc4_context_t)); +- if (text->cipher_dec_context == NULL) return SASL_NOMEM; +- +- /* initialize them */ +- rc4_init((rc4_context_t *) text->cipher_enc_context, +- (const unsigned char *) enckey, 16); +- rc4_init((rc4_context_t *) text->cipher_dec_context, +- (const unsigned char *) deckey, 16); +- +- return SASL_OK; +-} +- +-static int dec_rc4(context_t *text, +- const char *input, +- unsigned inputlen, +- unsigned char digest[16] __attribute__((unused)), +- char *output, +- unsigned *outputlen) +-{ +- /* decrypt the text part & HMAC */ +- rc4_decrypt((rc4_context_t *) text->cipher_dec_context, +- input, output, inputlen); +- +- /* no padding so we just subtract the HMAC to get the text length */ +- *outputlen = inputlen - 10; +- +- return SASL_OK; +-} +- +-static int enc_rc4(context_t *text, +- const char *input, +- unsigned inputlen, +- unsigned char digest[16], +- char *output, +- unsigned *outputlen) +-{ +- /* pad is zero */ +- *outputlen = inputlen+10; +- +- /* encrypt the text part */ +- rc4_encrypt((rc4_context_t *) text->cipher_enc_context, +- input, +- output, +- inputlen); +- +- /* encrypt the HMAC part */ +- rc4_encrypt((rc4_context_t *) text->cipher_enc_context, +- (const char *) digest, +- (output)+inputlen, 10); +- +- return SASL_OK; +-} +-#endif /* HAVE_OPENSSL */ + #endif /* WITH_RC4 */ + + struct digest_cipher available_ciphers[] = + { + #ifdef WITH_RC4 +- { "rc4-40", 40, 5, 0x01, &enc_rc4, &dec_rc4, &init_rc4, &free_rc4 }, +- { "rc4-56", 56, 7, 0x02, &enc_rc4, &dec_rc4, &init_rc4, &free_rc4 }, + { "rc4", 128, 16, 0x04, &enc_rc4, &dec_rc4, &init_rc4, &free_rc4 }, + #endif + #ifdef WITH_DES +@@ -2815,6 +2729,7 @@ + } + + if (cptr->name) { ++ text->cipher_name = cptr->name; + text->cipher_enc = cptr->cipher_enc; + text->cipher_dec = cptr->cipher_dec; + text->cipher_init = cptr->cipher_init; +@@ -2958,7 +2873,10 @@ + if (text->cipher_init) { + if (text->cipher_init(text, enckey, deckey) != SASL_OK) { + sparams->utils->seterror(sparams->utils->conn, 0, +- "couldn't init cipher"); ++ "couldn't init cipher '%s'", ++ text->cipher_name); ++ result = SASL_FAIL; ++ goto FreeAllMem; + } + } + } +@@ -3509,6 +3427,7 @@ + oparams->mech_ssf = ctext->cipher->ssf; + + nbits = ctext->cipher->n; ++ text->cipher_name = ctext->cipher->name; + text->cipher_enc = ctext->cipher->cipher_enc; + text->cipher_dec = ctext->cipher->cipher_dec; + text->cipher_free = ctext->cipher->cipher_free; +@@ -3733,7 +3652,13 @@ + + /* initialize cipher if need be */ + if (text->cipher_init) { +- text->cipher_init(text, enckey, deckey); ++ if (text->cipher_init(text, enckey, deckey) != SASL_OK) { ++ params->utils->seterror(params->utils->conn, 0, ++ "internal error: failed to init cipher '%s'", ++ text->cipher_name); ++ result = SASL_FAIL; ++ goto FreeAllocatedMem; ++ } + } + } + diff --git a/cyrus-sasl-2.1.27-cumulative-ossl3.patch b/cyrus-sasl-2.1.27-cumulative-ossl3.patch new file mode 100644 index 0000000..b61d0a3 --- /dev/null +++ b/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 *****************************/ + +@@ -291,6 +293,32 @@ + } + #endif + ++#if OPENSSL_VERSION_NUMBER >= 0x30000000L ++ ++/* Decalre as void given functions never use the result */ ++void *HMAC(const EVP_MD *evp_md, const void *key, int key_len, ++ const unsigned char *data, size_t data_len, ++ unsigned char *md, unsigned int *md_len) ++{ ++ const char *digest; ++ size_t digest_size; ++ size_t out_len; ++ void *ret = NULL; ++ ++ digest = EVP_MD_get0_name(evp_md); ++ if (digest == NULL) { ++ return NULL; ++ } ++ digest_size = EVP_MD_size(evp_md); ++ ++ ret = EVP_Q_mac(NULL, "hmac", NULL, digest, NULL, key, key_len, ++ data, data_len, md, digest_size, &out_len); ++ if (ret != NULL) { ++ *md_len = (unsigned int)out_len; ++ } ++ return ret; ++} ++#endif + + /* The result variable need to point to a buffer big enough for the [SHA-*] hash */ + static void +diff -uPr cyrus-sasl-2.1.27/saslauthd/lak.c cyrus-sasl-2.1.27.ossl3/saslauthd/lak.c +--- cyrus-sasl-2.1.27/saslauthd/lak.c 2022-01-09 11:30:50.000000000 -0400 ++++ cyrus-sasl-2.1.27.ossl3/saslauthd/lak.c 2022-01-09 11:30:50.000000001 -0400 +@@ -1806,18 +1806,36 @@ + return rc; + } + +- EVP_DigestInit(mdctx, md); +- EVP_DigestUpdate(mdctx, passwd, strlen(passwd)); ++ rc = EVP_DigestInit(mdctx, md); ++ if (rc != 1) { ++ rc = LAK_FAIL; ++ goto done; ++ } ++ rc = EVP_DigestUpdate(mdctx, passwd, strlen(passwd)); ++ if (rc != 1) { ++ rc = LAK_FAIL; ++ goto done; ++ } + if (hrock->salted) { +- EVP_DigestUpdate(mdctx, &cred[EVP_MD_size(md)], +- clen - EVP_MD_size(md)); ++ rc = EVP_DigestUpdate(mdctx, &cred[EVP_MD_size(md)], ++ clen - EVP_MD_size(md)); ++ if (rc != 1) { ++ rc = LAK_FAIL; ++ goto done; ++ } ++ } ++ rc = EVP_DigestFinal(mdctx, digest, NULL); ++ if (rc != 1) { ++ rc = LAK_FAIL; ++ goto done; + } +- EVP_DigestFinal(mdctx, digest, NULL); +- EVP_MD_CTX_free(mdctx); + + rc = memcmp((char *)cred, (char *)digest, EVP_MD_size(md)); ++ rc = rc ? LAK_INVALID_PASSWORD : LAK_OK; ++done: ++ EVP_MD_CTX_free(mdctx); + free(cred); +- return rc ? LAK_INVALID_PASSWORD : LAK_OK; ++ return rc; + } + + #endif /* HAVE_OPENSSL */ diff --git a/cyrus-sasl-2.1.27-more-tests.patch b/cyrus-sasl-2.1.27-more-tests.patch new file mode 100644 index 0000000..7e6435c --- /dev/null +++ b/cyrus-sasl-2.1.27-more-tests.patch @@ -0,0 +1,761 @@ +From 10ac4d4822023b24734acde3c07186937ad52813 Mon Sep 17 00:00:00 2001 +From: Dmitry Belyavskiy +Date: Wed, 6 Jan 2021 12:38:46 +0100 +Subject: [PATCH] Some basic PLAIN auth tests + +Signed-off-by: Dmitry Belyavskiy +--- + tests/runtests.py | 91 +++++++++++++++++++++++++++++++++++++++++ + tests/t_gssapi_cli.c | 97 +++++++++++++++++++++++++++++++++++++++----- + tests/t_gssapi_srv.c | 78 +++++++++++++++++++++++++++-------- + 3 files changed, 239 insertions(+), 27 deletions(-) + +diff --git a/tests/runtests.py b/tests/runtests.py +index fc9cf244..513ed3ff 100755 +--- a/tests/runtests.py ++++ b/tests/runtests.py +@@ -239,6 +239,96 @@ def gssapi_tests(testdir): + + os.killpg(kdc.pid, signal.SIGTERM) + ++def setup_plain(testdir): ++ """ Create sasldb file """ ++ sasldbfile = os.path.join(testdir, 'testsasldb.db') ++ ++ sasldbenv = {'SASL_PATH': os.path.join(testdir, '../../plugins/.libs'), ++ 'LD_LIBRARY_PATH' : os.path.join(testdir, '../../lib/.libs')} ++ ++ passwdprog = os.path.join(testdir, '../../utils/saslpasswd2') ++ ++ echo = subprocess.Popen(('echo', '1234567'), stdout=subprocess.PIPE) ++ subprocess.check_call([ ++ passwdprog, "-f", sasldbfile, "-c", "test", ++ "-u", "host.realm.test", "-p" ++ ], stdin=echo.stdout, env=sasldbenv, timeout=5) ++ ++ return (sasldbfile, sasldbenv) ++ ++def plain_test(sasldbfile, sasldbenv): ++ try: ++ srv = subprocess.Popen(["../tests/t_gssapi_srv", "-P", sasldbfile], ++ stdout=subprocess.PIPE, ++ stderr=subprocess.PIPE, env=sasldbenv) ++ srv.stdout.readline() # Wait for srv to say it is ready ++ cli = subprocess.Popen(["../tests/t_gssapi_cli", "-P", "1234567"], ++ stdout=subprocess.PIPE, ++ stderr=subprocess.PIPE, env=sasldbenv) ++ try: ++ cli.wait(timeout=5) ++ srv.wait(timeout=5) ++ except Exception as e: ++ print("Failed on {}".format(e)); ++ cli.kill() ++ srv.kill() ++ if cli.returncode != 0 or srv.returncode != 0: ++ raise Exception("CLI ({}): {} --> SRV ({}): {}".format( ++ cli.returncode, cli.stderr.read().decode('utf-8'), ++ srv.returncode, srv.stderr.read().decode('utf-8'))) ++ except Exception as e: ++ print("FAIL: {}".format(e)) ++ return ++ ++ print("PASS: PLAIN CLI({}) SRV({})".format( ++ cli.stdout.read().decode('utf-8').strip(), ++ srv.stdout.read().decode('utf-8').strip())) ++ return ++ ++def plain_mismatch_test(sasldbfile, sasldbenv): ++ result = "FAIL" ++ try: ++ srv = subprocess.Popen(["../tests/t_gssapi_srv", "-P", sasldbfile], ++ stdout=subprocess.PIPE, ++ stderr=subprocess.PIPE, env=sasldbenv) ++ srv.stdout.readline() # Wait for srv to say it is ready ++ bindings = base64.b64encode("CLI CBS".encode('utf-8')) ++ cli = subprocess.Popen(["../tests/t_gssapi_cli", "-P", "12345678"], ++ stdout=subprocess.PIPE, ++ stderr=subprocess.PIPE, env=sasldbenv) ++ try: ++ cli.wait(timeout=5) ++ srv.wait(timeout=5) ++ except Exception as e: ++ print("Failed on {}".format(e)); ++ cli.kill() ++ srv.kill() ++ if cli.returncode != 0 or srv.returncode != 0: ++ cli_err = cli.stderr.read().decode('utf-8').strip() ++ srv_err = srv.stderr.read().decode('utf-8').strip() ++ if "authentication failure" in srv_err: ++ result = "PASS" ++ raise Exception("CLI ({}): {} --> SRV ({}): {}".format( ++ cli.returncode, cli_err, srv.returncode, srv_err)) ++ except Exception as e: ++ print("{}: {}".format(result, e)) ++ return ++ ++ print("FAIL: This test should fail [CLI({}) SRV({})]".format( ++ cli.stdout.read().decode('utf-8').strip(), ++ srv.stdout.read().decode('utf-8').strip())) ++ return ++ ++def plain_tests(testdir): ++ sasldbfile, sasldbenv = setup_plain(testdir) ++ #print("DB file: {}, ENV: {}".format(sasldbfile, sasldbenv)) ++ print('SASLDB PLAIN:') ++ print(' ', end='') ++ plain_test(sasldbfile, sasldbenv) ++ ++ print('SASLDB PLAIN PASSWORD MISMATCH:') ++ print(' ', end='') ++ plain_mismatch_test(sasldbfile, sasldbenv) + + if __name__ == "__main__": + +@@ -254,3 +344,4 @@ def gssapi_tests(testdir): + os.makedirs(T) + + gssapi_tests(T) ++ plain_tests(T) +diff --git a/tests/t_gssapi_cli.c b/tests/t_gssapi_cli.c +index a44a3f58..20d22070 100644 +--- a/tests/t_gssapi_cli.c ++++ b/tests/t_gssapi_cli.c +@@ -16,6 +16,8 @@ + #include + #include + ++const char *testpass = NULL; ++ + static int setup_socket(void) + { + struct sockaddr_in addr; +@@ -34,9 +36,60 @@ static int setup_socket(void) + return sock; + } + ++static int get_user(void *context __attribute__((unused)), ++ int id, ++ const char **result, ++ unsigned *len) ++{ ++ const char *testuser = "test@host.realm.test"; ++ ++ if (! result) ++ return SASL_BADPARAM; ++ ++ switch (id) { ++ case SASL_CB_USER: ++ case SASL_CB_AUTHNAME: ++ *result = testuser; ++ break; ++ default: ++ return SASL_BADPARAM; ++ } ++ ++ if (len) *len = strlen(*result); ++ ++ return SASL_OK; ++} ++ ++static int get_pass(sasl_conn_t *conn __attribute__((unused)), ++ void *context __attribute__((unused)), ++ int id, ++ sasl_secret_t **psecret) ++{ ++ size_t len; ++ static sasl_secret_t *x; ++ ++ /* paranoia check */ ++ if (! conn || ! psecret || id != SASL_CB_PASS) ++ return SASL_BADPARAM; ++ ++ len = strlen(testpass); ++ ++ x = (sasl_secret_t *) realloc(x, sizeof(sasl_secret_t) + len); ++ ++ if (!x) { ++ return SASL_NOMEM; ++ } ++ ++ x->len = len; ++ strcpy((char *)x->data, testpass); ++ ++ *psecret = x; ++ return SASL_OK; ++} ++ + int main(int argc, char *argv[]) + { +- sasl_callback_t callbacks[2] = {}; ++ sasl_callback_t callbacks[4] = {}; + char buf[8192]; + const char *chosenmech; + sasl_conn_t *conn; +@@ -46,12 +99,18 @@ int main(int argc, char *argv[]) + char cb_buf[256]; + int sd; + int c, r; ++ const char *sasl_mech = "GSSAPI"; ++ int plain = 0; + +- while ((c = getopt(argc, argv, "c:")) != EOF) { ++ while ((c = getopt(argc, argv, "c:P:")) != EOF) { + switch (c) { + case 'c': + parse_cb(&cb, cb_buf, 256, optarg); + break; ++ case 'P': ++ plain = 1; ++ testpass = optarg; ++ break; + default: + break; + } +@@ -64,6 +123,22 @@ int main(int argc, char *argv[]) + callbacks[1].id = SASL_CB_LIST_END; + callbacks[1].proc = NULL; + callbacks[1].context = NULL; ++ callbacks[2].id = SASL_CB_LIST_END; ++ callbacks[2].proc = NULL; ++ callbacks[2].context = NULL; ++ callbacks[3].id = SASL_CB_LIST_END; ++ callbacks[3].proc = NULL; ++ callbacks[3].context = NULL; ++ ++ if (plain) { ++ sasl_mech = "PLAIN"; ++ ++ callbacks[1].id = SASL_CB_AUTHNAME; ++ callbacks[1].proc = (sasl_callback_ft)&get_user; ++ ++ callbacks[2].id = SASL_CB_PASS; ++ callbacks[2].proc = (sasl_callback_ft)&get_pass; ++ } + + r = sasl_client_init(callbacks); + if (r != SASL_OK) exit(-1); +@@ -78,11 +153,11 @@ int main(int argc, char *argv[]) + sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb); + } + +- r = sasl_client_start(conn, "GSSAPI", NULL, &data, &len, &chosenmech); ++ r = sasl_client_start(conn, sasl_mech, NULL, &data, &len, &chosenmech); + if (r != SASL_OK && r != SASL_CONTINUE) { +- saslerr(r, "starting SASL negotiation"); +- printf("\n%s\n", sasl_errdetail(conn)); +- exit(-1); ++ saslerr(r, "starting SASL negotiation"); ++ printf("\n%s\n", sasl_errdetail(conn)); ++ exit(-1); + } + + sd = setup_socket(); +@@ -92,11 +167,11 @@ int main(int argc, char *argv[]) + len = 8192; + recv_string(sd, buf, &len); + +- r = sasl_client_step(conn, buf, len, NULL, &data, &len); +- if (r != SASL_OK && r != SASL_CONTINUE) { +- saslerr(r, "performing SASL negotiation"); +- printf("\n%s\n", sasl_errdetail(conn)); +- exit(-1); ++ r = sasl_client_step(conn, buf, len, NULL, &data, &len); ++ if (r != SASL_OK && r != SASL_CONTINUE) { ++ saslerr(r, "performing SASL negotiation"); ++ printf("\n%s\n", sasl_errdetail(conn)); ++ exit(-1); + } + } + +diff --git a/tests/t_gssapi_srv.c b/tests/t_gssapi_srv.c +index ef1217f6..430cad65 100644 +--- a/tests/t_gssapi_srv.c ++++ b/tests/t_gssapi_srv.c +@@ -1,4 +1,5 @@ +-/* Copyright (C) Simo Sorce ++/* 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 @@ static int setup_socket(void) + return sd; + } + ++static int test_getopt(void *context __attribute__((unused)), ++ const char *plugin_name __attribute__((unused)), ++ const char *option, ++ const char **result, ++ unsigned *len) ++{ ++ if (sasldb_path && !strcmp(option, "sasldb_path")) { ++ *result = sasldb_path; ++ if (len) ++ *len = (unsigned) strlen(sasldb_path); ++ return SASL_OK; ++ } ++ ++ if (sasldb_path && !strcmp(option, "auxprop_plugin")) { ++ *result = auxprop_plugin; ++ if (len) ++ *len = (unsigned) strlen(auxprop_plugin); ++ return SASL_OK; ++ } ++ ++ if (sasldb_path && !strcmp(option, "pwcheck_method")) { ++ *result = pwcheck_method; ++ if (len) ++ *len = (unsigned) strlen(pwcheck_method); ++ return SASL_OK; ++ } ++ return SASL_FAIL; ++} ++ + int main(int argc, char *argv[]) + { +- sasl_callback_t callbacks[2] = {}; ++ sasl_callback_t callbacks[3] = {}; + char buf[8192]; + sasl_conn_t *conn; + const char *data; +@@ -56,25 +90,33 @@ int main(int argc, char *argv[]) + unsigned char cb_buf[256]; + int sd; + int c, r; ++ const char *sasl_mech = "GSSAPI"; ++ int plain = 0; + +- while ((c = getopt(argc, argv, "c:")) != EOF) { ++ while ((c = getopt(argc, argv, "c:P:")) != EOF) { + switch (c) { + case 'c': + parse_cb(&cb, cb_buf, 256, optarg); + break; ++ case 'P': ++ plain = 1; ++ sasldb_path = optarg; ++ break; + default: + break; + } + } + +- + /* initialize the sasl library */ + callbacks[0].id = SASL_CB_GETPATH; + callbacks[0].proc = (sasl_callback_ft)&getpath; + callbacks[0].context = NULL; +- callbacks[1].id = SASL_CB_LIST_END; +- callbacks[1].proc = NULL; ++ callbacks[1].id = SASL_CB_GETOPT; ++ callbacks[1].proc = (sasl_callback_ft)&test_getopt; + callbacks[1].context = NULL; ++ callbacks[2].id = SASL_CB_LIST_END; ++ callbacks[2].proc = NULL; ++ callbacks[2].context = NULL; + + r = sasl_server_init(callbacks, "t_gssapi_srv"); + if (r != SASL_OK) exit(-1); +@@ -90,16 +132,20 @@ int main(int argc, char *argv[]) + sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb); + } + ++ if (plain) { ++ sasl_mech = "PLAIN"; ++ } ++ + sd = setup_socket(); + + len = 8192; + recv_string(sd, buf, &len); + +- r = sasl_server_start(conn, "GSSAPI", buf, len, &data, &len); ++ r = sasl_server_start(conn, sasl_mech, buf, len, &data, &len); + if (r != SASL_OK && r != SASL_CONTINUE) { +- saslerr(r, "starting SASL negotiation"); +- printf("\n%s\n", sasl_errdetail(conn)); +- exit(-1); ++ saslerr(r, "starting SASL negotiation"); ++ printf("\n%s\n", sasl_errdetail(conn)); ++ exit(-1); + } + + while (r == SASL_CONTINUE) { +@@ -107,12 +153,12 @@ int main(int argc, char *argv[]) + len = 8192; + recv_string(sd, buf, &len); + +- r = sasl_server_step(conn, buf, len, &data, &len); +- if (r != SASL_OK && r != SASL_CONTINUE) { +- saslerr(r, "performing SASL negotiation"); +- printf("\n%s\n", sasl_errdetail(conn)); +- exit(-1); +- } ++ r = sasl_server_step(conn, buf, len, &data, &len); ++ if (r != SASL_OK && r != SASL_CONTINUE) { ++ saslerr(r, "performing SASL negotiation"); ++ printf("\n%s\n", sasl_errdetail(conn)); ++ exit(-1); ++ } + + } + +From d95b0afef1289194148090874799428e9e4f4cff Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Wed, 15 Apr 2020 11:57:17 -0400 +Subject: [PATCH] Test GSS-SPNEGO as well + +Signed-off-by: Simo Sorce +--- + tests/runtests.py | 91 ++++++++++++++++++++++++++++++++++++++++---- + tests/t_common.c | 13 ++++--- + tests/t_common.h | 3 +- + tests/t_gssapi_cli.c | 22 ++++++++++- + tests/t_gssapi_srv.c | 25 ++++++++++-- + 5 files changed, 134 insertions(+), 20 deletions(-) + +diff --git a/tests/runtests.py b/tests/runtests.py +index 513ed3ff..7be60745 100755 +--- a/tests/runtests.py ++++ b/tests/runtests.py +@@ -6,6 +6,7 @@ + import shutil + import signal + import subprocess ++import sys + import time + from string import Template + +@@ -149,11 +150,12 @@ def gssapi_basic_test(kenv): + srv.returncode, srv.stderr.read().decode('utf-8'))) + except Exception as e: + print("FAIL: {}".format(e)) +- return ++ return 1 + + print("PASS: CLI({}) SRV({})".format( + cli.stdout.read().decode('utf-8').strip(), + srv.stdout.read().decode('utf-8').strip())) ++ return 0 + + def gssapi_channel_binding_test(kenv): + try: +@@ -178,11 +180,12 @@ def gssapi_channel_binding_test(kenv): + srv.returncode, srv.stderr.read().decode('utf-8'))) + except Exception as e: + print("FAIL: {}".format(e)) +- return ++ return 1 + + print("PASS: CLI({}) SRV({})".format( + cli.stdout.read().decode('utf-8').strip(), + srv.stdout.read().decode('utf-8').strip())) ++ return 0 + + def gssapi_channel_binding_mismatch_test(kenv): + result = "FAIL" +@@ -212,11 +215,70 @@ def gssapi_channel_binding_mismatch_test(kenv): + cli.returncode, cli_err, srv.returncode, srv_err)) + except Exception as e: + print("{}: {}".format(result, e)) +- return ++ return 0 + + print("FAIL: This test should fail [CLI({}) SRV({})]".format( + cli.stdout.read().decode('utf-8').strip(), + srv.stdout.read().decode('utf-8').strip())) ++ return 1 ++ ++def gss_spnego_basic_test(kenv): ++ try: ++ srv = subprocess.Popen(["../tests/t_gssapi_srv", "-N"], ++ stdout=subprocess.PIPE, ++ stderr=subprocess.PIPE, env=kenv) ++ srv.stdout.readline() # Wait for srv to say it is ready ++ cli = subprocess.Popen(["../tests/t_gssapi_cli", "-N"], ++ stdout=subprocess.PIPE, ++ stderr=subprocess.PIPE, env=kenv) ++ try: ++ cli.wait(timeout=5) ++ srv.wait(timeout=5) ++ except Exception as e: ++ print("Failed on {}".format(e)); ++ cli.kill() ++ srv.kill() ++ if cli.returncode != 0 or srv.returncode != 0: ++ raise Exception("CLI ({}): {} --> SRV ({}): {}".format( ++ cli.returncode, cli.stderr.read().decode('utf-8'), ++ srv.returncode, srv.stderr.read().decode('utf-8'))) ++ except Exception as e: ++ print("FAIL: {}".format(e)) ++ return 1 ++ ++ print("PASS: CLI({}) SRV({})".format( ++ cli.stdout.read().decode('utf-8').strip(), ++ srv.stdout.read().decode('utf-8').strip())) ++ return 0 ++ ++def gss_spnego_zeromaxssf_test(kenv): ++ try: ++ srv = subprocess.Popen(["../tests/t_gssapi_srv", "-N", "-z"], ++ stdout=subprocess.PIPE, ++ stderr=subprocess.PIPE, env=kenv) ++ srv.stdout.readline() # Wait for srv to say it is ready ++ cli = subprocess.Popen(["../tests/t_gssapi_cli", "-N", "-z"], ++ stdout=subprocess.PIPE, ++ stderr=subprocess.PIPE, env=kenv) ++ try: ++ cli.wait(timeout=5) ++ srv.wait(timeout=5) ++ except Exception as e: ++ print("Failed on {}".format(e)); ++ cli.kill() ++ srv.kill() ++ if cli.returncode != 0 or srv.returncode != 0: ++ raise Exception("CLI ({}): {} --> SRV ({}): {}".format( ++ cli.returncode, cli.stderr.read().decode('utf-8'), ++ srv.returncode, srv.stderr.read().decode('utf-8'))) ++ except Exception as e: ++ print("FAIL: {}".format(e)) ++ return 1 ++ ++ print("PASS: CLI({}) SRV({})".format( ++ cli.stdout.read().decode('utf-8').strip(), ++ srv.stdout.read().decode('utf-8').strip())) ++ return 0 + + def gssapi_tests(testdir): + """ SASL/GSSAPI Tests """ +@@ -225,19 +287,30 @@ def gssapi_tests(testdir): + #print("KDC: {}, ENV: {}".format(kdc, kenv)) + kenv['KRB5_TRACE'] = os.path.join(testdir, 'trace.log') + ++ err = 0 ++ + print('GSSAPI BASIC:') + print(' ', end='') +- gssapi_basic_test(kenv) ++ err += gssapi_basic_test(kenv) + + print('GSSAPI CHANNEL BINDING:') + print(' ', end='') +- gssapi_channel_binding_test(kenv) ++ err += gssapi_channel_binding_test(kenv) + + print('GSSAPI CHANNEL BINDING MISMTACH:') + print(' ', end='') +- gssapi_channel_binding_mismatch_test(kenv) ++ err += gssapi_channel_binding_mismatch_test(kenv) ++ ++ print('GSS-SPNEGO BASIC:') ++ print(' ', end='') ++ err += gss_spnego_basic_test(kenv) ++ ++ print('GSS-SPNEGO 0 MAXSSF:') ++ print(' ', end='') ++ err += gss_spnego_zeromaxssf_test(kenv) + + os.killpg(kdc.pid, signal.SIGTERM) ++ return err + + def setup_plain(testdir): + """ Create sasldb file """ +@@ -343,5 +416,9 @@ def plain_tests(testdir): + shutil.rmtree(T) + os.makedirs(T) + +- gssapi_tests(T) + plain_tests(T) ++ ++ err = gssapi_tests(T) ++ if err != 0: ++ print('{} test(s) FAILED'.format(err)) ++ sys.exit(-1) +diff --git a/tests/t_common.c b/tests/t_common.c +index 478e6a1f..f56098ef 100644 +--- a/tests/t_common.c ++++ b/tests/t_common.c +@@ -23,20 +23,21 @@ void send_string(int sd, const char *s, unsigned int l) + if (ret != l) s_error("send data", ret, l, errno); + } + +-void recv_string(int sd, char *buf, unsigned int *buflen) ++void recv_string(int sd, char *buf, unsigned int *buflen, bool allow_eof) + { ++ unsigned int bufsize = *buflen; + unsigned int l; + ssize_t ret; + ++ *buflen = 0; ++ + ret = recv(sd, &l, sizeof(l), MSG_WAITALL); ++ if (allow_eof && ret == 0) return; + if (ret != sizeof(l)) s_error("recv size", ret, sizeof(l), errno); + +- if (l == 0) { +- *buflen = 0; +- return; +- } ++ if (l == 0) return; + +- if (*buflen < l) s_error("recv len", l, *buflen, E2BIG); ++ if (bufsize < l) s_error("recv len", l, bufsize, E2BIG); + + ret = recv(sd, buf, l, 0); + if (ret != l) s_error("recv data", ret, l, errno); +diff --git a/tests/t_common.h b/tests/t_common.h +index a10def17..be24a53d 100644 +--- a/tests/t_common.h ++++ b/tests/t_common.h +@@ -4,6 +4,7 @@ + #include "config.h" + + #include ++#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 20d22070..b1dd6ce0 100644 +--- a/tests/t_gssapi_cli.c ++++ b/tests/t_gssapi_cli.c +@@ -101,8 +101,10 @@ int main(int argc, char *argv[]) + int c, r; + const char *sasl_mech = "GSSAPI"; + int plain = 0; ++ bool spnego = false; ++ bool zeromaxssf = false; + +- while ((c = getopt(argc, argv, "c:P:")) != EOF) { ++ while ((c = getopt(argc, argv, "c:P:zN")) != EOF) { + switch (c) { + case 'c': + parse_cb(&cb, cb_buf, 256, optarg); +@@ -111,6 +113,12 @@ int main(int argc, char *argv[]) + plain = 1; + testpass = optarg; + break; ++ case 'z': ++ zeromaxssf = true; ++ break; ++ case 'N': ++ spnego = true; ++ break; + default: + break; + } +@@ -153,6 +161,16 @@ int main(int argc, char *argv[]) + sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb); + } + ++ if (spnego) { ++ sasl_mech = "GSS-SPNEGO"; ++ } ++ ++ if (zeromaxssf) { ++ /* set all security properties to 0 including maxssf */ ++ sasl_security_properties_t secprops = { 0 }; ++ sasl_setprop(conn, SASL_SEC_PROPS, &secprops); ++ } ++ + r = sasl_client_start(conn, sasl_mech, NULL, &data, &len, &chosenmech); + if (r != SASL_OK && r != SASL_CONTINUE) { + saslerr(r, "starting SASL negotiation"); +@@ -165,7 +183,7 @@ int main(int argc, char *argv[]) + while (r == SASL_CONTINUE) { + send_string(sd, data, len); + len = 8192; +- recv_string(sd, buf, &len); ++ recv_string(sd, buf, &len, false); + + r = sasl_client_step(conn, buf, len, NULL, &data, &len); + if (r != SASL_OK && r != SASL_CONTINUE) { +diff --git a/tests/t_gssapi_srv.c b/tests/t_gssapi_srv.c +index 430cad65..0adbd12f 100644 +--- a/tests/t_gssapi_srv.c ++++ b/tests/t_gssapi_srv.c +@@ -92,8 +92,10 @@ int main(int argc, char *argv[]) + int c, r; + const char *sasl_mech = "GSSAPI"; + int plain = 0; ++ bool spnego = false; ++ bool zeromaxssf = false; + +- while ((c = getopt(argc, argv, "c:P:")) != EOF) { ++ while ((c = getopt(argc, argv, "c:P:zN")) != EOF) { + switch (c) { + case 'c': + parse_cb(&cb, cb_buf, 256, optarg); +@@ -102,6 +104,12 @@ int main(int argc, char *argv[]) + plain = 1; + sasldb_path = optarg; + break; ++ case 'z': ++ zeromaxssf = true; ++ break; ++ case 'N': ++ spnego = true; ++ break; + default: + break; + } +@@ -136,10 +144,20 @@ int main(int argc, char *argv[]) + sasl_mech = "PLAIN"; + } + ++ if (spnego) { ++ sasl_mech = "GSS-SPNEGO"; ++ } ++ ++ if (zeromaxssf) { ++ /* set all security properties to 0 including maxssf */ ++ sasl_security_properties_t secprops = { 0 }; ++ sasl_setprop(conn, SASL_SEC_PROPS, &secprops); ++ } ++ + sd = setup_socket(); + + len = 8192; +- recv_string(sd, buf, &len); ++ recv_string(sd, buf, &len, false); + + r = sasl_server_start(conn, sasl_mech, buf, len, &data, &len); + if (r != SASL_OK && r != SASL_CONTINUE) { +@@ -151,7 +169,7 @@ int main(int argc, char *argv[]) + while (r == SASL_CONTINUE) { + send_string(sd, data, len); + len = 8192; +- recv_string(sd, buf, &len); ++ recv_string(sd, buf, &len, true); + + r = sasl_server_step(conn, buf, len, &data, &len); + if (r != SASL_OK && r != SASL_CONTINUE) { +@@ -159,7 +177,6 @@ int main(int argc, char *argv[]) + printf("\n%s\n", sasl_errdetail(conn)); + exit(-1); + } +- + } + + if (r != SASL_OK) exit(-1); + diff --git a/cyrus-sasl-2.1.27-nostrncpy.patch b/cyrus-sasl-2.1.27-nostrncpy.patch new file mode 100644 index 0000000..d009047 --- /dev/null +++ b/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/cyrus-sasl-2.1.28-SAST.patch b/cyrus-sasl-2.1.28-SAST.patch new file mode 100644 index 0000000..5d2f6e8 --- /dev/null +++ b/cyrus-sasl-2.1.28-SAST.patch @@ -0,0 +1,83 @@ +From 5703f2a26b0a183079beb7f1b176a3c24ede7309 Mon Sep 17 00:00:00 2001 +From: Rob Crittenden +Date: Wed, 15 May 2024 14:17:46 -0400 +Subject: [PATCH] Fix some issues uncovered by a static analyzer + +A few possible overruns and a memory leak. + +Signed-off-by: Rob Crittenden +--- + lib/common.c | 13 +++++++------ + saslauthd/auth_krb5.c | 1 + + saslauthd/testsaslauthd.c | 6 +++--- + 3 files changed, 11 insertions(+), 9 deletions(-) + +diff --git a/lib/common.c b/lib/common.c +index 6c5496a2..b9c8bf50 100644 +--- a/lib/common.c ++++ b/lib/common.c +@@ -2395,18 +2395,19 @@ int _sasl_ipfromstring(const char *addr, + + /* Parse the address */ + for (i = 0; addr[i] != '\0' && addr[i] != ';'; i++) { +- if (i >= NI_MAXHOST) ++ if (i >= NI_MAXHOST - 1) + return SASL_BADPARAM; + hbuf[i] = addr[i]; + } + hbuf[i] = '\0'; + +- if (addr[i] == ';') ++ if (addr[i] == ';') { + i++; +- /* XXX: Do we need this check? */ +- for (j = i; addr[j] != '\0'; j++) +- if (!isdigit((int)(addr[j]))) +- return SASL_BADPARAM; ++ /* XXX: Do we need this check? */ ++ for (j = i; addr[j] != '\0'; j++) ++ if (!isdigit((int)(addr[j]))) ++ return SASL_BADPARAM; ++ } + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; +diff --git a/saslauthd/auth_krb5.c b/saslauthd/auth_krb5.c +index c7cceeec..7750b55e 100644 +--- a/saslauthd/auth_krb5.c ++++ b/saslauthd/auth_krb5.c +@@ -203,6 +203,7 @@ auth_krb5 ( + + if (form_principal_name(user, service, realm, principalbuf, sizeof (principalbuf))) { + syslog(LOG_ERR, "auth_krb5: form_principal_name"); ++ krb5_free_context(context); + return strdup("NO saslauthd principal name error"); + } + +diff --git a/saslauthd/testsaslauthd.c b/saslauthd/testsaslauthd.c +index 8a0e4d9c..9267c43d 100644 +--- a/saslauthd/testsaslauthd.c ++++ b/saslauthd/testsaslauthd.c +@@ -70,8 +70,8 @@ int flags = LOG_USE_STDERR; + */ + int retry_read(int fd, void *inbuf, unsigned nbyte) + { +- int n; +- int nread = 0; ++ ssize_t n; ++ size_t nread = 0; + char *buf = (char *)inbuf; + + if (nbyte == 0) return 0; +@@ -233,7 +233,7 @@ static int saslauthd_verify_password(const char *saslauthd_path, + return -1; + } + +- count = (int)sizeof(response) < count ? sizeof(response) : count; ++ count = (int)sizeof(response) <= count ? sizeof(response) - 1: count; + if (retry_read(s, response, count) < count) { + close(s); + fprintf(stderr,"read failed\n"); +-- +2.45.0 + diff --git a/cyrus-sasl-2.1.28-fedora-c99.patch b/cyrus-sasl-2.1.28-fedora-c99.patch new file mode 100644 index 0000000..f269f1a --- /dev/null +++ b/cyrus-sasl-2.1.28-fedora-c99.patch @@ -0,0 +1,53 @@ +From 266f0acf7f5e029afbb3e263437039e50cd6c262 Mon Sep 17 00:00:00 2001 +From: Sam James +Date: Wed, 23 Feb 2022 00:45:15 +0000 +Subject: Fix check +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We're conditionally including based on HAVE_TIME_H in a bunch of places, +but we're not actually checking for time.h, so that's never going to be defined. + +While at it, add in a missing include in the cram plugin. + +This fixes a bunch of implicit declaration warnings: +``` + * cyrus-sasl-2.1.28/lib/saslutil.c:280:3: warning: implicit declaration of function ‘time’ [-Wimplicit-function-declaration] + * cyrus-sasl-2.1.28/lib/saslutil.c:364:41: warning: implicit declaration of function ‘clock’ [-Wimplicit-function-declaration] + * cyrus-sasl-2.1.28/plugins/cram.c:132:7: warning: implicit declaration of function ‘time’ [-Wimplicit-function-declaration] + * cyrus-sasl-2.1.28/lib/saslutil.c:280:3: warning: implicit declaration of function ‘time’ [-Wimplicit-function-declaration] + * cyrus-sasl-2.1.28/lib/saslutil.c:364:41: warning: implicit declaration of function ‘clock’ [-Wimplicit-function-declaration] + * cyrus-sasl-2.1.28/plugins/cram.c:132:7: warning: implicit declaration of function ‘time’ [-Wimplicit-function-declaration] +``` + +Signed-off-by: Sam James + +[Edited to apply to Fedora - DJ] +diff -rup a/configure.ac b/configure.ac +--- a/configure.ac 2023-04-20 00:31:33.578596460 -0400 ++++ b/configure.ac 2023-04-20 01:17:40.877579628 -0400 +@@ -1239,6 +1239,7 @@ AC_CHECK_HEADERS_ONCE([sys/time.h]) + AC_HEADER_DIRENT + AC_HEADER_SYS_WAIT + AC_CHECK_HEADERS(crypt.h des.h dlfcn.h fcntl.h limits.h malloc.h paths.h strings.h sys/file.h sys/time.h syslog.h unistd.h inttypes.h sys/uio.h sys/param.h sysexits.h stdarg.h varargs.h krb5.h) ++AC_CHECK_HEADERS(crypt.h des.h dlfcn.h fcntl.h limits.h malloc.h paths.h strings.h sys/file.h sys/time.h syslog.h time.h unistd.h inttypes.h sys/uio.h sys/param.h sysexits.h stdarg.h varargs.h krb5.h) + AC_CHECK_TYPES([long long, int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t],,,[ + #ifdef HAVE_INTTYPES_H + #include +Only in b: configure.ac.orig +Only in b: configure.ac.rej +diff -rup a/plugins/cram.c b/plugins/cram.c +--- a/plugins/cram.c 2022-02-18 16:50:42.000000000 -0500 ++++ b/plugins/cram.c 2023-04-20 01:20:12.228312652 -0400 +@@ -53,6 +53,10 @@ + #endif + #include + ++#ifdef HAVE_TIME_H ++#include ++#endif ++ + #include + #include + #include diff --git a/SPECS/cyrus-sasl.spec b/cyrus-sasl.spec similarity index 82% rename from SPECS/cyrus-sasl.spec rename to cyrus-sasl.spec index 74c8fff..1e0c4e8 100644 --- a/SPECS/cyrus-sasl.spec +++ b/cyrus-sasl.spec @@ -1,20 +1,30 @@ +## START: Set by rpmautospec +## (rpmautospec version 0.6.1) +## RPMAUTOSPEC: autorelease, autochangelog +%define autorelease(e:s:pb:n) %{?-p:0.}%{lua: + release_number = 22; + base_release_number = tonumber(rpm.expand("%{?-b*}%{!?-b:1}")); + print(release_number + base_release_number - 1); +}%{?-e:.%{-e*}}%{?-s:.%{-s*}}%{!?-n:%{?dist}} +## END: Set by rpmautospec + %global username saslauth -%global hint Saslauthd user -%global homedir /run/saslauthd %global _plugindir2 %{_libdir}/sasl2 %global bootstrap_cyrus_sasl 0 Summary: The Cyrus SASL library Name: cyrus-sasl -Version: 2.1.27 -Release: 6%{?dist} -License: BSD with advertising -Group: System Environment/Libraries +Version: 2.1.28 +Release: %autorelease +License: BSD-Attribution-HPND-disclaimer +URL: https://www.cyrusimap.org/sasl/ + # Source0 originally comes from https://www.cyrusimap.org/releases/; # make-no-dlcompatorsrp-tarball.sh removes the "dlcompat" subdirectory and builds a # new tarball. Source0: cyrus-sasl-%{version}-nodlcompatorsrp.tar.gz +Source3: saslauth.sysusers Source5: saslauthd.service Source7: sasl-mechlist.c Source9: saslauthd.sysconfig @@ -22,38 +32,42 @@ Source10: make-no-dlcompatorsrp-tarball.sh # From upstream git, required for reconfigure after applying patches to configure.ac # https://raw.githubusercontent.com/cyrusimap/cyrus-sasl/master/autogen.sh Source11: autogen.sh -URL: https://www.cyrusimap.org/sasl/ + + Requires: %{name}-lib%{?_isa} = %{version}-%{release} Patch11: cyrus-sasl-2.1.25-no_rpath.patch Patch15: cyrus-sasl-2.1.20-saslauthd.conf-path.patch Patch23: cyrus-sasl-2.1.23-man.patch Patch24: cyrus-sasl-2.1.21-sizes.patch +# 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 -Patch830: cyrus-sasl-2.1.27-CVE-2019-19906.patch -Patch831: cyrus-sasl-2.1.27-Add-basic-test-infrastructure.patch -Patch832: cyrus-sasl-2.1.27-Add-Channel-Binding-support-for-GSSAPI-GSS-SPNEGO.patch -Patch833: cyrus-sasl-2.1.27-Add-support-for-setting-max-ssf-0-to-GSS-SPNEGO.patch -Patch834: cyrus-sasl-2.1.27-Emit-debug-log-only-in-case-of-errors.patch -Patch900: 0001-CVE-2022-24407-Escape-password-for-SQL-insert-update.patch +Patch101: cyrus-sasl-2.1.27-Add-basic-test-infrastructure.patch +Patch102: cyrus-sasl-2.1.27-Add-Channel-Binding-support-for-GSSAPI-GSS-SPNEGO.patch +#https://github.com/simo5/cyrus-sasl/commit/ebd2387f06c84c7f9aac3167ec041bb01e5c6e48 +Patch106: cyrus-sasl-2.1.27-nostrncpy.patch +# Upstream PR: https://github.com/cyrusimap/cyrus-sasl/pull/635 +Patch107: cyrus-sasl-2.1.27-more-tests.patch +Patch108: cyrus-sasl-2.1.27-Add-support-for-setting-max-ssf-0-to-GSS-SPNEGO.patch +Patch500: cyrus-sasl-2.1.27-coverity.patch +Patch501: cyrus-sasl-2.1.27-cumulative-digestmd5.patch +Patch502: cyrus-sasl-2.1.27-cumulative-ossl3.patch +Patch503: cyrus-sasl-2.1.28-SAST.patch + +Patch599: cyrus-sasl-2.1.28-fedora-c99.patch -Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: autoconf, automake, libtool, gdbm-devel, groff BuildRequires: krb5-devel >= 1.2.2, openssl-devel, pam-devel, pkgconfig -BuildRequires: mariadb-connector-c-devel, postgresql-devel, zlib-devel -BuildRequires: libdb-devel +BuildRequires: mariadb-connector-c-devel, libpq-devel, zlib-devel %if ! %{bootstrap_cyrus_sasl} BuildRequires: openldap-devel %endif #build reqs for make check -BuildRequires: python36 nss_wrapper socket_wrapper krb5-server -%{?systemd_requires} -Requires(post): chkconfig +BuildRequires: python3 nss_wrapper socket_wrapper krb5-server +BuildRequires: make Requires(pre): /usr/sbin/useradd /usr/sbin/groupadd Requires(postun): /usr/sbin/userdel /usr/sbin/groupdel Requires: /sbin/nologin -Requires: systemd >= 211 Provides: user(%username) Provides: group(%username) @@ -64,7 +78,6 @@ SASL is the Simple Authentication and Security Layer, a method for adding authentication support to connection-based protocols. %package lib -Group: System Environment/Libraries Summary: Shared libraries needed by applications which use Cyrus SASL %description lib @@ -75,7 +88,6 @@ applications which use the Cyrus SASL library. Requires: %{name}-lib%{?_isa} = %{version}-%{release} Requires: %{name}%{?_isa} = %{version}-%{release} Requires: pkgconfig -Group: Development/Libraries Summary: Files needed for developing applications with Cyrus SASL %description devel @@ -84,7 +96,6 @@ compiling applications which use the Cyrus SASL library. %package gssapi Requires: %{name}-lib%{?_isa} = %{version}-%{release} -Group: System Environment/Libraries Summary: GSSAPI authentication support for Cyrus SASL %description gssapi @@ -94,7 +105,6 @@ authentication. %package plain Requires: %{name}-lib%{?_isa} = %{version}-%{release} -Group: System Environment/Libraries Summary: PLAIN and LOGIN authentication support for Cyrus SASL %description plain @@ -103,26 +113,15 @@ PLAIN and LOGIN authentication schemes. %package md5 Requires: %{name}-lib%{?_isa} = %{version}-%{release} -Group: System Environment/Libraries Summary: CRAM-MD5 and DIGEST-MD5 authentication support for Cyrus SASL %description md5 The %{name}-md5 package contains the Cyrus SASL plugins which support CRAM-MD5 and DIGEST-MD5 authentication schemes. -%package ntlm -Requires: %{name}-lib%{?_isa} = %{version}-%{release} -Group: System Environment/Libraries -Summary: NTLM authentication support for Cyrus SASL - -%description ntlm -The %{name}-ntlm package contains the Cyrus SASL plugin which supports -the NTLM authentication scheme. - # This would more appropriately be named cyrus-sasl-auxprop-sql. %package sql Requires: %{name}-lib%{?_isa} = %{version}-%{release} -Group: System Environment/Libraries Summary: SQL auxprop support for Cyrus SASL %description sql @@ -133,7 +132,6 @@ using a RDBMS for storing shared secrets. # This was *almost* named cyrus-sasl-auxprop-ldapdb, but that's a lot of typing. %package ldap Requires: %{name}-lib%{?_isa} = %{version}-%{release} -Group: System Environment/Libraries Summary: LDAP auxprop support for Cyrus SASL %description ldap @@ -143,7 +141,6 @@ a directory server, accessed using LDAP, for storing shared secrets. %package scram Requires: %{name}-lib%{?_isa} = %{version}-%{release} -Group: System Environment/Libraries Summary: SCRAM auxprop support for Cyrus SASL %description scram @@ -152,7 +149,6 @@ the SCRAM authentication scheme. %package gs2 Requires: %{name}-lib%{?_isa} = %{version}-%{release} -Group: System Environment/Libraries Summary: GS2 support for Cyrus SASL %description gs2 @@ -169,13 +165,16 @@ the GS2 authentication scheme. %patch23 -p1 -b .man %patch24 -p1 -b .sizes %patch49 -p1 -b .md5global.h -%patch60 -p1 -b .openssl_rc4 -%patch830 -p1 -b .CVE-2019-19906 -%patch831 -p1 -b .tests -%patch832 -p1 -b .gssapi_cbs -%patch833 -p1 -b .maxssf0 -%patch834 -p1 -b .nolog -%patch900 -p1 -b .CVE-2022-24407 +%patch101 -p1 -b .tests +%patch102 -p1 -b .gssapi_cbs +%patch106 -p1 -b .nostrncpy +%patch107 -p1 -b .moretests +%patch108 -p1 -b .maxssf0 +%patch500 -p1 -b .coverity +%patch501 -p1 -b .digestmd5 +%patch502 -p1 -b .ossl3 +%patch503 -p1 -b .sast +%patch599 -p1 -b .c99 %build # reconfigure @@ -184,6 +183,7 @@ rm configure aclocal.m4 config/ltmain.sh Makefile.in export NOCONFIGURE=yes sh autogen.sh +%set_build_flags # Find Kerberos. krb5_prefix=`krb5-config --prefix` if test x$krb5_prefix = x%{_prefix} ; then @@ -220,14 +220,8 @@ if test x"$LIB_DIR" != "x-L%{_libdir}"; then LDFLAGS="$LIB_DIR $LDFLAGS"; export LDFLAGS fi -# Patch config.sub to support ppc64p7 subarch (Fedora specific) -# This is similar to what the config.sub from automake has -for i in `find . -name config.sub`; do - perl -pi -e "s/ppc64-\*/ppc64-\* \| ppc64p7-\*/" $i -done - -CFLAGS="$RPM_OPT_FLAGS $CFLAGS $CPPFLAGS -fPIC -pie -Wl,-z,relro -Wl,-z,now"; export CFLAGS -LDFLAGS="$LDFLAGS -pie -Wl,-z,now"; export LDFLAGS +# run "make check" against the built library rather than the one in buildroot +LDFLAGS="-Wl,--enable-new-dtags $LDFLAGS"; export LDFLAGS echo "$CFLAGS" echo "$CPPFLAGS" @@ -242,8 +236,8 @@ echo "$LDFLAGS" --enable-gssapi${krb5_prefix:+=${krb5_prefix}} \ --with-gss_impl=mit \ --with-rc4 \ - --with-dblib=berkeley \ - --with-bdb=db \ + --with-dblib=gdbm \ + --with-dbpath=%{gdbm_db_file} \ --with-saslauthd=/run/saslauthd --without-pwcheck \ %if ! %{bootstrap_cyrus_sasl} --with-ldap \ @@ -252,7 +246,7 @@ echo "$LDFLAGS" --enable-anon \ --enable-cram \ --enable-digest \ - --enable-ntlm \ + --disable-ntlm \ --enable-plain \ --enable-login \ --enable-alwaystrue \ @@ -263,8 +257,8 @@ echo "$LDFLAGS" %endif --enable-sql --with-mysql=yes --with-pgsql=yes \ --without-sqlite \ + --enable-auth-sasldb \ "$@" - # --enable-auth-sasldb -- EXPERIMENTAL make sasldir=%{_plugindir2} make -C saslauthd testsaslauthd make -C sample @@ -294,9 +288,8 @@ install -m755 -d $RPM_BUILD_ROOT%{_mandir}/man8/ install -m644 -p saslauthd/saslauthd.mdoc $RPM_BUILD_ROOT%{_mandir}/man8/saslauthd.8 install -m644 -p saslauthd/testsaslauthd.8 $RPM_BUILD_ROOT%{_mandir}/man8/testsaslauthd.8 -# Install the init script for saslauthd and the init script's config file. -install -m755 -d $RPM_BUILD_ROOT/etc/rc.d/init.d $RPM_BUILD_ROOT/etc/sysconfig -install -d -m755 $RPM_BUILD_ROOT/%{_unitdir} +# Install 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 @@ -308,6 +301,9 @@ install -m755 -d $RPM_BUILD_ROOT/%{_plugindir2} ./libtool --mode=install \ install -m755 lib/sasl2-shared-mechlist $RPM_BUILD_ROOT/%{_sbindir}/ +# Sysusers file +install -p -D -m 0644 %{SOURCE3} %{buildroot}%{_sysusersdir}/cyrus-sasl.conf + # Remove unpackaged files from the buildroot. rm -f $RPM_BUILD_ROOT%{_libdir}/sasl2/libotp.* rm -f $RPM_BUILD_ROOT%{_libdir}/sasl2/*.a @@ -319,8 +315,7 @@ rm -f $RPM_BUILD_ROOT%{_mandir}/cat8/saslauthd.8 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} +%sysusers_create_compat %{SOURCE3} %post %systemd_post saslauthd.service @@ -331,16 +326,9 @@ getent passwd %{username} >/dev/null || useradd -r -g %{username} -d %{homedir} %postun %systemd_postun_with_restart saslauthd.service -%triggerun -n cyrus-sasl -- cyrus-sasl < 2.1.23-32 -/usr/bin/systemd-sysv-convert --save saslauthd >/dev/null 2>&1 || : -/sbin/chkconfig --del saslauthd >/dev/null 2>&1 || : -/bin/systemctl try-restart saslauthd.service >/dev/null 2>&1 || : - -%post lib -p /sbin/ldconfig -%postun lib -p /sbin/ldconfig +%ldconfig_scriptlets lib %files -%defattr(-,root,root) %doc saslauthd/LDAP_SASLAUTHD %{_mandir}/man8/* %{_sbindir}/pluginviewer @@ -348,10 +336,10 @@ getent passwd %{username} >/dev/null || useradd -r -g %{username} -d %{homedir} %{_sbindir}/testsaslauthd %config(noreplace) /etc/sysconfig/saslauthd %{_unitdir}/saslauthd.service -%ghost /run/saslauthd +%ghost %attr(755,root,root) /run/saslauthd +%{_sysusersdir}/cyrus-sasl.conf %files lib -%defattr(-,root,root) %license COPYING %doc AUTHORS doc/html/*.html %{_libdir}/libsasl*.so.* @@ -363,43 +351,31 @@ getent passwd %{username} >/dev/null || useradd -r -g %{username} -d %{homedir} %{_sbindir}/sasldblistusers2 %files plain -%defattr(-,root,root) %{_plugindir2}/*plain*.so* %{_plugindir2}/*login*.so* %if ! %{bootstrap_cyrus_sasl} %files ldap -%defattr(-,root,root) %{_plugindir2}/*ldapdb*.so* %endif %files md5 -%defattr(-,root,root) %{_plugindir2}/*crammd5*.so* %{_plugindir2}/*digestmd5*.so* -%files ntlm -%defattr(-,root,root) -%{_plugindir2}/*ntlm*.so* - %files sql -%defattr(-,root,root) %{_plugindir2}/*sql*.so* %files gssapi -%defattr(-,root,root) %{_plugindir2}/*gssapi*.so* %files scram -%defattr(-,root,root) %{_plugindir2}/libscram.so* %files gs2 -%defattr(-,root,root) %{_plugindir2}/libgs2.so* %files devel -%defattr(-,root,root) %{_bindir}/sasl2-sample-client %{_bindir}/sasl2-sample-server %{_includedir}/* @@ -409,40 +385,149 @@ getent passwd %{username} >/dev/null || useradd -r -g %{username} -d %{homedir} %{_sbindir}/sasl2-shared-mechlist %changelog -* Thu Feb 17 2022 Simo Sorce - 2.1.27-6 -- Fix for CVE-2022-24407 -- Resolves: rhbz#2055846 +## START: Generated by rpmautospec +* Thu Jun 20 2024 Rob Crittenden - 2.1.28-22 +- Update license to BSD-Attribution-HPND-disclaimer -* Tue May 5 2020 Simo Sorce - 2.1.27-5 -- Reduce excessive GSSAPI plugin logging -- Resolves: rhbz#1274734 +* Wed Jun 19 2024 Filip Janus - 2.1.28-21 +- Remove BerkeleyDB converting tool. It was intended to be removed in + RHEL10. Because There is no instance of BerkeleyDB in RHEL10/c10s + Resolves: RHEL-43136 -* Tue May 5 2020 Simo Sorce - 2.1.27-4 -- Add support for setting maxssf=0 in GSS-SPNEGO -- Resolves: rhbz#1822133 +* Tue Jun 11 2024 Rob Crittenden - 2.1.28-20 +- Fix some issues uncovered by a static analyzer -* Tue May 5 2020 Simo Sorce - 2.1.27-3 +* Wed Jan 24 2024 Fedora Release Engineering - 2.1.28-19 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Fri Jan 19 2024 Fedora Release Engineering - 2.1.28-18 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Wed Jan 17 2024 Florian Weimer - 2.1.28-17 +- sasl-mechlist.c: Cast function pointer to the expected type + +* Mon Jan 15 2024 Rob Crittenden - 2.1.28-16 +- Disable and drop the ntlm plugin as it is removed upstream + +* Thu Jan 11 2024 Rob Crittenden - 2.1.28-15 +- tests: Switch openldap database to the LMDB backend + +* Mon Jan 08 2024 Rob Crittenden - 2.1.28-14 +- Add a mode and ownership to the ghost /run/saslauthd directory + +* Fri Sep 08 2023 Simo Sorce - 2.1.28-13 +- Migrate license field to SPDX format + +* Wed Jul 19 2023 Yaakov Selkowitz - 2.1.28-12 +- Add --enable-new-dtags to LDFLAGS + +* Wed Jul 19 2023 Fedora Release Engineering - 2.1.28-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + +* Thu Apr 20 2023 DJ Delorie - 2.1.28-10 +- Fix C99 compatibility issue + +* Thu Jan 19 2023 Fedora Release Engineering - 2.1.28-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + +* Thu Aug 18 2022 Kalev Lember - 2.1.28-8 +- Avoid requires on systemd as well as per updated guidelines + +* Fri Aug 05 2022 Kalev Lember - 2.1.28-7 +- Avoid systemd_requires as per updated packaging guidelines + +* Mon Aug 01 2022 Simo Sorce - 2.1.28-6 +- Fix memory leak in digestmd5 patches + +* Wed Jul 20 2022 Fedora Release Engineering - 2.1.28-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + +* Thu Jun 09 2022 Simo Sorce - 2.1.28-4 +- Use systemd sysusers to create saslauth user + +* Thu Jun 09 2022 Simo Sorce - 2.1.28-3 +- Enable sasldb authentication mechanism + +* Wed May 11 2022 Simo Sorce - 2.1.28-2 +- Fix changelog section with correct syntax + +* Wed Feb 23 2022 Simo Sorce - 2.1.28-1 +- Update to 2.1.28 + +* Wed Feb 23 2022 Simo Sorce - 2.1.27-49 +- Move to use autorelease macro + +* Tue Oct 12 2021 Simo Sorce - 2.1.27-16 +- Fix rpath patch +- Resolves: rhbz#2012172 + +* Wed Oct 6 2021 Simo Sorce - 2.1.27-15 +- More openssl 3 compatibility and digestmd5 updates. + +* Tue Sep 14 2021 Sahana Prasad - 2.1.27-14 +- Rebuilt with OpenSSL 3.0.0 + +* Tue Aug 10 2021 Dmitry Belyavskiy - 2.1.27-13 +- Preserve GDBM error to correctly deal with GDBM sasldb +- Related: rhbz#1952926 + +* Wed Jul 21 2021 Fedora Release Engineering - 2.1.27-12 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + +* Mon May 03 2021 Dmitry Belyavskiy - 2.1.27-11 +- Fix some coverity issues +- Set default sasldb database to GDBM instead of BerkeleyDB +- Add the migration tool from BerkeleyDB +- Add some PLAIN auth tests + +* Tue Apr 06 2021 Simo Sorce - 2.1.27-10 +- Fix issues with autoconf 2.70+ + +* Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek - 2.1.27-9 +- Rebuilt for updated systemd-rpm-macros + See https://pagure.io/fesco/issue/2583. + +* 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 -- Resolves: rhbz#1817054 +- Add support for setting maxssf=0 in GSS-SPNEGO +- Reduce excessive GSSAPI plugin logging -* Tue May 5 2020 Simo Sorce - 2.1.27-2 -- Backport fix for CVE-2019-19906 -- Resolves: rhbz#1804036 +* Thu Mar 19 2020 Simo Sorce - 2.1.27-4 +- Fix CVE 2019 19906 -* Fri Jun 14 2019 Simo Sorce - 2.1.27-1 -- Rc7 to final source -- Resovles bz#1618744 +* Tue Jan 28 2020 Fedora Release Engineering - 2.1.27-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild -* Thu Jun 13 2019 Simo Sorce - 2.1.27-0.4rc7 -- Add patch form Upstream PR559 to use RC4 implementation from OpenSSL -- Resolves bz#1618744 -- Fix multilib issue bz#1663120 +* Wed Jul 24 2019 Fedora Release Engineering - 2.1.27-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild -* Mon Jul 30 2018 Florian Weimer - 2.1.27-0.3rc7 -- Rebuild with fixed binutils +* Thu Jun 13 2019 Simo Sorce - 2.1.27-1 +- Update to final 2.1.27 sources +- Also add patch to use OpenSSL RC4, currently proposed as PR 559 -* Wed Jul 25 2018 Petr Kubat - 2.1.27-0.2rc7 -- Rebuilt for gdbm +* 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 @@ -1162,3 +1247,5 @@ getent passwd %{username} >/dev/null || useradd -r -g %{username} -d %{homedir} * Fri Aug 13 1999 Tim Powers - first build for Powertools + +## END: Generated by rpmautospec diff --git a/SOURCES/make-no-dlcompatorsrp-tarball.sh b/make-no-dlcompatorsrp-tarball.sh similarity index 91% rename from SOURCES/make-no-dlcompatorsrp-tarball.sh rename to make-no-dlcompatorsrp-tarball.sh index a0a3245..e58dc3b 100755 --- a/SOURCES/make-no-dlcompatorsrp-tarball.sh +++ b/make-no-dlcompatorsrp-tarball.sh @@ -1,6 +1,6 @@ #!/bin/bash -e # -# See ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/ for unmodified sources. +# See https://github.com/cyrusimap/cyrus-sasl/releases for unmodified sources. # tmppath=`mktemp -d ${TMPDIR:-/tmp}/make-no-dlcompat-tarball-XXXXXX` diff --git a/SOURCES/sasl-mechlist.c b/sasl-mechlist.c similarity index 97% rename from SOURCES/sasl-mechlist.c rename to sasl-mechlist.c index 680e983..222898c 100644 --- a/SOURCES/sasl-mechlist.c +++ b/sasl-mechlist.c @@ -34,7 +34,7 @@ main(int argc, char **argv) int ret, i; const char *mechs, **globals; sasl_callback_t callbacks[] = { - {SASL_CB_GETOPT, my_getopt, NULL}, + {SASL_CB_GETOPT, (int (*)(void)) my_getopt, NULL}, {SASL_CB_LIST_END}, }; sasl_conn_t *connection; diff --git a/saslauth.sysusers b/saslauth.sysusers new file mode 100644 index 0000000..eb6e42c --- /dev/null +++ b/saslauth.sysusers @@ -0,0 +1,4 @@ +#Type Name ID GECOS Home directory Shell +g saslauth 76 +u saslauth - "Saslauthd user" /run/saslauthd /sbin/nologin +m saslauth saslauth diff --git a/SOURCES/saslauthd.service b/saslauthd.service similarity index 100% rename from SOURCES/saslauthd.service rename to saslauthd.service diff --git a/SOURCES/saslauthd.sysconfig b/saslauthd.sysconfig similarity index 100% rename from SOURCES/saslauthd.sysconfig rename to saslauthd.sysconfig diff --git a/sources b/sources new file mode 100644 index 0000000..2ddc63c --- /dev/null +++ b/sources @@ -0,0 +1 @@ +SHA512 (cyrus-sasl-2.1.28-nodlcompatorsrp.tar.gz) = 9a80b363718774ac5b9b8b71c7eba7c48d760296542b4d545010ba4fc463d0da807fc8efd314381467e4c44b3b055082882f3ac03e8f829db2a543e271d70cbc