Compare commits

...

No commits in common. 'c9' and 'i10c-beta' have entirely different histories.

@ -1 +1 @@
c9e6848d9cc6f9588e0e7a75423f9a3aed3f10db SOURCES/cyrus-sasl-2.1.27-nodlcompatorsrp.tar.gz
080218941dfbbb6dc6d27e02358f12bed5b52eb2 SOURCES/cyrus-sasl-2.1.28-nodlcompatorsrp.tar.gz

2
.gitignore vendored

@ -1 +1 @@
SOURCES/cyrus-sasl-2.1.27-nodlcompatorsrp.tar.gz
SOURCES/cyrus-sasl-2.1.28-nodlcompatorsrp.tar.gz

@ -1,82 +0,0 @@
From 37f2e0f0658d78a1496dc277f402f8b577ce6aae Mon Sep 17 00:00:00 2001
From: Klaus Espenlaub <klaus@espenlaub.com>
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 <klaus@espenlaub.com>
---
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 ?
"<omitted>" : 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

@ -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"
+ ])

@ -1,24 +1,24 @@
From aa8b6b2275fd14ba2cca3d2339ae61c7e7ddfa70 Mon Sep 17 00:00:00 2001
Backport of commit ids (minor inline mods to make them apply):
975edbb69070eba6b035f08776de771a129cfb57
ea8eb892e44129ac3890298da91c868d5592ed20
From 975edbb69070eba6b035f08776de771a129cfb57 Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Tue, 5 May 2020 14:08:48 -0400
Date: Fri, 20 Mar 2020 14:51:04 -0400
Subject: [PATCH] Add Channel Binding support for GSSAPI/GSS-SPNEGO
Backport of commit ids:
829a6ed086432e26dafa9d1dcf892aef4c42cfbd
944bd8a6205f840b105206ef83e8f6b9dff0138e
Signed-off-by: Simo Sorce <simo@redhat.com>
---
plugins/gssapi.c | 30 +++++++++++---
tests/runtests.py | 93 ++++++++++++++++++++++++++++++++++++++++----
tests/t_common.c | 24 ++++++++----
tests/t_common.h | 5 ++-
tests/t_gssapi_cli.c | 24 ++++++++++--
tests/t_gssapi_srv.c | 24 ++++++++++--
6 files changed, 172 insertions(+), 28 deletions(-)
tests/t_common.c | 14 +++++++
tests/t_common.h | 2 +
tests/t_gssapi_cli.c | 21 +++++++++-
tests/t_gssapi_srv.c | 21 +++++++++-
6 files changed, 164 insertions(+), 17 deletions(-)
diff --git a/plugins/gssapi.c b/plugins/gssapi.c
index ff663da..5d900c5 100644
index ff663da7..5d900c5e 100644
--- a/plugins/gssapi.c
+++ b/plugins/gssapi.c
@@ -830,7 +830,9 @@ gssapi_server_mech_authneg(context_t *text,
@ -122,7 +122,7 @@ index ff663da..5d900c5 100644
gssapi_required_prompts, /* required_prompts */
&gss_spnego_oid, /* glob_context */
diff --git a/tests/runtests.py b/tests/runtests.py
index f645adf..fc9cf24 100755
index f645adf4..fc9cf244 100755
--- a/tests/runtests.py
+++ b/tests/runtests.py
@@ -1,6 +1,7 @@
@ -245,45 +245,10 @@ 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
@@ -1,4 +1,5 @@
-/* TBD, add (C) */
+/* Copyright (C) Simo Sorce <simo@redhat.com>
+ * See COPYING file for License */
#include <t_common.h>
@@ -13,9 +14,6 @@ void send_string(int sd, const char *s, unsigned int l)
{
ssize_t ret;
-fprintf(stderr, "s:%u ", l);
-fflush(stderr);
-
ret = send(sd, &l, sizeof(l), 0);
if (ret != sizeof(l)) s_error("send size", ret, sizeof(l), errno);
@@ -34,8 +32,6 @@ void recv_string(int sd, char *buf, unsigned int *buflen)
if (ret != sizeof(l)) s_error("recv size", ret, sizeof(l), errno);
if (l == 0) {
-fprintf(stderr, "r:0 ");
-fflush(stderr);
*buflen = 0;
return;
}
@@ -45,8 +41,6 @@ fflush(stderr);
ret = recv(sd, buf, l, 0);
if (ret != l) s_error("recv data", ret, l, errno);
-fprintf(stderr, "r:%ld ", ret);
-fflush(stderr);
*buflen = ret;
}
@@ -65,4 +59,18 @@ int getpath(void *context __attribute__((unused)), const char **path)
@@ -65,4 +65,18 @@ int getpath(void *context __attribute__((unused)), const char **path)
return SASL_OK;
}
@ -303,17 +268,10 @@ index 7168b2f..478e6a1 100644
+ cb->len = len;
+}
diff --git a/tests/t_common.h b/tests/t_common.h
index 4ee1976..a10def1 100644
index 4ee1976c..0d08d8ba 100644
--- a/tests/t_common.h
+++ b/tests/t_common.h
@@ -1,4 +1,5 @@
-/* TBD, add (C) */
+/* Copyright (C) Simo Sorce <simo@redhat.com>
+ * See COPYING file for License */
#include "config.h"
@@ -7,9 +8,11 @@
@@ -7,9 +7,11 @@
#include <sys/socket.h>
#include <sasl.h>
@ -326,17 +284,10 @@ index 4ee1976..a10def1 100644
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 c833c055..6b5664eb 100644
--- a/tests/t_gssapi_cli.c
+++ b/tests/t_gssapi_cli.c
@@ -1,4 +1,5 @@
-/* TBD, add (C) */
+/* Copyright (C) Simo Sorce <simo@redhat.com>
+ * See COPYING file for License */
#include "t_common.h"
@@ -13,6 +14,7 @@
@@ -13,6 +13,7 @@
#include <arpa/inet.h>
#include <saslplug.h>
@ -344,7 +295,7 @@ index c833c05..a44a3f5 100644
static int setup_socket(void)
{
@@ -32,7 +34,7 @@ static int setup_socket(void)
@@ -32,7 +33,7 @@ static int setup_socket(void)
return sock;
}
@ -353,7 +304,7 @@ index c833c05..a44a3f5 100644
{
sasl_callback_t callbacks[2] = {};
char buf[8192];
@@ -40,8 +42,20 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
@@ -40,8 +41,20 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
sasl_conn_t *conn;
const char *data;
unsigned int len;
@ -375,7 +326,7 @@ index c833c05..a44a3f5 100644
/* initialize the sasl library */
callbacks[0].id = SASL_CB_GETPATH;
@@ -60,6 +74,10 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
@@ -60,6 +73,10 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
exit(-1);
}
@ -387,17 +338,10 @@ index c833c05..a44a3f5 100644
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 29f538dd..3a8a5d44 100644
--- a/tests/t_gssapi_srv.c
+++ b/tests/t_gssapi_srv.c
@@ -1,4 +1,5 @@
-/* TBD, add (C) */
+/* Copyright (C) Simo Sorce <simo@redhat.com>
+ * See COPYING file for License */
#include "t_common.h"
@@ -44,15 +45,28 @@ static int setup_socket(void)
@@ -44,15 +44,28 @@ static int setup_socket(void)
return sd;
}
@ -428,7 +372,7 @@ index 29f538d..ef1217f 100644
/* initialize the sasl library */
callbacks[0].id = SASL_CB_GETPATH;
@@ -72,6 +86,10 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
@@ -72,6 +85,10 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
exit(-1);
}
@ -439,6 +383,93 @@ index 29f538d..ef1217f 100644
sd = setup_socket();
len = 8192;
--
2.18.2
From ea8eb892e44129ac3890298da91c868d5592ed20 Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Fri, 20 Mar 2020 14:52:15 -0400
Subject: [PATCH] Fixup minor issues in previous PR.
Remove spurious debugging code, this was left in by mistake.
Add C notices, this was omitted by mistake.
Signed-off-by: Simo Sorce <simo@redhat.com>
---
tests/t_common.c | 10 ++--------
tests/t_common.h | 3 ++-
tests/t_gssapi_cli.c | 3 ++-
tests/t_gssapi_srv.c | 3 ++-
4 files changed, 8 insertions(+), 11 deletions(-)
diff --git a/tests/t_common.c b/tests/t_common.c
index 87875b48..478e6a1f 100644
--- a/tests/t_common.c
+++ b/tests/t_common.c
@@ -1,4 +1,5 @@
-/* TBD, add (C) */
+/* Copyright (C) Simo Sorce <simo@redhat.com>
+ * See COPYING file for License */
#include <t_common.h>
@@ -13,9 +14,6 @@ void send_string(int sd, const char *s, unsigned int l)
{
ssize_t ret;
-fprintf(stderr, "s:%u ", l);
-fflush(stderr);
-
ret = send(sd, &l, sizeof(l), 0);
if (ret != sizeof(l)) s_error("send size", ret, sizeof(l), errno);
@@ -34,8 +32,6 @@ void recv_string(int sd, char *buf, unsigned int *buflen)
if (ret != sizeof(l)) s_error("recv size", ret, sizeof(l), errno);
if (l == 0) {
-fprintf(stderr, "r:0 ");
-fflush(stderr);
*buflen = 0;
return;
}
@@ -45,8 +41,6 @@ fflush(stderr);
ret = recv(sd, buf, l, 0);
if (ret != l) s_error("recv data", ret, l, errno);
-fprintf(stderr, "r:%ld ", ret);
-fflush(stderr);
*buflen = ret;
}
diff --git a/tests/t_common.h b/tests/t_common.h
index 0d08d8ba..a10def17 100644
--- a/tests/t_common.h
+++ b/tests/t_common.h
@@ -1,4 +1,5 @@
-/* TBD, add (C) */
+/* Copyright (C) Simo Sorce <simo@redhat.com>
+ * See COPYING file for License */
#include "config.h"
diff --git a/tests/t_gssapi_cli.c b/tests/t_gssapi_cli.c
index 6b5664eb..a44a3f58 100644
--- a/tests/t_gssapi_cli.c
+++ b/tests/t_gssapi_cli.c
@@ -1,4 +1,5 @@
-/* TBD, add (C) */
+/* Copyright (C) Simo Sorce <simo@redhat.com>
+ * See COPYING file for License */
#include "t_common.h"
diff --git a/tests/t_gssapi_srv.c b/tests/t_gssapi_srv.c
index 3a8a5d44..ef1217f6 100644
--- a/tests/t_gssapi_srv.c
+++ b/tests/t_gssapi_srv.c
@@ -1,4 +1,5 @@
-/* TBD, add (C) */
+/* Copyright (C) Simo Sorce <simo@redhat.com>
+ * See COPYING file for License */
#include "t_common.h"

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

@ -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 <saslplug.h>
#include <saslutil.h>
+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 <simo@redhat.com>
+/* Copyright (C) Simo Sorce <simo@redhat.com>,
+ * Dmitry Belyavskiy <dbelyavs@redhat.com>
* See COPYING file for License */
#include "t_common.h"
@@ -15,6 +16,10 @@
#include <arpa/inet.h>
#include <saslplug.h>
+const char *sasldb_path = NULL,
+ *auxprop_plugin = "sasldb",
+ *pwcheck_method = "auxprop-hashed";
+
static int setup_socket(void)
{
struct sockaddr_in addr;
@@ -45,9 +50,38 @@
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);

@ -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 <simo@redhat.com>
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 <simo@redhat.com>
---
m4/sasl2.m4 | 13 +++++++
plugins/gssapi.c | 44 ++++++++++++++++++++-
tests/runtests.py | 91 ++++++++++++++++++++++++++++++++++++++++----
tests/t_common.c | 13 ++++---
tests/t_common.h | 3 +-
tests/t_gssapi_cli.c | 25 ++++++++++--
tests/t_gssapi_srv.c | 28 +++++++++++---
7 files changed, 194 insertions(+), 23 deletions(-)
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 <errno.h>
+#include <stdbool.h>
#include <stdio.h>
#include <sys/socket.h>
@@ -12,7 +13,7 @@
void s_error(const char *hdr, ssize_t ret, ssize_t len, int err);
void send_string(int sd, const char *s, unsigned int l);
-void recv_string(int sd, char *buf, unsigned int *buflen);
+void recv_string(int sd, char *buf, unsigned int *buflen, bool allow_eof);
void saslerr(int why, const char *what);
int getpath(void *context __attribute__((unused)), const char **path);
void parse_cb(sasl_channel_binding_t *cb, char *buf, unsigned max, char *in);
diff --git a/tests/t_gssapi_cli.c b/tests/t_gssapi_cli.c
index a44a3f5..d9eafe1 100644
--- a/tests/t_gssapi_cli.c
+++ b/tests/t_gssapi_cli.c
@@ -46,12 +46,21 @@ int main(int argc, char *argv[])
char cb_buf[256];
int sd;
int c, r;
+ const char *sasl_mech = "GSSAPI";
+ bool spnego = false;
+ bool zeromaxssf = false;
- while ((c = getopt(argc, argv, "c:")) != EOF) {
+ while ((c = getopt(argc, argv, "c:zN")) != EOF) {
switch (c) {
case 'c':
parse_cb(&cb, cb_buf, 256, optarg);
break;
+ case 'z':
+ zeromaxssf = true;
+ break;
+ case 'N':
+ spnego = true;
+ break;
default:
break;
}
@@ -78,7 +87,17 @@ int main(int argc, char *argv[])
sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb);
}
- r = sasl_client_start(conn, "GSSAPI", NULL, &data, &len, &chosenmech);
+ if (spnego) {
+ sasl_mech = "GSS-SPNEGO";
+ }
+
+ if (zeromaxssf) {
+ /* set all security properties to 0 including maxssf */
+ sasl_security_properties_t secprops = { 0 };
+ sasl_setprop(conn, SASL_SEC_PROPS, &secprops);
+ }
+
+ r = sasl_client_start(conn, sasl_mech, NULL, &data, &len, &chosenmech);
if (r != SASL_OK && r != SASL_CONTINUE) {
saslerr(r, "starting SASL negotiation");
printf("\n%s\n", sasl_errdetail(conn));
@@ -90,7 +109,7 @@ int main(int argc, char *argv[])
while (r == SASL_CONTINUE) {
send_string(sd, data, len);
len = 8192;
- recv_string(sd, buf, &len);
+ recv_string(sd, buf, &len, false);
r = sasl_client_step(conn, buf, len, NULL, &data, &len);
if (r != SASL_OK && r != SASL_CONTINUE) {
diff --git a/tests/t_gssapi_srv.c b/tests/t_gssapi_srv.c
index ef1217f..448a218 100644
--- a/tests/t_gssapi_srv.c
+++ b/tests/t_gssapi_srv.c
@@ -56,12 +56,21 @@ int main(int argc, char *argv[])
unsigned char cb_buf[256];
int sd;
int c, r;
+ const char *sasl_mech = "GSSAPI";
+ bool spnego = false;
+ bool zeromaxssf = false;
- while ((c = getopt(argc, argv, "c:")) != EOF) {
+ while ((c = getopt(argc, argv, "c:zN")) != EOF) {
switch (c) {
case 'c':
parse_cb(&cb, cb_buf, 256, optarg);
break;
+ case 'z':
+ zeromaxssf = true;
+ break;
+ case 'N':
+ spnego = true;
+ break;
default:
break;
}
@@ -90,12 +99,22 @@ int main(int argc, char *argv[])
sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb);
}
+ if (spnego) {
+ sasl_mech = "GSS-SPNEGO";
+ }
+
+ if (zeromaxssf) {
+ /* set all security properties to 0 including maxssf */
+ sasl_security_properties_t secprops = { 0 };
+ sasl_setprop(conn, SASL_SEC_PROPS, &secprops);
+ }
+
sd = setup_socket();
len = 8192;
- recv_string(sd, buf, &len);
+ recv_string(sd, buf, &len, false);
- r = sasl_server_start(conn, "GSSAPI", buf, len, &data, &len);
+ r = sasl_server_start(conn, sasl_mech, buf, len, &data, &len);
if (r != SASL_OK && r != SASL_CONTINUE) {
saslerr(r, "starting SASL negotiation");
printf("\n%s\n", sasl_errdetail(conn));
@@ -105,7 +124,7 @@ int main(int argc, char *argv[])
while (r == SASL_CONTINUE) {
send_string(sd, data, len);
len = 8192;
- recv_string(sd, buf, &len);
+ recv_string(sd, buf, &len, true);
r = sasl_server_step(conn, buf, len, &data, &len);
if (r != SASL_OK && r != SASL_CONTINUE) {
@@ -113,7 +132,6 @@ int main(int argc, char *argv[])
printf("\n%s\n", sasl_errdetail(conn));
exit(-1);
}
-
}
if (r != SASL_OK) exit(-1);
--
2.18.2
if (params->props.security_flags & SASL_SEC_PASS_CREDENTIALS) {
req_flags = req_flags | GSS_C_DELEG_FLAG;

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

@ -1,569 +0,0 @@
diff -up cyrus-sasl-2.1.27/configure.ac.frombdb cyrus-sasl-2.1.27/configure.ac
--- cyrus-sasl-2.1.27/configure.ac.frombdb 2021-06-04 13:02:07.790112263 +0200
+++ cyrus-sasl-2.1.27/configure.ac 2021-06-04 13:02:07.798112327 +0200
@@ -1091,6 +1091,9 @@ AC_SUBST(SASL_STATIC_SRCS)
AC_SUBST(SASL_STATIC_OBJS)
AC_SUBST(SASL_STATIC_LIBS)
+CYRUS_BERKELEY_DB_STATIC_LIB()
+AC_SUBST(BDB_STATIC_LIBADD)
+
AC_ARG_WITH(plugindir, [ --with-plugindir=DIR set the directory where plugins will
be found [[LIBDIR/sasl2]] ],
plugindir=$withval,
diff -up cyrus-sasl-2.1.27/m4/berkdb.m4.frombdb cyrus-sasl-2.1.27/m4/berkdb.m4
--- cyrus-sasl-2.1.27/m4/berkdb.m4.frombdb 2016-01-29 18:35:35.000000000 +0100
+++ cyrus-sasl-2.1.27/m4/berkdb.m4 2021-06-04 13:02:07.798112327 +0200
@@ -286,3 +286,10 @@ AC_DEFUN([CYRUS_BERKELEY_DB_CHK],
CPPFLAGS=$cmu_save_CPPFLAGS
])
+
+AC_DEFUN([CYRUS_BERKELEY_DB_STATIC_LIB],
+[
+BDB_STATIC_LIBADD="/dev/null -lpthread"
+AC_CHECK_FILE([/usr/lib64/libdb-5.3.a],[BDB_STATIC_LIBADD="/usr/lib64/libdb-5.3.a -lpthread "],[])
+AC_CHECK_FILE([/usr/lib/libdb-5.3.a],[BDB_STATIC_LIBADD="/usr/lib/libdb-5.3.a -lpthread"],[])
+])
diff -up cyrus-sasl-2.1.27/m4/sasldb.m4.frombdb cyrus-sasl-2.1.27/m4/sasldb.m4
--- cyrus-sasl-2.1.27/m4/sasldb.m4.frombdb 2017-07-13 20:45:19.000000000 +0200
+++ cyrus-sasl-2.1.27/m4/sasldb.m4 2021-06-04 13:02:07.798112327 +0200
@@ -111,7 +111,7 @@ AC_MSG_RESULT($dblib)
SASL_DB_BACKEND="db_${dblib}.lo"
SASL_DB_BACKEND_STATIC="db_${dblib}.o allockey.o"
SASL_DB_BACKEND_STATIC_SRCS="\$(top_srcdir)/sasldb/db_${dblib}.c \$(top_srcdir)/sasldb/allockey.c"
-SASL_DB_UTILS="saslpasswd2 sasldblistusers2"
+SASL_DB_UTILS="cyrusbdb2current saslpasswd2 sasldblistusers2"
SASL_DB_MANS="saslpasswd2.8 sasldblistusers2.8"
case "$dblib" in
diff -up cyrus-sasl-2.1.27/sasldb/db_gdbm.c.frombdb cyrus-sasl-2.1.27/sasldb/db_gdbm.c
--- cyrus-sasl-2.1.27/sasldb/db_gdbm.c.frombdb 2017-07-13 14:34:03.000000000 +0200
+++ cyrus-sasl-2.1.27/sasldb/db_gdbm.c 2021-06-04 13:04:24.098206887 +0200
@@ -67,6 +67,7 @@ int _sasldb_getdata(const sasl_utils_t *
void *cntxt;
sasl_getopt_t *getopt;
const char *path = SASL_DB_PATH;
+ int fetch_errno = 0;
if (!utils) return SASL_BADPARAM;
if (!authid || !propName || !realm || !out || !max_out) {
@@ -99,6 +100,9 @@ int _sasldb_getdata(const sasl_utils_t *
}
db = gdbm_open((char *)path, 0, GDBM_READER, S_IRUSR | S_IWUSR, NULL);
if (! db) {
+ utils->log(conn, SASL_LOG_ERR,
+ "SASL error opening password file. "
+ "Have you performed the migration from db2 using cyrusbdb2current?\n");
utils->seterror(cntxt, 0, "Could not open %s: gdbm_errno=%d",
path, gdbm_errno);
result = SASL_FAIL;
@@ -107,9 +111,10 @@ int _sasldb_getdata(const sasl_utils_t *
gkey.dptr = key;
gkey.dsize = key_len;
gvalue = gdbm_fetch(db, gkey);
+ fetch_errno = gdbm_errno;
gdbm_close(db);
if (! gvalue.dptr) {
- if (gdbm_errno == GDBM_ITEM_NOT_FOUND) {
+ if (fetch_errno == GDBM_ITEM_NOT_FOUND) {
utils->seterror(conn, SASL_NOLOG,
"user: %s@%s property: %s not found in %s",
authid, realm, propName, path);
@@ -186,7 +191,8 @@ int _sasldb_putdata(const sasl_utils_t *
if (! db) {
utils->log(conn, SASL_LOG_ERR,
"SASL error opening password file. "
- "Do you have write permissions?\n");
+ "Do you have write permissions?\n"
+ "Have you performed the migration from db2 using cyrusbdb2current?\n");
utils->seterror(conn, 0, "Could not open %s for write: gdbm_errno=%d",
path, gdbm_errno);
result = SASL_FAIL;
@@ -298,6 +304,9 @@ sasldb_handle _sasldb_getkeyhandle(const
db = gdbm_open((char *)path, 0, GDBM_READER, S_IRUSR | S_IWUSR, NULL);
if(!db) {
+ utils->log(conn, SASL_LOG_ERR,
+ "SASL error opening password file. "
+ "Have you performed the migration from db2 using cyrusbdb2current?\n");
utils->seterror(conn, 0, "Could not open %s: gdbm_errno=%d",
path, gdbm_errno);
return NULL;
diff -up cyrus-sasl-2.1.27/utils/cyrusbdb2current.8.frombdb cyrus-sasl-2.1.27/utils/cyrusbdb2current.8
--- cyrus-sasl-2.1.27/utils/cyrusbdb2current.8.frombdb 2021-06-04 13:02:07.798112327 +0200
+++ cyrus-sasl-2.1.27/utils/cyrusbdb2current.8 2021-06-04 13:02:07.798112327 +0200
@@ -0,0 +1,159 @@
+.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+. ds C`
+. ds C'
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is >0, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.\"
+.\" Avoid warning from groff about undefined register 'F'.
+.de IX
+..
+.nr rF 0
+.if \n(.g .if rF .nr rF 1
+.if (\n(rF:(\n(.g==0)) \{\
+. if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. if !\nF==2 \{\
+. nr % 0
+. nr F 2
+. \}
+. \}
+.\}
+.rr rF
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "CYRUSBDB2CURRENT 1"
+.TH CYRUSBDB2CURRENT 1 "2021-04-28" "perl v5.30.3" "User Contributed Perl Documentation"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+cyrusbdb2current \- command\-line utility converting the SASLDB database from
+BerkeleyDB to the database format currently used bys sasldb.
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+cyrusbdb2current <sasldb_old_path> <sasldb_new_path>
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+\&\fBcyrusbdb2current\fR converts the current sasldb database from BerkeleyDB format to the
+currently used database format. It is \fB\s-1STRONGLY RECOMMENDED\s0\fR to make a backup
+of the current database before the conversion.
+.PP
+We expect that the old path is \fB/etc/sasldb2\fR and the new one is
+\&\fB/etc/sasl2/sasldb2\fR
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fBsaslpasswd2\fR\|(8)
+.PP
+rfc4422 \- Simple Authentication and Security Layer (\s-1SASL\s0)
diff -up cyrus-sasl-2.1.27/utils/cyrusbdb2current.c.frombdb cyrus-sasl-2.1.27/utils/cyrusbdb2current.c
--- cyrus-sasl-2.1.27/utils/cyrusbdb2current.c.frombdb 2021-06-04 13:02:07.798112327 +0200
+++ cyrus-sasl-2.1.27/utils/cyrusbdb2current.c 2021-06-04 13:02:07.798112327 +0200
@@ -0,0 +1,282 @@
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sasl.h>
+#include <saslplug.h>
+#include "../sasldb/sasldb.h"
+
+/* Cheating to make the utils work out right */
+extern const sasl_utils_t *sasl_global_utils;
+sasl_conn_t *globalconn;
+
+typedef void *listcb_t(const char *, const char *, const char *,
+ const char *, unsigned);
+
+void listusers_cb(const char *authid, const char *realm,
+ const char *propName, const char *secret,
+ unsigned seclen)
+{
+ if (!authid || !propName || !realm) {
+ fprintf(stderr,"userlist callback has bad param");
+ return;
+ }
+
+ /* the entries that just say the mechanism exists */
+ if (strlen(authid)==0) return;
+
+ printf("Converting: %s@%s (%s)...",authid,realm,propName);
+
+ _sasldb_putdata(sasl_global_utils, globalconn,
+ authid, realm, propName,
+ secret, seclen);
+
+ printf("ok\n");
+}
+
+/*
+ * List all users in database
+ */
+
+#include <db.h>
+
+#define DB_VERSION_FULL ((DB_VERSION_MAJOR << 24) | (DB_VERSION_MINOR << 16) | DB_VERSION_PATCH)
+/*
+ * Open the database
+ *
+ */
+static int berkeleydb_open(const char *path,DB **mbdb)
+{
+ int ret;
+
+#if DB_VERSION_FULL < 0x03000000
+ ret = db_open(path, DB_HASH, DB_CREATE, 0664, NULL, NULL, mbdb);
+#else /* DB_VERSION_FULL < 0x03000000 */
+ ret = db_create(mbdb, NULL, 0);
+ if (ret == 0 && *mbdb != NULL)
+ {
+#if DB_VERSION_FULL >= 0x04010000
+ ret = (*mbdb)->open(*mbdb, NULL, path, NULL, DB_HASH, DB_CREATE, 0664);
+#else
+ ret = (*mbdb)->open(*mbdb, path, NULL, DB_HASH, DB_CREATE, 0664);
+#endif
+ if (ret != 0)
+ {
+ (void) (*mbdb)->close(*mbdb, 0);
+ *mbdb = NULL;
+ }
+ }
+#endif /* DB_VERSION_FULL < 0x03000000 */
+
+ if (ret != 0) {
+ fprintf(stderr,"Error opening password file %s\n", path);
+ return SASL_FAIL;
+ }
+
+ return SASL_OK;
+}
+
+/*
+ * Close the database
+ *
+ */
+
+static void berkeleydb_close(DB *mbdb)
+{
+ int ret;
+
+ ret = mbdb->close(mbdb, 0);
+ if (ret!=0) {
+ fprintf(stderr,"error closing sasldb: %s",
+ db_strerror(ret));
+ }
+}
+
+int listusers(const char *path, listcb_t *cb)
+{
+ int result;
+ DB *mbdb = NULL;
+ DBC *cursor;
+ DBT key, data;
+
+ /* open the db */
+ result=berkeleydb_open(path, &mbdb);
+ if (result!=SASL_OK) goto cleanup;
+
+ /* make cursor */
+#if DB_VERSION_FULL < 0x03060000
+ result = mbdb->cursor(mbdb, NULL,&cursor);
+#else
+ result = mbdb->cursor(mbdb, NULL,&cursor, 0);
+#endif /* DB_VERSION_FULL < 0x03060000 */
+
+ if (result!=0) {
+ fprintf(stderr,"Making cursor failure: %s\n",db_strerror(result));
+ result = SASL_FAIL;
+ goto cleanup;
+ }
+
+ memset(&key,0, sizeof(key));
+ memset(&data,0,sizeof(data));
+
+ /* loop thru */
+ result = cursor->c_get(cursor, &key, &data,
+ DB_FIRST);
+
+ while (result != DB_NOTFOUND)
+ {
+ char *authid;
+ char *realm;
+ char *tmp;
+ unsigned int len;
+ char prop[1024];
+ int numnulls = 0;
+ unsigned int lup;
+
+ /* make sure there are exactly 2 null's */
+ for (lup=0;lup<key.size;lup++)
+ if (((char *)key.data)[lup]=='\0')
+ numnulls++;
+
+ if (numnulls != 2) {
+ fprintf(stderr,"warning: probable database corruption\n");
+ result = cursor->c_get(cursor, &key, &data, DB_NEXT);
+ continue;
+ }
+
+ authid = key.data;
+ realm = authid + strlen(authid)+1;
+ tmp = realm + strlen(realm)+1;
+ len = key.size - (tmp - authid);
+
+ /* make sure we have enough space of prop */
+ if (len >=sizeof(prop)) {
+ fprintf(stderr,"warning: absurdly long prop name\n");
+ result = cursor->c_get(cursor, &key, &data, DB_NEXT);
+ continue;
+ }
+
+ memcpy(prop, tmp, key.size - (tmp - ((char *)key.data)));
+ prop[key.size - (tmp - ((char *)key.data))] = '\0';
+
+ if (*authid) {
+ /* don't check return values */
+ cb(authid,realm,prop,data.data,data.size);
+ }
+
+ result = cursor->c_get(cursor, &key, &data, DB_NEXT);
+ }
+
+ if (result != DB_NOTFOUND) {
+ fprintf(stderr,"failure: %s\n",db_strerror(result));
+ result = SASL_FAIL;
+ goto cleanup;
+ }
+
+ result = cursor->c_close(cursor);
+ if (result != 0) {
+ result = SASL_FAIL;
+ goto cleanup;
+ }
+
+ result = SASL_OK;
+
+ cleanup:
+
+ if (mbdb != NULL) berkeleydb_close(mbdb);
+ return result;
+}
+
+
+char *db = NULL, *db_new=NULL;
+
+int good_getopt(void *context __attribute__((unused)),
+ const char *plugin_name __attribute__((unused)),
+ const char *option,
+ const char **result,
+ unsigned *len)
+{
+ if (db_new && !strcmp(option, "sasldb_path")) {
+ *result = db_new;
+ if (len)
+ *len = strlen(db_new);
+ return SASL_OK;
+ }
+
+ return SASL_FAIL;
+}
+
+static struct sasl_callback goodsasl_cb[] = {
+ { SASL_CB_GETOPT, (int (*)(void))&good_getopt, NULL },
+ { SASL_CB_LIST_END, NULL, NULL }
+};
+
+int main(int argc, char **argv)
+{
+ int result;
+ FILE *f;
+
+ if (argc != 3) {
+ fprintf(stderr, "Usage: cyrusbdb2current old_sasldb new_sasldb\n");
+ fprintf(stderr, "old_sasldb is presumably /etc/sasldb2\n");
+ fprintf(stderr, "new_sasldb is presumably /etc/sasl2/sasldb2\n");
+ return 1;
+ }
+
+ db = argv[1];
+ db_new = argv[2];
+
+ if (strcmp(db, db_new) == 0) {
+ fprintf(stderr, "Old and new files should be different\n");
+ return 1;
+ }
+
+
+ f = fopen(db_new, "rb");
+ if (f != NULL) {
+ fprintf(stderr, "The specified target file %s already exists\n", db_new);
+ fclose(f);
+ return 1;
+ }
+
+ result = sasl_server_init(goodsasl_cb, "dbconverter");
+ if (result != SASL_OK) {
+ fprintf(stderr, "couldn't init saslv2\n");
+ return 1;
+ }
+
+ result = sasl_server_new("sasldb",
+ "localhost",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ 0,
+ &globalconn);
+ if (result != SASL_OK) {
+ fprintf(stderr, "couldn't create globalconn\n");
+ return 1;
+ }
+
+ if(_sasl_check_db(sasl_global_utils,globalconn) != SASL_OK) {
+ fprintf(stderr, "target DB %s is not OK\n", db_new);
+ return 1;
+ }
+
+ printf("\nThis program will take the sasldb file specified on the\n"
+ "command line and convert it to a new sasldb specified\n"
+ "on the command line. It is STRONGLY RECOMMENDED that you\n"
+ "backup sasldb before allowing this program to run\n\n"
+ "We are going to convert %s and our output will be in %s\n\n"
+ "Press return to continue\n", db, db_new);
+
+ getchar();
+
+ listusers(db, (listcb_t *) &listusers_cb);
+
+ sasl_dispose(&globalconn);
+ sasl_done();
+
+ exit(0);
+}
diff -up cyrus-sasl-2.1.27/utils/Makefile.am.frombdb cyrus-sasl-2.1.27/utils/Makefile.am
--- cyrus-sasl-2.1.27/utils/Makefile.am.frombdb 2018-10-05 16:40:16.000000000 +0200
+++ cyrus-sasl-2.1.27/utils/Makefile.am 2021-06-04 13:02:07.798112327 +0200
@@ -46,14 +46,14 @@ all_sasl_libs = ../lib/libsasl2.la $(SAS
all_sasl_static_libs = ../lib/.libs/libsasl2.a $(SASL_DB_LIB) $(LIB_SOCKET) $(GSSAPIBASE_LIBS) $(GSSAPI_LIBS) $(SASL_KRB_LIB) $(LIB_DES) $(PLAIN_LIBS) $(SRP_LIBS) $(LIB_MYSQL) $(LIB_PGSQL) $(LIB_SQLITE)
sbin_PROGRAMS = @SASL_DB_UTILS@ @SMTPTEST_PROGRAM@ pluginviewer
-EXTRA_PROGRAMS = saslpasswd2 sasldblistusers2 testsuite testsuitestatic smtptest pluginviewer
+EXTRA_PROGRAMS = saslpasswd2 sasldblistusers2 testsuite testsuitestatic smtptest pluginviewer cyrusbdb2current
noinst_PROGRAMS = dbconverter-2
if NO_SASL_DB_MANS
man_MANS =
else
-man_MANS = saslpasswd2.8 sasldblistusers2.8 pluginviewer.8
+man_MANS = saslpasswd2.8 sasldblistusers2.8 pluginviewer.8 cyrusbdb2current.8
endif
saslpasswd2_LDADD = ../sasldb/libsasldb.la $(all_sasl_libs)
@@ -63,6 +63,7 @@ sasldblistusers2_SOURCES = sasldblistuse
dbconverter_2_LDADD = ../sasldb/libsasldb.la $(all_sasl_libs)
pluginviewer_LDADD = $(all_sasl_libs)
pluginviewer_SOURCES = pluginviewer.c
+cyrusbdb2current_LDADD = ../sasldb/libsasldb.la @BDB_STATIC_LIBADD@ $(all_sasl_libs)
testsuite_LDADD = $(all_sasl_libs) @DMALLOC_LIBS@

@ -1,6 +1,6 @@
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 2022-09-08 12:22:03.782961573 -0400
+++ cyrus-sasl-2.1.27.digestmd5/plugins/digestmd5.c 2022-09-08 12:24:20.289994669 -0400
--- 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 */
@ -105,7 +105,7 @@ diff -uPr cyrus-sasl-2.1.27/plugins/digestmd5.c cyrus-sasl-2.1.27.digestmd5/plug
/* setup dec context */
c++;
@@ -1102,34 +1114,83 @@
@@ -1102,60 +1114,143 @@
memcpy(c->ivec, ((char *) deckey) + 8, 8);
@ -201,7 +201,9 @@ diff -uPr cyrus-sasl-2.1.27/plugins/digestmd5.c cyrus-sasl-2.1.27.digestmd5/plug
}
static int init_rc4(context_t *text,
@@ -1139,23 +1200,57 @@
unsigned char enckey[16],
unsigned char deckey[16])
{
EVP_CIPHER_CTX *ctx;
int rc;
@ -240,24 +242,24 @@ diff -uPr cyrus-sasl-2.1.27/plugins/digestmd5.c cyrus-sasl-2.1.27.digestmd5/plug
+ 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;
- text->cipher_dec_context = (void *)ctx;
+
+ rc = SASL_OK;
- return SASL_OK;
+
+done:
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ EVP_CIPHER_free(cipher);
@ -269,7 +271,7 @@ diff -uPr cyrus-sasl-2.1.27/plugins/digestmd5.c cyrus-sasl-2.1.27.digestmd5/plug
}
static int dec_rc4(context_t *text,
@@ -1169,14 +1264,14 @@
@@ -1169,14 +1260,14 @@
int rc;
/* decrypt the text part & HMAC */
@ -286,7 +288,7 @@ diff -uPr cyrus-sasl-2.1.27/plugins/digestmd5.c cyrus-sasl-2.1.27.digestmd5/plug
(unsigned char *)output + len, &len);
if (rc != 1) return SASL_FAIL;
@@ -1198,7 +1293,7 @@
@@ -1198,7 +1289,7 @@
int len;
int rc;
/* encrypt the text part */
@ -295,7 +297,7 @@ diff -uPr cyrus-sasl-2.1.27/plugins/digestmd5.c cyrus-sasl-2.1.27.digestmd5/plug
(unsigned char *)output, &len,
(const unsigned char *)input, inputlen);
if (rc != 1) return SASL_FAIL;
@@ -1206,14 +1301,14 @@
@@ -1206,14 +1297,14 @@
*outputlen = len;
/* encrypt the `MAC part */
@ -312,7 +314,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 +1316,11 @@
@@ -1221,194 +1312,11 @@
return SASL_OK;
}
@ -424,8 +426,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,
@ -501,7 +509,7 @@ diff -uPr cyrus-sasl-2.1.27/plugins/digestmd5.c cyrus-sasl-2.1.27.digestmd5/plug
{ "rc4", 128, 16, 0x04, &enc_rc4, &dec_rc4, &init_rc4, &free_rc4 },
#endif
#ifdef WITH_DES
@@ -2815,6 +2733,7 @@
@@ -2815,6 +2729,7 @@
}
if (cptr->name) {
@ -509,7 +517,7 @@ diff -uPr cyrus-sasl-2.1.27/plugins/digestmd5.c cyrus-sasl-2.1.27.digestmd5/plug
text->cipher_enc = cptr->cipher_enc;
text->cipher_dec = cptr->cipher_dec;
text->cipher_init = cptr->cipher_init;
@@ -2958,7 +2877,10 @@
@@ -2958,7 +2873,10 @@
if (text->cipher_init) {
if (text->cipher_init(text, enckey, deckey) != SASL_OK) {
sparams->utils->seterror(sparams->utils->conn, 0,
@ -521,7 +529,7 @@ diff -uPr cyrus-sasl-2.1.27/plugins/digestmd5.c cyrus-sasl-2.1.27.digestmd5/plug
}
}
}
@@ -3509,6 +3431,7 @@
@@ -3509,6 +3427,7 @@
oparams->mech_ssf = ctext->cipher->ssf;
nbits = ctext->cipher->n;
@ -529,7 +537,7 @@ diff -uPr cyrus-sasl-2.1.27/plugins/digestmd5.c cyrus-sasl-2.1.27.digestmd5/plug
text->cipher_enc = ctext->cipher->cipher_enc;
text->cipher_dec = ctext->cipher->cipher_dec;
text->cipher_free = ctext->cipher->cipher_free;
@@ -3733,7 +3656,13 @@
@@ -3733,7 +3652,13 @@
/* initialize cipher if need be */
if (text->cipher_init) {

@ -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,7 +58,7 @@ 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 2022-01-09 11:30:50.000000000 -0400

@ -1,74 +0,0 @@
From 3b0149cf3d235247b051b7cb7663bc3dadbb999b Mon Sep 17 00:00:00 2001
From: Pavel Raiskup <praiskup@redhat.com>
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 <praiskup@redhat.com>
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 <dlfcn.h>
#include <stdio.h>
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)

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

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

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

@ -1,25 +0,0 @@
From dcc9f51cbd4ed622cfb0f9b1c141eb2ffe3b12f1 Mon Sep 17 00:00:00 2001
From: Quanah Gibson-Mount <quanah@symas.com>
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;

@ -1,156 +0,0 @@
From 8aa9ae816ddf66921b4a8a0f422517e6f2e55ac6 Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Wed, 27 Mar 2019 14:29:08 -0400
Subject: [PATCH] Use Openssl RC4 when available
Signed-off-by: Simo Sorce <simo@redhat.com>
---
configure.ac | 5 +--
plugins/digestmd5.c | 107 +++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 108 insertions(+), 4 deletions(-)
diff --git a/configure.ac b/configure.ac
index 388f5d02..cfdee4a2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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 <openssl/evp.h>
+
+static void free_rc4(context_t *text)
+{
+ if (text->cipher_enc_context) {
+ EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *)text->cipher_enc_context);
+ text->cipher_enc_context = NULL;
+ }
+ if (text->cipher_dec_context) {
+ EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *)text->cipher_dec_context);
+ text->cipher_dec_context = NULL;
+ }
+}
+
+static int init_rc4(context_t *text,
+ unsigned char enckey[16],
+ unsigned char deckey[16])
+{
+ EVP_CIPHER_CTX *ctx;
+ int rc;
+
+ ctx = EVP_CIPHER_CTX_new();
+ if (ctx == NULL) return SASL_NOMEM;
+
+ rc = EVP_EncryptInit_ex(ctx, EVP_rc4(), NULL, enckey, NULL);
+ if (rc != 1) return SASL_FAIL;
+
+ text->cipher_enc_context = (void *)ctx;
+
+ ctx = EVP_CIPHER_CTX_new();
+ if (ctx == NULL) return SASL_NOMEM;
+
+ rc = EVP_DecryptInit_ex(ctx, EVP_rc4(), NULL, deckey, NULL);
+ if (rc != 1) return SASL_FAIL;
+
+ text->cipher_dec_context = (void *)ctx;
+
+ return SASL_OK;
+}
+
+static int dec_rc4(context_t *text,
+ const char *input,
+ unsigned inputlen,
+ unsigned char digest[16] __attribute__((unused)),
+ char *output,
+ unsigned *outputlen)
+{
+ int len;
+ int rc;
+
+ /* decrypt the text part & HMAC */
+ rc = EVP_DecryptUpdate((EVP_CIPHER_CTX *)text->cipher_dec_context,
+ (unsigned char *)output, &len,
+ (const unsigned char *)input, inputlen);
+ if (rc != 1) return SASL_FAIL;
+
+ *outputlen = len;
+
+ rc = EVP_DecryptFinal_ex((EVP_CIPHER_CTX *)text->cipher_dec_context,
+ (unsigned char *)output + len, &len);
+ if (rc != 1) return SASL_FAIL;
+
+ *outputlen += len;
+
+ /* subtract the HMAC to get the text length */
+ *outputlen -= 10;
+
+ return SASL_OK;
+}
+
+static int enc_rc4(context_t *text,
+ const char *input,
+ unsigned inputlen,
+ unsigned char digest[16],
+ char *output,
+ unsigned *outputlen)
+{
+ int len;
+ int rc;
+ /* encrypt the text part */
+ rc = EVP_EncryptUpdate((EVP_CIPHER_CTX *)text->cipher_enc_context,
+ (unsigned char *)output, &len,
+ (const unsigned char *)input, inputlen);
+ if (rc != 1) return SASL_FAIL;
+
+ *outputlen = len;
+
+ /* encrypt the `MAC part */
+ rc = EVP_EncryptUpdate((EVP_CIPHER_CTX *)text->cipher_enc_context,
+ (unsigned char *)output + *outputlen, &len,
+ digest, 10);
+ if (rc != 1) return SASL_FAIL;
+
+ *outputlen += len;
+
+ rc = EVP_EncryptFinal_ex((EVP_CIPHER_CTX *)text->cipher_enc_context,
+ (unsigned char *)output + *outputlen, &len);
+ if (rc != 1) return SASL_FAIL;
+
+ *outputlen += len;
+
+ return SASL_OK;
+}
+#else
/* quick generic implementation of RC4 */
struct rc4_context_s {
unsigned char sbox[256];
@@ -1296,7 +1401,7 @@ static int enc_rc4(context_t *text,
return SASL_OK;
}
-
+#endif /* HAVE_OPENSSL */
#endif /* WITH_RC4 */
struct digest_cipher available_ciphers[] =

@ -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;

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

@ -1,22 +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
%global gdbm_db_file /etc/sasl2/sasldb2
Summary: The Cyrus SASL library
Name: cyrus-sasl
Version: 2.1.27
Release: 21%{?dist}
License: BSD with advertising
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
@ -25,52 +33,41 @@ Source10: make-no-dlcompatorsrp-tarball.sh
# https://raw.githubusercontent.com/cyrusimap/cyrus-sasl/master/autogen.sh
Source11: autogen.sh
Requires: %{name}-lib%{?_isa} = %{version}-%{release}
Patch11: cyrus-sasl-2.1.25-no_rpath.patch
Patch15: cyrus-sasl-2.1.20-saslauthd.conf-path.patch
Patch23: cyrus-sasl-2.1.23-man.patch
Patch24: cyrus-sasl-2.1.21-sizes.patch
# The 64 bit *INT8 type is not used anywhere and other types match
Patch49: cyrus-sasl-2.1.26-md5global.patch
Patch60: cyrus-sasl-pr559-RC4-openssl.patch
Patch100: cyrus-sasl-cve-2019-19906.patch
Patch101: cyrus-sasl-2.1.27-Add-basic-test-infrastructure.patch
Patch102: cyrus-sasl-2.1.27-Add-Channel-Binding-support-for-GSSAPI-GSS-SPNEGO.patch
Patch103: cyrus-sasl-2.1.27-Add-support-for-setting-max-ssf-0-to-GSS-SPNEGO.patch
Patch104: cyrus-sasl-2.1.27-Emit-debug-log-only-in-case-of-errors.patch
Patch105: cyrus-sasl-2.1.27-fix-for-autoconf270.patch
#https://github.com/simo5/cyrus-sasl/commit/ebd2387f06c84c7f9aac3167ec041bb01e5c6e48
Patch106: cyrus-sasl-2.1.27-nostrncpy.patch
# Upstream PR: https://github.com/cyrusimap/cyrus-sasl/pull/635
Patch107: cyrus-sasl-2.1.27-Add-basic-test-plain-auth.patch
#Migration tool should be removed from RHEL10
Patch108: cyrus-sasl-2.1.27-Migration-from-BerkeleyDB.patch
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
Patch900: 0001-CVE-2022-24407-Escape-password-for-SQL-insert-update.patch
Patch599: cyrus-sasl-2.1.28-fedora-c99.patch
BuildRequires: autoconf, automake, libtool, gdbm-devel, groff
BuildRequires: krb5-devel >= 1.19, openssl-devel, pam-devel, pkgconfig
BuildRequires: krb5-devel >= 1.2.2, openssl-devel, pam-devel, pkgconfig
BuildRequires: mariadb-connector-c-devel, libpq-devel, zlib-devel
%if ! %{bootstrap_cyrus_sasl}
BuildRequires: openldap-devel
%endif
#build reqs for migration from BerkeleyDB
#should be removed from RHEL10
BuildRequires: libdb-devel-static
#build reqs for make check
BuildRequires: python3 nss_wrapper socket_wrapper krb5-server
%{?systemd_requires}
Requires: %{name}-lib = %{version}-%{release}
Requires: systemd
#Requires/Provides related to the saslauthd user creation
Requires: /sbin/nologin
BuildRequires: make
Requires(pre): /usr/sbin/useradd /usr/sbin/groupadd
Requires(postun): /usr/sbin/userdel /usr/sbin/groupdel
Requires: /sbin/nologin
Provides: user(%username)
Provides: group(%username)
@ -88,8 +85,8 @@ The %{name}-lib package contains shared libraries which are needed by
applications which use the Cyrus SASL library.
%package devel
Requires: %{name}-lib = %{version}-%{release}
Requires: %{name} = %{version}-%{release}
Requires: %{name}-lib%{?_isa} = %{version}-%{release}
Requires: %{name}%{?_isa} = %{version}-%{release}
Requires: pkgconfig
Summary: Files needed for developing applications with Cyrus SASL
@ -122,14 +119,6 @@ Summary: CRAM-MD5 and DIGEST-MD5 authentication support for Cyrus SASL
The %{name}-md5 package contains the Cyrus SASL plugins which support
CRAM-MD5 and DIGEST-MD5 authentication schemes.
%package ntlm
Requires: %{name}-lib%{?_isa} = %{version}-%{release}
Summary: NTLM authentication support for Cyrus SASL
%description ntlm
The %{name}-ntlm package contains the Cyrus SASL plugin which supports
the NTLM authentication scheme.
# This would more appropriately be named cyrus-sasl-auxprop-sql.
%package sql
Requires: %{name}-lib%{?_isa} = %{version}-%{release}
@ -176,20 +165,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
%patch500 -p1 -b .coverity
%patch501 -p1 -b .digestmd5
%patch502 -p1 -b .ossl3
%patch900 -p1 -b .CVE-2022-24407
%patch503 -p1 -b .sast
%patch599 -p1 -b .c99
%build
# reconfigure
@ -198,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
@ -234,7 +220,8 @@ if test x"$LIB_DIR" != "x-L%{_libdir}"; then
LDFLAGS="$LIB_DIR $LDFLAGS"; export LDFLAGS
fi
CFLAGS="$RPM_OPT_FLAGS $CFLAGS $CPPFLAGS -fPIC -pie -Wl,-z,relro -Wl,-z,now"; export CFLAGS
# 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"
@ -259,7 +246,7 @@ echo "$LDFLAGS"
--enable-anon \
--enable-cram \
--enable-digest \
--enable-ntlm \
--disable-ntlm \
--enable-plain \
--enable-login \
--enable-alwaystrue \
@ -270,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
@ -292,8 +279,6 @@ install -m755 -d $RPM_BUILD_ROOT%{_bindir}
install -m755 sample/client $RPM_BUILD_ROOT%{_bindir}/sasl2-sample-client
./libtool --mode=install \
install -m755 sample/server $RPM_BUILD_ROOT%{_bindir}/sasl2-sample-server
#Migration tool should be removed from RHEL10
mv $RPM_BUILD_ROOT%{_sbindir}/cyrusbdb2current $RPM_BUILD_ROOT%{_bindir}/cyrusbdb2current
./libtool --mode=install \
install -m755 saslauthd/testsaslauthd $RPM_BUILD_ROOT%{_sbindir}/testsaslauthd
@ -316,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
@ -327,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
@ -349,7 +336,8 @@ 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
%license COPYING
@ -361,7 +349,6 @@ getent passwd %{username} >/dev/null || useradd -r -g %{username} -d %{homedir}
%{_plugindir2}/*sasldb*.so*
%{_sbindir}/saslpasswd2
%{_sbindir}/sasldblistusers2
%{_bindir}/cyrusbdb2current
%files plain
%{_plugindir2}/*plain*.so*
@ -376,9 +363,6 @@ getent passwd %{username} >/dev/null || useradd -r -g %{username} -d %{homedir}
%{_plugindir2}/*crammd5*.so*
%{_plugindir2}/*digestmd5*.so*
%files ntlm
%{_plugindir2}/*ntlm*.so*
%files sql
%{_plugindir2}/*sql*.so*
@ -401,54 +385,110 @@ getent passwd %{username} >/dev/null || useradd -r -g %{username} -d %{homedir}
%{_sbindir}/sasl2-shared-mechlist
%changelog
* Mon Aug 1 2022 Simo Sorce <simo@redhat.com> - 2.1.27-21
- Fix memleak
* Tue Nov 26 2024 MSVSphere Packaging Team <packager@msvsphere-os.ru> - 2.1.28-22
- Rebuilt for MSVSphere 10
## START: Generated by rpmautospec
* Thu Jun 20 2024 Rob Crittenden <rcritten@redhat.com> - 2.1.28-22
- Update license to BSD-Attribution-HPND-disclaimer
* Wed Jun 19 2024 Filip Janus <fjanus@redhat.com> - 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 Jun 11 2024 Rob Crittenden <rcritten@redhat.com> - 2.1.28-20
- Fix some issues uncovered by a static analyzer
* Wed Jan 24 2024 Fedora Release Engineering <releng@fedoraproject.org> - 2.1.28-19
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Wed Feb 23 2022 Simo Sorce <simo@redhat.com> - 2.1.27-20
- Fix for CVE-2022-24407
- Resolves: rhbz#2055848
* Fri Jan 19 2024 Fedora Release Engineering <releng@fedoraproject.org> - 2.1.28-18
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Wed Feb 9 2022 Simo Sorce <simo@redhat.com> - 2.1.27-19
- Fix a memleak in one of the OpenSSL 3 compat patches
found by covscan
* Wed Jan 17 2024 Florian Weimer <fweimer@redhat.com> - 2.1.28-17
- sasl-mechlist.c: Cast function pointer to the expected type
* Mon Feb 7 2022 Simo Sorce <simo@redhat.com> - 2.1.27-18
- Update OpenSSL 3 related compatibility patch backports
* Mon Jan 15 2024 Rob Crittenden <rcritten@redhat.com> - 2.1.28-16
- Disable and drop the ntlm plugin as it is removed upstream
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 2.1.27-17
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
* Thu Jan 11 2024 Rob Crittenden <rcritten@redhat.com> - 2.1.28-15
- tests: Switch openldap database to the LMDB backend
* Wed Jul 28 2021 Simo Sorce <simo@redhat.com> - 2.1.27-16
- Rebuild to pass gating after fixing rhbz#1983928
* Mon Jan 08 2024 Rob Crittenden <rcritten@redhat.com> - 2.1.28-14
- Add a mode and ownership to the ghost /run/saslauthd directory
* Wed Jul 28 2021 Florian Weimer <fweimer@redhat.com> - 2.1.27-15
- Rebuild to pick up OpenSSL 3.0 Beta ABI (#1984097)
* Fri Sep 08 2023 Simo Sorce <simo@redhat.com> - 2.1.28-13
- Migrate license field to SPDX format
* Mon Jul 19 2021 Simo Sorce <simo@redhat.com> - 2.1.27-14
- Fix crashs on missing legacy algorithms
Resolves: rhbz#1974354
* Wed Jul 19 2023 Yaakov Selkowitz <yselkowi@redhat.com> - 2.1.28-12
- Add --enable-new-dtags to LDFLAGS
* Wed Jun 16 2021 Mohan Boddu <mboddu@redhat.com> - 2.1.27-13
- Rebuilt for RHEL 9 BETA for openssl 3.0
Related: rhbz#1971065
* Wed Jul 19 2023 Fedora Release Engineering <releng@fedoraproject.org> - 2.1.28-11
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
* Fri Jun 04 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 2.1.27-12
- Incorporate the upstream gdbm specific patch from
https://github.com/cyrusimap/cyrus-sasl/pull/554
- Resolves rhbz#1947971
* Thu Apr 20 2023 DJ Delorie <dj@redhat.com> - 2.1.28-10
- Fix C99 compatibility issue
* Wed Apr 28 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 2.1.27-11
* Thu Jan 19 2023 Fedora Release Engineering <releng@fedoraproject.org> - 2.1.28-9
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
* Thu Aug 18 2022 Kalev Lember <klember@redhat.com> - 2.1.28-8
- Avoid requires on systemd as well as per updated guidelines
* Fri Aug 05 2022 Kalev Lember <klember@redhat.com> - 2.1.28-7
- Avoid systemd_requires as per updated packaging guidelines
* Mon Aug 01 2022 Simo Sorce <simo@redhat.com> - 2.1.28-6
- Fix memory leak in digestmd5 patches
* Wed Jul 20 2022 Fedora Release Engineering <releng@fedoraproject.org> - 2.1.28-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
* Thu Jun 09 2022 Simo Sorce <simo@redhat.com> - 2.1.28-4
- Use systemd sysusers to create saslauth user
* Thu Jun 09 2022 Simo Sorce <simo@redhat.com> - 2.1.28-3
- Enable sasldb authentication mechanism
* Wed May 11 2022 Simo Sorce <simo@redhat.com> - 2.1.28-2
- Fix changelog section with correct syntax
* Wed Feb 23 2022 Simo Sorce <simo@redhat.com> - 2.1.28-1
- Update to 2.1.28
* Wed Feb 23 2022 Simo Sorce <simo@redhat.com> - 2.1.27-49
- Move to use autorelease macro
* Tue Oct 12 2021 Simo Sorce <simo@redhat.com> - 2.1.27-16
- Fix rpath patch
- Resolves: rhbz#2012172
* Wed Oct 6 2021 Simo Sorce <simo@redhat.com> - 2.1.27-15
- More openssl 3 compatibility and digestmd5 updates.
* Tue Sep 14 2021 Sahana Prasad <sahana@redhat.com> - 2.1.27-14
- Rebuilt with OpenSSL 3.0.0
* Tue Aug 10 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 2.1.27-13
- Preserve GDBM error to correctly deal with GDBM sasldb
- Related: rhbz#1952926
* Wed Jul 21 2021 Fedora Release Engineering <releng@fedoraproject.org> - 2.1.27-12
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
* Mon May 03 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 2.1.27-11
- Fix some coverity issues
- Set default sasldb database to GDBM instead of BerkeleyDB
- Add the migration tool from BerkeleyDB
- Add some PLAIN auth tests
- Resolves rhbz#1947971
* Thu Apr 15 2021 Mohan Boddu <mboddu@redhat.com> - 2.1.27-10
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
* Tue Apr 06 2021 Simo Sorce <simo@redhat.com> - 2.1.27-10
- Fix issues with autoconf 2.70+
* Mon Apr 12 2021 Dmitry Belyavskiy <dbelyavs@redhat.com> - 2.1.27-9
- Coverity-related fixes (#1938700)
* Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 2.1.27-9
- Rebuilt for updated systemd-rpm-macros
See https://pagure.io/fesco/issue/2583.
* Mon Feb 08 2021 Pavel Raiskup <praiskup@redhat.com> - 2.1.27-8
- rebuild for libpq ABI fix rhbz#1908268
@ -1210,3 +1250,5 @@ getent passwd %{username} >/dev/null || useradd -r -g %{username} -d %{homedir}
* Fri Aug 13 1999 Tim Powers <timp@redhat.com>
- first build for Powertools
## END: Generated by rpmautospec

Loading…
Cancel
Save