commit
66386fd602
@ -0,0 +1 @@
|
||||
080218941dfbbb6dc6d27e02358f12bed5b52eb2 SOURCES/cyrus-sasl-2.1.28-nodlcompatorsrp.tar.gz
|
@ -0,0 +1 @@
|
||||
SOURCES/cyrus-sasl-2.1.28-nodlcompatorsrp.tar.gz
|
@ -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
|
||||
|
@ -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
|
@ -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);
|
||||
|
@ -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).
|
@ -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_cv_runpath_switch="none"
|
||||
+ ])
|
@ -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
|
@ -0,0 +1,475 @@
|
||||
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: Fri, 20 Mar 2020 14:51:04 -0400
|
||||
Subject: [PATCH] Add Channel Binding support for GSSAPI/GSS-SPNEGO
|
||||
|
||||
Signed-off-by: Simo Sorce <simo@redhat.com>
|
||||
---
|
||||
plugins/gssapi.c | 30 +++++++++++---
|
||||
tests/runtests.py | 93 ++++++++++++++++++++++++++++++++++++++++----
|
||||
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 ff663da7..5d900c5e 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 f645adf4..fc9cf244 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 7168b2f1..87875b48 100644
|
||||
--- a/tests/t_common.c
|
||||
+++ b/tests/t_common.c
|
||||
@@ -65,4 +65,18 @@ int getpath(void *context __attribute__((unused)), const char **path)
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
+void parse_cb(sasl_channel_binding_t *cb, char *buf, unsigned max, char *in)
|
||||
+{
|
||||
+ unsigned len;
|
||||
+ int r;
|
||||
|
||||
+ r = sasl_decode64(in, strlen(in), buf, max, &len);
|
||||
+ if (r != SASL_OK) {
|
||||
+ saslerr(r, "failed to parse channel bindings");
|
||||
+ exit(-1);
|
||||
+ }
|
||||
+ cb->name = "TEST BINDINGS";
|
||||
+ cb->critical = 0;
|
||||
+ cb->data = (unsigned char *)buf;
|
||||
+ cb->len = len;
|
||||
+}
|
||||
diff --git a/tests/t_common.h b/tests/t_common.h
|
||||
index 4ee1976c..0d08d8ba 100644
|
||||
--- a/tests/t_common.h
|
||||
+++ b/tests/t_common.h
|
||||
@@ -7,9 +7,11 @@
|
||||
#include <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 c833c055..6b5664eb 100644
|
||||
--- a/tests/t_gssapi_cli.c
|
||||
+++ b/tests/t_gssapi_cli.c
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <saslplug.h>
|
||||
+#include <saslutil.h>
|
||||
|
||||
static int setup_socket(void)
|
||||
{
|
||||
@@ -32,7 +33,7 @@ static int setup_socket(void)
|
||||
return sock;
|
||||
}
|
||||
|
||||
-int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
|
||||
+int main(int argc, char *argv[])
|
||||
{
|
||||
sasl_callback_t callbacks[2] = {};
|
||||
char buf[8192];
|
||||
@@ -40,8 +41,20 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
|
||||
sasl_conn_t *conn;
|
||||
const char *data;
|
||||
unsigned int len;
|
||||
+ sasl_channel_binding_t cb = {0};
|
||||
+ char cb_buf[256];
|
||||
int sd;
|
||||
- int r;
|
||||
+ int c, r;
|
||||
+
|
||||
+ while ((c = getopt(argc, argv, "c:")) != EOF) {
|
||||
+ switch (c) {
|
||||
+ case 'c':
|
||||
+ parse_cb(&cb, cb_buf, 256, optarg);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
/* initialize the sasl library */
|
||||
callbacks[0].id = SASL_CB_GETPATH;
|
||||
@@ -60,6 +73,10 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
+ if (cb.name) {
|
||||
+ sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb);
|
||||
+ }
|
||||
+
|
||||
r = sasl_client_start(conn, "GSSAPI", NULL, &data, &len, &chosenmech);
|
||||
if (r != SASL_OK && r != SASL_CONTINUE) {
|
||||
saslerr(r, "starting SASL negotiation");
|
||||
diff --git a/tests/t_gssapi_srv.c b/tests/t_gssapi_srv.c
|
||||
index 29f538dd..3a8a5d44 100644
|
||||
--- a/tests/t_gssapi_srv.c
|
||||
+++ b/tests/t_gssapi_srv.c
|
||||
@@ -44,15 +44,28 @@ static int setup_socket(void)
|
||||
return sd;
|
||||
}
|
||||
|
||||
-int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
|
||||
+int main(int argc, char *argv[])
|
||||
{
|
||||
sasl_callback_t callbacks[2] = {};
|
||||
char buf[8192];
|
||||
sasl_conn_t *conn;
|
||||
const char *data;
|
||||
unsigned int len;
|
||||
+ sasl_channel_binding_t cb = {0};
|
||||
+ unsigned char cb_buf[256];
|
||||
int sd;
|
||||
- int r;
|
||||
+ int c, r;
|
||||
+
|
||||
+ while ((c = getopt(argc, argv, "c:")) != EOF) {
|
||||
+ switch (c) {
|
||||
+ case 'c':
|
||||
+ parse_cb(&cb, cb_buf, 256, optarg);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
|
||||
/* initialize the sasl library */
|
||||
callbacks[0].id = SASL_CB_GETPATH;
|
||||
@@ -72,6 +85,10 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
+ if (cb.name) {
|
||||
+ sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb);
|
||||
+ }
|
||||
+
|
||||
sd = setup_socket();
|
||||
|
||||
len = 8192;
|
||||
|
||||
From ea8eb892e44129ac3890298da91c868d5592ed20 Mon Sep 17 00:00:00 2001
|
||||
From: Simo Sorce <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"
|
||||
|
||||
|
@ -0,0 +1,642 @@
|
||||
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: Sat, 14 Mar 2020 10:50:19 -0400
|
||||
Subject: [PATCH] Add basic test infrastructure
|
||||
|
||||
First test is for SASL/GSSAPI
|
||||
|
||||
Signed-off-by: Simo Sorce <simo@redhat.com>
|
||||
|
||||
:x
|
||||
---
|
||||
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 +++++++++++++++++++++++++++
|
||||
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
|
||||
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 f7d3b22e..102e2a3e 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -65,7 +65,7 @@ else
|
||||
INSTALLOSX =
|
||||
endif
|
||||
|
||||
-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 3610671b..dd7908a3 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -1516,8 +1516,9 @@ plugins/Makefile
|
||||
lib/Makefile
|
||||
utils/Makefile
|
||||
sample/Makefile
|
||||
-pwcheck/Makefile])
|
||||
+pwcheck/Makefile
|
||||
+tests/Makefile])
|
||||
AC_OUTPUT
|
||||
|
||||
AC_MSG_NOTICE([
|
||||
|
||||
diff --git a/tests/Makefile.am b/tests/Makefile.am
|
||||
new file mode 100644
|
||||
index 00000000..1edf010a
|
||||
--- /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 00000000..f645adf4
|
||||
--- /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 00000000..7168b2f1
|
||||
--- /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 00000000..4ee1976c
|
||||
--- /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 00000000..c833c055
|
||||
--- /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 00000000..29f538dd
|
||||
--- /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;
|
||||
+}
|
||||
+
|
||||
|
@ -0,0 +1,95 @@
|
||||
Backport of part of Upstream PR#603 minimal part needed for interop
|
||||
|
||||
From 0e722dd3266d5ebd0f889462cc23856fde3d21ed Mon Sep 17 00:00:00 2001
|
||||
From: Simo Sorce <simo@redhat.com>
|
||||
Date: Thu, 19 Sep 2019 15:58:04 -0400
|
||||
Subject: [PATCH] Add support for setting max ssf 0 to GSS-SPNEGO
|
||||
|
||||
This is needed to interop with Windows within a TLS channel.
|
||||
|
||||
Signed-off-by: Simo Sorce <simo@redhat.com>
|
||||
---
|
||||
m4/sasl2.m4 | 13 +++++++++++++
|
||||
plugins/gssapi.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
|
||||
2 files changed, 57 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/m4/sasl2.m4 b/m4/sasl2.m4
|
||||
index 17f5d081..60306943 100644
|
||||
--- a/m4/sasl2.m4
|
||||
+++ b/m4/sasl2.m4
|
||||
@@ -287,6 +287,19 @@ if test "$gssapi" != no; then
|
||||
AC_CHECK_FUNCS(gss_oid_equal)
|
||||
LIBS="$cmu_save_LIBS"
|
||||
|
||||
+ cmu_save_LIBS="$LIBS"
|
||||
+ LIBS="$LIBS $GSSAPIBASE_LIBS"
|
||||
+ if test "$ac_cv_header_gssapi_gssapi_krb5_h" = "yes"; then
|
||||
+ AC_CHECK_DECL(GSS_KRB5_CRED_NO_CI_FLAGS_X,
|
||||
+ [AC_DEFINE(HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X,1,
|
||||
+ [Define if your GSSAPI implementation supports GSS_KRB5_CRED_NO_CI_FLAGS_X])],,
|
||||
+ [
|
||||
+ AC_INCLUDES_DEFAULT
|
||||
+ #include <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 46de7d48..cca6cc0a 100644
|
||||
--- a/plugins/gssapi.c
|
||||
+++ b/plugins/gssapi.c
|
||||
@@ -2123,7 +2123,50 @@ static int gssapi_client_mech_step(void *conn_context,
|
||||
/* We want to try for privacy */
|
||||
req_flags |= GSS_C_CONF_FLAG;
|
||||
}
|
||||
- }
|
||||
+#ifdef HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X
|
||||
+ /* The krb5 mechanism automatically adds INTEG and CONF flags even when
|
||||
+ * not specified, this has the effect of rendering explicit requests
|
||||
+ * of no confidentiality and integrity via setting maxssf 0 moot.
|
||||
+ * However to interoperate with Windows machines it needs to be
|
||||
+ * possible to unset these flags as Windows machines refuse to allow
|
||||
+ * two layers (say TLS and GSSAPI) to both provide these services.
|
||||
+ * So if we do not suppress these flags a SASL/GSS-SPNEGO negotiation
|
||||
+ * over, say, LDAPS will fail against Windows Servers */
|
||||
+ } else if (params->props.max_ssf == 0) {
|
||||
+ gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER;
|
||||
+ if (client_creds == GSS_C_NO_CREDENTIAL) {
|
||||
+ gss_OID_set_desc mechs = { 0 };
|
||||
+ gss_OID_set desired_mechs = GSS_C_NO_OID_SET;
|
||||
+ if (text->mech_type != GSS_C_NO_OID) {
|
||||
+ mechs.count = 1;
|
||||
+ mechs.elements = text->mech_type;
|
||||
+ desired_mechs = &mechs;
|
||||
+ }
|
||||
+
|
||||
+ maj_stat = gss_acquire_cred(&min_stat, GSS_C_NO_NAME,
|
||||
+ GSS_C_INDEFINITE, desired_mechs,
|
||||
+ GSS_C_INITIATE,
|
||||
+ &text->client_creds, NULL, NULL);
|
||||
+ if (GSS_ERROR(maj_stat)) {
|
||||
+ sasl_gss_seterror(text->utils, maj_stat, min_stat);
|
||||
+ sasl_gss_free_context_contents(text);
|
||||
+ return SASL_FAIL;
|
||||
+ }
|
||||
+ client_creds = text->client_creds;
|
||||
+ }
|
||||
+
|
||||
+ maj_stat = gss_set_cred_option(&min_stat, &client_creds,
|
||||
+ (gss_OID)GSS_KRB5_CRED_NO_CI_FLAGS_X,
|
||||
+ &empty_buffer);
|
||||
+ if (GSS_ERROR(maj_stat)) {
|
||||
+ sasl_gss_seterror(text->utils, maj_stat, min_stat);
|
||||
+ sasl_gss_free_context_contents(text);
|
||||
+ return SASL_FAIL;
|
||||
+ }
|
||||
+#endif
|
||||
+ }
|
||||
+
|
||||
+
|
||||
|
||||
if (params->props.security_flags & SASL_SEC_PASS_CREDENTIALS) {
|
||||
req_flags = req_flags | GSS_C_DELEG_FLAG;
|
@ -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;
|
||||
}
|
||||
|
@ -0,0 +1,554 @@
|
||||
diff -uPr cyrus-sasl-2.1.27/plugins/digestmd5.c cyrus-sasl-2.1.27.digestmd5/plugins/digestmd5.c
|
||||
--- cyrus-sasl-2.1.27/plugins/digestmd5.c 2021-09-30 17:13:06.573093526 -0400
|
||||
+++ cyrus-sasl-2.1.27.digestmd5/plugins/digestmd5.c 2021-09-30 17:26:31.818378442 -0400
|
||||
@@ -80,6 +80,12 @@
|
||||
# endif
|
||||
#endif /* WITH_DES */
|
||||
|
||||
+/* legacy provider with openssl 3.0 */
|
||||
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
+# include <openssl/provider.h>
|
||||
+# include <openssl/crypto.h>
|
||||
+#endif
|
||||
+
|
||||
#ifdef WIN32
|
||||
# include <winsock2.h>
|
||||
#else /* Unix */
|
||||
@@ -170,6 +176,12 @@
|
||||
|
||||
typedef struct cipher_context cipher_context_t;
|
||||
|
||||
+typedef struct crypto_context {
|
||||
+ void *libctx;
|
||||
+ cipher_context_t *enc_ctx;
|
||||
+ cipher_context_t *dec_ctx;
|
||||
+} crypto_context_t;
|
||||
+
|
||||
/* cached auth info used for fast reauth */
|
||||
typedef struct reauth_entry {
|
||||
char *authid;
|
||||
@@ -254,12 +266,12 @@
|
||||
decode_context_t decode_context;
|
||||
|
||||
/* if privacy mode is used use these functions for encode and decode */
|
||||
+ char *cipher_name;
|
||||
cipher_function_t *cipher_enc;
|
||||
cipher_function_t *cipher_dec;
|
||||
cipher_init_t *cipher_init;
|
||||
cipher_free_t *cipher_free;
|
||||
- struct cipher_context *cipher_enc_context;
|
||||
- struct cipher_context *cipher_dec_context;
|
||||
+ crypto_context_t crypto;
|
||||
} context_t;
|
||||
|
||||
struct digest_cipher {
|
||||
@@ -888,7 +900,7 @@
|
||||
char *output,
|
||||
unsigned *outputlen)
|
||||
{
|
||||
- des_context_t *c = (des_context_t *) text->cipher_dec_context;
|
||||
+ des_context_t *c = (des_context_t *) text->crypto.dec_ctx;
|
||||
int padding, p;
|
||||
|
||||
des_ede2_cbc_encrypt((void *) input,
|
||||
@@ -925,7 +937,7 @@
|
||||
char *output,
|
||||
unsigned *outputlen)
|
||||
{
|
||||
- des_context_t *c = (des_context_t *) text->cipher_enc_context;
|
||||
+ des_context_t *c = (des_context_t *) text->crypto.enc_ctx;
|
||||
int len;
|
||||
int paddinglen;
|
||||
|
||||
@@ -973,7 +985,7 @@
|
||||
return SASL_FAIL;
|
||||
memcpy(c->ivec, ((char *) enckey) + 8, 8);
|
||||
|
||||
- text->cipher_enc_context = (cipher_context_t *) c;
|
||||
+ text->crypto.enc_ctx = (cipher_context_t *) c;
|
||||
|
||||
/* setup dec context */
|
||||
c++;
|
||||
@@ -987,7 +999,7 @@
|
||||
|
||||
memcpy(c->ivec, ((char *) deckey) + 8, 8);
|
||||
|
||||
- text->cipher_dec_context = (cipher_context_t *) c;
|
||||
+ text->crypto.dec_ctx = (cipher_context_t *) c;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
@@ -1006,7 +1018,7 @@
|
||||
char *output,
|
||||
unsigned *outputlen)
|
||||
{
|
||||
- des_context_t *c = (des_context_t *) text->cipher_dec_context;
|
||||
+ des_context_t *c = (des_context_t *) text->crypto.dec_ctx;
|
||||
int p, padding = 0;
|
||||
|
||||
des_cbc_encrypt((void *) input,
|
||||
@@ -1046,7 +1058,7 @@
|
||||
char *output,
|
||||
unsigned *outputlen)
|
||||
{
|
||||
- des_context_t *c = (des_context_t *) text->cipher_enc_context;
|
||||
+ des_context_t *c = (des_context_t *) text->crypto.enc_ctx;
|
||||
int len;
|
||||
int paddinglen;
|
||||
|
||||
@@ -1093,7 +1105,7 @@
|
||||
|
||||
memcpy(c->ivec, ((char *) enckey) + 8, 8);
|
||||
|
||||
- text->cipher_enc_context = (cipher_context_t *) c;
|
||||
+ text->crypto.enc_ctx = (cipher_context_t *) c;
|
||||
|
||||
/* setup dec context */
|
||||
c++;
|
||||
@@ -1102,60 +1114,143 @@
|
||||
|
||||
memcpy(c->ivec, ((char *) deckey) + 8, 8);
|
||||
|
||||
- text->cipher_dec_context = (cipher_context_t *) c;
|
||||
+ text->crypto.dec_ctx = (cipher_context_t *) c;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
static void free_des(context_t *text)
|
||||
{
|
||||
- /* free des contextss. only cipher_enc_context needs to be free'd,
|
||||
- since cipher_dec_context was allocated at the same time. */
|
||||
- if (text->cipher_enc_context) text->utils->free(text->cipher_enc_context);
|
||||
+ /* free des contextss. only enc_ctx needs to be free'd,
|
||||
+ since dec_cxt was allocated at the same time. */
|
||||
+ if (text->crypto.enc_ctx) {
|
||||
+ text->utils->free(text->crypto.enc_ctx);
|
||||
+ }
|
||||
}
|
||||
|
||||
#endif /* WITH_DES */
|
||||
|
||||
#ifdef WITH_RC4
|
||||
-#ifdef HAVE_OPENSSL
|
||||
#include <openssl/evp.h>
|
||||
|
||||
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
+typedef struct ossl3_library_context {
|
||||
+ OSSL_LIB_CTX *libctx;
|
||||
+ OSSL_PROVIDER *legacy_provider;
|
||||
+ OSSL_PROVIDER *default_provider;
|
||||
+} ossl3_context_t;
|
||||
+
|
||||
+static int init_ossl3_ctx(context_t *text)
|
||||
+{
|
||||
+ ossl3_context_t *ctx = text->utils->malloc(sizeof(ossl3_context_t));
|
||||
+ if (!ctx) return SASL_NOMEM;
|
||||
+
|
||||
+ ctx->libctx = OSSL_LIB_CTX_new();
|
||||
+ if (!ctx->libctx) {
|
||||
+ text->utils->free(ctx);
|
||||
+ return SASL_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ /* Load both legacy and default provider as both may be needed */
|
||||
+ /* if they fail keep going and an error will be raised when we try to
|
||||
+ * fetch the cipher later */
|
||||
+ ctx->legacy_provider = OSSL_PROVIDER_load(ctx->libctx, "legacy");
|
||||
+ ctx->default_provider = OSSL_PROVIDER_load(ctx->libctx, "default");
|
||||
+ text->crypto.libctx = (void *)ctx;
|
||||
+
|
||||
+ return SASL_OK;
|
||||
+}
|
||||
+
|
||||
+static void free_ossl3_ctx(context_t *text)
|
||||
+{
|
||||
+ ossl3_context_t *ctx;
|
||||
+
|
||||
+ if (!text->crypto.libctx) return;
|
||||
+
|
||||
+ ctx = (ossl3_context_t *)text->crypto.libctx;
|
||||
+
|
||||
+ if (ctx->legacy_provider) OSSL_PROVIDER_unload(ctx->legacy_provider);
|
||||
+ if (ctx->default_provider) OSSL_PROVIDER_unload(ctx->default_provider);
|
||||
+ if (ctx->libctx) OSSL_LIB_CTX_free(ctx->libctx);
|
||||
+
|
||||
+ text->utils->free(ctx);
|
||||
+ text->crypto.libctx = NULL;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
static void free_rc4(context_t *text)
|
||||
{
|
||||
- if (text->cipher_enc_context) {
|
||||
- EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *)text->cipher_enc_context);
|
||||
- text->cipher_enc_context = NULL;
|
||||
- }
|
||||
- if (text->cipher_dec_context) {
|
||||
- EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *)text->cipher_dec_context);
|
||||
- text->cipher_dec_context = NULL;
|
||||
+ if (text->crypto.enc_ctx) {
|
||||
+ EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *)text->crypto.enc_ctx);
|
||||
+ text->crypto.enc_ctx = NULL;
|
||||
+ }
|
||||
+ if (text->crypto.dec_ctx) {
|
||||
+ EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *)text->crypto.dec_ctx);
|
||||
+ text->crypto.dec_ctx = NULL;
|
||||
}
|
||||
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
+ free_ossl3_ctx(text);
|
||||
+#endif
|
||||
}
|
||||
|
||||
static int init_rc4(context_t *text,
|
||||
unsigned char enckey[16],
|
||||
unsigned char deckey[16])
|
||||
{
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
int rc;
|
||||
|
||||
- ctx = EVP_CIPHER_CTX_new();
|
||||
- if (ctx == NULL) return SASL_NOMEM;
|
||||
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
+ EVP_CIPHER *cipher;
|
||||
+ ossl3_context_t *ossl3_ctx;
|
||||
|
||||
- rc = EVP_EncryptInit_ex(ctx, EVP_rc4(), NULL, enckey, NULL);
|
||||
- if (rc != 1) return SASL_FAIL;
|
||||
+ rc = init_ossl3_ctx(text);
|
||||
+ if (rc != SASL_OK) return rc;
|
||||
+
|
||||
+ ossl3_ctx = (ossl3_context_t *)text->crypto.libctx;
|
||||
+ cipher = EVP_CIPHER_fetch(ossl3_ctx->libctx, "RC4", "");
|
||||
+#else
|
||||
+ const EVP_CIPHER *cipher;
|
||||
+ cipher = EVP_rc4();
|
||||
+#endif
|
||||
|
||||
- text->cipher_enc_context = (void *)ctx;
|
||||
|
||||
ctx = EVP_CIPHER_CTX_new();
|
||||
- if (ctx == NULL) return SASL_NOMEM;
|
||||
+ if (ctx == NULL) {
|
||||
+ rc = SASL_NOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
|
||||
- rc = EVP_DecryptInit_ex(ctx, EVP_rc4(), NULL, deckey, NULL);
|
||||
- if (rc != 1) return SASL_FAIL;
|
||||
+ rc = EVP_EncryptInit_ex(ctx, cipher, NULL, enckey, NULL);
|
||||
+ if (rc != 1) {
|
||||
+ rc = SASL_FAIL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ text->crypto.enc_ctx = (void *)ctx;
|
||||
|
||||
- text->cipher_dec_context = (void *)ctx;
|
||||
+ ctx = EVP_CIPHER_CTX_new();
|
||||
+ if (ctx == NULL) {
|
||||
+ rc = SASL_NOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
|
||||
- return SASL_OK;
|
||||
+ rc = EVP_DecryptInit_ex(ctx, cipher, NULL, deckey, NULL);
|
||||
+ if (rc != 1) {
|
||||
+ rc = SASL_FAIL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ text->crypto.dec_ctx = (void *)ctx;
|
||||
+
|
||||
+ rc = SASL_OK;
|
||||
+
|
||||
+done:
|
||||
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
+ EVP_CIPHER_free(cipher);
|
||||
+#endif
|
||||
+ if (rc != SASL_OK) {
|
||||
+ free_rc4(text);
|
||||
+ }
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
static int dec_rc4(context_t *text,
|
||||
@@ -1169,14 +1260,14 @@
|
||||
int rc;
|
||||
|
||||
/* decrypt the text part & HMAC */
|
||||
- rc = EVP_DecryptUpdate((EVP_CIPHER_CTX *)text->cipher_dec_context,
|
||||
+ rc = EVP_DecryptUpdate((EVP_CIPHER_CTX *)text->crypto.dec_ctx,
|
||||
(unsigned char *)output, &len,
|
||||
(const unsigned char *)input, inputlen);
|
||||
if (rc != 1) return SASL_FAIL;
|
||||
|
||||
*outputlen = len;
|
||||
|
||||
- rc = EVP_DecryptFinal_ex((EVP_CIPHER_CTX *)text->cipher_dec_context,
|
||||
+ rc = EVP_DecryptFinal_ex((EVP_CIPHER_CTX *)text->crypto.dec_ctx,
|
||||
(unsigned char *)output + len, &len);
|
||||
if (rc != 1) return SASL_FAIL;
|
||||
|
||||
@@ -1198,7 +1289,7 @@
|
||||
int len;
|
||||
int rc;
|
||||
/* encrypt the text part */
|
||||
- rc = EVP_EncryptUpdate((EVP_CIPHER_CTX *)text->cipher_enc_context,
|
||||
+ rc = EVP_EncryptUpdate((EVP_CIPHER_CTX *)text->crypto.enc_ctx,
|
||||
(unsigned char *)output, &len,
|
||||
(const unsigned char *)input, inputlen);
|
||||
if (rc != 1) return SASL_FAIL;
|
||||
@@ -1206,14 +1297,14 @@
|
||||
*outputlen = len;
|
||||
|
||||
/* encrypt the `MAC part */
|
||||
- rc = EVP_EncryptUpdate((EVP_CIPHER_CTX *)text->cipher_enc_context,
|
||||
+ rc = EVP_EncryptUpdate((EVP_CIPHER_CTX *)text->crypto.enc_ctx,
|
||||
(unsigned char *)output + *outputlen, &len,
|
||||
digest, 10);
|
||||
if (rc != 1) return SASL_FAIL;
|
||||
|
||||
*outputlen += len;
|
||||
|
||||
- rc = EVP_EncryptFinal_ex((EVP_CIPHER_CTX *)text->cipher_enc_context,
|
||||
+ rc = EVP_EncryptFinal_ex((EVP_CIPHER_CTX *)text->crypto.enc_ctx,
|
||||
(unsigned char *)output + *outputlen, &len);
|
||||
if (rc != 1) return SASL_FAIL;
|
||||
|
||||
@@ -1221,194 +1312,11 @@
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
-#else
|
||||
-/* quick generic implementation of RC4 */
|
||||
-struct rc4_context_s {
|
||||
- unsigned char sbox[256];
|
||||
- int i, j;
|
||||
-};
|
||||
-
|
||||
-typedef struct rc4_context_s rc4_context_t;
|
||||
-
|
||||
-static void rc4_init(rc4_context_t *text,
|
||||
- const unsigned char *key,
|
||||
- unsigned keylen)
|
||||
-{
|
||||
- int i, j;
|
||||
-
|
||||
- /* fill in linearly s0=0 s1=1... */
|
||||
- for (i=0;i<256;i++)
|
||||
- text->sbox[i]=i;
|
||||
-
|
||||
- j=0;
|
||||
- for (i = 0; i < 256; i++) {
|
||||
- unsigned char tmp;
|
||||
- /* j = (j + Si + Ki) mod 256 */
|
||||
- j = (j + text->sbox[i] + key[i % keylen]) % 256;
|
||||
-
|
||||
- /* swap Si and Sj */
|
||||
- tmp = text->sbox[i];
|
||||
- text->sbox[i] = text->sbox[j];
|
||||
- text->sbox[j] = tmp;
|
||||
- }
|
||||
-
|
||||
- /* counters initialized to 0 */
|
||||
- text->i = 0;
|
||||
- text->j = 0;
|
||||
-}
|
||||
-
|
||||
-static void rc4_encrypt(rc4_context_t *text,
|
||||
- const char *input,
|
||||
- char *output,
|
||||
- unsigned len)
|
||||
-{
|
||||
- int tmp;
|
||||
- int i = text->i;
|
||||
- int j = text->j;
|
||||
- int t;
|
||||
- int K;
|
||||
- const char *input_end = input + len;
|
||||
-
|
||||
- while (input < input_end) {
|
||||
- i = (i + 1) % 256;
|
||||
-
|
||||
- j = (j + text->sbox[i]) % 256;
|
||||
-
|
||||
- /* swap Si and Sj */
|
||||
- tmp = text->sbox[i];
|
||||
- text->sbox[i] = text->sbox[j];
|
||||
- text->sbox[j] = tmp;
|
||||
-
|
||||
- t = (text->sbox[i] + text->sbox[j]) % 256;
|
||||
-
|
||||
- K = text->sbox[t];
|
||||
-
|
||||
- /* byte K is Xor'ed with plaintext */
|
||||
- *output++ = *input++ ^ K;
|
||||
- }
|
||||
-
|
||||
- text->i = i;
|
||||
- text->j = j;
|
||||
-}
|
||||
-
|
||||
-static void rc4_decrypt(rc4_context_t *text,
|
||||
- const char *input,
|
||||
- char *output,
|
||||
- unsigned len)
|
||||
-{
|
||||
- int tmp;
|
||||
- int i = text->i;
|
||||
- int j = text->j;
|
||||
- int t;
|
||||
- int K;
|
||||
- const char *input_end = input + len;
|
||||
-
|
||||
- while (input < input_end) {
|
||||
- i = (i + 1) % 256;
|
||||
-
|
||||
- j = (j + text->sbox[i]) % 256;
|
||||
-
|
||||
- /* swap Si and Sj */
|
||||
- tmp = text->sbox[i];
|
||||
- text->sbox[i] = text->sbox[j];
|
||||
- text->sbox[j] = tmp;
|
||||
-
|
||||
- t = (text->sbox[i] + text->sbox[j]) % 256;
|
||||
-
|
||||
- K = text->sbox[t];
|
||||
-
|
||||
- /* byte K is Xor'ed with plaintext */
|
||||
- *output++ = *input++ ^ K;
|
||||
- }
|
||||
-
|
||||
- text->i = i;
|
||||
- text->j = j;
|
||||
-}
|
||||
-
|
||||
-static void free_rc4(context_t *text)
|
||||
-{
|
||||
- /* free rc4 context structures */
|
||||
-
|
||||
- if (text->cipher_enc_context) {
|
||||
- text->utils->free(text->cipher_enc_context);
|
||||
- text->cipher_enc_context = NULL;
|
||||
- }
|
||||
- if (text->cipher_dec_context) {
|
||||
- text->utils->free(text->cipher_dec_context);
|
||||
- text->cipher_dec_context = NULL;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static int init_rc4(context_t *text,
|
||||
- unsigned char enckey[16],
|
||||
- unsigned char deckey[16])
|
||||
-{
|
||||
- /* allocate rc4 context structures */
|
||||
- text->cipher_enc_context=
|
||||
- (cipher_context_t *) text->utils->malloc(sizeof(rc4_context_t));
|
||||
- if (text->cipher_enc_context == NULL) return SASL_NOMEM;
|
||||
-
|
||||
- text->cipher_dec_context=
|
||||
- (cipher_context_t *) text->utils->malloc(sizeof(rc4_context_t));
|
||||
- if (text->cipher_dec_context == NULL) return SASL_NOMEM;
|
||||
-
|
||||
- /* initialize them */
|
||||
- rc4_init((rc4_context_t *) text->cipher_enc_context,
|
||||
- (const unsigned char *) enckey, 16);
|
||||
- rc4_init((rc4_context_t *) text->cipher_dec_context,
|
||||
- (const unsigned char *) deckey, 16);
|
||||
-
|
||||
- return SASL_OK;
|
||||
-}
|
||||
-
|
||||
-static int dec_rc4(context_t *text,
|
||||
- const char *input,
|
||||
- unsigned inputlen,
|
||||
- unsigned char digest[16] __attribute__((unused)),
|
||||
- char *output,
|
||||
- unsigned *outputlen)
|
||||
-{
|
||||
- /* decrypt the text part & HMAC */
|
||||
- rc4_decrypt((rc4_context_t *) text->cipher_dec_context,
|
||||
- input, output, inputlen);
|
||||
-
|
||||
- /* no padding so we just subtract the HMAC to get the text length */
|
||||
- *outputlen = inputlen - 10;
|
||||
-
|
||||
- return SASL_OK;
|
||||
-}
|
||||
-
|
||||
-static int enc_rc4(context_t *text,
|
||||
- const char *input,
|
||||
- unsigned inputlen,
|
||||
- unsigned char digest[16],
|
||||
- char *output,
|
||||
- unsigned *outputlen)
|
||||
-{
|
||||
- /* pad is zero */
|
||||
- *outputlen = inputlen+10;
|
||||
-
|
||||
- /* encrypt the text part */
|
||||
- rc4_encrypt((rc4_context_t *) text->cipher_enc_context,
|
||||
- input,
|
||||
- output,
|
||||
- inputlen);
|
||||
-
|
||||
- /* encrypt the HMAC part */
|
||||
- rc4_encrypt((rc4_context_t *) text->cipher_enc_context,
|
||||
- (const char *) digest,
|
||||
- (output)+inputlen, 10);
|
||||
-
|
||||
- return SASL_OK;
|
||||
-}
|
||||
-#endif /* HAVE_OPENSSL */
|
||||
#endif /* WITH_RC4 */
|
||||
|
||||
struct digest_cipher available_ciphers[] =
|
||||
{
|
||||
#ifdef WITH_RC4
|
||||
- { "rc4-40", 40, 5, 0x01, &enc_rc4, &dec_rc4, &init_rc4, &free_rc4 },
|
||||
- { "rc4-56", 56, 7, 0x02, &enc_rc4, &dec_rc4, &init_rc4, &free_rc4 },
|
||||
{ "rc4", 128, 16, 0x04, &enc_rc4, &dec_rc4, &init_rc4, &free_rc4 },
|
||||
#endif
|
||||
#ifdef WITH_DES
|
||||
@@ -2815,6 +2729,7 @@
|
||||
}
|
||||
|
||||
if (cptr->name) {
|
||||
+ text->cipher_name = cptr->name;
|
||||
text->cipher_enc = cptr->cipher_enc;
|
||||
text->cipher_dec = cptr->cipher_dec;
|
||||
text->cipher_init = cptr->cipher_init;
|
||||
@@ -2958,7 +2873,10 @@
|
||||
if (text->cipher_init) {
|
||||
if (text->cipher_init(text, enckey, deckey) != SASL_OK) {
|
||||
sparams->utils->seterror(sparams->utils->conn, 0,
|
||||
- "couldn't init cipher");
|
||||
+ "couldn't init cipher '%s'",
|
||||
+ text->cipher_name);
|
||||
+ result = SASL_FAIL;
|
||||
+ goto FreeAllMem;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3509,6 +3427,7 @@
|
||||
oparams->mech_ssf = ctext->cipher->ssf;
|
||||
|
||||
nbits = ctext->cipher->n;
|
||||
+ text->cipher_name = ctext->cipher->name;
|
||||
text->cipher_enc = ctext->cipher->cipher_enc;
|
||||
text->cipher_dec = ctext->cipher->cipher_dec;
|
||||
text->cipher_free = ctext->cipher->cipher_free;
|
||||
@@ -3733,7 +3652,13 @@
|
||||
|
||||
/* initialize cipher if need be */
|
||||
if (text->cipher_init) {
|
||||
- text->cipher_init(text, enckey, deckey);
|
||||
+ if (text->cipher_init(text, enckey, deckey) != SASL_OK) {
|
||||
+ params->utils->seterror(params->utils->conn, 0,
|
||||
+ "internal error: failed to init cipher '%s'",
|
||||
+ text->cipher_name);
|
||||
+ result = SASL_FAIL;
|
||||
+ goto FreeAllocatedMem;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,109 @@
|
||||
diff -uPr cyrus-sasl-2.1.27/configure.ac cyrus-sasl-2.1.27.ossl3/configure.ac
|
||||
--- cyrus-sasl-2.1.27/configure.ac 2021-10-06 11:29:53.274375206 -0400
|
||||
+++ cyrus-sasl-2.1.27.ossl3/configure.ac 2021-10-06 11:31:19.966726775 -0400
|
||||
@@ -1115,7 +1115,11 @@
|
||||
with_rc4=yes)
|
||||
|
||||
if test "$with_rc4" != no; then
|
||||
- AC_DEFINE(WITH_RC4,[],[Use RC4])
|
||||
+ if test "$with_openssl" = no; then
|
||||
+ AC_WARN([OpenSSL not found -- RC4 will be disabled])
|
||||
+ else
|
||||
+ AC_DEFINE(WITH_RC4,[],[Use RC4])
|
||||
+ fi
|
||||
fi
|
||||
|
||||
building_for_macosx=no
|
||||
diff -uPr cyrus-sasl-2.1.27/plugins/scram.c cyrus-sasl-2.1.27.ossl3/plugins/scram.c
|
||||
--- cyrus-sasl-2.1.27/plugins/scram.c 2018-11-08 12:29:57.000000000 -0500
|
||||
+++ cyrus-sasl-2.1.27.ossl3/plugins/scram.c 2021-10-06 11:31:04.407484201 -0400
|
||||
@@ -65,7 +65,9 @@
|
||||
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/evp.h>
|
||||
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
#include <openssl/hmac.h>
|
||||
+#endif
|
||||
|
||||
/***************************** Common Section *****************************/
|
||||
|
||||
@@ -291,6 +293,32 @@
|
||||
}
|
||||
#endif
|
||||
|
||||
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
+
|
||||
+/* Decalre as void given functions never use the result */
|
||||
+void *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
|
||||
+ const unsigned char *data, size_t data_len,
|
||||
+ unsigned char *md, unsigned int *md_len)
|
||||
+{
|
||||
+ const char *digest;
|
||||
+ size_t digest_size;
|
||||
+ size_t out_len;
|
||||
+ void *ret = NULL;
|
||||
+
|
||||
+ digest = EVP_MD_get0_name(evp_md);
|
||||
+ if (digest == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ digest_size = EVP_MD_size(evp_md);
|
||||
+
|
||||
+ ret = EVP_Q_mac(NULL, "hmac", NULL, digest, NULL, key, key_len,
|
||||
+ data, data_len, md, digest_size, &out_len);
|
||||
+ if (ret != NULL) {
|
||||
+ *md_len = (unsigned int)out_len;
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+#endif
|
||||
|
||||
/* The result variable need to point to a buffer big enough for the [SHA-*] hash */
|
||||
static void
|
||||
diff -uPr cyrus-sasl-2.1.27/saslauthd/lak.c cyrus-sasl-2.1.27.ossl3/saslauthd/lak.c
|
||||
--- cyrus-sasl-2.1.27/saslauthd/lak.c 2022-01-09 11:30:50.000000000 -0400
|
||||
+++ cyrus-sasl-2.1.27.ossl3/saslauthd/lak.c 2022-01-09 11:30:50.000000001 -0400
|
||||
@@ -1806,18 +1806,36 @@
|
||||
return rc;
|
||||
}
|
||||
|
||||
- EVP_DigestInit(mdctx, md);
|
||||
- EVP_DigestUpdate(mdctx, passwd, strlen(passwd));
|
||||
+ rc = EVP_DigestInit(mdctx, md);
|
||||
+ if (rc != 1) {
|
||||
+ rc = LAK_FAIL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ rc = EVP_DigestUpdate(mdctx, passwd, strlen(passwd));
|
||||
+ if (rc != 1) {
|
||||
+ rc = LAK_FAIL;
|
||||
+ goto done;
|
||||
+ }
|
||||
if (hrock->salted) {
|
||||
- EVP_DigestUpdate(mdctx, &cred[EVP_MD_size(md)],
|
||||
- clen - EVP_MD_size(md));
|
||||
+ rc = EVP_DigestUpdate(mdctx, &cred[EVP_MD_size(md)],
|
||||
+ clen - EVP_MD_size(md));
|
||||
+ if (rc != 1) {
|
||||
+ rc = LAK_FAIL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+ rc = EVP_DigestFinal(mdctx, digest, NULL);
|
||||
+ if (rc != 1) {
|
||||
+ rc = LAK_FAIL;
|
||||
+ goto done;
|
||||
}
|
||||
- EVP_DigestFinal(mdctx, digest, NULL);
|
||||
- EVP_MD_CTX_free(mdctx);
|
||||
|
||||
rc = memcmp((char *)cred, (char *)digest, EVP_MD_size(md));
|
||||
+ rc = rc ? LAK_INVALID_PASSWORD : LAK_OK;
|
||||
+done:
|
||||
+ EVP_MD_CTX_free(mdctx);
|
||||
free(cred);
|
||||
- return rc ? LAK_INVALID_PASSWORD : LAK_OK;
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
#endif /* HAVE_OPENSSL */
|
@ -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,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));
|
@ -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,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
|
@ -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, (int (*)(void)) 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;
|
||||
}
|
@ -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
|
@ -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
|
@ -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=
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue