import cyrus-sasl-2.1.27-17.el9

This commit is contained in:
CentOS Sources 2021-11-03 23:44:24 -04:00 committed by Stepan Oksanichenko
commit 6f6f3f825e
24 changed files with 4506 additions and 0 deletions

1
.cyrus-sasl.metadata Normal file
View File

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

1
.gitignore vendored Normal file
View File

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

37
SOURCES/autogen.sh Normal file
View File

@ -0,0 +1,37 @@
#!/bin/sh
# Run this to generate all the initial makefiles, etc.
test -n "$srcdir" || srcdir=`dirname "$0"`
test -n "$srcdir" || srcdir=.
olddir=`pwd`
cd $srcdir
(test -f configure.ac) || {
echo "*** ERROR: Directory "\`$srcdir\'" does not look like the top-level project directory ***"
exit 1
}
PKG_NAME=`autoconf --trace 'AC_INIT:$1' configure.ac`
if [ "$#" = 0 -a "x$NOCONFIGURE" = "x" ]; then
echo "*** WARNING: I am going to run \`configure' with no arguments." >&2
echo "*** If you wish to pass any to it, please specify them on the" >&2
echo "*** \`$0\' command line." >&2
echo "" >&2
fi
aclocal --install || exit 1
autoreconf --verbose --force --install -Wno-portability || exit 1
cd $olddir
if [ "$NOCONFIGURE" = "" ]; then
$srcdir/configure "$@" || exit 1
if [ "$1" = "--help" ]; then exit 0 else
echo "Now type \`make\' to compile $PKG_NAME" || exit 1
fi
else
echo "Skipping configure process."
fi

View File

@ -0,0 +1,26 @@
diff -up cyrus-sasl-2.1.27/saslauthd/saslauthd.mdoc.path cyrus-sasl-2.1.27/saslauthd/saslauthd.mdoc
--- cyrus-sasl-2.1.27/saslauthd/saslauthd.mdoc.path 2015-10-15 15:44:43.000000000 +0200
+++ cyrus-sasl-2.1.27/saslauthd/saslauthd.mdoc 2015-11-20 15:05:30.421377527 +0100
@@ -221,7 +221,7 @@ instead.
.Em (All platforms that support OpenLDAP 2.0 or higher)
.Pp
Authenticate against an ldap server. The ldap configuration parameters are
-read from /usr/local/etc/saslauthd.conf. The location of this file can be
+read from /etc/saslauthd.conf. The location of this file can be
changed with the -O parameter. See the LDAP_SASLAUTHD file included with the
distribution for the list of available parameters.
.It Li sia
@@ -251,10 +251,10 @@ these ticket files can cause serious per
servers. (Kerberos
was never intended to be used in this manner, anyway.)
.Sh FILES
-.Bl -tag -width "/var/run/saslauthd/mux"
-.It Pa /var/run/saslauthd/mux
+.Bl -tag -width "/run/saslauthd/mux"
+.It Pa /run/saslauthd/mux
The default communications socket.
-.It Pa /usr/local/etc/saslauthd.conf
+.It Pa /etc/saslauthd.conf
The default configuration file for ldap support.
.El
.Sh SEE ALSO

View File

@ -0,0 +1,119 @@
diff -up cyrus-sasl-2.1.27/configure.ac.sizes cyrus-sasl-2.1.27/configure.ac
--- cyrus-sasl-2.1.27/configure.ac.sizes 2015-11-18 09:46:24.000000000 +0100
+++ cyrus-sasl-2.1.27/configure.ac 2015-11-20 15:11:20.474588247 +0100
@@ -1312,6 +1312,10 @@ AC_HEADER_STDC
AC_HEADER_DIRENT
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS(crypt.h des.h dlfcn.h fcntl.h limits.h malloc.h paths.h strings.h sys/file.h sys/time.h syslog.h unistd.h inttypes.h sys/uio.h sys/param.h sysexits.h stdarg.h varargs.h krb5.h)
+AC_CHECK_TYPES([long long, int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t],,,[
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif])
IPv6_CHECK_SS_FAMILY()
IPv6_CHECK_SA_LEN()
diff -up cyrus-sasl-2.1.27/include/makemd5.c.sizes cyrus-sasl-2.1.27/include/makemd5.c
--- cyrus-sasl-2.1.27/include/makemd5.c.sizes 2015-10-15 15:44:43.000000000 +0200
+++ cyrus-sasl-2.1.27/include/makemd5.c 2015-11-20 15:11:20.477588240 +0100
@@ -82,12 +82,19 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "../config.h"
+#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
static void
my_strupr(char *s)
@@ -122,6 +129,18 @@ my_strupr(char *s)
static void
try_signed(FILE *f, int len)
{
+#ifdef HAVE_INT8_T
+ BITSIZE(int8_t);
+#endif
+#ifdef HAVE_INT16_T
+ BITSIZE(int16_t);
+#endif
+#ifdef HAVE_INT32_T
+ BITSIZE(int32_t);
+#endif
+#ifdef HAVE_INT64_T
+ BITSIZE(int64_t);
+#endif
BITSIZE(signed char);
BITSIZE(short);
BITSIZE(int);
@@ -135,6 +154,18 @@ try_signed(FILE *f, int len)
static void
try_unsigned(FILE *f, int len)
{
+#ifdef HAVE_UINT8_T
+ BITSIZE(uint8_t);
+#endif
+#ifdef HAVE_UINT16_T
+ BITSIZE(uint16_t);
+#endif
+#ifdef HAVE_UINT32_T
+ BITSIZE(uint32_t);
+#endif
+#ifdef HAVE_UINT64_T
+ BITSIZE(uint64_t);
+#endif
BITSIZE(unsigned char);
BITSIZE(unsigned short);
BITSIZE(unsigned int);
@@ -165,6 +196,11 @@ static int print_pre(FILE *f)
"/* POINTER defines a generic pointer type */\n"
"typedef unsigned char *POINTER;\n"
"\n"
+#ifdef HAVE_INTTYPES_H
+ "/* We try to define integer types for our use */\n"
+ "#include <inttypes.h>\n"
+ "\n"
+#endif
);
return 1;
}
@@ -212,31 +248,15 @@ int main(int argc, char **argv)
print_pre(f);
-#ifndef HAVE_INT8_T
try_signed (f, 8);
-#endif /* HAVE_INT8_T */
-#ifndef HAVE_INT16_T
try_signed (f, 16);
-#endif /* HAVE_INT16_T */
-#ifndef HAVE_INT32_T
try_signed (f, 32);
-#endif /* HAVE_INT32_T */
-#ifndef HAVE_INT64_T
try_signed (f, 64);
-#endif /* HAVE_INT64_T */
-#ifndef HAVE_U_INT8_T
try_unsigned (f, 8);
-#endif /* HAVE_INT8_T */
-#ifndef HAVE_U_INT16_T
try_unsigned (f, 16);
-#endif /* HAVE_U_INT16_T */
-#ifndef HAVE_U_INT32_T
try_unsigned (f, 32);
-#endif /* HAVE_U_INT32_T */
-#ifndef HAVE_U_INT64_T
try_unsigned (f, 64);
-#endif /* HAVE_U_INT64_T */
print_post(f);

View File

@ -0,0 +1,24 @@
diff -up cyrus-sasl-2.1.26/saslauthd/testsaslauthd.8.man cyrus-sasl-2.1.26/saslauthd/testsaslauthd.8
--- cyrus-sasl-2.1.26/saslauthd/testsaslauthd.8.man 2013-09-03 15:25:26.818042047 +0200
+++ cyrus-sasl-2.1.26/saslauthd/testsaslauthd.8 2013-09-03 15:25:26.818042047 +0200
@@ -0,0 +1,20 @@
+.\" Hey, EMACS: -*- nroff -*-
+.TH TESTSASLAUTHD 8 "14 October 2006"
+.SH NAME
+testsaslauthd \- test utility for the SASL authentication server
+.SH SYNOPSIS
+.B testsaslauthd
+.RI "[ " \(hyr " " realm " ] [ " \(hys " " servicename " ] [ " \(hyf " " socket " " path " ] [ " \(hyR " " repeatnum " ]"
+.SH DESCRIPTION
+This manual page documents briefly the
+.B testsaslauthd
+command.
+.PP
+.SH SEE ALSO
+.BR saslauthd (8).
+.br
+.SH AUTHOR
+testsaslauthd was written by Carnegie Mellon University.
+.PP
+This manual page was written by Roberto C. Sanchez <roberto@connexer.com>,
+for the Debian project (but may be used by others).

View File

@ -0,0 +1,20 @@
diff -up cyrus-sasl-2.1.25/m4/cyrus.m4.no_rpath cyrus-sasl-2.1.25/m4/cyrus.m4
--- cyrus-sasl-2.1.25/m4/cyrus.m4.no_rpath 2010-01-22 16:12:01.000000000 +0100
+++ cyrus-sasl-2.1.25/m4/cyrus.m4 2012-12-06 14:59:47.956102057 +0100
@@ -32,14 +32,5 @@ AC_DEFUN([CMU_ADD_LIBPATH_TO], [
dnl runpath initialization
AC_DEFUN([CMU_GUESS_RUNPATH_SWITCH], [
# CMU GUESS RUNPATH SWITCH
- AC_CACHE_CHECK(for runpath switch, andrew_cv_runpath_switch, [
- # first, try -R
- SAVE_LDFLAGS="${LDFLAGS}"
- LDFLAGS="-R /usr/lib"
- AC_TRY_LINK([],[],[andrew_cv_runpath_switch="-R"], [
- LDFLAGS="-Wl,-rpath,/usr/lib"
- AC_TRY_LINK([],[],[andrew_cv_runpath_switch="-Wl,-rpath,"],
- [andrew_cv_runpath_switch="none"])
- ])
- LDFLAGS="${SAVE_LDFLAGS}"
- ])])
+ andrew_runpath_switch="none"
+ ])

View File

@ -0,0 +1,24 @@
diff -up cyrus-sasl-2.1.27/include/Makefile.am.md5global.h cyrus-sasl-2.1.27/include/Makefile.am
--- cyrus-sasl-2.1.27/include/Makefile.am.md5global.h 2018-05-17 13:33:49.588368350 +0200
+++ cyrus-sasl-2.1.27/include/Makefile.am 2018-05-17 13:38:19.377316869 +0200
@@ -49,20 +49,7 @@ saslinclude_HEADERS = hmac-md5.h md5.h m
noinst_PROGRAMS = makemd5
-makemd5_SOURCES = makemd5.c
-
-makemd5$(BUILD_EXEEXT) $(makemd5_OBJECTS): CC=$(CC_FOR_BUILD)
-makemd5$(BUILD_EXEEXT) $(makemd5_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
-makemd5$(BUILD_EXEEXT): LDFLAGS=$(LDFLAGS_FOR_BUILD)
-
-md5global.h: makemd5$(BUILD_EXEEXT) Makefile
- -rm -f $@
- ./$< $@
-
-BUILT_SOURCES = md5global.h
-
EXTRA_DIST = NTMakefile
-DISTCLEANFILES = md5global.h
if MACOSX
framedir = /Library/Frameworks/SASL2.framework

View File

@ -0,0 +1,444 @@
From aa8b6b2275fd14ba2cca3d2339ae61c7e7ddfa70 Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Tue, 5 May 2020 14:08:48 -0400
Subject: [PATCH] Add Channel Binding support for GSSAPI/GSS-SPNEGO
Backport of commit ids:
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(-)
diff --git a/plugins/gssapi.c b/plugins/gssapi.c
index ff663da..5d900c5 100644
--- a/plugins/gssapi.c
+++ b/plugins/gssapi.c
@@ -830,7 +830,9 @@ gssapi_server_mech_authneg(context_t *text,
gss_buffer_desc name_without_realm;
gss_name_t client_name_MN = NULL, without = NULL;
gss_OID mech_type;
-
+ gss_channel_bindings_t bindings = GSS_C_NO_CHANNEL_BINDINGS;
+ struct gss_channel_bindings_struct cb = {0};
+
input_token = &real_input_token;
output_token = &real_output_token;
output_token->value = NULL; output_token->length = 0;
@@ -902,6 +904,12 @@ gssapi_server_mech_authneg(context_t *text,
real_input_token.length = clientinlen;
}
+ if (params->cbinding != NULL) {
+ cb.application_data.length = params->cbinding->len;
+ cb.application_data.value = params->cbinding->data;
+ bindings = &cb;
+ }
+
GSS_LOCK_MUTEX_CTX(params->utils, text);
maj_stat =
@@ -909,7 +917,7 @@ gssapi_server_mech_authneg(context_t *text,
&(text->gss_ctx),
server_creds,
input_token,
- GSS_C_NO_CHANNEL_BINDINGS,
+ bindings,
&text->client_name,
&mech_type,
output_token,
@@ -1505,7 +1513,8 @@ static sasl_server_plug_t gssapi_server_plugins[] =
| SASL_SEC_PASS_CREDENTIALS,
SASL_FEAT_WANT_CLIENT_FIRST
| SASL_FEAT_ALLOWS_PROXY
- | SASL_FEAT_DONTUSE_USERPASSWD, /* features */
+ | SASL_FEAT_DONTUSE_USERPASSWD
+ | SASL_FEAT_CHANNEL_BINDING, /* features */
NULL, /* glob_context */
&gssapi_server_mech_new, /* mech_new */
&gssapi_server_mech_step, /* mech_step */
@@ -1529,6 +1538,7 @@ static sasl_server_plug_t gssapi_server_plugins[] =
SASL_FEAT_WANT_CLIENT_FIRST
| SASL_FEAT_ALLOWS_PROXY
| SASL_FEAT_DONTUSE_USERPASSWD
+ | SASL_FEAT_CHANNEL_BINDING
| SASL_FEAT_SUPPORTS_HTTP, /* features */
&gss_spnego_oid, /* glob_context */
&gssapi_server_mech_new, /* mech_new */
@@ -1662,6 +1672,8 @@ static int gssapi_client_mech_step(void *conn_context,
input_token->value = NULL;
input_token->length = 0;
gss_cred_id_t client_creds = (gss_cred_id_t)params->gss_creds;
+ gss_channel_bindings_t bindings = GSS_C_NO_CHANNEL_BINDINGS;
+ struct gss_channel_bindings_struct cb = {0};
if (clientout)
*clientout = NULL;
@@ -1777,6 +1789,12 @@ static int gssapi_client_mech_step(void *conn_context,
req_flags = req_flags | GSS_C_DELEG_FLAG;
}
+ if (params->cbinding != NULL) {
+ cb.application_data.length = params->cbinding->len;
+ cb.application_data.value = params->cbinding->data;
+ bindings = &cb;
+ }
+
GSS_LOCK_MUTEX_CTX(params->utils, text);
maj_stat = gss_init_sec_context(&min_stat,
client_creds, /* GSS_C_NO_CREDENTIAL */
@@ -1785,7 +1803,7 @@ static int gssapi_client_mech_step(void *conn_context,
text->mech_type,
req_flags,
0,
- GSS_C_NO_CHANNEL_BINDINGS,
+ bindings,
input_token,
NULL,
output_token,
@@ -2190,7 +2208,8 @@ static sasl_client_plug_t gssapi_client_plugins[] =
| SASL_SEC_PASS_CREDENTIALS, /* security_flags */
SASL_FEAT_NEEDSERVERFQDN
| SASL_FEAT_WANT_CLIENT_FIRST
- | SASL_FEAT_ALLOWS_PROXY, /* features */
+ | SASL_FEAT_ALLOWS_PROXY
+ | SASL_FEAT_CHANNEL_BINDING, /* features */
gssapi_required_prompts, /* required_prompts */
GSS_C_NO_OID, /* glob_context */
&gssapi_client_mech_new, /* mech_new */
@@ -2213,6 +2232,7 @@ static sasl_client_plug_t gssapi_client_plugins[] =
SASL_FEAT_NEEDSERVERFQDN
| SASL_FEAT_WANT_CLIENT_FIRST
| SASL_FEAT_ALLOWS_PROXY
+ | SASL_FEAT_CHANNEL_BINDING
| SASL_FEAT_SUPPORTS_HTTP, /* features */
gssapi_required_prompts, /* required_prompts */
&gss_spnego_oid, /* glob_context */
diff --git a/tests/runtests.py b/tests/runtests.py
index f645adf..fc9cf24 100755
--- a/tests/runtests.py
+++ b/tests/runtests.py
@@ -1,6 +1,7 @@
#!/usr/bin/python3
import argparse
+import base64
import os
import shutil
import signal
@@ -126,14 +127,7 @@ def setup_kdc(testdir, env):
return kdc, env
-
-def gssapi_tests(testdir):
- """ SASL/GSSAPI Tests """
- env = setup_socket_wrappers(testdir)
- kdc, kenv = setup_kdc(testdir, env)
- #print("KDC: {}, ENV: {}".format(kdc, kenv))
- kenv['KRB5_TRACE'] = os.path.join(testdir, 'trace.log')
-
+def gssapi_basic_test(kenv):
try:
srv = subprocess.Popen(["../tests/t_gssapi_srv"],
stdout=subprocess.PIPE,
@@ -155,11 +149,94 @@ def gssapi_tests(testdir):
srv.returncode, srv.stderr.read().decode('utf-8')))
except Exception as e:
print("FAIL: {}".format(e))
+ return
+
+ print("PASS: CLI({}) SRV({})".format(
+ cli.stdout.read().decode('utf-8').strip(),
+ srv.stdout.read().decode('utf-8').strip()))
+
+def gssapi_channel_binding_test(kenv):
+ try:
+ bindings = base64.b64encode("MATCHING CBS".encode('utf-8'))
+ srv = subprocess.Popen(["../tests/t_gssapi_srv", "-c", bindings],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=kenv)
+ srv.stdout.readline() # Wait for srv to say it is ready
+ cli = subprocess.Popen(["../tests/t_gssapi_cli", "-c", bindings],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=kenv)
+ try:
+ cli.wait(timeout=5)
+ srv.wait(timeout=5)
+ except Exception as e:
+ print("Failed on {}".format(e));
+ cli.kill()
+ srv.kill()
+ if cli.returncode != 0 or srv.returncode != 0:
+ raise Exception("CLI ({}): {} --> SRV ({}): {}".format(
+ cli.returncode, cli.stderr.read().decode('utf-8'),
+ srv.returncode, srv.stderr.read().decode('utf-8')))
+ except Exception as e:
+ print("FAIL: {}".format(e))
+ return
print("PASS: CLI({}) SRV({})".format(
cli.stdout.read().decode('utf-8').strip(),
srv.stdout.read().decode('utf-8').strip()))
+def gssapi_channel_binding_mismatch_test(kenv):
+ result = "FAIL"
+ try:
+ bindings = base64.b64encode("SRV CBS".encode('utf-8'))
+ srv = subprocess.Popen(["../tests/t_gssapi_srv", "-c", bindings],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=kenv)
+ srv.stdout.readline() # Wait for srv to say it is ready
+ bindings = base64.b64encode("CLI CBS".encode('utf-8'))
+ cli = subprocess.Popen(["../tests/t_gssapi_cli", "-c", bindings],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=kenv)
+ try:
+ cli.wait(timeout=5)
+ srv.wait(timeout=5)
+ except Exception as e:
+ print("Failed on {}".format(e));
+ cli.kill()
+ srv.kill()
+ if cli.returncode != 0 or srv.returncode != 0:
+ cli_err = cli.stderr.read().decode('utf-8').strip()
+ srv_err = srv.stderr.read().decode('utf-8').strip()
+ if "authentication failure" in srv_err:
+ result = "PASS"
+ raise Exception("CLI ({}): {} --> SRV ({}): {}".format(
+ cli.returncode, cli_err, srv.returncode, srv_err))
+ except Exception as e:
+ print("{}: {}".format(result, e))
+ return
+
+ print("FAIL: This test should fail [CLI({}) SRV({})]".format(
+ cli.stdout.read().decode('utf-8').strip(),
+ srv.stdout.read().decode('utf-8').strip()))
+
+def gssapi_tests(testdir):
+ """ SASL/GSSAPI Tests """
+ env = setup_socket_wrappers(testdir)
+ kdc, kenv = setup_kdc(testdir, env)
+ #print("KDC: {}, ENV: {}".format(kdc, kenv))
+ kenv['KRB5_TRACE'] = os.path.join(testdir, 'trace.log')
+
+ print('GSSAPI BASIC:')
+ print(' ', end='')
+ gssapi_basic_test(kenv)
+
+ print('GSSAPI CHANNEL BINDING:')
+ print(' ', end='')
+ gssapi_channel_binding_test(kenv)
+
+ print('GSSAPI CHANNEL BINDING MISMTACH:')
+ print(' ', end='')
+ gssapi_channel_binding_mismatch_test(kenv)
+
os.killpg(kdc.pid, signal.SIGTERM)
diff --git a/tests/t_common.c b/tests/t_common.c
index 7168b2f..478e6a1 100644
--- a/tests/t_common.c
+++ b/tests/t_common.c
@@ -1,4 +1,5 @@
-/* TBD, add (C) */
+/* Copyright (C) Simo Sorce <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)
return SASL_OK;
}
+void parse_cb(sasl_channel_binding_t *cb, char *buf, unsigned max, char *in)
+{
+ unsigned len;
+ int r;
+ r = sasl_decode64(in, strlen(in), buf, max, &len);
+ if (r != SASL_OK) {
+ saslerr(r, "failed to parse channel bindings");
+ exit(-1);
+ }
+ cb->name = "TEST BINDINGS";
+ cb->critical = 0;
+ cb->data = (unsigned char *)buf;
+ cb->len = len;
+}
diff --git a/tests/t_common.h b/tests/t_common.h
index 4ee1976..a10def1 100644
--- a/tests/t_common.h
+++ b/tests/t_common.h
@@ -1,4 +1,5 @@
-/* TBD, add (C) */
+/* Copyright (C) Simo Sorce <simo@redhat.com>
+ * See COPYING file for License */
#include "config.h"
@@ -7,9 +8,11 @@
#include <sys/socket.h>
#include <sasl.h>
+#include <saslutil.h>
void s_error(const char *hdr, ssize_t ret, ssize_t len, int err);
void send_string(int sd, const char *s, unsigned int l);
void recv_string(int sd, char *buf, unsigned int *buflen);
void saslerr(int why, const char *what);
int getpath(void *context __attribute__((unused)), const char **path);
+void parse_cb(sasl_channel_binding_t *cb, char *buf, unsigned max, char *in);
diff --git a/tests/t_gssapi_cli.c b/tests/t_gssapi_cli.c
index c833c05..a44a3f5 100644
--- 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 @@
#include <arpa/inet.h>
#include <saslplug.h>
+#include <saslutil.h>
static int setup_socket(void)
{
@@ -32,7 +34,7 @@ static int setup_socket(void)
return sock;
}
-int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
+int main(int argc, char *argv[])
{
sasl_callback_t callbacks[2] = {};
char buf[8192];
@@ -40,8 +42,20 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
sasl_conn_t *conn;
const char *data;
unsigned int len;
+ sasl_channel_binding_t cb = {0};
+ char cb_buf[256];
int sd;
- int r;
+ int c, r;
+
+ while ((c = getopt(argc, argv, "c:")) != EOF) {
+ switch (c) {
+ case 'c':
+ parse_cb(&cb, cb_buf, 256, optarg);
+ break;
+ default:
+ break;
+ }
+ }
/* initialize the sasl library */
callbacks[0].id = SASL_CB_GETPATH;
@@ -60,6 +74,10 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
exit(-1);
}
+ if (cb.name) {
+ sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb);
+ }
+
r = sasl_client_start(conn, "GSSAPI", NULL, &data, &len, &chosenmech);
if (r != SASL_OK && r != SASL_CONTINUE) {
saslerr(r, "starting SASL negotiation");
diff --git a/tests/t_gssapi_srv.c b/tests/t_gssapi_srv.c
index 29f538d..ef1217f 100644
--- 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)
return sd;
}
-int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
+int main(int argc, char *argv[])
{
sasl_callback_t callbacks[2] = {};
char buf[8192];
sasl_conn_t *conn;
const char *data;
unsigned int len;
+ sasl_channel_binding_t cb = {0};
+ unsigned char cb_buf[256];
int sd;
- int r;
+ int c, r;
+
+ while ((c = getopt(argc, argv, "c:")) != EOF) {
+ switch (c) {
+ case 'c':
+ parse_cb(&cb, cb_buf, 256, optarg);
+ break;
+ default:
+ break;
+ }
+ }
+
/* initialize the sasl library */
callbacks[0].id = SASL_CB_GETPATH;
@@ -72,6 +86,10 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
exit(-1);
}
+ if (cb.name) {
+ sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb);
+ }
+
sd = setup_socket();
len = 8192;
--
2.18.2

View File

@ -0,0 +1,641 @@
From 82e299e970461c153a036bb1fbc84e808f926e12 Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Tue, 5 May 2020 14:06:57 -0400
Subject: [PATCH] Add basic test infrastructure
First test is for SASL/GSSAPI
Backport of upstream commit id:
18ff41d5d18f61c2ded7235dad1d9618aa84784b
Signed-off-by: Simo Sorce <simo@redhat.com>
---
Makefile.am | 2 +-
configure.ac | 3 +-
tests/Makefile.am | 79 +++++++++++++++++++
tests/runtests.py | 179 +++++++++++++++++++++++++++++++++++++++++++
tests/t_common.c | 68 ++++++++++++++++
tests/t_common.h | 15 ++++
tests/t_gssapi_cli.c | 95 +++++++++++++++++++++++
tests/t_gssapi_srv.c | 111 +++++++++++++++++++++++++++
8 files changed, 550 insertions(+), 2 deletions(-)
create mode 100644 tests/Makefile.am
create mode 100755 tests/runtests.py
create mode 100644 tests/t_common.c
create mode 100644 tests/t_common.h
create mode 100644 tests/t_gssapi_cli.c
create mode 100644 tests/t_gssapi_srv.c
diff --git a/Makefile.am b/Makefile.am
index 83dae6f..fc24509 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -70,7 +70,7 @@ else
INSTALLOSX =
endif
-SUBDIRS=include sasldb common lib plugins utils $(PWC) $(SAM) $(JAV) $(SAD)
+SUBDIRS=include sasldb common lib plugins utils $(PWC) $(SAM) $(JAV) $(SAD) tests
EXTRA_DIST=config doc docsrc win32 mac dlcompat-20010505 NTMakefile \
INSTALL.TXT libsasl2.pc.in
diff --git a/configure.ac b/configure.ac
index ca5936a..c1d2182 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1575,7 +1575,8 @@ java/javax/Makefile
java/javax/security/Makefile
java/javax/security/auth/Makefile
java/javax/security/auth/callback/Makefile
-pwcheck/Makefile)
+pwcheck/Makefile
+tests/Makefile)
AC_MSG_NOTICE([
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644
index 0000000..1edf010
--- /dev/null
+++ b/tests/Makefile.am
@@ -0,0 +1,79 @@
+# Makefile.am -- automake input for cyrus-sasl tests
+# Simo Sorce
+#
+################################################################
+# Copyright (c) 2000 Carnegie Mellon University. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# 3. The name "Carnegie Mellon University" must not be used to
+# endorse or promote products derived from this software without
+# prior written permission. For permission or any other legal
+# details, please contact
+# Office of Technology Transfer
+# Carnegie Mellon University
+# 5000 Forbes Avenue
+# Pittsburgh, PA 15213-3890
+# (412) 268-4387, fax: (412) 268-7395
+# tech-transfer@andrew.cmu.edu
+#
+# 4. Redistributions of any form whatsoever must retain the following
+# acknowledgment:
+# "This product includes software developed by Computing Services
+# at Carnegie Mellon University (http://www.cmu.edu/computing/)."
+#
+# CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+# AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+################################################################
+
+AM_CPPFLAGS=-I$(top_srcdir)/include -DPLUGINDIR='"${top_srcdir}/plugins/.libs"'
+
+COMMON_LDADD = ../lib/libsasl2.la $(GSSAPIBASE_LIBS) $(GSSAPI_LIBS) $(LIB_SOCKET)
+
+t_gssapi_cli_SOURCES = \
+ t_common.c \
+ t_gssapi_cli.c
+
+t_gssapi_cli_LDADD = $(COMMON_LDADD)
+
+t_gssapi_srv_SOURCES = \
+ t_common.c \
+ t_gssapi_srv.c
+
+t_gssapi_srv_LDADD = $(COMMON_LDADD)
+
+check_PROGRAMS = \
+ t_gssapi_cli \
+ t_gssapi_srv \
+ $(NULL)
+
+noinst_PROGRAMS = $(check_PROGRAMS)
+
+EXTRA_DIST = \
+ runtests.py \
+ $(NULL)
+
+all: $(check_PROGRAMS)
+
+check:
+if MACOSX
+# skip Mac OSX for now
+else
+ $(srcdir)/runtests.py $(CHECKARGS)
+endif
diff --git a/tests/runtests.py b/tests/runtests.py
new file mode 100755
index 0000000..f645adf
--- /dev/null
+++ b/tests/runtests.py
@@ -0,0 +1,179 @@
+#!/usr/bin/python3
+
+import argparse
+import os
+import shutil
+import signal
+import subprocess
+import time
+from string import Template
+
+
+def setup_socket_wrappers(testdir):
+ """ Try to set up socket wrappers """
+ wrapdir = os.path.join(testdir, 'w')
+ os.makedirs(wrapdir)
+
+ wrappers = subprocess.Popen(['pkg-config', '--exists', 'socket_wrapper'])
+ wrappers.wait()
+ if wrappers.returncode != 0:
+ raise Exception('Socket Wrappers not available')
+
+ wrappers = subprocess.Popen(['pkg-config', '--exists', 'nss_wrapper'])
+ wrappers.wait()
+ if wrappers.returncode != 0:
+ raise Exception('NSS Wrappers not available')
+
+ hosts = os.path.join(wrapdir, 'hosts')
+ with open(hosts, 'w+') as conffile:
+ conffile.write('127.0.0.9 host.realm.test')
+
+ return {'LD_PRELOAD': 'libsocket_wrapper.so libnss_wrapper.so',
+ 'SOCKET_WRAPPER_DIR': wrapdir,
+ 'SOCKET_WRAPPER_DEFAULT_IFACE': '9',
+ 'NSS_WRAPPER_HOSTNAME': 'host.realm.test',
+ 'NSS_WRAPPER_HOSTS': hosts}
+
+
+KERBEROS_CONF = '''
+[libdefaults]
+ default_realm = REALM.TEST
+ dns_lookup_realm = false
+ dns_lookup_kdc = false
+ rdns = false
+ ticket_lifetime = 24h
+ forwardable = yes
+ default_ccache_name = FILE://${TESTDIR}/ccache
+ udp_preference_limit = 1
+
+[domain_realm]
+ .realm.test = REALM.TEST
+ realm.test = REALM.TEST
+
+[realms]
+ REALM.TEST = {
+ kdc = 127.0.0.9
+ admin_server = 127.0.0.9
+ acl_file = ${TESTDIR}/kadm.acl
+ dict_file = /usr/share/dict/words
+ admin_keytab = ${TESTDIR}/kadm.keytab
+ database_name = ${TESTDIR}/kdc.db
+ key_stash_file = ${TESTDIR}/kdc.stash
+ }
+
+[kdcdefaults]
+ kdc_ports = 88
+ kdc_tcp_ports = 88
+
+[logging]
+ kdc = FILE:${TESTDIR}/kdc.log
+ admin_server = FILE:${TESTDIR}/kadm.log
+ default = FILE:${TESTDIR}/krb5.log
+'''
+
+
+def setup_kdc(testdir, env):
+ """ Setup KDC and start process """
+ krbconf = os.path.join(testdir, 'krb.conf')
+ env['KRB5_CONFIG'] = krbconf
+
+ kenv = {'KRB5_KDC_PROFILE': krbconf,
+ 'PATH': '/sbin:/bin:/usr/sbin:/usr/bin'}
+ kenv.update(env)
+
+ # KDC/KRB5 CONFIG
+ templ = Template(KERBEROS_CONF)
+ text = templ.substitute({'TESTDIR': testdir})
+ with open(krbconf, 'w+') as conffile:
+ conffile.write(text)
+
+ testlog = os.path.join(testdir, 'kdc.log')
+ log = open(testlog, 'a')
+
+ subprocess.check_call([
+ "kdb5_util", "create",
+ "-r", "REALM.TEST", "-s", "-P", "password"
+ ], stdout=log, stderr=log, env=kenv, timeout=5)
+
+ kdc = subprocess.Popen(['krb5kdc', '-n'], env=kenv, preexec_fn=os.setsid)
+ time.sleep(5)
+
+ # Add a user and genrate a keytab
+ keytab = os.path.join(testdir, "user.keytab")
+ subprocess.check_call([
+ "kadmin.local", "-q",
+ "addprinc -randkey user"
+ ], stdout=log, stderr=log, env=kenv, timeout=5)
+
+ subprocess.check_call([
+ "kadmin.local", "-q",
+ "ktadd -k {} user".format(keytab)
+ ], stdout=log, stderr=log, env=kenv, timeout=5)
+ env['KRB5_CLIENT_KTNAME'] = keytab
+
+ # Add a service and genrate a keytab
+ keytab = os.path.join(testdir, "test.keytab")
+ subprocess.check_call([
+ "kadmin.local", "-q",
+ "addprinc -randkey test/host.realm.test"
+ ], stdout=log, stderr=log, env=kenv, timeout=5)
+
+ subprocess.check_call([
+ "kadmin.local", "-q",
+ "ktadd -k {} test/host.realm.test".format(keytab)
+ ], stdout=log, stderr=log, env=kenv, timeout=5)
+ env['KRB5_KTNAME'] = keytab
+
+ return kdc, env
+
+
+def gssapi_tests(testdir):
+ """ SASL/GSSAPI Tests """
+ env = setup_socket_wrappers(testdir)
+ kdc, kenv = setup_kdc(testdir, env)
+ #print("KDC: {}, ENV: {}".format(kdc, kenv))
+ kenv['KRB5_TRACE'] = os.path.join(testdir, 'trace.log')
+
+ try:
+ srv = subprocess.Popen(["../tests/t_gssapi_srv"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=kenv)
+ srv.stdout.readline() # Wait for srv to say it is ready
+ cli = subprocess.Popen(["../tests/t_gssapi_cli"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=kenv)
+ try:
+ cli.wait(timeout=5)
+ srv.wait(timeout=5)
+ except Exception as e:
+ print("Failed on {}".format(e));
+ cli.kill()
+ srv.kill()
+ if cli.returncode != 0 or srv.returncode != 0:
+ raise Exception("CLI ({}): {} --> SRV ({}): {}".format(
+ cli.returncode, cli.stderr.read().decode('utf-8'),
+ srv.returncode, srv.stderr.read().decode('utf-8')))
+ except Exception as e:
+ print("FAIL: {}".format(e))
+
+ print("PASS: CLI({}) SRV({})".format(
+ cli.stdout.read().decode('utf-8').strip(),
+ srv.stdout.read().decode('utf-8').strip()))
+
+ os.killpg(kdc.pid, signal.SIGTERM)
+
+
+if __name__ == "__main__":
+
+ P = argparse.ArgumentParser(description='Cyrus SASL Tests')
+ P.add_argument('--testdir', default=os.path.join(os.getcwd(), '.tests'),
+ help="Directory for running tests")
+ A = vars(P.parse_args())
+
+ T = A['testdir']
+
+ if os.path.exists(T):
+ shutil.rmtree(T)
+ os.makedirs(T)
+
+ gssapi_tests(T)
diff --git a/tests/t_common.c b/tests/t_common.c
new file mode 100644
index 0000000..7168b2f
--- /dev/null
+++ b/tests/t_common.c
@@ -0,0 +1,68 @@
+/* TBD, add (C) */
+
+#include <t_common.h>
+
+void s_error(const char *hdr, ssize_t ret, ssize_t len, int err)
+{
+ fprintf(stderr, "%s l:%ld/%ld [%d] %s",
+ hdr, ret, len, err, strerror(err));
+ exit(-1);
+}
+
+void send_string(int sd, const char *s, unsigned int l)
+{
+ ssize_t ret;
+
+fprintf(stderr, "s:%u ", l);
+fflush(stderr);
+
+ ret = send(sd, &l, sizeof(l), 0);
+ if (ret != sizeof(l)) s_error("send size", ret, sizeof(l), errno);
+
+ if (l == 0) return;
+
+ ret = send(sd, s, l, 0);
+ if (ret != l) s_error("send data", ret, l, errno);
+}
+
+void recv_string(int sd, char *buf, unsigned int *buflen)
+{
+ unsigned int l;
+ ssize_t ret;
+
+ ret = recv(sd, &l, sizeof(l), MSG_WAITALL);
+ if (ret != sizeof(l)) s_error("recv size", ret, sizeof(l), errno);
+
+ if (l == 0) {
+fprintf(stderr, "r:0 ");
+fflush(stderr);
+ *buflen = 0;
+ return;
+ }
+
+ if (*buflen < l) s_error("recv len", l, *buflen, E2BIG);
+
+ ret = recv(sd, buf, l, 0);
+ if (ret != l) s_error("recv data", ret, l, errno);
+
+fprintf(stderr, "r:%ld ", ret);
+fflush(stderr);
+ *buflen = ret;
+}
+
+void saslerr(int why, const char *what)
+{
+ fprintf(stderr, "%s: %s", what, sasl_errstring(why, NULL, NULL));
+}
+
+int getpath(void *context __attribute__((unused)), const char **path)
+{
+ if (! path) {
+ return SASL_BADPARAM;
+ }
+
+ *path = PLUGINDIR;
+ return SASL_OK;
+}
+
+
diff --git a/tests/t_common.h b/tests/t_common.h
new file mode 100644
index 0000000..4ee1976
--- /dev/null
+++ b/tests/t_common.h
@@ -0,0 +1,15 @@
+/* TBD, add (C) */
+
+#include "config.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/socket.h>
+
+#include <sasl.h>
+
+void s_error(const char *hdr, ssize_t ret, ssize_t len, int err);
+void send_string(int sd, const char *s, unsigned int l);
+void recv_string(int sd, char *buf, unsigned int *buflen);
+void saslerr(int why, const char *what);
+int getpath(void *context __attribute__((unused)), const char **path);
diff --git a/tests/t_gssapi_cli.c b/tests/t_gssapi_cli.c
new file mode 100644
index 0000000..c833c05
--- /dev/null
+++ b/tests/t_gssapi_cli.c
@@ -0,0 +1,95 @@
+/* TBD, add (C) */
+
+#include "t_common.h"
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <string.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <arpa/inet.h>
+#include <saslplug.h>
+
+static int setup_socket(void)
+{
+ struct sockaddr_in addr;
+ int sock, ret;
+
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (sock < 0) s_error("socket", 0, 0, errno);
+
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = inet_addr("127.0.0.9");
+ addr.sin_port = htons(9000);
+
+ ret = connect(sock, (struct sockaddr *)&addr, sizeof(addr));
+ if (ret != 0) s_error("connect", 0, 0, errno);
+
+ return sock;
+}
+
+int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
+{
+ sasl_callback_t callbacks[2] = {};
+ char buf[8192];
+ const char *chosenmech;
+ sasl_conn_t *conn;
+ const char *data;
+ unsigned int len;
+ int sd;
+ int r;
+
+ /* initialize the sasl library */
+ callbacks[0].id = SASL_CB_GETPATH;
+ callbacks[0].proc = (sasl_callback_ft)&getpath;
+ callbacks[0].context = NULL;
+ callbacks[1].id = SASL_CB_LIST_END;
+ callbacks[1].proc = NULL;
+ callbacks[1].context = NULL;
+
+ r = sasl_client_init(callbacks);
+ if (r != SASL_OK) exit(-1);
+
+ r = sasl_client_new("test", "host.realm.test", NULL, NULL, NULL, 0, &conn);
+ if (r != SASL_OK) {
+ saslerr(r, "allocating connection state");
+ exit(-1);
+ }
+
+ r = sasl_client_start(conn, "GSSAPI", NULL, &data, &len, &chosenmech);
+ if (r != SASL_OK && r != SASL_CONTINUE) {
+ saslerr(r, "starting SASL negotiation");
+ printf("\n%s\n", sasl_errdetail(conn));
+ exit(-1);
+ }
+
+ sd = setup_socket();
+
+ while (r == SASL_CONTINUE) {
+ send_string(sd, data, len);
+ len = 8192;
+ recv_string(sd, buf, &len);
+
+ r = sasl_client_step(conn, buf, len, NULL, &data, &len);
+ if (r != SASL_OK && r != SASL_CONTINUE) {
+ saslerr(r, "performing SASL negotiation");
+ printf("\n%s\n", sasl_errdetail(conn));
+ exit(-1);
+ }
+ }
+
+ if (r != SASL_OK) exit(-1);
+
+ if (len > 0) {
+ send_string(sd, data, len);
+ }
+
+ fprintf(stdout, "DONE\n");
+ fflush(stdout);
+ return 0;
+}
+
diff --git a/tests/t_gssapi_srv.c b/tests/t_gssapi_srv.c
new file mode 100644
index 0000000..29f538d
--- /dev/null
+++ b/tests/t_gssapi_srv.c
@@ -0,0 +1,111 @@
+/* TBD, add (C) */
+
+#include "t_common.h"
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <string.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <arpa/inet.h>
+#include <saslplug.h>
+
+static int setup_socket(void)
+{
+ struct sockaddr_in addr;
+ int sock, ret, sd;
+
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (sock < 0) s_error("socket", 0, 0, errno);
+
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = inet_addr("127.0.0.9");
+ addr.sin_port = htons(9000);
+
+ ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr));
+ if (ret != 0) s_error("bind", 0, 0, errno);
+
+ ret = listen(sock, 1);
+ if (ret != 0) s_error("listen", 0, 0, errno);
+
+ /* signal we are ready */
+ fprintf(stdout, "READY\n");
+ fflush(stdout);
+
+ /* block until the client connects */
+ sd = accept(sock, NULL, NULL);
+ if (sd < 0) s_error("accept", 0, 0, errno);
+
+ close(sock);
+ return sd;
+}
+
+int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
+{
+ sasl_callback_t callbacks[2] = {};
+ char buf[8192];
+ sasl_conn_t *conn;
+ const char *data;
+ unsigned int len;
+ int sd;
+ int r;
+
+ /* initialize the sasl library */
+ callbacks[0].id = SASL_CB_GETPATH;
+ callbacks[0].proc = (sasl_callback_ft)&getpath;
+ callbacks[0].context = NULL;
+ callbacks[1].id = SASL_CB_LIST_END;
+ callbacks[1].proc = NULL;
+ callbacks[1].context = NULL;
+
+ r = sasl_server_init(callbacks, "t_gssapi_srv");
+ if (r != SASL_OK) exit(-1);
+
+ r = sasl_server_new("test", "host.realm.test", NULL, NULL, NULL,
+ callbacks, 0, &conn);
+ if (r != SASL_OK) {
+ saslerr(r, "allocating connection state");
+ exit(-1);
+ }
+
+ sd = setup_socket();
+
+ len = 8192;
+ recv_string(sd, buf, &len);
+
+ r = sasl_server_start(conn, "GSSAPI", buf, len, &data, &len);
+ if (r != SASL_OK && r != SASL_CONTINUE) {
+ saslerr(r, "starting SASL negotiation");
+ printf("\n%s\n", sasl_errdetail(conn));
+ exit(-1);
+ }
+
+ while (r == SASL_CONTINUE) {
+ send_string(sd, data, len);
+ len = 8192;
+ recv_string(sd, buf, &len);
+
+ r = sasl_server_step(conn, buf, len, &data, &len);
+ if (r != SASL_OK && r != SASL_CONTINUE) {
+ saslerr(r, "performing SASL negotiation");
+ printf("\n%s\n", sasl_errdetail(conn));
+ exit(-1);
+ }
+
+ }
+
+ if (r != SASL_OK) exit(-1);
+
+ if (len > 0) {
+ send_string(sd, data, len);
+ }
+
+ fprintf(stdout, "DONE\n");
+ fflush(stdout);
+ return 0;
+}
+
--
2.18.2

View File

@ -0,0 +1,411 @@
diff -Nru cyrus-sasl-2.1.27/tests/runtests.py cyrus-sasl-2.1.27-beldmit/tests/runtests.py
--- cyrus-sasl-2.1.27/tests/runtests.py 2020-12-23 14:31:35.564537485 +0100
+++ cyrus-sasl-2.1.27-beldmit/tests/runtests.py 2020-12-23 14:30:46.933219377 +0100
@@ -313,6 +313,99 @@
return err
+def setup_plain(testdir):
+ """ Create sasldb file """
+ sasldbfile = os.path.join(testdir, 'testsasldb.db')
+
+ sasldbenv = {'SASL_PATH': os.path.join(testdir, '../../plugins/.libs'),
+ 'LD_LIBRARY_PATH' : os.path.join(testdir, '../../lib/.libs')}
+
+ passwdprog = os.path.join(testdir, '../../utils/saslpasswd2')
+
+ echo = subprocess.Popen(('echo', '1234567'), stdout=subprocess.PIPE)
+ subprocess.check_call([
+ passwdprog, "-f", sasldbfile, "-c", "test",
+ "-u", "host.realm.test", "-p"
+ ], stdin=echo.stdout, env=sasldbenv, timeout=5)
+
+ return (sasldbfile, sasldbenv)
+
+def plain_test(sasldbfile, sasldbenv):
+ try:
+ srv = subprocess.Popen(["../tests/t_gssapi_srv", "-P", sasldbfile],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=sasldbenv)
+ srv.stdout.readline() # Wait for srv to say it is ready
+ cli = subprocess.Popen(["../tests/t_gssapi_cli", "-P", "1234567"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=sasldbenv)
+ try:
+ cli.wait(timeout=5)
+ srv.wait(timeout=5)
+ except Exception as e:
+ print("Failed on {}".format(e));
+ cli.kill()
+ srv.kill()
+ if cli.returncode != 0 or srv.returncode != 0:
+ raise Exception("CLI ({}): {} --> SRV ({}): {}".format(
+ cli.returncode, cli.stderr.read().decode('utf-8'),
+ srv.returncode, srv.stderr.read().decode('utf-8')))
+ except Exception as e:
+ print("FAIL: {}".format(e))
+ return 1
+
+ print("PASS: PLAIN CLI({}) SRV({})".format(
+ cli.stdout.read().decode('utf-8').strip(),
+ srv.stdout.read().decode('utf-8').strip()))
+ return 0
+
+def plain_mismatch_test(sasldbfile, sasldbenv):
+ result = "FAIL"
+ try:
+ srv = subprocess.Popen(["../tests/t_gssapi_srv", "-P", sasldbfile],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=sasldbenv)
+ srv.stdout.readline() # Wait for srv to say it is ready
+ bindings = base64.b64encode("CLI CBS".encode('utf-8'))
+ cli = subprocess.Popen(["../tests/t_gssapi_cli", "-P", "12345678"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=sasldbenv)
+ try:
+ cli.wait(timeout=5)
+ srv.wait(timeout=5)
+ except Exception as e:
+ print("Failed on {}".format(e));
+ cli.kill()
+ srv.kill()
+ if cli.returncode != 0 or srv.returncode != 0:
+ cli_err = cli.stderr.read().decode('utf-8').strip()
+ srv_err = srv.stderr.read().decode('utf-8').strip()
+ if "authentication failure" in srv_err:
+ result = "PASS"
+ raise Exception("CLI ({}): {} --> SRV ({}): {}".format(
+ cli.returncode, cli_err, srv.returncode, srv_err))
+ except Exception as e:
+ print("{}: {}".format(result, e))
+ return 0
+
+ print("FAIL: This test should fail [CLI({}) SRV({})]".format(
+ cli.stdout.read().decode('utf-8').strip(),
+ srv.stdout.read().decode('utf-8').strip()))
+ return 1
+
+def plain_tests(testdir):
+ err = 0
+ sasldbfile, sasldbenv = setup_plain(testdir)
+ #print("DB file: {}, ENV: {}".format(sasldbfile, sasldbenv))
+ print('SASLDB PLAIN:')
+ print(' ', end='')
+ err += plain_test(sasldbfile, sasldbenv)
+
+ print('SASLDB PLAIN PASSWORD MISMATCH:')
+ print(' ', end='')
+ err += plain_mismatch_test(sasldbfile, sasldbenv)
+
+ return err
if __name__ == "__main__":
@@ -329,5 +422,9 @@
err = gssapi_tests(T)
if err != 0:
- print('{} test(s) FAILED'.format(err))
+ print('{} GSSAPI test(s) FAILED'.format(err))
+
+ err = plain_tests(T)
+ if err != 0:
+ print('{} PLAIN test(s) FAILED'.format(err))
sys.exit(-1)
diff -Nru cyrus-sasl-2.1.27/tests/t_gssapi_cli.c cyrus-sasl-2.1.27-beldmit/tests/t_gssapi_cli.c
--- cyrus-sasl-2.1.27/tests/t_gssapi_cli.c 2020-12-23 14:31:35.564537485 +0100
+++ cyrus-sasl-2.1.27-beldmit/tests/t_gssapi_cli.c 2021-01-06 11:26:15.460662537 +0100
@@ -16,6 +16,8 @@
#include <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);

View File

@ -0,0 +1,435 @@
From 49e965f41257a0ed299c58a7cf1c120ddf944aaa Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Tue, 5 May 2020 14:51:36 -0400
Subject: [PATCH] Add support for setting max ssf 0 to GSS-SPNEGO
Bacport form this proposed PR (still open at bacport time):
https://github.com/cyrusimap/cyrus-sasl/pull/603
Signed-off-by: Simo Sorce <simo@redhat.com>
---
m4/sasl2.m4 | 13 +++++++
plugins/gssapi.c | 44 ++++++++++++++++++++-
tests/runtests.py | 91 ++++++++++++++++++++++++++++++++++++++++----
tests/t_common.c | 13 ++++---
tests/t_common.h | 3 +-
tests/t_gssapi_cli.c | 25 ++++++++++--
tests/t_gssapi_srv.c | 28 +++++++++++---
7 files changed, 194 insertions(+), 23 deletions(-)
diff --git a/m4/sasl2.m4 b/m4/sasl2.m4
index 56e0504..6effe99 100644
--- a/m4/sasl2.m4
+++ b/m4/sasl2.m4
@@ -287,6 +287,19 @@ if test "$gssapi" != no; then
AC_CHECK_FUNCS(gss_oid_equal)
LIBS="$cmu_save_LIBS"
+ cmu_save_LIBS="$LIBS"
+ LIBS="$LIBS $GSSAPIBASE_LIBS"
+ if test "$ac_cv_header_gssapi_gssapi_krb5_h" = "yes"; then
+ AC_CHECK_DECL(GSS_KRB5_CRED_NO_CI_FLAGS_X,
+ [AC_DEFINE(HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X,1,
+ [Define if your GSSAPI implementation supports GSS_KRB5_CRED_NO_CI_FLAGS_X])],,
+ [
+ AC_INCLUDES_DEFAULT
+ #include <gssapi/gssapi_krb5.h>
+ ])
+ fi
+ LIBS="$cmu_save_LIBS"
+
cmu_save_LIBS="$LIBS"
LIBS="$LIBS $GSSAPIBASE_LIBS"
AC_CHECK_FUNCS(gss_get_name_attribute)
diff --git a/plugins/gssapi.c b/plugins/gssapi.c
index 5d900c5..7480316 100644
--- a/plugins/gssapi.c
+++ b/plugins/gssapi.c
@@ -1783,7 +1783,49 @@ static int gssapi_client_mech_step(void *conn_context,
/* We want to try for privacy */
req_flags |= GSS_C_CONF_FLAG;
}
- }
+#ifdef HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X
+ /* The krb5 mechanism automatically adds INTEG and CONF flags even when
+ * not specified, this has the effect of rendering explicit requests
+ * of no confidentiality and integrity via setting maxssf 0 moot.
+ * However to interoperate with Windows machines it needs to be
+ * possible to unset these flags as Windows machines refuse to allow
+ * two layers (say TLS and GSSAPI) to both provide these services.
+ * So if we do not suppress these flags a SASL/GSS-SPNEGO negotiation
+ * over, say, LDAPS will fail against Windows Servers */
+ } else if (params->props.max_ssf == 0) {
+ gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER;
+ if (client_creds == GSS_C_NO_CREDENTIAL) {
+ gss_OID_set_desc mechs = { 0 };
+ gss_OID_set desired_mechs = GSS_C_NO_OID_SET;
+ if (text->mech_type != GSS_C_NO_OID) {
+ mechs.count = 1;
+ mechs.elements = text->mech_type;
+ desired_mechs = &mechs;
+ }
+
+ maj_stat = gss_acquire_cred(&min_stat, GSS_C_NO_NAME,
+ GSS_C_INDEFINITE, desired_mechs,
+ GSS_C_INITIATE,
+ &text->client_creds, NULL, NULL);
+ if (GSS_ERROR(maj_stat)) {
+ sasl_gss_seterror(text->utils, maj_stat, min_stat);
+ sasl_gss_free_context_contents(text);
+ return SASL_FAIL;
+ }
+ client_creds = text->client_creds;
+ }
+
+ maj_stat = gss_set_cred_option(&min_stat, &client_creds,
+ (gss_OID)GSS_KRB5_CRED_NO_CI_FLAGS_X,
+ &empty_buffer);
+ if (GSS_ERROR(maj_stat)) {
+ sasl_gss_seterror(text->utils, maj_stat, min_stat);
+ sasl_gss_free_context_contents(text);
+ return SASL_FAIL;
+ }
+#endif
+ }
+
if (params->props.security_flags & SASL_SEC_PASS_CREDENTIALS) {
req_flags = req_flags | GSS_C_DELEG_FLAG;
diff --git a/tests/runtests.py b/tests/runtests.py
index fc9cf24..4106401 100755
--- a/tests/runtests.py
+++ b/tests/runtests.py
@@ -6,6 +6,7 @@ import os
import shutil
import signal
import subprocess
+import sys
import time
from string import Template
@@ -149,11 +150,12 @@ def gssapi_basic_test(kenv):
srv.returncode, srv.stderr.read().decode('utf-8')))
except Exception as e:
print("FAIL: {}".format(e))
- return
+ return 1
print("PASS: CLI({}) SRV({})".format(
cli.stdout.read().decode('utf-8').strip(),
srv.stdout.read().decode('utf-8').strip()))
+ return 0
def gssapi_channel_binding_test(kenv):
try:
@@ -178,11 +180,12 @@ def gssapi_channel_binding_test(kenv):
srv.returncode, srv.stderr.read().decode('utf-8')))
except Exception as e:
print("FAIL: {}".format(e))
- return
+ return 1
print("PASS: CLI({}) SRV({})".format(
cli.stdout.read().decode('utf-8').strip(),
srv.stdout.read().decode('utf-8').strip()))
+ return 0
def gssapi_channel_binding_mismatch_test(kenv):
result = "FAIL"
@@ -212,11 +215,70 @@ def gssapi_channel_binding_mismatch_test(kenv):
cli.returncode, cli_err, srv.returncode, srv_err))
except Exception as e:
print("{}: {}".format(result, e))
- return
+ return 0
print("FAIL: This test should fail [CLI({}) SRV({})]".format(
cli.stdout.read().decode('utf-8').strip(),
srv.stdout.read().decode('utf-8').strip()))
+ return 1
+
+def gss_spnego_basic_test(kenv):
+ try:
+ srv = subprocess.Popen(["../tests/t_gssapi_srv", "-N"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=kenv)
+ srv.stdout.readline() # Wait for srv to say it is ready
+ cli = subprocess.Popen(["../tests/t_gssapi_cli", "-N"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=kenv)
+ try:
+ cli.wait(timeout=5)
+ srv.wait(timeout=5)
+ except Exception as e:
+ print("Failed on {}".format(e));
+ cli.kill()
+ srv.kill()
+ if cli.returncode != 0 or srv.returncode != 0:
+ raise Exception("CLI ({}): {} --> SRV ({}): {}".format(
+ cli.returncode, cli.stderr.read().decode('utf-8'),
+ srv.returncode, srv.stderr.read().decode('utf-8')))
+ except Exception as e:
+ print("FAIL: {}".format(e))
+ return 1
+
+ print("PASS: CLI({}) SRV({})".format(
+ cli.stdout.read().decode('utf-8').strip(),
+ srv.stdout.read().decode('utf-8').strip()))
+ return 0
+
+def gss_spnego_zeromaxssf_test(kenv):
+ try:
+ srv = subprocess.Popen(["../tests/t_gssapi_srv", "-N", "-z"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=kenv)
+ srv.stdout.readline() # Wait for srv to say it is ready
+ cli = subprocess.Popen(["../tests/t_gssapi_cli", "-N", "-z"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, env=kenv)
+ try:
+ cli.wait(timeout=5)
+ srv.wait(timeout=5)
+ except Exception as e:
+ print("Failed on {}".format(e));
+ cli.kill()
+ srv.kill()
+ if cli.returncode != 0 or srv.returncode != 0:
+ raise Exception("CLI ({}): {} --> SRV ({}): {}".format(
+ cli.returncode, cli.stderr.read().decode('utf-8'),
+ srv.returncode, srv.stderr.read().decode('utf-8')))
+ except Exception as e:
+ print("FAIL: {}".format(e))
+ return 1
+
+ print("PASS: CLI({}) SRV({})".format(
+ cli.stdout.read().decode('utf-8').strip(),
+ srv.stdout.read().decode('utf-8').strip()))
+ return 0
def gssapi_tests(testdir):
""" SASL/GSSAPI Tests """
@@ -225,20 +287,32 @@ def gssapi_tests(testdir):
#print("KDC: {}, ENV: {}".format(kdc, kenv))
kenv['KRB5_TRACE'] = os.path.join(testdir, 'trace.log')
+ err = 0
+
print('GSSAPI BASIC:')
print(' ', end='')
- gssapi_basic_test(kenv)
+ err += gssapi_basic_test(kenv)
print('GSSAPI CHANNEL BINDING:')
print(' ', end='')
- gssapi_channel_binding_test(kenv)
+ err += gssapi_channel_binding_test(kenv)
print('GSSAPI CHANNEL BINDING MISMTACH:')
print(' ', end='')
- gssapi_channel_binding_mismatch_test(kenv)
+ err += gssapi_channel_binding_mismatch_test(kenv)
+
+ print('GSS-SPNEGO BASIC:')
+ print(' ', end='')
+ err += gss_spnego_basic_test(kenv)
+
+ print('GSS-SPNEGO 0 MAXSSF:')
+ print(' ', end='')
+ err += gss_spnego_zeromaxssf_test(kenv)
os.killpg(kdc.pid, signal.SIGTERM)
+ return err
+
if __name__ == "__main__":
@@ -253,4 +327,7 @@ if __name__ == "__main__":
shutil.rmtree(T)
os.makedirs(T)
- gssapi_tests(T)
+ err = gssapi_tests(T)
+ if err != 0:
+ print('{} test(s) FAILED'.format(err))
+ sys.exit(-1)
diff --git a/tests/t_common.c b/tests/t_common.c
index 478e6a1..f56098e 100644
--- a/tests/t_common.c
+++ b/tests/t_common.c
@@ -23,20 +23,21 @@ void send_string(int sd, const char *s, unsigned int l)
if (ret != l) s_error("send data", ret, l, errno);
}
-void recv_string(int sd, char *buf, unsigned int *buflen)
+void recv_string(int sd, char *buf, unsigned int *buflen, bool allow_eof)
{
+ unsigned int bufsize = *buflen;
unsigned int l;
ssize_t ret;
+ *buflen = 0;
+
ret = recv(sd, &l, sizeof(l), MSG_WAITALL);
+ if (allow_eof && ret == 0) return;
if (ret != sizeof(l)) s_error("recv size", ret, sizeof(l), errno);
- if (l == 0) {
- *buflen = 0;
- return;
- }
+ if (l == 0) return;
- if (*buflen < l) s_error("recv len", l, *buflen, E2BIG);
+ if (bufsize < l) s_error("recv len", l, bufsize, E2BIG);
ret = recv(sd, buf, l, 0);
if (ret != l) s_error("recv data", ret, l, errno);
diff --git a/tests/t_common.h b/tests/t_common.h
index a10def1..be24a53 100644
--- a/tests/t_common.h
+++ b/tests/t_common.h
@@ -4,6 +4,7 @@
#include "config.h"
#include <errno.h>
+#include <stdbool.h>
#include <stdio.h>
#include <sys/socket.h>
@@ -12,7 +13,7 @@
void s_error(const char *hdr, ssize_t ret, ssize_t len, int err);
void send_string(int sd, const char *s, unsigned int l);
-void recv_string(int sd, char *buf, unsigned int *buflen);
+void recv_string(int sd, char *buf, unsigned int *buflen, bool allow_eof);
void saslerr(int why, const char *what);
int getpath(void *context __attribute__((unused)), const char **path);
void parse_cb(sasl_channel_binding_t *cb, char *buf, unsigned max, char *in);
diff --git a/tests/t_gssapi_cli.c b/tests/t_gssapi_cli.c
index a44a3f5..d9eafe1 100644
--- a/tests/t_gssapi_cli.c
+++ b/tests/t_gssapi_cli.c
@@ -46,12 +46,21 @@ int main(int argc, char *argv[])
char cb_buf[256];
int sd;
int c, r;
+ const char *sasl_mech = "GSSAPI";
+ bool spnego = false;
+ bool zeromaxssf = false;
- while ((c = getopt(argc, argv, "c:")) != EOF) {
+ while ((c = getopt(argc, argv, "c:zN")) != EOF) {
switch (c) {
case 'c':
parse_cb(&cb, cb_buf, 256, optarg);
break;
+ case 'z':
+ zeromaxssf = true;
+ break;
+ case 'N':
+ spnego = true;
+ break;
default:
break;
}
@@ -78,7 +87,17 @@ int main(int argc, char *argv[])
sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb);
}
- r = sasl_client_start(conn, "GSSAPI", NULL, &data, &len, &chosenmech);
+ if (spnego) {
+ sasl_mech = "GSS-SPNEGO";
+ }
+
+ if (zeromaxssf) {
+ /* set all security properties to 0 including maxssf */
+ sasl_security_properties_t secprops = { 0 };
+ sasl_setprop(conn, SASL_SEC_PROPS, &secprops);
+ }
+
+ r = sasl_client_start(conn, sasl_mech, NULL, &data, &len, &chosenmech);
if (r != SASL_OK && r != SASL_CONTINUE) {
saslerr(r, "starting SASL negotiation");
printf("\n%s\n", sasl_errdetail(conn));
@@ -90,7 +109,7 @@ int main(int argc, char *argv[])
while (r == SASL_CONTINUE) {
send_string(sd, data, len);
len = 8192;
- recv_string(sd, buf, &len);
+ recv_string(sd, buf, &len, false);
r = sasl_client_step(conn, buf, len, NULL, &data, &len);
if (r != SASL_OK && r != SASL_CONTINUE) {
diff --git a/tests/t_gssapi_srv.c b/tests/t_gssapi_srv.c
index ef1217f..448a218 100644
--- a/tests/t_gssapi_srv.c
+++ b/tests/t_gssapi_srv.c
@@ -56,12 +56,21 @@ int main(int argc, char *argv[])
unsigned char cb_buf[256];
int sd;
int c, r;
+ const char *sasl_mech = "GSSAPI";
+ bool spnego = false;
+ bool zeromaxssf = false;
- while ((c = getopt(argc, argv, "c:")) != EOF) {
+ while ((c = getopt(argc, argv, "c:zN")) != EOF) {
switch (c) {
case 'c':
parse_cb(&cb, cb_buf, 256, optarg);
break;
+ case 'z':
+ zeromaxssf = true;
+ break;
+ case 'N':
+ spnego = true;
+ break;
default:
break;
}
@@ -90,12 +99,22 @@ int main(int argc, char *argv[])
sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb);
}
+ if (spnego) {
+ sasl_mech = "GSS-SPNEGO";
+ }
+
+ if (zeromaxssf) {
+ /* set all security properties to 0 including maxssf */
+ sasl_security_properties_t secprops = { 0 };
+ sasl_setprop(conn, SASL_SEC_PROPS, &secprops);
+ }
+
sd = setup_socket();
len = 8192;
- recv_string(sd, buf, &len);
+ recv_string(sd, buf, &len, false);
- r = sasl_server_start(conn, "GSSAPI", buf, len, &data, &len);
+ r = sasl_server_start(conn, sasl_mech, buf, len, &data, &len);
if (r != SASL_OK && r != SASL_CONTINUE) {
saslerr(r, "starting SASL negotiation");
printf("\n%s\n", sasl_errdetail(conn));
@@ -105,7 +124,7 @@ int main(int argc, char *argv[])
while (r == SASL_CONTINUE) {
send_string(sd, data, len);
len = 8192;
- recv_string(sd, buf, &len);
+ recv_string(sd, buf, &len, true);
r = sasl_server_step(conn, buf, len, &data, &len);
if (r != SASL_OK && r != SASL_CONTINUE) {
@@ -113,7 +132,6 @@ int main(int argc, char *argv[])
printf("\n%s\n", sasl_errdetail(conn));
exit(-1);
}
-
}
if (r != SASL_OK) exit(-1);
--
2.18.2

View File

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

View File

@ -0,0 +1,569 @@
diff -up cyrus-sasl-2.1.27/configure.ac.frombdb cyrus-sasl-2.1.27/configure.ac
--- cyrus-sasl-2.1.27/configure.ac.frombdb 2021-06-04 13:02:07.790112263 +0200
+++ cyrus-sasl-2.1.27/configure.ac 2021-06-04 13:02:07.798112327 +0200
@@ -1091,6 +1091,9 @@ AC_SUBST(SASL_STATIC_SRCS)
AC_SUBST(SASL_STATIC_OBJS)
AC_SUBST(SASL_STATIC_LIBS)
+CYRUS_BERKELEY_DB_STATIC_LIB()
+AC_SUBST(BDB_STATIC_LIBADD)
+
AC_ARG_WITH(plugindir, [ --with-plugindir=DIR set the directory where plugins will
be found [[LIBDIR/sasl2]] ],
plugindir=$withval,
diff -up cyrus-sasl-2.1.27/m4/berkdb.m4.frombdb cyrus-sasl-2.1.27/m4/berkdb.m4
--- cyrus-sasl-2.1.27/m4/berkdb.m4.frombdb 2016-01-29 18:35:35.000000000 +0100
+++ cyrus-sasl-2.1.27/m4/berkdb.m4 2021-06-04 13:02:07.798112327 +0200
@@ -286,3 +286,10 @@ AC_DEFUN([CYRUS_BERKELEY_DB_CHK],
CPPFLAGS=$cmu_save_CPPFLAGS
])
+
+AC_DEFUN([CYRUS_BERKELEY_DB_STATIC_LIB],
+[
+BDB_STATIC_LIBADD="/dev/null -lpthread"
+AC_CHECK_FILE([/usr/lib64/libdb-5.3.a],[BDB_STATIC_LIBADD="/usr/lib64/libdb-5.3.a -lpthread "],[])
+AC_CHECK_FILE([/usr/lib/libdb-5.3.a],[BDB_STATIC_LIBADD="/usr/lib/libdb-5.3.a -lpthread"],[])
+])
diff -up cyrus-sasl-2.1.27/m4/sasldb.m4.frombdb cyrus-sasl-2.1.27/m4/sasldb.m4
--- cyrus-sasl-2.1.27/m4/sasldb.m4.frombdb 2017-07-13 20:45:19.000000000 +0200
+++ cyrus-sasl-2.1.27/m4/sasldb.m4 2021-06-04 13:02:07.798112327 +0200
@@ -111,7 +111,7 @@ AC_MSG_RESULT($dblib)
SASL_DB_BACKEND="db_${dblib}.lo"
SASL_DB_BACKEND_STATIC="db_${dblib}.o allockey.o"
SASL_DB_BACKEND_STATIC_SRCS="\$(top_srcdir)/sasldb/db_${dblib}.c \$(top_srcdir)/sasldb/allockey.c"
-SASL_DB_UTILS="saslpasswd2 sasldblistusers2"
+SASL_DB_UTILS="cyrusbdb2current saslpasswd2 sasldblistusers2"
SASL_DB_MANS="saslpasswd2.8 sasldblistusers2.8"
case "$dblib" in
diff -up cyrus-sasl-2.1.27/sasldb/db_gdbm.c.frombdb cyrus-sasl-2.1.27/sasldb/db_gdbm.c
--- cyrus-sasl-2.1.27/sasldb/db_gdbm.c.frombdb 2017-07-13 14:34:03.000000000 +0200
+++ cyrus-sasl-2.1.27/sasldb/db_gdbm.c 2021-06-04 13:04:24.098206887 +0200
@@ -67,6 +67,7 @@ int _sasldb_getdata(const sasl_utils_t *
void *cntxt;
sasl_getopt_t *getopt;
const char *path = SASL_DB_PATH;
+ int fetch_errno = 0;
if (!utils) return SASL_BADPARAM;
if (!authid || !propName || !realm || !out || !max_out) {
@@ -99,6 +100,9 @@ int _sasldb_getdata(const sasl_utils_t *
}
db = gdbm_open((char *)path, 0, GDBM_READER, S_IRUSR | S_IWUSR, NULL);
if (! db) {
+ utils->log(conn, SASL_LOG_ERR,
+ "SASL error opening password file. "
+ "Have you performed the migration from db2 using cyrusbdb2current?\n");
utils->seterror(cntxt, 0, "Could not open %s: gdbm_errno=%d",
path, gdbm_errno);
result = SASL_FAIL;
@@ -107,9 +111,10 @@ int _sasldb_getdata(const sasl_utils_t *
gkey.dptr = key;
gkey.dsize = key_len;
gvalue = gdbm_fetch(db, gkey);
+ fetch_errno = gdbm_errno;
gdbm_close(db);
if (! gvalue.dptr) {
- if (gdbm_errno == GDBM_ITEM_NOT_FOUND) {
+ if (fetch_errno == GDBM_ITEM_NOT_FOUND) {
utils->seterror(conn, SASL_NOLOG,
"user: %s@%s property: %s not found in %s",
authid, realm, propName, path);
@@ -186,7 +191,8 @@ int _sasldb_putdata(const sasl_utils_t *
if (! db) {
utils->log(conn, SASL_LOG_ERR,
"SASL error opening password file. "
- "Do you have write permissions?\n");
+ "Do you have write permissions?\n"
+ "Have you performed the migration from db2 using cyrusbdb2current?\n");
utils->seterror(conn, 0, "Could not open %s for write: gdbm_errno=%d",
path, gdbm_errno);
result = SASL_FAIL;
@@ -298,6 +304,9 @@ sasldb_handle _sasldb_getkeyhandle(const
db = gdbm_open((char *)path, 0, GDBM_READER, S_IRUSR | S_IWUSR, NULL);
if(!db) {
+ utils->log(conn, SASL_LOG_ERR,
+ "SASL error opening password file. "
+ "Have you performed the migration from db2 using cyrusbdb2current?\n");
utils->seterror(conn, 0, "Could not open %s: gdbm_errno=%d",
path, gdbm_errno);
return NULL;
diff -up cyrus-sasl-2.1.27/utils/cyrusbdb2current.8.frombdb cyrus-sasl-2.1.27/utils/cyrusbdb2current.8
--- cyrus-sasl-2.1.27/utils/cyrusbdb2current.8.frombdb 2021-06-04 13:02:07.798112327 +0200
+++ cyrus-sasl-2.1.27/utils/cyrusbdb2current.8 2021-06-04 13:02:07.798112327 +0200
@@ -0,0 +1,159 @@
+.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+. ds C`
+. ds C'
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is >0, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.\"
+.\" Avoid warning from groff about undefined register 'F'.
+.de IX
+..
+.nr rF 0
+.if \n(.g .if rF .nr rF 1
+.if (\n(rF:(\n(.g==0)) \{\
+. if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. if !\nF==2 \{\
+. nr % 0
+. nr F 2
+. \}
+. \}
+.\}
+.rr rF
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "CYRUSBDB2CURRENT 1"
+.TH CYRUSBDB2CURRENT 1 "2021-04-28" "perl v5.30.3" "User Contributed Perl Documentation"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+cyrusbdb2current \- command\-line utility converting the SASLDB database from
+BerkeleyDB to the database format currently used bys sasldb.
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+cyrusbdb2current <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@

View File

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

View File

@ -0,0 +1,73 @@
From 4edb8ce82ac530f473a8728bae01d9fc8535c9cb Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Mon, 21 Jun 2021 14:24:18 -0400
Subject: [PATCH] Gracefully handle failed initializations
In OpenSSL 3.0 these algorithms have been moved to the legacy provider
which is not enabled by default. This means allocation can and do fail.
Handle failed allocations by returning an actual error instead of
crashing later with a NULL context.
Signed-off-by: Simo Sorce <simo@redhat.com>
---
plugins/digestmd5.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/plugins/digestmd5.c b/plugins/digestmd5.c
index c6b54317..b2617536 100644
--- a/plugins/digestmd5.c
+++ b/plugins/digestmd5.c
@@ -254,6 +254,7 @@ typedef struct context {
decode_context_t decode_context;
/* if privacy mode is used use these functions for encode and decode */
+ char *cipher_name;
cipher_function_t *cipher_enc;
cipher_function_t *cipher_dec;
cipher_init_t *cipher_init;
@@ -2821,6 +2822,7 @@ static int digestmd5_server_mech_step2(server_context_t *stext,
}
if (cptr->name) {
+ text->cipher_name = cptr->name;
text->cipher_enc = cptr->cipher_enc;
text->cipher_dec = cptr->cipher_dec;
text->cipher_init = cptr->cipher_init;
@@ -2964,7 +2966,10 @@ static int digestmd5_server_mech_step2(server_context_t *stext,
if (text->cipher_init) {
if (text->cipher_init(text, enckey, deckey) != SASL_OK) {
sparams->utils->seterror(sparams->utils->conn, 0,
- "couldn't init cipher");
+ "couldn't init cipher '%s'",
+ text->cipher_name);
+ result = SASL_FAIL;
+ goto FreeAllMem;
}
}
}
@@ -3515,6 +3520,7 @@ static int make_client_response(context_t *text,
oparams->mech_ssf = ctext->cipher->ssf;
nbits = ctext->cipher->n;
+ text->cipher_name = ctext->cipher->name;
text->cipher_enc = ctext->cipher->cipher_enc;
text->cipher_dec = ctext->cipher->cipher_dec;
text->cipher_free = ctext->cipher->cipher_free;
@@ -3739,7 +3745,13 @@ static int make_client_response(context_t *text,
/* initialize cipher if need be */
if (text->cipher_init) {
- text->cipher_init(text, enckey, deckey);
+ if (text->cipher_init(text, enckey, deckey) != SASL_OK) {
+ params->utils->seterror(params->utils->conn, 0,
+ "internal error: failed to init cipher '%s'",
+ text->cipher_name);
+ result = SASL_FAIL;
+ goto FreeAllocatedMem;
+ }
}
}
--
2.31.1

View File

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

View File

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

View File

@ -0,0 +1,156 @@
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[] =

View File

@ -0,0 +1,41 @@
#!/bin/bash -e
#
# See https://github.com/cyrusimap/cyrus-sasl/releases for unmodified sources.
#
tmppath=`mktemp -d ${TMPDIR:-/tmp}/make-no-dlcompat-tarball-XXXXXX`
if test -z "$tmppath" ; then
echo Error creating temporary directory.
exit 1
fi
trap "rm -fr $tmppath" EXIT
initialdir=`pwd`
for tarball in ${initialdir}/cyrus-sasl-*.tar.{gz,bz2} ; do
if ! test -s "$tarball" ; then
continue
fi
rm -fr $tmppath/*
pushd $tmppath > /dev/null
case "$tarball" in
*nodlcompat*)
: Do nothing.
;;
*.gz)
gzip -dc "$tarball" | tar xf -
rm -fr cyrus-sasl-*/dlcompat*
rm -fr cyrus-sasl-*/plugins/srp*
tar cf - * | gzip -9c > \
$initialdir/`basename $tarball .tar.gz`-nodlcompatorsrp.tar.gz
;;
*.bz2)
bzip2 -dc "$tarball" | tar xf -
rm -fr cyrus-sasl-*/dlcompat*
rm -fr cyrus-sasl-*/plugins/srp*
tar cf - * | bzip2 -9c > \
$initialdir/`basename $tarball .tar.bz2`-nodlcompatorsrp.tar.bz2
;;
esac
popd > /dev/null
done

99
SOURCES/sasl-mechlist.c Normal file
View File

@ -0,0 +1,99 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "sasl.h"
static int
my_getopt(void *context, const char *plugin_name,
const char *option, const char **result, unsigned *len)
{
if (result) {
*result = NULL;
#if 0
fprintf(stderr, "Getopt plugin=%s%s%s/option=%s%s%s -> ",
plugin_name ? "\"" : "",
plugin_name ? plugin_name : "(null)",
plugin_name ? "\"" : "",
option ? "\"" : "",
option ? option : "(null)",
option ? "\"" : "");
fprintf(stderr, "'%s'.\n", *result ? *result : "");
#endif
}
if (len) {
*len = 0;
}
return 0;
}
int
main(int argc, char **argv)
{
int ret, i;
const char *mechs, **globals;
sasl_callback_t callbacks[] = {
{SASL_CB_GETOPT, my_getopt, NULL},
{SASL_CB_LIST_END},
};
sasl_conn_t *connection;
char hostname[512];
if ((argc > 1) && (argv[1][0] == '-')) {
fprintf(stderr, "Usage: %s [appname [hostname] ]\n", argv[0]);
return 0;
}
ret = sasl_server_init(callbacks, argc > 1 ? argv[1] : "sasl-mechlist");
if (ret != SASL_OK) {
fprintf(stderr, "Error in sasl_server_init(): %s\n",
sasl_errstring(ret, NULL, NULL));
}
connection = NULL;
strcpy(hostname, "localhost");
gethostname(hostname, sizeof(hostname));
ret = sasl_server_new(argc > 2 ? argv[2] : "host",
hostname,
NULL,
NULL,
NULL,
callbacks,
0,
&connection);
if (ret != SASL_OK) {
fprintf(stderr, "Error in sasl_server_new(): %s\n",
sasl_errstring(ret, NULL, NULL));
}
ret = sasl_listmech(connection,
getenv("USER") ? getenv("USER") : "root",
"Available mechanisms: ",
",",
"\n",
&mechs,
NULL,
NULL);
if (ret != SASL_OK) {
fprintf(stderr, "Error in sasl_listmechs(): %s\n",
sasl_errstring(ret, NULL, NULL));
} else {
fprintf(stdout, "%s", mechs);
}
globals = sasl_global_listmech();
for (i = 0; (globals != NULL) && (globals[i] != NULL); i++) {
if (i == 0) {
fprintf(stdout, "Library supports: ");
}
fprintf(stdout, "%s", globals[i]);
if (globals[i + 1] != NULL) {
fprintf(stdout, ",");
} else {
fprintf(stdout, "\n");
}
}
return 0;
}

12
SOURCES/saslauthd.service Normal file
View File

@ -0,0 +1,12 @@
[Unit]
Description=SASL authentication daemon.
[Service]
Type=forking
PIDFile=/run/saslauthd/saslauthd.pid
EnvironmentFile=/etc/sysconfig/saslauthd
ExecStart=/usr/sbin/saslauthd -m $SOCKETDIR -a $MECH $FLAGS
RuntimeDirectory=saslauthd
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,11 @@
# Directory in which to place saslauthd's listening socket, pid file, and so
# on. This directory must already exist.
SOCKETDIR=/run/saslauthd
# Mechanism to use when checking passwords. Run "saslauthd -v" to get a list
# of which mechanism your installation was compiled with the ablity to use.
MECH=pam
# Additional flags to pass to saslauthd on the command line. See saslauthd(8)
# for the list of accepted flags.
FLAGS=

1188
SPECS/cyrus-sasl.spec Normal file

File diff suppressed because it is too large Load Diff