From eba3ea5ff90fbdee0d2c0a64b9bc356f4f6e9633 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 18 Nov 2021 15:07:26 -0500 Subject: [PATCH] Update to 2.1.28 Fixes CVE-2022-24407 Drop patches that have been included (possibly modified) upstream Adjust backports that upstream decided not to put in 2.1 but are accepted in the master branch Adjust backports that are still in PRs Adjust downstream patches (migration to GDBM) Signed-off-by: Simo Sorce --- .gitignore | 1 + ...inding-support-for-GSSAPI-GSS-SPNEGO.patch | 317 ++++---- ...2.1.27-Add-basic-test-infrastructure.patch | 51 +- ...asl-2.1.27-Add-basic-test-plain-auth.patch | 411 ---------- ...-for-setting-max-ssf-0-to-GSS-SPNEGO.patch | 366 +-------- ...mit-debug-log-only-in-case-of-errors.patch | 42 - ...asl-2.1.27-Migration-from-BerkeleyDB.patch | 13 +- cyrus-sasl-2.1.27-cumulative-digestmd5.patch | 12 +- cyrus-sasl-2.1.27-cumulative-ossl3.patch | 37 +- cyrus-sasl-2.1.27-fix-for-autoconf270.patch | 74 -- cyrus-sasl-2.1.27-more-tests.patch | 761 ++++++++++++++++++ cyrus-sasl-cve-2019-19906.patch | 25 - cyrus-sasl-pr559-RC4-openssl.patch | 156 ---- cyrus-sasl.spec | 26 +- sources | 2 +- 15 files changed, 1020 insertions(+), 1274 deletions(-) delete mode 100644 cyrus-sasl-2.1.27-Add-basic-test-plain-auth.patch delete mode 100644 cyrus-sasl-2.1.27-Emit-debug-log-only-in-case-of-errors.patch delete mode 100644 cyrus-sasl-2.1.27-fix-for-autoconf270.patch create mode 100644 cyrus-sasl-2.1.27-more-tests.patch delete mode 100644 cyrus-sasl-cve-2019-19906.patch delete mode 100644 cyrus-sasl-pr559-RC4-openssl.patch diff --git a/.gitignore b/.gitignore index b3ce182..fdf5983 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ cyrus-sasl-2.1.23-nodlcompatorsrp.tar.gz /cyrus-sasl-2.1.26-nodlcompatorsrp.tar.gz /cyrus-sasl-2.1.27-rc7-nodlcompatorsrp.tar.gz /cyrus-sasl-2.1.27-nodlcompatorsrp.tar.gz +/cyrus-sasl-2.1.28-nodlcompatorsrp.tar.gz diff --git a/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 index 242b436..b95d8f1 100644 --- a/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/cyrus-sasl-2.1.27-Add-basic-test-infrastructure.patch b/cyrus-sasl-2.1.27-Add-basic-test-infrastructure.patch index 2f6a35c..171b309 100644 --- a/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-basic-test-plain-auth.patch b/cyrus-sasl-2.1.27-Add-basic-test-plain-auth.patch deleted file mode 100644 index 35903d0..0000000 --- a/cyrus-sasl-2.1.27-Add-basic-test-plain-auth.patch +++ /dev/null @@ -1,411 +0,0 @@ -diff -Nru cyrus-sasl-2.1.27/tests/runtests.py cyrus-sasl-2.1.27-beldmit/tests/runtests.py ---- cyrus-sasl-2.1.27/tests/runtests.py 2020-12-23 14:31:35.564537485 +0100 -+++ cyrus-sasl-2.1.27-beldmit/tests/runtests.py 2020-12-23 14:30:46.933219377 +0100 -@@ -313,6 +313,99 @@ - - return err - -+def setup_plain(testdir): -+ """ Create sasldb file """ -+ sasldbfile = os.path.join(testdir, 'testsasldb.db') -+ -+ sasldbenv = {'SASL_PATH': os.path.join(testdir, '../../plugins/.libs'), -+ 'LD_LIBRARY_PATH' : os.path.join(testdir, '../../lib/.libs')} -+ -+ passwdprog = os.path.join(testdir, '../../utils/saslpasswd2') -+ -+ echo = subprocess.Popen(('echo', '1234567'), stdout=subprocess.PIPE) -+ subprocess.check_call([ -+ passwdprog, "-f", sasldbfile, "-c", "test", -+ "-u", "host.realm.test", "-p" -+ ], stdin=echo.stdout, env=sasldbenv, timeout=5) -+ -+ return (sasldbfile, sasldbenv) -+ -+def plain_test(sasldbfile, sasldbenv): -+ try: -+ srv = subprocess.Popen(["../tests/t_gssapi_srv", "-P", sasldbfile], -+ stdout=subprocess.PIPE, -+ stderr=subprocess.PIPE, env=sasldbenv) -+ srv.stdout.readline() # Wait for srv to say it is ready -+ cli = subprocess.Popen(["../tests/t_gssapi_cli", "-P", "1234567"], -+ stdout=subprocess.PIPE, -+ stderr=subprocess.PIPE, env=sasldbenv) -+ try: -+ cli.wait(timeout=5) -+ srv.wait(timeout=5) -+ except Exception as e: -+ print("Failed on {}".format(e)); -+ cli.kill() -+ srv.kill() -+ if cli.returncode != 0 or srv.returncode != 0: -+ raise Exception("CLI ({}): {} --> SRV ({}): {}".format( -+ cli.returncode, cli.stderr.read().decode('utf-8'), -+ srv.returncode, srv.stderr.read().decode('utf-8'))) -+ except Exception as e: -+ print("FAIL: {}".format(e)) -+ return 1 -+ -+ print("PASS: PLAIN CLI({}) SRV({})".format( -+ cli.stdout.read().decode('utf-8').strip(), -+ srv.stdout.read().decode('utf-8').strip())) -+ return 0 -+ -+def plain_mismatch_test(sasldbfile, sasldbenv): -+ result = "FAIL" -+ try: -+ srv = subprocess.Popen(["../tests/t_gssapi_srv", "-P", sasldbfile], -+ stdout=subprocess.PIPE, -+ stderr=subprocess.PIPE, env=sasldbenv) -+ srv.stdout.readline() # Wait for srv to say it is ready -+ bindings = base64.b64encode("CLI CBS".encode('utf-8')) -+ cli = subprocess.Popen(["../tests/t_gssapi_cli", "-P", "12345678"], -+ stdout=subprocess.PIPE, -+ stderr=subprocess.PIPE, env=sasldbenv) -+ try: -+ cli.wait(timeout=5) -+ srv.wait(timeout=5) -+ except Exception as e: -+ print("Failed on {}".format(e)); -+ cli.kill() -+ srv.kill() -+ if cli.returncode != 0 or srv.returncode != 0: -+ cli_err = cli.stderr.read().decode('utf-8').strip() -+ srv_err = srv.stderr.read().decode('utf-8').strip() -+ if "authentication failure" in srv_err: -+ result = "PASS" -+ raise Exception("CLI ({}): {} --> SRV ({}): {}".format( -+ cli.returncode, cli_err, srv.returncode, srv_err)) -+ except Exception as e: -+ print("{}: {}".format(result, e)) -+ return 0 -+ -+ print("FAIL: This test should fail [CLI({}) SRV({})]".format( -+ cli.stdout.read().decode('utf-8').strip(), -+ srv.stdout.read().decode('utf-8').strip())) -+ return 1 -+ -+def plain_tests(testdir): -+ err = 0 -+ sasldbfile, sasldbenv = setup_plain(testdir) -+ #print("DB file: {}, ENV: {}".format(sasldbfile, sasldbenv)) -+ print('SASLDB PLAIN:') -+ print(' ', end='') -+ err += plain_test(sasldbfile, sasldbenv) -+ -+ print('SASLDB PLAIN PASSWORD MISMATCH:') -+ print(' ', end='') -+ err += plain_mismatch_test(sasldbfile, sasldbenv) -+ -+ return err - - if __name__ == "__main__": - -@@ -329,5 +422,9 @@ - - err = gssapi_tests(T) - if err != 0: -- print('{} test(s) FAILED'.format(err)) -+ print('{} GSSAPI test(s) FAILED'.format(err)) -+ -+ err = plain_tests(T) -+ if err != 0: -+ print('{} PLAIN test(s) FAILED'.format(err)) - sys.exit(-1) -diff -Nru cyrus-sasl-2.1.27/tests/t_gssapi_cli.c cyrus-sasl-2.1.27-beldmit/tests/t_gssapi_cli.c ---- cyrus-sasl-2.1.27/tests/t_gssapi_cli.c 2020-12-23 14:31:35.564537485 +0100 -+++ cyrus-sasl-2.1.27-beldmit/tests/t_gssapi_cli.c 2021-01-06 11:26:15.460662537 +0100 -@@ -16,6 +16,8 @@ - #include - #include - -+const char *testpass = NULL; -+ - static int setup_socket(void) - { - struct sockaddr_in addr; -@@ -34,9 +36,60 @@ - return sock; - } - -+static int get_user(void *context __attribute__((unused)), -+ int id, -+ const char **result, -+ unsigned *len) -+{ -+ const char *testuser = "test@host.realm.test"; -+ -+ if (! result) -+ return SASL_BADPARAM; -+ -+ switch (id) { -+ case SASL_CB_USER: -+ case SASL_CB_AUTHNAME: -+ *result = testuser; -+ break; -+ default: -+ return SASL_BADPARAM; -+ } -+ -+ if (len) *len = strlen(*result); -+ -+ return SASL_OK; -+} -+ -+static int get_pass(sasl_conn_t *conn __attribute__((unused)), -+ void *context __attribute__((unused)), -+ int id, -+ sasl_secret_t **psecret) -+{ -+ size_t len; -+ static sasl_secret_t *x; -+ -+ /* paranoia check */ -+ if (! conn || ! psecret || id != SASL_CB_PASS) -+ return SASL_BADPARAM; -+ -+ len = strlen(testpass); -+ -+ x = (sasl_secret_t *) realloc(x, sizeof(sasl_secret_t) + len); -+ -+ if (!x) { -+ return SASL_NOMEM; -+ } -+ -+ x->len = len; -+ strcpy((char *)x->data, testpass); -+ -+ *psecret = x; -+ return SASL_OK; -+} -+ - int main(int argc, char *argv[]) - { -- sasl_callback_t callbacks[2] = {}; -+ sasl_callback_t callbacks[4] = {}; - char buf[8192]; - const char *chosenmech; - sasl_conn_t *conn; -@@ -49,8 +102,9 @@ - const char *sasl_mech = "GSSAPI"; - bool spnego = false; - bool zeromaxssf = false; -+ bool plain = false; - -- while ((c = getopt(argc, argv, "c:zN")) != EOF) { -+ while ((c = getopt(argc, argv, "c:zNP:")) != EOF) { - switch (c) { - case 'c': - parse_cb(&cb, cb_buf, 256, optarg); -@@ -61,6 +115,10 @@ - case 'N': - spnego = true; - break; -+ case 'P': -+ plain = true; -+ testpass = optarg; -+ break; - default: - break; - } -@@ -73,6 +131,12 @@ - callbacks[1].id = SASL_CB_LIST_END; - callbacks[1].proc = NULL; - callbacks[1].context = NULL; -+ callbacks[2].id = SASL_CB_LIST_END; -+ callbacks[2].proc = NULL; -+ callbacks[2].context = NULL; -+ callbacks[3].id = SASL_CB_LIST_END; -+ callbacks[3].proc = NULL; -+ callbacks[3].context = NULL; - - r = sasl_client_init(callbacks); - if (r != SASL_OK) exit(-1); -@@ -91,6 +155,16 @@ - sasl_mech = "GSS-SPNEGO"; - } - -+ if (plain) { -+ sasl_mech = "PLAIN"; -+ -+ callbacks[1].id = SASL_CB_AUTHNAME; -+ callbacks[1].proc = (sasl_callback_ft)&get_user; -+ -+ callbacks[2].id = SASL_CB_PASS; -+ callbacks[2].proc = (sasl_callback_ft)&get_pass; -+ } -+ - if (zeromaxssf) { - /* set all security properties to 0 including maxssf */ - sasl_security_properties_t secprops = { 0 }; -@@ -99,9 +173,9 @@ - - r = sasl_client_start(conn, sasl_mech, NULL, &data, &len, &chosenmech); - if (r != SASL_OK && r != SASL_CONTINUE) { -- saslerr(r, "starting SASL negotiation"); -- printf("\n%s\n", sasl_errdetail(conn)); -- exit(-1); -+ saslerr(r, "starting SASL negotiation"); -+ printf("\n%s\n", sasl_errdetail(conn)); -+ exit(-1); - } - - sd = setup_socket(); -@@ -111,11 +185,11 @@ - len = 8192; - recv_string(sd, buf, &len, false); - -- r = sasl_client_step(conn, buf, len, NULL, &data, &len); -- if (r != SASL_OK && r != SASL_CONTINUE) { -- saslerr(r, "performing SASL negotiation"); -- printf("\n%s\n", sasl_errdetail(conn)); -- exit(-1); -+ r = sasl_client_step(conn, buf, len, NULL, &data, &len); -+ if (r != SASL_OK && r != SASL_CONTINUE) { -+ saslerr(r, "performing SASL negotiation"); -+ printf("\n%s\n", sasl_errdetail(conn)); -+ exit(-1); - } - } - -diff -Nru cyrus-sasl-2.1.27/tests/t_gssapi_srv.c cyrus-sasl-2.1.27-beldmit/tests/t_gssapi_srv.c ---- cyrus-sasl-2.1.27/tests/t_gssapi_srv.c 2020-12-23 14:31:35.565537492 +0100 -+++ cyrus-sasl-2.1.27-beldmit/tests/t_gssapi_srv.c 2021-01-06 11:27:48.373257373 +0100 -@@ -1,4 +1,5 @@ --/* Copyright (C) Simo Sorce -+/* Copyright (C) Simo Sorce , -+ * Dmitry Belyavskiy - * See COPYING file for License */ - - #include "t_common.h" -@@ -15,6 +16,10 @@ - #include - #include - -+const char *sasldb_path = NULL, -+ *auxprop_plugin = "sasldb", -+ *pwcheck_method = "auxprop-hashed"; -+ - static int setup_socket(void) - { - struct sockaddr_in addr; -@@ -45,9 +50,38 @@ - return sd; - } - -+static int test_getopt(void *context __attribute__((unused)), -+ const char *plugin_name __attribute__((unused)), -+ const char *option, -+ const char **result, -+ unsigned *len) -+{ -+ if (sasldb_path && !strcmp(option, "sasldb_path")) { -+ *result = sasldb_path; -+ if (len) -+ *len = (unsigned) strlen(sasldb_path); -+ return SASL_OK; -+ } -+ -+ if (sasldb_path && !strcmp(option, "auxprop_plugin")) { -+ *result = auxprop_plugin; -+ if (len) -+ *len = (unsigned) strlen(auxprop_plugin); -+ return SASL_OK; -+ } -+ -+ if (sasldb_path && !strcmp(option, "pwcheck_method")) { -+ *result = pwcheck_method; -+ if (len) -+ *len = (unsigned) strlen(pwcheck_method); -+ return SASL_OK; -+ } -+ return SASL_FAIL; -+} -+ - int main(int argc, char *argv[]) - { -- sasl_callback_t callbacks[2] = {}; -+ sasl_callback_t callbacks[3] = {}; - char buf[8192]; - sasl_conn_t *conn; - const char *data; -@@ -59,8 +93,9 @@ - const char *sasl_mech = "GSSAPI"; - bool spnego = false; - bool zeromaxssf = false; -+ bool plain = false; - -- while ((c = getopt(argc, argv, "c:zN")) != EOF) { -+ while ((c = getopt(argc, argv, "c:zNP:")) != EOF) { - switch (c) { - case 'c': - parse_cb(&cb, cb_buf, 256, optarg); -@@ -71,6 +106,10 @@ - case 'N': - spnego = true; - break; -+ case 'P': -+ plain = true; -+ sasldb_path = optarg; -+ break; - default: - break; - } -@@ -81,9 +120,12 @@ - callbacks[0].id = SASL_CB_GETPATH; - callbacks[0].proc = (sasl_callback_ft)&getpath; - callbacks[0].context = NULL; -- callbacks[1].id = SASL_CB_LIST_END; -- callbacks[1].proc = NULL; -+ callbacks[1].id = SASL_CB_GETOPT; -+ callbacks[1].proc = (sasl_callback_ft)&test_getopt; - callbacks[1].context = NULL; -+ callbacks[2].id = SASL_CB_LIST_END; -+ callbacks[2].proc = NULL; -+ callbacks[2].context = NULL; - - r = sasl_server_init(callbacks, "t_gssapi_srv"); - if (r != SASL_OK) exit(-1); -@@ -103,6 +145,10 @@ - sasl_mech = "GSS-SPNEGO"; - } - -+ if (plain) { -+ sasl_mech = "PLAIN"; -+ } -+ - if (zeromaxssf) { - /* set all security properties to 0 including maxssf */ - sasl_security_properties_t secprops = { 0 }; -@@ -116,9 +162,9 @@ - - r = sasl_server_start(conn, sasl_mech, buf, len, &data, &len); - if (r != SASL_OK && r != SASL_CONTINUE) { -- saslerr(r, "starting SASL negotiation"); -- printf("\n%s\n", sasl_errdetail(conn)); -- exit(-1); -+ saslerr(r, "starting SASL negotiation"); -+ printf("\n%s\n", sasl_errdetail(conn)); -+ exit(-1); - } - - while (r == SASL_CONTINUE) { -@@ -126,12 +172,12 @@ - len = 8192; - recv_string(sd, buf, &len, true); - -- r = sasl_server_step(conn, buf, len, &data, &len); -- if (r != SASL_OK && r != SASL_CONTINUE) { -- saslerr(r, "performing SASL negotiation"); -- printf("\n%s\n", sasl_errdetail(conn)); -- exit(-1); -- } -+ r = sasl_server_step(conn, buf, len, &data, &len); -+ if (r != SASL_OK && r != SASL_CONTINUE) { -+ saslerr(r, "performing SASL negotiation"); -+ printf("\n%s\n", sasl_errdetail(conn)); -+ exit(-1); -+ } - } - - if (r != SASL_OK) exit(-1); diff --git a/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 index c8c4a79..46f89ed 100644 --- 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 @@ -1,24 +1,20 @@ -From 49e965f41257a0ed299c58a7cf1c120ddf944aaa Mon Sep 17 00:00:00 2001 +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: Tue, 5 May 2020 14:51:36 -0400 +Date: Thu, 19 Sep 2019 15:58:04 -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 +This is needed to interop with Windows within a TLS channel. 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(-) + 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 56e0504..6effe99 100644 +index 17f5d081..60306943 100644 --- a/m4/sasl2.m4 +++ b/m4/sasl2.m4 @@ -287,6 +287,19 @@ if test "$gssapi" != no; then @@ -42,10 +38,10 @@ index 56e0504..6effe99 100644 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 +index 46de7d48..cca6cc0a 100644 --- a/plugins/gssapi.c +++ b/plugins/gssapi.c -@@ -1783,7 +1783,49 @@ static int gssapi_client_mech_step(void *conn_context, +@@ -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; } @@ -93,343 +89,7 @@ index 5d900c5..7480316 100644 +#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 + 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-Emit-debug-log-only-in-case-of-errors.patch b/cyrus-sasl-2.1.27-Emit-debug-log-only-in-case-of-errors.patch deleted file mode 100644 index d5e1334..0000000 --- a/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/cyrus-sasl-2.1.27-Migration-from-BerkeleyDB.patch b/cyrus-sasl-2.1.27-Migration-from-BerkeleyDB.patch index beffea3..2bc9fe8 100644 --- a/cyrus-sasl-2.1.27-Migration-from-BerkeleyDB.patch +++ b/cyrus-sasl-2.1.27-Migration-from-BerkeleyDB.patch @@ -32,8 +32,8 @@ diff -up cyrus-sasl-2.1.27/m4/sasldb.m4.frombdb cyrus-sasl-2.1.27/m4/sasldb.m4 SASL_DB_BACKEND="db_${dblib}.lo" SASL_DB_BACKEND_STATIC="db_${dblib}.o allockey.o" SASL_DB_BACKEND_STATIC_SRCS="\$(top_srcdir)/sasldb/db_${dblib}.c \$(top_srcdir)/sasldb/allockey.c" --SASL_DB_UTILS="saslpasswd2 sasldblistusers2" -+SASL_DB_UTILS="cyrusbdb2current saslpasswd2 sasldblistusers2" +-SASL_DB_UTILS="saslpasswd2\$(EXEEXT) sasldblistusers2\$(EXEEXT)" ++SASL_DB_UTILS="cyrusbdb2current\$(EXEEXT) saslpasswd2\$(EXEEXT) sasldblistusers2\$(EXEEXT)" SASL_DB_MANS="saslpasswd2.8 sasldblistusers2.8" case "$dblib" in @@ -58,18 +58,15 @@ diff -up cyrus-sasl-2.1.27/sasldb/db_gdbm.c.frombdb cyrus-sasl-2.1.27/sasldb/db_ utils->seterror(cntxt, 0, "Could not open %s: gdbm_errno=%d", path, gdbm_errno); result = SASL_FAIL; -@@ -107,9 +111,10 @@ int _sasldb_getdata(const sasl_utils_t * +@@ -107,7 +111,7 @@ int _sasldb_getdata(const sasl_utils_t * gkey.dptr = key; gkey.dsize = key_len; gvalue = gdbm_fetch(db, gkey); +- int fetch_errno = gdbm_errno; + fetch_errno = gdbm_errno; + gdbm_close(db); if (! gvalue.dptr) { -- if (gdbm_errno == GDBM_ITEM_NOT_FOUND) { -+ if (fetch_errno == GDBM_ITEM_NOT_FOUND) { - utils->seterror(conn, SASL_NOLOG, - "user: %s@%s property: %s not found in %s", - authid, realm, propName, path); @@ -186,7 +191,8 @@ int _sasldb_putdata(const sasl_utils_t * if (! db) { utils->log(conn, SASL_LOG_ERR, diff --git a/cyrus-sasl-2.1.27-cumulative-digestmd5.patch b/cyrus-sasl-2.1.27-cumulative-digestmd5.patch index d61130f..62bb91d 100644 --- a/cyrus-sasl-2.1.27-cumulative-digestmd5.patch +++ b/cyrus-sasl-2.1.27-cumulative-digestmd5.patch @@ -310,7 +310,7 @@ diff -uPr cyrus-sasl-2.1.27/plugins/digestmd5.c cyrus-sasl-2.1.27.digestmd5/plug (unsigned char *)output + *outputlen, &len); if (rc != 1) return SASL_FAIL; -@@ -1221,188 +1312,11 @@ +@@ -1221,194 +1312,11 @@ return SASL_OK; } @@ -422,8 +422,14 @@ diff -uPr cyrus-sasl-2.1.27/plugins/digestmd5.c cyrus-sasl-2.1.27.digestmd5/plug -{ - /* free rc4 context structures */ - -- if(text->cipher_enc_context) text->utils->free(text->cipher_enc_context); -- if(text->cipher_dec_context) text->utils->free(text->cipher_dec_context); +- 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, diff --git a/cyrus-sasl-2.1.27-cumulative-ossl3.patch b/cyrus-sasl-2.1.27-cumulative-ossl3.patch index 0d0eb39..b61d0a3 100644 --- a/cyrus-sasl-2.1.27-cumulative-ossl3.patch +++ b/cyrus-sasl-2.1.27-cumulative-ossl3.patch @@ -27,7 +27,7 @@ diff -uPr cyrus-sasl-2.1.27/plugins/scram.c cyrus-sasl-2.1.27.ossl3/plugins/scra /***************************** Common Section *****************************/ -@@ -267,6 +271,32 @@ +@@ -291,6 +293,32 @@ } #endif @@ -58,12 +58,12 @@ diff -uPr cyrus-sasl-2.1.27/plugins/scram.c cyrus-sasl-2.1.27.ossl3/plugins/scra +} +#endif - /* The result variable need to point to a buffer big enough for the [SHA-1] hash */ + /* 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 2021-10-06 11:29:53.281375315 -0400 -+++ cyrus-sasl-2.1.27.ossl3/saslauthd/lak.c 2021-10-06 11:30:59.022400245 -0400 -@@ -1805,13 +1805,29 @@ +--- 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; } @@ -71,13 +71,13 @@ diff -uPr cyrus-sasl-2.1.27/saslauthd/lak.c cyrus-sasl-2.1.27.ossl3/saslauthd/la - EVP_DigestUpdate(mdctx, passwd, strlen(passwd)); + rc = EVP_DigestInit(mdctx, md); + if (rc != 1) { -+ EVP_MD_CTX_free(mdctx); -+ return LAK_FAIL; ++ rc = LAK_FAIL; ++ goto done; + } + rc = EVP_DigestUpdate(mdctx, passwd, strlen(passwd)); + if (rc != 1) { -+ EVP_MD_CTX_free(mdctx); -+ return LAK_FAIL; ++ rc = LAK_FAIL; ++ goto done; + } if (hrock->salted) { - EVP_DigestUpdate(mdctx, &cred[EVP_MD_size(md)], @@ -85,16 +85,25 @@ diff -uPr cyrus-sasl-2.1.27/saslauthd/lak.c cyrus-sasl-2.1.27.ossl3/saslauthd/la + rc = EVP_DigestUpdate(mdctx, &cred[EVP_MD_size(md)], + clen - EVP_MD_size(md)); + if (rc != 1) { -+ EVP_MD_CTX_free(mdctx); -+ return LAK_FAIL; ++ rc = LAK_FAIL; ++ goto done; + } + } + rc = EVP_DigestFinal(mdctx, digest, NULL); + if (rc != 1) { -+ EVP_MD_CTX_free(mdctx); -+ return LAK_FAIL; ++ rc = LAK_FAIL; ++ goto done; } - EVP_DigestFinal(mdctx, digest, NULL); - EVP_MD_CTX_free(mdctx); +- 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-fix-for-autoconf270.patch b/cyrus-sasl-2.1.27-fix-for-autoconf270.patch deleted file mode 100644 index 3c6e7be..0000000 --- a/cyrus-sasl-2.1.27-fix-for-autoconf270.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 3b0149cf3d235247b051b7cb7663bc3dadbb999b Mon Sep 17 00:00:00 2001 -From: Pavel Raiskup -Date: Thu, 1 Apr 2021 17:17:52 +0200 -Subject: [PATCH] configure.ac: avoid side-effects in AC_CACHE_VAL - -In the COMMANDS-TO-SET-IT argument, per Autoconf docs: -https://www.gnu.org/software/autoconf/manual/autoconf-2.63/html_node/Caching-Results.html ---- - configure.ac | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/configure.ac b/configure.ac -index a106d35e..d333496d 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -220,11 +220,14 @@ void foo() { int i=0;} - int main() { void *self, *ptr1, *ptr2; self=dlopen(NULL,RTLD_LAZY); - if(self) { ptr1=dlsym(self,"foo"); ptr2=dlsym(self,"_foo"); - if(ptr1 && !ptr2) exit(0); } exit(1); } --], [sasl_cv_dlsym_adds_uscore=yes], sasl_cv_dlsym_adds_uscore=no -- AC_DEFINE(DLSYM_NEEDS_UNDERSCORE, [], [Do we need a leading _ for dlsym?]), -+], [sasl_cv_dlsym_adds_uscore=yes], sasl_cv_dlsym_adds_uscore=no, - AC_MSG_WARN(cross-compiler, we'll do our best))) - LIBS="$cmu_save_LIBS" - AC_MSG_RESULT($sasl_cv_dlsym_adds_uscore) -+ -+ if test "$sasl_cv_dlsym_adds_uscore" = no; then -+ AC_DEFINE(DLSYM_NEEDS_UNDERSCORE, [], [Do we need a leading _ for dlsym?]) -+ fi - fi - fi - -From d3bcaf62f6213e7635e9c4a574f39a831e333980 Mon Sep 17 00:00:00 2001 -From: Pavel Raiskup -Date: Thu, 1 Apr 2021 17:26:28 +0200 -Subject: [PATCH] configure.ac: properly quote macro arguments - -Autoconf 2.70+ is more picky about the quotation (even though with -previous versions the arguments should have been quoted, too). When we -don't quote macros inside the AC_CACHE_VAL macro - some of the Autoconf -initialization is wrongly ordered in ./configure script and we keep -seeing bugs like: - - ./configure: line 2165: ac_fn_c_try_run: command not found - -Original report: https://bugzilla.redhat.com/1943013 ---- - configure.ac | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/configure.ac b/configure.ac -index d333496d..7281cba0 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -213,15 +213,16 @@ if test $sasl_cv_uscore = yes; then - AC_MSG_CHECKING(whether dlsym adds the underscore for us) - cmu_save_LIBS="$LIBS" - LIBS="$LIBS $SASL_DL_LIB" -- AC_CACHE_VAL(sasl_cv_dlsym_adds_uscore,AC_TRY_RUN( [ -+ AC_CACHE_VAL([sasl_cv_dlsym_adds_uscore], -+ [AC_TRY_RUN([ - #include - #include - void foo() { int i=0;} - int main() { void *self, *ptr1, *ptr2; self=dlopen(NULL,RTLD_LAZY); - if(self) { ptr1=dlsym(self,"foo"); ptr2=dlsym(self,"_foo"); - if(ptr1 && !ptr2) exit(0); } exit(1); } --], [sasl_cv_dlsym_adds_uscore=yes], sasl_cv_dlsym_adds_uscore=no, -- AC_MSG_WARN(cross-compiler, we'll do our best))) -+], [sasl_cv_dlsym_adds_uscore=yes], [sasl_cv_dlsym_adds_uscore=no], -+ [AC_MSG_WARN(cross-compiler, we'll do our best)])]) - LIBS="$cmu_save_LIBS" - AC_MSG_RESULT($sasl_cv_dlsym_adds_uscore) - diff --git a/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-cve-2019-19906.patch b/cyrus-sasl-cve-2019-19906.patch deleted file mode 100644 index acdf682..0000000 --- a/cyrus-sasl-cve-2019-19906.patch +++ /dev/null @@ -1,25 +0,0 @@ -From dcc9f51cbd4ed622cfb0f9b1c141eb2ffe3b12f1 Mon Sep 17 00:00:00 2001 -From: Quanah Gibson-Mount -Date: Tue, 18 Feb 2020 19:05:12 +0000 -Subject: [PATCH] Fix #587 - -Off by one error in common.c, CVE-2019-19906. - -Thanks to Stephan Zeisberg for reporting ---- - lib/common.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/lib/common.c b/lib/common.c -index bc3bf1df..9969d6aa 100644 ---- a/lib/common.c -+++ b/lib/common.c -@@ -190,7 +190,7 @@ int _sasl_add_string(char **out, size_t *alloclen, - - if (add==NULL) add = "(null)"; - -- addlen=strlen(add); /* only compute once */ -+ addlen=strlen(add)+1; /* only compute once */ - if (_buf_alloc(out, alloclen, (*outlen)+addlen)!=SASL_OK) - return SASL_NOMEM; - diff --git a/cyrus-sasl-pr559-RC4-openssl.patch b/cyrus-sasl-pr559-RC4-openssl.patch deleted file mode 100644 index f884423..0000000 --- a/cyrus-sasl-pr559-RC4-openssl.patch +++ /dev/null @@ -1,156 +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 -@@ -1103,13 +1103,12 @@ AC_ARG_WITH(configdir, [ --with-configdir=DIR set the directory where confi - configdir='${plugindir}:${sysconfdir}/sasl2') - AC_SUBST(configdir) - --dnl look for rc4 libraries. we accept the CMU one or one from openSSL --AC_ARG_WITH(rc4, [ --with-rc4 use internal rc4 routines [[yes]] ], -+AC_ARG_WITH(rc4, [ --with-rc4 use rc4 routines [[yes]] ], - with_rc4=$withval, - with_rc4=yes) - - if test "$with_rc4" != no; then -- AC_DEFINE(WITH_RC4,[],[Use internal RC4 implementation?]) -+ AC_DEFINE(WITH_RC4,[],[Use RC4]) - fi - - building_for_macosx=no -diff --git a/plugins/digestmd5.c b/plugins/digestmd5.c -index df35093d..c6b54317 100644 ---- a/plugins/digestmd5.c -+++ b/plugins/digestmd5.c -@@ -1117,6 +1117,111 @@ static void free_des(context_t *text) - #endif /* WITH_DES */ - - #ifdef WITH_RC4 -+#ifdef HAVE_OPENSSL -+#include -+ -+static void free_rc4(context_t *text) -+{ -+ if (text->cipher_enc_context) { -+ EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *)text->cipher_enc_context); -+ text->cipher_enc_context = NULL; -+ } -+ if (text->cipher_dec_context) { -+ EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *)text->cipher_dec_context); -+ text->cipher_dec_context = NULL; -+ } -+} -+ -+static int init_rc4(context_t *text, -+ unsigned char enckey[16], -+ unsigned char deckey[16]) -+{ -+ EVP_CIPHER_CTX *ctx; -+ int rc; -+ -+ ctx = EVP_CIPHER_CTX_new(); -+ if (ctx == NULL) return SASL_NOMEM; -+ -+ rc = EVP_EncryptInit_ex(ctx, EVP_rc4(), NULL, enckey, NULL); -+ if (rc != 1) return SASL_FAIL; -+ -+ text->cipher_enc_context = (void *)ctx; -+ -+ ctx = EVP_CIPHER_CTX_new(); -+ if (ctx == NULL) return SASL_NOMEM; -+ -+ rc = EVP_DecryptInit_ex(ctx, EVP_rc4(), NULL, deckey, NULL); -+ if (rc != 1) return SASL_FAIL; -+ -+ text->cipher_dec_context = (void *)ctx; -+ -+ return SASL_OK; -+} -+ -+static int dec_rc4(context_t *text, -+ const char *input, -+ unsigned inputlen, -+ unsigned char digest[16] __attribute__((unused)), -+ char *output, -+ unsigned *outputlen) -+{ -+ int len; -+ int rc; -+ -+ /* decrypt the text part & HMAC */ -+ rc = EVP_DecryptUpdate((EVP_CIPHER_CTX *)text->cipher_dec_context, -+ (unsigned char *)output, &len, -+ (const unsigned char *)input, inputlen); -+ if (rc != 1) return SASL_FAIL; -+ -+ *outputlen = len; -+ -+ rc = EVP_DecryptFinal_ex((EVP_CIPHER_CTX *)text->cipher_dec_context, -+ (unsigned char *)output + len, &len); -+ if (rc != 1) return SASL_FAIL; -+ -+ *outputlen += len; -+ -+ /* subtract the HMAC to get the text length */ -+ *outputlen -= 10; -+ -+ return SASL_OK; -+} -+ -+static int enc_rc4(context_t *text, -+ const char *input, -+ unsigned inputlen, -+ unsigned char digest[16], -+ char *output, -+ unsigned *outputlen) -+{ -+ int len; -+ int rc; -+ /* encrypt the text part */ -+ rc = EVP_EncryptUpdate((EVP_CIPHER_CTX *)text->cipher_enc_context, -+ (unsigned char *)output, &len, -+ (const unsigned char *)input, inputlen); -+ if (rc != 1) return SASL_FAIL; -+ -+ *outputlen = len; -+ -+ /* encrypt the `MAC part */ -+ rc = EVP_EncryptUpdate((EVP_CIPHER_CTX *)text->cipher_enc_context, -+ (unsigned char *)output + *outputlen, &len, -+ digest, 10); -+ if (rc != 1) return SASL_FAIL; -+ -+ *outputlen += len; -+ -+ rc = EVP_EncryptFinal_ex((EVP_CIPHER_CTX *)text->cipher_enc_context, -+ (unsigned char *)output + *outputlen, &len); -+ if (rc != 1) return SASL_FAIL; -+ -+ *outputlen += len; -+ -+ return SASL_OK; -+} -+#else - /* quick generic implementation of RC4 */ - struct rc4_context_s { - unsigned char sbox[256]; -@@ -1296,7 +1401,7 @@ static int enc_rc4(context_t *text, - - return SASL_OK; - } -- -+#endif /* HAVE_OPENSSL */ - #endif /* WITH_RC4 */ - - struct digest_cipher available_ciphers[] = diff --git a/cyrus-sasl.spec b/cyrus-sasl.spec index 5200ea9..96c7bb3 100644 --- a/cyrus-sasl.spec +++ b/cyrus-sasl.spec @@ -8,7 +8,7 @@ Summary: The Cyrus SASL library Name: cyrus-sasl -Version: 2.1.27 +Version: 2.1.28 Release: %autorelease License: BSD with advertising URL: https://www.cyrusimap.org/sasl/ @@ -32,25 +32,20 @@ Patch23: cyrus-sasl-2.1.23-man.patch Patch24: cyrus-sasl-2.1.21-sizes.patch # The 64 bit *INT8 type is not used anywhere and other types match Patch49: cyrus-sasl-2.1.26-md5global.patch -Patch60: cyrus-sasl-pr559-RC4-openssl.patch -Patch100: cyrus-sasl-cve-2019-19906.patch Patch101: cyrus-sasl-2.1.27-Add-basic-test-infrastructure.patch Patch102: cyrus-sasl-2.1.27-Add-Channel-Binding-support-for-GSSAPI-GSS-SPNEGO.patch -Patch103: cyrus-sasl-2.1.27-Add-support-for-setting-max-ssf-0-to-GSS-SPNEGO.patch -Patch104: cyrus-sasl-2.1.27-Emit-debug-log-only-in-case-of-errors.patch -Patch105: cyrus-sasl-2.1.27-fix-for-autoconf270.patch #https://github.com/simo5/cyrus-sasl/commit/ebd2387f06c84c7f9aac3167ec041bb01e5c6e48 Patch106: cyrus-sasl-2.1.27-nostrncpy.patch # Upstream PR: https://github.com/cyrusimap/cyrus-sasl/pull/635 -Patch107: cyrus-sasl-2.1.27-Add-basic-test-plain-auth.patch +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 #Migration tool should be removed from Fedora 36 -Patch108: cyrus-sasl-2.1.27-Migration-from-BerkeleyDB.patch +Patch109: cyrus-sasl-2.1.27-Migration-from-BerkeleyDB.patch Patch500: cyrus-sasl-2.1.27-coverity.patch Patch501: cyrus-sasl-2.1.27-cumulative-digestmd5.patch Patch502: cyrus-sasl-2.1.27-cumulative-ossl3.patch -Patch900: 0001-CVE-2022-24407-Escape-password-for-SQL-insert-update.patch BuildRequires: autoconf, automake, libtool, gdbm-devel, groff BuildRequires: krb5-devel >= 1.2.2, openssl-devel, pam-devel, pkgconfig @@ -174,23 +169,16 @@ the GS2 authentication scheme. %patch23 -p1 -b .man %patch24 -p1 -b .sizes %patch49 -p1 -b .md5global.h -%patch60 -p1 -b .openssl_rc4 -%patch100 -p1 -b .cve_2019_19906 %patch101 -p1 -b .tests %patch102 -p1 -b .gssapi_cbs -%patch103 -p1 -b .maxssf0 -%patch104 -p1 -b .nolog -%patch105 -p1 -b .autoconf270 %patch106 -p1 -b .nostrncpy -%patch107 -p1 -b .plaintests -%patch108 -p1 -b .frombdb +%patch107 -p1 -b .moretests +%patch108 -p1 -b .maxssf0 +%patch109 -p1 -b .frombdb %patch500 -p1 -b .coverity %patch501 -p1 -b .digestmd5 %patch502 -p1 -b .ossl3 - -%patch900 -p1 -b .CVE-2022-24407 - %build # reconfigure cp %{SOURCE11} ./ diff --git a/sources b/sources index cf1def5..2ddc63c 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (cyrus-sasl-2.1.27-nodlcompatorsrp.tar.gz) = 86c45f729d5cf0aacc20c880d1cea5d927536c602d5d5866838036f00babfd5b89cb94d14a2c6ca4d78073f8f5c08da0f1f64a9a32b26c5f1e28b0d9246fd38e +SHA512 (cyrus-sasl-2.1.28-nodlcompatorsrp.tar.gz) = 9a80b363718774ac5b9b8b71c7eba7c48d760296542b4d545010ba4fc463d0da807fc8efd314381467e4c44b3b055082882f3ac03e8f829db2a543e271d70cbc