import cyrus-sasl-2.1.27-17.el9
This commit is contained in:
		
						commit
						6f6f3f825e
					
				
							
								
								
									
										1
									
								
								.cyrus-sasl.metadata
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.cyrus-sasl.metadata
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| c9e6848d9cc6f9588e0e7a75423f9a3aed3f10db SOURCES/cyrus-sasl-2.1.27-nodlcompatorsrp.tar.gz | ||||
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| SOURCES/cyrus-sasl-2.1.27-nodlcompatorsrp.tar.gz | ||||
							
								
								
									
										37
									
								
								SOURCES/autogen.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								SOURCES/autogen.sh
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | ||||
| #!/bin/sh | ||||
| # Run this to generate all the initial makefiles, etc. | ||||
| test -n "$srcdir" || srcdir=`dirname "$0"` | ||||
| test -n "$srcdir" || srcdir=. | ||||
| 
 | ||||
| olddir=`pwd` | ||||
| 
 | ||||
| cd $srcdir | ||||
| 
 | ||||
| (test -f configure.ac) || { | ||||
| 	echo "*** ERROR: Directory "\`$srcdir\'" does not look like the top-level project directory ***" | ||||
| 	exit 1 | ||||
| } | ||||
| 
 | ||||
| PKG_NAME=`autoconf --trace 'AC_INIT:$1' configure.ac` | ||||
| 
 | ||||
| if [ "$#" = 0 -a "x$NOCONFIGURE" = "x" ]; then | ||||
| 	echo "*** WARNING: I am going to run \`configure' with no arguments." >&2 | ||||
| 	echo "*** If you wish to pass any to it, please specify them on the" >&2 | ||||
| 	echo "*** \`$0\' command line." >&2 | ||||
| 	echo "" >&2 | ||||
| fi | ||||
| 
 | ||||
| aclocal --install || exit 1 | ||||
| autoreconf --verbose --force --install -Wno-portability || exit 1 | ||||
| 
 | ||||
| cd $olddir | ||||
| if [ "$NOCONFIGURE" = "" ]; then | ||||
| 	$srcdir/configure "$@" || exit 1 | ||||
| 
 | ||||
| 	if [ "$1" = "--help" ]; then exit 0 else | ||||
| 		echo "Now type \`make\' to compile $PKG_NAME" || exit 1 | ||||
| 	fi | ||||
| else | ||||
| 	echo "Skipping configure process." | ||||
| fi | ||||
| 
 | ||||
							
								
								
									
										26
									
								
								SOURCES/cyrus-sasl-2.1.20-saslauthd.conf-path.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								SOURCES/cyrus-sasl-2.1.20-saslauthd.conf-path.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| diff -up cyrus-sasl-2.1.27/saslauthd/saslauthd.mdoc.path cyrus-sasl-2.1.27/saslauthd/saslauthd.mdoc
 | ||||
| --- cyrus-sasl-2.1.27/saslauthd/saslauthd.mdoc.path	2015-10-15 15:44:43.000000000 +0200
 | ||||
| +++ cyrus-sasl-2.1.27/saslauthd/saslauthd.mdoc	2015-11-20 15:05:30.421377527 +0100
 | ||||
| @@ -221,7 +221,7 @@ instead.
 | ||||
|  .Em (All platforms that support OpenLDAP 2.0 or higher) | ||||
|  .Pp | ||||
|  Authenticate against an ldap server.  The ldap configuration parameters are | ||||
| -read from /usr/local/etc/saslauthd.conf.  The location of this file can be
 | ||||
| +read from /etc/saslauthd.conf.  The location of this file can be
 | ||||
|  changed with the -O parameter. See the LDAP_SASLAUTHD file included with the | ||||
|  distribution for the list of available parameters. | ||||
|  .It Li sia | ||||
| @@ -251,10 +251,10 @@ these ticket files can cause serious per
 | ||||
|  servers. (Kerberos | ||||
|  was never intended to be used in this manner, anyway.) | ||||
|  .Sh FILES | ||||
| -.Bl -tag -width "/var/run/saslauthd/mux"
 | ||||
| -.It Pa /var/run/saslauthd/mux
 | ||||
| +.Bl -tag -width "/run/saslauthd/mux"
 | ||||
| +.It Pa /run/saslauthd/mux
 | ||||
|  The default communications socket. | ||||
| -.It Pa /usr/local/etc/saslauthd.conf
 | ||||
| +.It Pa /etc/saslauthd.conf
 | ||||
|  The default configuration file for ldap support. | ||||
|  .El | ||||
|  .Sh SEE ALSO | ||||
							
								
								
									
										119
									
								
								SOURCES/cyrus-sasl-2.1.21-sizes.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								SOURCES/cyrus-sasl-2.1.21-sizes.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,119 @@ | ||||
| diff -up cyrus-sasl-2.1.27/configure.ac.sizes cyrus-sasl-2.1.27/configure.ac
 | ||||
| --- cyrus-sasl-2.1.27/configure.ac.sizes	2015-11-18 09:46:24.000000000 +0100
 | ||||
| +++ cyrus-sasl-2.1.27/configure.ac	2015-11-20 15:11:20.474588247 +0100
 | ||||
| @@ -1312,6 +1312,10 @@ AC_HEADER_STDC
 | ||||
|  AC_HEADER_DIRENT | ||||
|  AC_HEADER_SYS_WAIT | ||||
|  AC_CHECK_HEADERS(crypt.h des.h dlfcn.h fcntl.h limits.h malloc.h paths.h strings.h sys/file.h sys/time.h syslog.h unistd.h inttypes.h sys/uio.h sys/param.h sysexits.h stdarg.h varargs.h krb5.h) | ||||
| +AC_CHECK_TYPES([long long, int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t],,,[
 | ||||
| +#ifdef HAVE_INTTYPES_H
 | ||||
| +#include <inttypes.h>
 | ||||
| +#endif])
 | ||||
|   | ||||
|  IPv6_CHECK_SS_FAMILY() | ||||
|  IPv6_CHECK_SA_LEN() | ||||
| diff -up cyrus-sasl-2.1.27/include/makemd5.c.sizes cyrus-sasl-2.1.27/include/makemd5.c
 | ||||
| --- cyrus-sasl-2.1.27/include/makemd5.c.sizes	2015-10-15 15:44:43.000000000 +0200
 | ||||
| +++ cyrus-sasl-2.1.27/include/makemd5.c	2015-11-20 15:11:20.477588240 +0100
 | ||||
| @@ -82,12 +82,19 @@
 | ||||
|   */ | ||||
|   | ||||
|   | ||||
| +#ifdef HAVE_CONFIG_H
 | ||||
| +#include "../config.h"
 | ||||
| +#endif
 | ||||
|   | ||||
|  #include <stdio.h> | ||||
|  #include <string.h> | ||||
|  #include <stdlib.h> | ||||
|  #include <ctype.h> | ||||
|   | ||||
| +#ifdef HAVE_INTTYPES_H
 | ||||
| +#include <inttypes.h>
 | ||||
| +#endif
 | ||||
| +
 | ||||
|   | ||||
|  static void | ||||
|  my_strupr(char *s) | ||||
| @@ -122,6 +129,18 @@ my_strupr(char *s)
 | ||||
|  static void | ||||
|  try_signed(FILE *f, int len) | ||||
|  { | ||||
| +#ifdef HAVE_INT8_T
 | ||||
| +    BITSIZE(int8_t);
 | ||||
| +#endif
 | ||||
| +#ifdef HAVE_INT16_T
 | ||||
| +    BITSIZE(int16_t);
 | ||||
| +#endif
 | ||||
| +#ifdef HAVE_INT32_T
 | ||||
| +    BITSIZE(int32_t);
 | ||||
| +#endif
 | ||||
| +#ifdef HAVE_INT64_T
 | ||||
| +    BITSIZE(int64_t);
 | ||||
| +#endif
 | ||||
|      BITSIZE(signed char); | ||||
|      BITSIZE(short); | ||||
|      BITSIZE(int); | ||||
| @@ -135,6 +154,18 @@ try_signed(FILE *f, int len)
 | ||||
|  static void | ||||
|  try_unsigned(FILE *f, int len) | ||||
|  { | ||||
| +#ifdef HAVE_UINT8_T
 | ||||
| +    BITSIZE(uint8_t);
 | ||||
| +#endif
 | ||||
| +#ifdef HAVE_UINT16_T
 | ||||
| +    BITSIZE(uint16_t);
 | ||||
| +#endif
 | ||||
| +#ifdef HAVE_UINT32_T
 | ||||
| +    BITSIZE(uint32_t);
 | ||||
| +#endif
 | ||||
| +#ifdef HAVE_UINT64_T
 | ||||
| +    BITSIZE(uint64_t);
 | ||||
| +#endif
 | ||||
|      BITSIZE(unsigned char); | ||||
|      BITSIZE(unsigned short); | ||||
|      BITSIZE(unsigned int); | ||||
| @@ -165,6 +196,11 @@ static int print_pre(FILE *f)
 | ||||
|  	  "/* POINTER defines a generic pointer type */\n" | ||||
|  	  "typedef unsigned char *POINTER;\n" | ||||
|  	  "\n" | ||||
| +#ifdef HAVE_INTTYPES_H
 | ||||
| +	  "/* We try to define integer types for our use */\n"
 | ||||
| +	  "#include <inttypes.h>\n"
 | ||||
| +	  "\n"
 | ||||
| +#endif
 | ||||
|  	  ); | ||||
|    return 1; | ||||
|  } | ||||
| @@ -212,31 +248,15 @@ int main(int argc, char **argv)
 | ||||
|   | ||||
|    print_pre(f); | ||||
|   | ||||
| -#ifndef HAVE_INT8_T
 | ||||
|      try_signed (f, 8); | ||||
| -#endif /* HAVE_INT8_T */
 | ||||
| -#ifndef HAVE_INT16_T
 | ||||
|      try_signed (f, 16); | ||||
| -#endif /* HAVE_INT16_T */
 | ||||
| -#ifndef HAVE_INT32_T
 | ||||
|      try_signed (f, 32); | ||||
| -#endif /* HAVE_INT32_T */
 | ||||
| -#ifndef HAVE_INT64_T
 | ||||
|      try_signed (f, 64); | ||||
| -#endif /* HAVE_INT64_T */
 | ||||
|   | ||||
| -#ifndef HAVE_U_INT8_T
 | ||||
|      try_unsigned (f, 8); | ||||
| -#endif /* HAVE_INT8_T */
 | ||||
| -#ifndef HAVE_U_INT16_T
 | ||||
|      try_unsigned (f, 16); | ||||
| -#endif /* HAVE_U_INT16_T */
 | ||||
| -#ifndef HAVE_U_INT32_T
 | ||||
|      try_unsigned (f, 32); | ||||
| -#endif /* HAVE_U_INT32_T */
 | ||||
| -#ifndef HAVE_U_INT64_T
 | ||||
|      try_unsigned (f, 64); | ||||
| -#endif /* HAVE_U_INT64_T */
 | ||||
|   | ||||
|      print_post(f); | ||||
|     | ||||
							
								
								
									
										24
									
								
								SOURCES/cyrus-sasl-2.1.23-man.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								SOURCES/cyrus-sasl-2.1.23-man.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| diff -up cyrus-sasl-2.1.26/saslauthd/testsaslauthd.8.man cyrus-sasl-2.1.26/saslauthd/testsaslauthd.8
 | ||||
| --- cyrus-sasl-2.1.26/saslauthd/testsaslauthd.8.man	2013-09-03 15:25:26.818042047 +0200
 | ||||
| +++ cyrus-sasl-2.1.26/saslauthd/testsaslauthd.8	2013-09-03 15:25:26.818042047 +0200
 | ||||
| @@ -0,0 +1,20 @@
 | ||||
| +.\"                                      Hey, EMACS: -*- nroff -*-
 | ||||
| +.TH TESTSASLAUTHD 8 "14 October 2006"
 | ||||
| +.SH NAME
 | ||||
| +testsaslauthd \- test utility for the SASL authentication server
 | ||||
| +.SH SYNOPSIS
 | ||||
| +.B testsaslauthd
 | ||||
| +.RI "[ " \(hyr " " realm " ] [ " \(hys " " servicename " ] [ " \(hyf " " socket " " path " ] [ " \(hyR " " repeatnum " ]"
 | ||||
| +.SH DESCRIPTION
 | ||||
| +This manual page documents briefly the
 | ||||
| +.B testsaslauthd
 | ||||
| +command.
 | ||||
| +.PP
 | ||||
| +.SH SEE ALSO
 | ||||
| +.BR saslauthd (8).
 | ||||
| +.br
 | ||||
| +.SH AUTHOR
 | ||||
| +testsaslauthd was written by Carnegie Mellon University.
 | ||||
| +.PP
 | ||||
| +This manual page was written by Roberto C. Sanchez <roberto@connexer.com>,
 | ||||
| +for the Debian project (but may be used by others).
 | ||||
							
								
								
									
										20
									
								
								SOURCES/cyrus-sasl-2.1.25-no_rpath.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								SOURCES/cyrus-sasl-2.1.25-no_rpath.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| diff -up cyrus-sasl-2.1.25/m4/cyrus.m4.no_rpath cyrus-sasl-2.1.25/m4/cyrus.m4
 | ||||
| --- cyrus-sasl-2.1.25/m4/cyrus.m4.no_rpath	2010-01-22 16:12:01.000000000 +0100
 | ||||
| +++ cyrus-sasl-2.1.25/m4/cyrus.m4	2012-12-06 14:59:47.956102057 +0100
 | ||||
| @@ -32,14 +32,5 @@ AC_DEFUN([CMU_ADD_LIBPATH_TO], [
 | ||||
|  dnl runpath initialization | ||||
|  AC_DEFUN([CMU_GUESS_RUNPATH_SWITCH], [ | ||||
|     # CMU GUESS RUNPATH SWITCH | ||||
| -  AC_CACHE_CHECK(for runpath switch, andrew_cv_runpath_switch, [
 | ||||
| -    # first, try -R
 | ||||
| -    SAVE_LDFLAGS="${LDFLAGS}"
 | ||||
| -    LDFLAGS="-R /usr/lib"
 | ||||
| -    AC_TRY_LINK([],[],[andrew_cv_runpath_switch="-R"], [
 | ||||
| -  	LDFLAGS="-Wl,-rpath,/usr/lib"
 | ||||
| -    AC_TRY_LINK([],[],[andrew_cv_runpath_switch="-Wl,-rpath,"],
 | ||||
| -    [andrew_cv_runpath_switch="none"])
 | ||||
| -    ])
 | ||||
| -  LDFLAGS="${SAVE_LDFLAGS}"
 | ||||
| -  ])])
 | ||||
| +    andrew_runpath_switch="none"
 | ||||
| +  ])
 | ||||
							
								
								
									
										24
									
								
								SOURCES/cyrus-sasl-2.1.26-md5global.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								SOURCES/cyrus-sasl-2.1.26-md5global.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| diff -up cyrus-sasl-2.1.27/include/Makefile.am.md5global.h cyrus-sasl-2.1.27/include/Makefile.am
 | ||||
| --- cyrus-sasl-2.1.27/include/Makefile.am.md5global.h	2018-05-17 13:33:49.588368350 +0200
 | ||||
| +++ cyrus-sasl-2.1.27/include/Makefile.am	2018-05-17 13:38:19.377316869 +0200
 | ||||
| @@ -49,20 +49,7 @@ saslinclude_HEADERS = hmac-md5.h md5.h m
 | ||||
|   | ||||
|  noinst_PROGRAMS = makemd5 | ||||
|   | ||||
| -makemd5_SOURCES = makemd5.c
 | ||||
| -
 | ||||
| -makemd5$(BUILD_EXEEXT) $(makemd5_OBJECTS): CC=$(CC_FOR_BUILD)
 | ||||
| -makemd5$(BUILD_EXEEXT) $(makemd5_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
 | ||||
| -makemd5$(BUILD_EXEEXT): LDFLAGS=$(LDFLAGS_FOR_BUILD)
 | ||||
| -
 | ||||
| -md5global.h: makemd5$(BUILD_EXEEXT) Makefile
 | ||||
| -	-rm -f $@
 | ||||
| -	./$< $@
 | ||||
| -
 | ||||
| -BUILT_SOURCES = md5global.h
 | ||||
| -
 | ||||
|  EXTRA_DIST = NTMakefile | ||||
| -DISTCLEANFILES = md5global.h
 | ||||
|   | ||||
|  if MACOSX | ||||
|  framedir = /Library/Frameworks/SASL2.framework | ||||
| @ -0,0 +1,444 @@ | ||||
| From aa8b6b2275fd14ba2cca3d2339ae61c7e7ddfa70 Mon Sep 17 00:00:00 2001 | ||||
| From: Simo Sorce <simo@redhat.com> | ||||
| Date: Tue, 5 May 2020 14:08:48 -0400 | ||||
| Subject: [PATCH] Add Channel Binding support for GSSAPI/GSS-SPNEGO | ||||
| 
 | ||||
| Backport of commit ids: | ||||
| 829a6ed086432e26dafa9d1dcf892aef4c42cfbd | ||||
| 944bd8a6205f840b105206ef83e8f6b9dff0138e | ||||
| 
 | ||||
| Signed-off-by: Simo Sorce <simo@redhat.com> | ||||
| ---
 | ||||
|  plugins/gssapi.c     | 30 +++++++++++--- | ||||
|  tests/runtests.py    | 93 ++++++++++++++++++++++++++++++++++++++++---- | ||||
|  tests/t_common.c     | 24 ++++++++---- | ||||
|  tests/t_common.h     |  5 ++- | ||||
|  tests/t_gssapi_cli.c | 24 ++++++++++-- | ||||
|  tests/t_gssapi_srv.c | 24 ++++++++++-- | ||||
|  6 files changed, 172 insertions(+), 28 deletions(-) | ||||
| 
 | ||||
| diff --git a/plugins/gssapi.c b/plugins/gssapi.c
 | ||||
| index ff663da..5d900c5 100644
 | ||||
| --- a/plugins/gssapi.c
 | ||||
| +++ b/plugins/gssapi.c
 | ||||
| @@ -830,7 +830,9 @@ gssapi_server_mech_authneg(context_t *text,
 | ||||
|      gss_buffer_desc name_without_realm; | ||||
|      gss_name_t client_name_MN = NULL, without = NULL; | ||||
|      gss_OID mech_type; | ||||
| -	
 | ||||
| +    gss_channel_bindings_t bindings = GSS_C_NO_CHANNEL_BINDINGS;
 | ||||
| +    struct gss_channel_bindings_struct cb = {0};
 | ||||
| +
 | ||||
|      input_token = &real_input_token; | ||||
|      output_token = &real_output_token; | ||||
|      output_token->value = NULL; output_token->length = 0; | ||||
| @@ -902,6 +904,12 @@ gssapi_server_mech_authneg(context_t *text,
 | ||||
|  	real_input_token.length = clientinlen; | ||||
|      } | ||||
|   | ||||
| +    if (params->cbinding != NULL) {
 | ||||
| +        cb.application_data.length = params->cbinding->len;
 | ||||
| +        cb.application_data.value = params->cbinding->data;
 | ||||
| +        bindings = &cb;
 | ||||
| +    }
 | ||||
| +
 | ||||
|   | ||||
|      GSS_LOCK_MUTEX_CTX(params->utils, text); | ||||
|      maj_stat = | ||||
| @@ -909,7 +917,7 @@ gssapi_server_mech_authneg(context_t *text,
 | ||||
|  			       &(text->gss_ctx), | ||||
|  			       server_creds, | ||||
|  			       input_token, | ||||
| -			       GSS_C_NO_CHANNEL_BINDINGS,
 | ||||
| +			       bindings,
 | ||||
|  			       &text->client_name, | ||||
|  			       &mech_type, | ||||
|  			       output_token, | ||||
| @@ -1505,7 +1513,8 @@ static sasl_server_plug_t gssapi_server_plugins[] =
 | ||||
|  	| SASL_SEC_PASS_CREDENTIALS, | ||||
|  	SASL_FEAT_WANT_CLIENT_FIRST | ||||
|  	| SASL_FEAT_ALLOWS_PROXY | ||||
| -	| SASL_FEAT_DONTUSE_USERPASSWD,	/* features */
 | ||||
| +	| SASL_FEAT_DONTUSE_USERPASSWD
 | ||||
| +	| SASL_FEAT_CHANNEL_BINDING,	/* features */
 | ||||
|  	NULL,				/* glob_context */ | ||||
|  	&gssapi_server_mech_new,	/* mech_new */ | ||||
|  	&gssapi_server_mech_step,	/* mech_step */ | ||||
| @@ -1529,6 +1538,7 @@ static sasl_server_plug_t gssapi_server_plugins[] =
 | ||||
|  	SASL_FEAT_WANT_CLIENT_FIRST | ||||
|  	| SASL_FEAT_ALLOWS_PROXY | ||||
|  	| SASL_FEAT_DONTUSE_USERPASSWD | ||||
| +	| SASL_FEAT_CHANNEL_BINDING
 | ||||
|  	| SASL_FEAT_SUPPORTS_HTTP,	/* features */ | ||||
|  	&gss_spnego_oid,		/* glob_context */ | ||||
|  	&gssapi_server_mech_new,	/* mech_new */ | ||||
| @@ -1662,6 +1672,8 @@ static int gssapi_client_mech_step(void *conn_context,
 | ||||
|      input_token->value = NULL;  | ||||
|      input_token->length = 0; | ||||
|      gss_cred_id_t client_creds = (gss_cred_id_t)params->gss_creds; | ||||
| +    gss_channel_bindings_t bindings = GSS_C_NO_CHANNEL_BINDINGS;
 | ||||
| +    struct gss_channel_bindings_struct cb = {0};
 | ||||
|   | ||||
|      if (clientout) | ||||
|          *clientout = NULL; | ||||
| @@ -1777,6 +1789,12 @@ static int gssapi_client_mech_step(void *conn_context,
 | ||||
|  	    req_flags = req_flags |  GSS_C_DELEG_FLAG; | ||||
|  	} | ||||
|   | ||||
| +        if (params->cbinding != NULL) {
 | ||||
| +            cb.application_data.length = params->cbinding->len;
 | ||||
| +            cb.application_data.value = params->cbinding->data;
 | ||||
| +            bindings = &cb;
 | ||||
| +        }
 | ||||
| +
 | ||||
|  	GSS_LOCK_MUTEX_CTX(params->utils, text); | ||||
|  	maj_stat = gss_init_sec_context(&min_stat, | ||||
|  					client_creds, /* GSS_C_NO_CREDENTIAL */ | ||||
| @@ -1785,7 +1803,7 @@ static int gssapi_client_mech_step(void *conn_context,
 | ||||
|  					text->mech_type, | ||||
|  					req_flags, | ||||
|  					0, | ||||
| -					GSS_C_NO_CHANNEL_BINDINGS,
 | ||||
| +					bindings,
 | ||||
|  					input_token, | ||||
|  					NULL, | ||||
|  					output_token, | ||||
| @@ -2190,7 +2208,8 @@ static sasl_client_plug_t gssapi_client_plugins[] =
 | ||||
|  	| SASL_SEC_PASS_CREDENTIALS,    /* security_flags */ | ||||
|  	SASL_FEAT_NEEDSERVERFQDN | ||||
|  	| SASL_FEAT_WANT_CLIENT_FIRST | ||||
| -	| SASL_FEAT_ALLOWS_PROXY,	/* features */
 | ||||
| +	| SASL_FEAT_ALLOWS_PROXY
 | ||||
| +	| SASL_FEAT_CHANNEL_BINDING,	/* features */
 | ||||
|  	gssapi_required_prompts,	/* required_prompts */ | ||||
|  	GSS_C_NO_OID,			/* glob_context */ | ||||
|  	&gssapi_client_mech_new,	/* mech_new */ | ||||
| @@ -2213,6 +2232,7 @@ static sasl_client_plug_t gssapi_client_plugins[] =
 | ||||
|  	SASL_FEAT_NEEDSERVERFQDN | ||||
|  	| SASL_FEAT_WANT_CLIENT_FIRST | ||||
|  	| SASL_FEAT_ALLOWS_PROXY | ||||
| +	| SASL_FEAT_CHANNEL_BINDING
 | ||||
|  	| SASL_FEAT_SUPPORTS_HTTP,	/* features */ | ||||
|  	gssapi_required_prompts,	/* required_prompts */ | ||||
|  	&gss_spnego_oid,		/* glob_context */ | ||||
| diff --git a/tests/runtests.py b/tests/runtests.py
 | ||||
| index f645adf..fc9cf24 100755
 | ||||
| --- a/tests/runtests.py
 | ||||
| +++ b/tests/runtests.py
 | ||||
| @@ -1,6 +1,7 @@
 | ||||
|  #!/usr/bin/python3 | ||||
|   | ||||
|  import argparse | ||||
| +import base64
 | ||||
|  import os | ||||
|  import shutil | ||||
|  import signal | ||||
| @@ -126,14 +127,7 @@ def setup_kdc(testdir, env):
 | ||||
|   | ||||
|      return kdc, env | ||||
|   | ||||
| -
 | ||||
| -def gssapi_tests(testdir):
 | ||||
| -    """ SASL/GSSAPI Tests """
 | ||||
| -    env = setup_socket_wrappers(testdir)
 | ||||
| -    kdc, kenv = setup_kdc(testdir, env)
 | ||||
| -    #print("KDC: {}, ENV: {}".format(kdc, kenv))
 | ||||
| -    kenv['KRB5_TRACE'] = os.path.join(testdir, 'trace.log')
 | ||||
| -
 | ||||
| +def gssapi_basic_test(kenv):
 | ||||
|      try: | ||||
|          srv = subprocess.Popen(["../tests/t_gssapi_srv"], | ||||
|                                 stdout=subprocess.PIPE, | ||||
| @@ -155,11 +149,94 @@ def gssapi_tests(testdir):
 | ||||
|                  srv.returncode, srv.stderr.read().decode('utf-8'))) | ||||
|      except Exception as e: | ||||
|          print("FAIL: {}".format(e)) | ||||
| +        return
 | ||||
| +
 | ||||
| +    print("PASS: CLI({}) SRV({})".format(
 | ||||
| +        cli.stdout.read().decode('utf-8').strip(),
 | ||||
| +        srv.stdout.read().decode('utf-8').strip()))
 | ||||
| +
 | ||||
| +def gssapi_channel_binding_test(kenv):
 | ||||
| +    try:
 | ||||
| +        bindings = base64.b64encode("MATCHING CBS".encode('utf-8'))
 | ||||
| +        srv = subprocess.Popen(["../tests/t_gssapi_srv", "-c", bindings],
 | ||||
| +                               stdout=subprocess.PIPE,
 | ||||
| +                               stderr=subprocess.PIPE, env=kenv)
 | ||||
| +        srv.stdout.readline() # Wait for srv to say it is ready
 | ||||
| +        cli = subprocess.Popen(["../tests/t_gssapi_cli", "-c", bindings],
 | ||||
| +                               stdout=subprocess.PIPE,
 | ||||
| +                               stderr=subprocess.PIPE, env=kenv)
 | ||||
| +        try:
 | ||||
| +            cli.wait(timeout=5)
 | ||||
| +            srv.wait(timeout=5)
 | ||||
| +        except Exception as e:
 | ||||
| +            print("Failed on {}".format(e));
 | ||||
| +            cli.kill()
 | ||||
| +            srv.kill()
 | ||||
| +        if cli.returncode != 0 or srv.returncode != 0:
 | ||||
| +            raise Exception("CLI ({}): {} --> SRV ({}): {}".format(
 | ||||
| +                cli.returncode, cli.stderr.read().decode('utf-8'),
 | ||||
| +                srv.returncode, srv.stderr.read().decode('utf-8')))
 | ||||
| +    except Exception as e:
 | ||||
| +        print("FAIL: {}".format(e))
 | ||||
| +        return
 | ||||
|   | ||||
|      print("PASS: CLI({}) SRV({})".format( | ||||
|          cli.stdout.read().decode('utf-8').strip(), | ||||
|          srv.stdout.read().decode('utf-8').strip())) | ||||
|   | ||||
| +def gssapi_channel_binding_mismatch_test(kenv):
 | ||||
| +    result = "FAIL"
 | ||||
| +    try:
 | ||||
| +        bindings = base64.b64encode("SRV CBS".encode('utf-8'))
 | ||||
| +        srv = subprocess.Popen(["../tests/t_gssapi_srv", "-c", bindings],
 | ||||
| +                               stdout=subprocess.PIPE,
 | ||||
| +                               stderr=subprocess.PIPE, env=kenv)
 | ||||
| +        srv.stdout.readline() # Wait for srv to say it is ready
 | ||||
| +        bindings = base64.b64encode("CLI CBS".encode('utf-8'))
 | ||||
| +        cli = subprocess.Popen(["../tests/t_gssapi_cli", "-c", bindings],
 | ||||
| +                               stdout=subprocess.PIPE,
 | ||||
| +                               stderr=subprocess.PIPE, env=kenv)
 | ||||
| +        try:
 | ||||
| +            cli.wait(timeout=5)
 | ||||
| +            srv.wait(timeout=5)
 | ||||
| +        except Exception as e:
 | ||||
| +            print("Failed on {}".format(e));
 | ||||
| +            cli.kill()
 | ||||
| +            srv.kill()
 | ||||
| +        if cli.returncode != 0 or srv.returncode != 0:
 | ||||
| +            cli_err = cli.stderr.read().decode('utf-8').strip()
 | ||||
| +            srv_err = srv.stderr.read().decode('utf-8').strip()
 | ||||
| +            if "authentication failure" in srv_err:
 | ||||
| +                result = "PASS"
 | ||||
| +            raise Exception("CLI ({}): {} --> SRV ({}): {}".format(
 | ||||
| +                cli.returncode, cli_err, srv.returncode, srv_err))
 | ||||
| +    except Exception as e:
 | ||||
| +        print("{}: {}".format(result, e))
 | ||||
| +        return
 | ||||
| +
 | ||||
| +    print("FAIL: This test should fail [CLI({}) SRV({})]".format(
 | ||||
| +        cli.stdout.read().decode('utf-8').strip(),
 | ||||
| +        srv.stdout.read().decode('utf-8').strip()))
 | ||||
| +
 | ||||
| +def gssapi_tests(testdir):
 | ||||
| +    """ SASL/GSSAPI Tests """
 | ||||
| +    env = setup_socket_wrappers(testdir)
 | ||||
| +    kdc, kenv = setup_kdc(testdir, env)
 | ||||
| +    #print("KDC: {}, ENV: {}".format(kdc, kenv))
 | ||||
| +    kenv['KRB5_TRACE'] = os.path.join(testdir, 'trace.log')
 | ||||
| +
 | ||||
| +    print('GSSAPI BASIC:')
 | ||||
| +    print('    ', end='')
 | ||||
| +    gssapi_basic_test(kenv)
 | ||||
| +
 | ||||
| +    print('GSSAPI CHANNEL BINDING:')
 | ||||
| +    print('    ', end='')
 | ||||
| +    gssapi_channel_binding_test(kenv)
 | ||||
| +
 | ||||
| +    print('GSSAPI CHANNEL BINDING MISMTACH:')
 | ||||
| +    print('    ', end='')
 | ||||
| +    gssapi_channel_binding_mismatch_test(kenv)
 | ||||
| +
 | ||||
|      os.killpg(kdc.pid, signal.SIGTERM) | ||||
|   | ||||
|   | ||||
| diff --git a/tests/t_common.c b/tests/t_common.c
 | ||||
| index 7168b2f..478e6a1 100644
 | ||||
| --- a/tests/t_common.c
 | ||||
| +++ b/tests/t_common.c
 | ||||
| @@ -1,4 +1,5 @@
 | ||||
| -/* TBD, add (C) */
 | ||||
| +/* Copyright (C) Simo Sorce <simo@redhat.com>
 | ||||
| + * See COPYING file for License */
 | ||||
|   | ||||
|  #include <t_common.h> | ||||
|   | ||||
| @@ -13,9 +14,6 @@ void send_string(int sd, const char *s, unsigned int l)
 | ||||
|  { | ||||
|      ssize_t ret; | ||||
|   | ||||
| -fprintf(stderr, "s:%u ", l);
 | ||||
| -fflush(stderr);
 | ||||
| -
 | ||||
|      ret = send(sd, &l, sizeof(l), 0); | ||||
|      if (ret != sizeof(l)) s_error("send size", ret, sizeof(l), errno); | ||||
|   | ||||
| @@ -34,8 +32,6 @@ void recv_string(int sd, char *buf, unsigned int *buflen)
 | ||||
|      if (ret != sizeof(l)) s_error("recv size", ret, sizeof(l), errno); | ||||
|   | ||||
|      if (l == 0) { | ||||
| -fprintf(stderr, "r:0 ");
 | ||||
| -fflush(stderr);
 | ||||
|          *buflen = 0; | ||||
|          return; | ||||
|      } | ||||
| @@ -45,8 +41,6 @@ fflush(stderr);
 | ||||
|      ret = recv(sd, buf, l, 0); | ||||
|      if (ret != l) s_error("recv data", ret, l, errno); | ||||
|   | ||||
| -fprintf(stderr, "r:%ld ", ret);
 | ||||
| -fflush(stderr);
 | ||||
|      *buflen = ret; | ||||
|  } | ||||
|   | ||||
| @@ -65,4 +59,18 @@ int getpath(void *context __attribute__((unused)), const char **path)
 | ||||
|      return SASL_OK; | ||||
|  } | ||||
|   | ||||
| +void parse_cb(sasl_channel_binding_t *cb, char *buf, unsigned max, char *in)
 | ||||
| +{
 | ||||
| +    unsigned len;
 | ||||
| +    int r;
 | ||||
|   | ||||
| +    r = sasl_decode64(in, strlen(in), buf, max, &len);
 | ||||
| +    if (r != SASL_OK) {
 | ||||
| +        saslerr(r, "failed to parse channel bindings");
 | ||||
| +        exit(-1);
 | ||||
| +    }
 | ||||
| +    cb->name = "TEST BINDINGS";
 | ||||
| +    cb->critical = 0;
 | ||||
| +    cb->data = (unsigned char *)buf;
 | ||||
| +    cb->len = len;
 | ||||
| +}
 | ||||
| diff --git a/tests/t_common.h b/tests/t_common.h
 | ||||
| index 4ee1976..a10def1 100644
 | ||||
| --- a/tests/t_common.h
 | ||||
| +++ b/tests/t_common.h
 | ||||
| @@ -1,4 +1,5 @@
 | ||||
| -/* TBD, add (C) */
 | ||||
| +/* Copyright (C) Simo Sorce <simo@redhat.com>
 | ||||
| + * See COPYING file for License */
 | ||||
|   | ||||
|  #include "config.h" | ||||
|   | ||||
| @@ -7,9 +8,11 @@
 | ||||
|  #include <sys/socket.h> | ||||
|   | ||||
|  #include <sasl.h> | ||||
| +#include <saslutil.h>
 | ||||
|   | ||||
|  void s_error(const char *hdr, ssize_t ret, ssize_t len, int err); | ||||
|  void send_string(int sd, const char *s, unsigned int l); | ||||
|  void recv_string(int sd, char *buf, unsigned int *buflen); | ||||
|  void saslerr(int why, const char *what); | ||||
|  int getpath(void *context __attribute__((unused)), const char **path); | ||||
| +void parse_cb(sasl_channel_binding_t *cb, char *buf, unsigned max, char *in);
 | ||||
| diff --git a/tests/t_gssapi_cli.c b/tests/t_gssapi_cli.c
 | ||||
| index c833c05..a44a3f5 100644
 | ||||
| --- a/tests/t_gssapi_cli.c
 | ||||
| +++ b/tests/t_gssapi_cli.c
 | ||||
| @@ -1,4 +1,5 @@
 | ||||
| -/* TBD, add (C) */
 | ||||
| +/* Copyright (C) Simo Sorce <simo@redhat.com>
 | ||||
| + * See COPYING file for License */
 | ||||
|   | ||||
|  #include "t_common.h" | ||||
|   | ||||
| @@ -13,6 +14,7 @@
 | ||||
|   | ||||
|  #include <arpa/inet.h> | ||||
|  #include <saslplug.h> | ||||
| +#include <saslutil.h>
 | ||||
|   | ||||
|  static int setup_socket(void) | ||||
|  { | ||||
| @@ -32,7 +34,7 @@ static int setup_socket(void)
 | ||||
|      return sock; | ||||
|  } | ||||
|   | ||||
| -int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
 | ||||
| +int main(int argc, char *argv[])
 | ||||
|  { | ||||
|      sasl_callback_t callbacks[2] = {}; | ||||
|      char buf[8192]; | ||||
| @@ -40,8 +42,20 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
 | ||||
|      sasl_conn_t *conn; | ||||
|      const char *data; | ||||
|      unsigned int len; | ||||
| +    sasl_channel_binding_t cb = {0};
 | ||||
| +    char cb_buf[256];
 | ||||
|      int sd; | ||||
| -    int r;
 | ||||
| +    int c, r;
 | ||||
| +
 | ||||
| +    while ((c = getopt(argc, argv, "c:")) != EOF) {
 | ||||
| +        switch (c) {
 | ||||
| +        case 'c':
 | ||||
| +            parse_cb(&cb, cb_buf, 256, optarg);
 | ||||
| +            break;
 | ||||
| +        default:
 | ||||
| +            break;
 | ||||
| +        }
 | ||||
| +    }
 | ||||
|   | ||||
|      /* initialize the sasl library */ | ||||
|      callbacks[0].id = SASL_CB_GETPATH; | ||||
| @@ -60,6 +74,10 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
 | ||||
|          exit(-1); | ||||
|      } | ||||
|   | ||||
| +    if (cb.name) {
 | ||||
| +        sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb);
 | ||||
| +    }
 | ||||
| +
 | ||||
|      r = sasl_client_start(conn, "GSSAPI", NULL, &data, &len, &chosenmech); | ||||
|      if (r != SASL_OK && r != SASL_CONTINUE) { | ||||
|  	saslerr(r, "starting SASL negotiation"); | ||||
| diff --git a/tests/t_gssapi_srv.c b/tests/t_gssapi_srv.c
 | ||||
| index 29f538d..ef1217f 100644
 | ||||
| --- a/tests/t_gssapi_srv.c
 | ||||
| +++ b/tests/t_gssapi_srv.c
 | ||||
| @@ -1,4 +1,5 @@
 | ||||
| -/* TBD, add (C) */
 | ||||
| +/* Copyright (C) Simo Sorce <simo@redhat.com>
 | ||||
| + * See COPYING file for License */
 | ||||
|   | ||||
|  #include "t_common.h" | ||||
|   | ||||
| @@ -44,15 +45,28 @@ static int setup_socket(void)
 | ||||
|      return sd; | ||||
|  } | ||||
|   | ||||
| -int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
 | ||||
| +int main(int argc, char *argv[])
 | ||||
|  { | ||||
|      sasl_callback_t callbacks[2] = {}; | ||||
|      char buf[8192]; | ||||
|      sasl_conn_t *conn; | ||||
|      const char *data; | ||||
|      unsigned int len; | ||||
| +    sasl_channel_binding_t cb = {0};
 | ||||
| +    unsigned char cb_buf[256];
 | ||||
|      int sd; | ||||
| -    int r;
 | ||||
| +    int c, r;
 | ||||
| +
 | ||||
| +    while ((c = getopt(argc, argv, "c:")) != EOF) {
 | ||||
| +        switch (c) {
 | ||||
| +        case 'c':
 | ||||
| +            parse_cb(&cb, cb_buf, 256, optarg);
 | ||||
| +            break;
 | ||||
| +        default:
 | ||||
| +            break;
 | ||||
| +        }
 | ||||
| +    }
 | ||||
| +
 | ||||
|   | ||||
|      /* initialize the sasl library */ | ||||
|      callbacks[0].id = SASL_CB_GETPATH; | ||||
| @@ -72,6 +86,10 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
 | ||||
|          exit(-1); | ||||
|      } | ||||
|   | ||||
| +    if (cb.name) {
 | ||||
| +        sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb);
 | ||||
| +    }
 | ||||
| +
 | ||||
|      sd = setup_socket(); | ||||
|   | ||||
|      len = 8192; | ||||
| -- 
 | ||||
| 2.18.2 | ||||
| 
 | ||||
							
								
								
									
										641
									
								
								SOURCES/cyrus-sasl-2.1.27-Add-basic-test-infrastructure.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										641
									
								
								SOURCES/cyrus-sasl-2.1.27-Add-basic-test-infrastructure.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,641 @@ | ||||
| From 82e299e970461c153a036bb1fbc84e808f926e12 Mon Sep 17 00:00:00 2001 | ||||
| From: Simo Sorce <simo@redhat.com> | ||||
| Date: Tue, 5 May 2020 14:06:57 -0400 | ||||
| Subject: [PATCH] Add basic test infrastructure | ||||
| 
 | ||||
| First test is for SASL/GSSAPI | ||||
| 
 | ||||
| Backport of upstream commit id: | ||||
| 18ff41d5d18f61c2ded7235dad1d9618aa84784b | ||||
| 
 | ||||
| Signed-off-by: Simo Sorce <simo@redhat.com> | ||||
| ---
 | ||||
|  Makefile.am          |   2 +- | ||||
|  configure.ac         |   3 +- | ||||
|  tests/Makefile.am    |  79 +++++++++++++++++++ | ||||
|  tests/runtests.py    | 179 +++++++++++++++++++++++++++++++++++++++++++ | ||||
|  tests/t_common.c     |  68 ++++++++++++++++ | ||||
|  tests/t_common.h     |  15 ++++ | ||||
|  tests/t_gssapi_cli.c |  95 +++++++++++++++++++++++ | ||||
|  tests/t_gssapi_srv.c | 111 +++++++++++++++++++++++++++ | ||||
|  8 files changed, 550 insertions(+), 2 deletions(-) | ||||
|  create mode 100644 tests/Makefile.am | ||||
|  create mode 100755 tests/runtests.py | ||||
|  create mode 100644 tests/t_common.c | ||||
|  create mode 100644 tests/t_common.h | ||||
|  create mode 100644 tests/t_gssapi_cli.c | ||||
|  create mode 100644 tests/t_gssapi_srv.c | ||||
| 
 | ||||
| diff --git a/Makefile.am b/Makefile.am
 | ||||
| index 83dae6f..fc24509 100644
 | ||||
| --- a/Makefile.am
 | ||||
| +++ b/Makefile.am
 | ||||
| @@ -70,7 +70,7 @@ else
 | ||||
|  INSTALLOSX =  | ||||
|  endif | ||||
|   | ||||
| -SUBDIRS=include sasldb common lib plugins utils $(PWC) $(SAM) $(JAV) $(SAD)
 | ||||
| +SUBDIRS=include sasldb common lib plugins utils $(PWC) $(SAM) $(JAV) $(SAD) tests
 | ||||
|  EXTRA_DIST=config doc docsrc win32 mac dlcompat-20010505 NTMakefile \ | ||||
|      INSTALL.TXT libsasl2.pc.in | ||||
|   | ||||
| diff --git a/configure.ac b/configure.ac
 | ||||
| index ca5936a..c1d2182 100644
 | ||||
| --- a/configure.ac
 | ||||
| +++ b/configure.ac
 | ||||
| @@ -1575,7 +1575,8 @@ java/javax/Makefile
 | ||||
|  java/javax/security/Makefile | ||||
|  java/javax/security/auth/Makefile | ||||
|  java/javax/security/auth/callback/Makefile | ||||
| -pwcheck/Makefile)
 | ||||
| +pwcheck/Makefile
 | ||||
| +tests/Makefile)
 | ||||
|   | ||||
|  AC_MSG_NOTICE([ | ||||
|   | ||||
| diff --git a/tests/Makefile.am b/tests/Makefile.am
 | ||||
| new file mode 100644 | ||||
| index 0000000..1edf010
 | ||||
| --- /dev/null
 | ||||
| +++ b/tests/Makefile.am
 | ||||
| @@ -0,0 +1,79 @@
 | ||||
| +# Makefile.am -- automake input for cyrus-sasl tests
 | ||||
| +# Simo Sorce
 | ||||
| +#
 | ||||
| +################################################################
 | ||||
| +# Copyright (c) 2000 Carnegie Mellon University.  All rights reserved.
 | ||||
| +#
 | ||||
| +# Redistribution and use in source and binary forms, with or without
 | ||||
| +# modification, are permitted provided that the following conditions
 | ||||
| +# are met:
 | ||||
| +#
 | ||||
| +# 1. Redistributions of source code must retain the above copyright
 | ||||
| +#    notice, this list of conditions and the following disclaimer.
 | ||||
| +#
 | ||||
| +# 2. Redistributions in binary form must reproduce the above copyright
 | ||||
| +#    notice, this list of conditions and the following disclaimer in
 | ||||
| +#    the documentation and/or other materials provided with the
 | ||||
| +#    distribution.
 | ||||
| +#
 | ||||
| +# 3. The name "Carnegie Mellon University" must not be used to
 | ||||
| +#    endorse or promote products derived from this software without
 | ||||
| +#    prior written permission. For permission or any other legal
 | ||||
| +#    details, please contact
 | ||||
| +#      Office of Technology Transfer
 | ||||
| +#      Carnegie Mellon University
 | ||||
| +#      5000 Forbes Avenue
 | ||||
| +#      Pittsburgh, PA  15213-3890
 | ||||
| +#      (412) 268-4387, fax: (412) 268-7395
 | ||||
| +#      tech-transfer@andrew.cmu.edu
 | ||||
| +#
 | ||||
| +# 4. Redistributions of any form whatsoever must retain the following
 | ||||
| +#    acknowledgment:
 | ||||
| +#    "This product includes software developed by Computing Services
 | ||||
| +#     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
 | ||||
| +#
 | ||||
| +# CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
 | ||||
| +# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 | ||||
| +# AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
 | ||||
| +# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | ||||
| +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
 | ||||
| +# AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | ||||
| +# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | ||||
| +#
 | ||||
| +################################################################
 | ||||
| +
 | ||||
| +AM_CPPFLAGS=-I$(top_srcdir)/include -DPLUGINDIR='"${top_srcdir}/plugins/.libs"'
 | ||||
| +
 | ||||
| +COMMON_LDADD = ../lib/libsasl2.la $(GSSAPIBASE_LIBS) $(GSSAPI_LIBS) $(LIB_SOCKET)
 | ||||
| +
 | ||||
| +t_gssapi_cli_SOURCES = \
 | ||||
| +	t_common.c \
 | ||||
| +	t_gssapi_cli.c
 | ||||
| +
 | ||||
| +t_gssapi_cli_LDADD = $(COMMON_LDADD)
 | ||||
| +
 | ||||
| +t_gssapi_srv_SOURCES = \
 | ||||
| +	t_common.c \
 | ||||
| +	t_gssapi_srv.c
 | ||||
| +
 | ||||
| +t_gssapi_srv_LDADD = $(COMMON_LDADD)
 | ||||
| +
 | ||||
| +check_PROGRAMS = \
 | ||||
| +	t_gssapi_cli \
 | ||||
| +	t_gssapi_srv \
 | ||||
| +	$(NULL)
 | ||||
| +
 | ||||
| +noinst_PROGRAMS = $(check_PROGRAMS)
 | ||||
| +
 | ||||
| +EXTRA_DIST = \
 | ||||
| +	runtests.py \
 | ||||
| +	$(NULL)
 | ||||
| +
 | ||||
| +all: $(check_PROGRAMS)
 | ||||
| +
 | ||||
| +check:
 | ||||
| +if MACOSX
 | ||||
| +# skip Mac OSX for now
 | ||||
| +else
 | ||||
| +	$(srcdir)/runtests.py $(CHECKARGS)
 | ||||
| +endif
 | ||||
| diff --git a/tests/runtests.py b/tests/runtests.py
 | ||||
| new file mode 100755 | ||||
| index 0000000..f645adf
 | ||||
| --- /dev/null
 | ||||
| +++ b/tests/runtests.py
 | ||||
| @@ -0,0 +1,179 @@
 | ||||
| +#!/usr/bin/python3
 | ||||
| +
 | ||||
| +import argparse
 | ||||
| +import os
 | ||||
| +import shutil
 | ||||
| +import signal
 | ||||
| +import subprocess
 | ||||
| +import time
 | ||||
| +from string import Template
 | ||||
| +
 | ||||
| +
 | ||||
| +def setup_socket_wrappers(testdir):
 | ||||
| +    """ Try to set up socket wrappers """
 | ||||
| +    wrapdir = os.path.join(testdir, 'w')
 | ||||
| +    os.makedirs(wrapdir)
 | ||||
| +
 | ||||
| +    wrappers = subprocess.Popen(['pkg-config', '--exists', 'socket_wrapper'])
 | ||||
| +    wrappers.wait()
 | ||||
| +    if wrappers.returncode != 0:
 | ||||
| +        raise Exception('Socket Wrappers not available')
 | ||||
| +
 | ||||
| +    wrappers = subprocess.Popen(['pkg-config', '--exists', 'nss_wrapper'])
 | ||||
| +    wrappers.wait()
 | ||||
| +    if wrappers.returncode != 0:
 | ||||
| +        raise Exception('NSS Wrappers not available')
 | ||||
| +
 | ||||
| +    hosts = os.path.join(wrapdir, 'hosts')
 | ||||
| +    with open(hosts, 'w+') as conffile:
 | ||||
| +        conffile.write('127.0.0.9 host.realm.test')
 | ||||
| +
 | ||||
| +    return {'LD_PRELOAD': 'libsocket_wrapper.so libnss_wrapper.so',
 | ||||
| +            'SOCKET_WRAPPER_DIR': wrapdir,
 | ||||
| +            'SOCKET_WRAPPER_DEFAULT_IFACE': '9',
 | ||||
| +            'NSS_WRAPPER_HOSTNAME': 'host.realm.test',
 | ||||
| +            'NSS_WRAPPER_HOSTS': hosts}
 | ||||
| +
 | ||||
| +
 | ||||
| +KERBEROS_CONF = '''
 | ||||
| +[libdefaults]
 | ||||
| +  default_realm = REALM.TEST
 | ||||
| +  dns_lookup_realm = false
 | ||||
| +  dns_lookup_kdc = false
 | ||||
| +  rdns = false
 | ||||
| +  ticket_lifetime = 24h
 | ||||
| +  forwardable = yes
 | ||||
| +  default_ccache_name = FILE://${TESTDIR}/ccache
 | ||||
| +  udp_preference_limit = 1
 | ||||
| +
 | ||||
| +[domain_realm]
 | ||||
| +  .realm.test = REALM.TEST
 | ||||
| +  realm.test = REALM.TEST
 | ||||
| +
 | ||||
| +[realms]
 | ||||
| + REALM.TEST = {
 | ||||
| +  kdc = 127.0.0.9
 | ||||
| +  admin_server = 127.0.0.9
 | ||||
| +  acl_file = ${TESTDIR}/kadm.acl
 | ||||
| +  dict_file = /usr/share/dict/words
 | ||||
| +  admin_keytab = ${TESTDIR}/kadm.keytab
 | ||||
| +  database_name = ${TESTDIR}/kdc.db
 | ||||
| +  key_stash_file = ${TESTDIR}/kdc.stash
 | ||||
| + }
 | ||||
| +
 | ||||
| +[kdcdefaults]
 | ||||
| + kdc_ports = 88
 | ||||
| + kdc_tcp_ports = 88
 | ||||
| +
 | ||||
| +[logging]
 | ||||
| +  kdc = FILE:${TESTDIR}/kdc.log
 | ||||
| +  admin_server = FILE:${TESTDIR}/kadm.log
 | ||||
| +  default = FILE:${TESTDIR}/krb5.log
 | ||||
| +'''
 | ||||
| +
 | ||||
| +
 | ||||
| +def setup_kdc(testdir, env):
 | ||||
| +    """ Setup KDC and start process """
 | ||||
| +    krbconf = os.path.join(testdir, 'krb.conf')
 | ||||
| +    env['KRB5_CONFIG'] = krbconf
 | ||||
| +
 | ||||
| +    kenv = {'KRB5_KDC_PROFILE': krbconf,
 | ||||
| +            'PATH': '/sbin:/bin:/usr/sbin:/usr/bin'}
 | ||||
| +    kenv.update(env)
 | ||||
| +
 | ||||
| +    # KDC/KRB5 CONFIG
 | ||||
| +    templ = Template(KERBEROS_CONF)
 | ||||
| +    text = templ.substitute({'TESTDIR': testdir})
 | ||||
| +    with open(krbconf, 'w+') as conffile:
 | ||||
| +        conffile.write(text)
 | ||||
| +
 | ||||
| +    testlog = os.path.join(testdir, 'kdc.log')
 | ||||
| +    log = open(testlog, 'a')
 | ||||
| +
 | ||||
| +    subprocess.check_call([
 | ||||
| +        "kdb5_util", "create",
 | ||||
| +        "-r", "REALM.TEST", "-s", "-P", "password"
 | ||||
| +        ], stdout=log, stderr=log, env=kenv, timeout=5)
 | ||||
| +
 | ||||
| +    kdc = subprocess.Popen(['krb5kdc', '-n'], env=kenv, preexec_fn=os.setsid)
 | ||||
| +    time.sleep(5)
 | ||||
| +
 | ||||
| +    # Add a user and genrate a keytab
 | ||||
| +    keytab = os.path.join(testdir, "user.keytab")
 | ||||
| +    subprocess.check_call([
 | ||||
| +        "kadmin.local", "-q",
 | ||||
| +        "addprinc -randkey user"
 | ||||
| +        ], stdout=log, stderr=log, env=kenv, timeout=5)
 | ||||
| +
 | ||||
| +    subprocess.check_call([
 | ||||
| +        "kadmin.local", "-q",
 | ||||
| +        "ktadd -k {} user".format(keytab)
 | ||||
| +        ], stdout=log, stderr=log, env=kenv, timeout=5)
 | ||||
| +    env['KRB5_CLIENT_KTNAME'] = keytab
 | ||||
| +
 | ||||
| +    # Add a service and genrate a keytab
 | ||||
| +    keytab = os.path.join(testdir, "test.keytab")
 | ||||
| +    subprocess.check_call([
 | ||||
| +        "kadmin.local", "-q",
 | ||||
| +        "addprinc -randkey test/host.realm.test"
 | ||||
| +        ], stdout=log, stderr=log, env=kenv, timeout=5)
 | ||||
| +
 | ||||
| +    subprocess.check_call([
 | ||||
| +        "kadmin.local", "-q",
 | ||||
| +        "ktadd -k {} test/host.realm.test".format(keytab)
 | ||||
| +        ], stdout=log, stderr=log, env=kenv, timeout=5)
 | ||||
| +    env['KRB5_KTNAME'] = keytab
 | ||||
| +
 | ||||
| +    return kdc, env
 | ||||
| +
 | ||||
| +
 | ||||
| +def gssapi_tests(testdir):
 | ||||
| +    """ SASL/GSSAPI Tests """
 | ||||
| +    env = setup_socket_wrappers(testdir)
 | ||||
| +    kdc, kenv = setup_kdc(testdir, env)
 | ||||
| +    #print("KDC: {}, ENV: {}".format(kdc, kenv))
 | ||||
| +    kenv['KRB5_TRACE'] = os.path.join(testdir, 'trace.log')
 | ||||
| +
 | ||||
| +    try:
 | ||||
| +        srv = subprocess.Popen(["../tests/t_gssapi_srv"],
 | ||||
| +                               stdout=subprocess.PIPE,
 | ||||
| +                               stderr=subprocess.PIPE, env=kenv)
 | ||||
| +        srv.stdout.readline() # Wait for srv to say it is ready
 | ||||
| +        cli = subprocess.Popen(["../tests/t_gssapi_cli"],
 | ||||
| +                               stdout=subprocess.PIPE,
 | ||||
| +                               stderr=subprocess.PIPE, env=kenv)
 | ||||
| +        try:
 | ||||
| +            cli.wait(timeout=5)
 | ||||
| +            srv.wait(timeout=5)
 | ||||
| +        except Exception as e:
 | ||||
| +            print("Failed on {}".format(e));
 | ||||
| +            cli.kill()
 | ||||
| +            srv.kill()
 | ||||
| +        if cli.returncode != 0 or srv.returncode != 0:
 | ||||
| +            raise Exception("CLI ({}): {} --> SRV ({}): {}".format(
 | ||||
| +                cli.returncode, cli.stderr.read().decode('utf-8'),
 | ||||
| +                srv.returncode, srv.stderr.read().decode('utf-8')))
 | ||||
| +    except Exception as e:
 | ||||
| +        print("FAIL: {}".format(e))
 | ||||
| +
 | ||||
| +    print("PASS: CLI({}) SRV({})".format(
 | ||||
| +        cli.stdout.read().decode('utf-8').strip(),
 | ||||
| +        srv.stdout.read().decode('utf-8').strip()))
 | ||||
| +
 | ||||
| +    os.killpg(kdc.pid, signal.SIGTERM)
 | ||||
| +
 | ||||
| +
 | ||||
| +if __name__ == "__main__":
 | ||||
| +
 | ||||
| +    P = argparse.ArgumentParser(description='Cyrus SASL Tests')
 | ||||
| +    P.add_argument('--testdir', default=os.path.join(os.getcwd(), '.tests'),
 | ||||
| +                   help="Directory for running tests")
 | ||||
| +    A = vars(P.parse_args())
 | ||||
| +
 | ||||
| +    T = A['testdir']
 | ||||
| +
 | ||||
| +    if os.path.exists(T):
 | ||||
| +        shutil.rmtree(T)
 | ||||
| +    os.makedirs(T)
 | ||||
| +
 | ||||
| +    gssapi_tests(T)
 | ||||
| diff --git a/tests/t_common.c b/tests/t_common.c
 | ||||
| new file mode 100644 | ||||
| index 0000000..7168b2f
 | ||||
| --- /dev/null
 | ||||
| +++ b/tests/t_common.c
 | ||||
| @@ -0,0 +1,68 @@
 | ||||
| +/* TBD, add (C) */
 | ||||
| +
 | ||||
| +#include <t_common.h>
 | ||||
| +
 | ||||
| +void s_error(const char *hdr, ssize_t ret, ssize_t len, int err)
 | ||||
| +{
 | ||||
| +    fprintf(stderr, "%s l:%ld/%ld [%d] %s",
 | ||||
| +            hdr, ret, len, err, strerror(err));
 | ||||
| +    exit(-1);
 | ||||
| +}
 | ||||
| +
 | ||||
| +void send_string(int sd, const char *s, unsigned int l)
 | ||||
| +{
 | ||||
| +    ssize_t ret;
 | ||||
| +
 | ||||
| +fprintf(stderr, "s:%u ", l);
 | ||||
| +fflush(stderr);
 | ||||
| +
 | ||||
| +    ret = send(sd, &l, sizeof(l), 0);
 | ||||
| +    if (ret != sizeof(l)) s_error("send size", ret, sizeof(l), errno);
 | ||||
| +
 | ||||
| +    if (l == 0) return;
 | ||||
| +
 | ||||
| +    ret = send(sd, s, l, 0);
 | ||||
| +    if (ret != l) s_error("send data", ret, l, errno);
 | ||||
| +}
 | ||||
| +
 | ||||
| +void recv_string(int sd, char *buf, unsigned int *buflen)
 | ||||
| +{
 | ||||
| +    unsigned int l;
 | ||||
| +    ssize_t ret;
 | ||||
| +
 | ||||
| +    ret = recv(sd, &l, sizeof(l), MSG_WAITALL);
 | ||||
| +    if (ret != sizeof(l)) s_error("recv size", ret, sizeof(l), errno);
 | ||||
| +
 | ||||
| +    if (l == 0) {
 | ||||
| +fprintf(stderr, "r:0 ");
 | ||||
| +fflush(stderr);
 | ||||
| +        *buflen = 0;
 | ||||
| +        return;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    if (*buflen < l) s_error("recv len", l, *buflen, E2BIG);
 | ||||
| +
 | ||||
| +    ret = recv(sd, buf, l, 0);
 | ||||
| +    if (ret != l) s_error("recv data", ret, l, errno);
 | ||||
| +
 | ||||
| +fprintf(stderr, "r:%ld ", ret);
 | ||||
| +fflush(stderr);
 | ||||
| +    *buflen = ret;
 | ||||
| +}
 | ||||
| +
 | ||||
| +void saslerr(int why, const char *what)
 | ||||
| +{
 | ||||
| +    fprintf(stderr, "%s: %s", what, sasl_errstring(why, NULL, NULL));
 | ||||
| +}
 | ||||
| +
 | ||||
| +int getpath(void *context __attribute__((unused)), const char **path)
 | ||||
| +{
 | ||||
| +    if (! path) {
 | ||||
| +        return SASL_BADPARAM;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    *path = PLUGINDIR;
 | ||||
| +    return SASL_OK;
 | ||||
| +}
 | ||||
| +
 | ||||
| +
 | ||||
| diff --git a/tests/t_common.h b/tests/t_common.h
 | ||||
| new file mode 100644 | ||||
| index 0000000..4ee1976
 | ||||
| --- /dev/null
 | ||||
| +++ b/tests/t_common.h
 | ||||
| @@ -0,0 +1,15 @@
 | ||||
| +/* TBD, add (C) */
 | ||||
| +
 | ||||
| +#include "config.h"
 | ||||
| +
 | ||||
| +#include <errno.h>
 | ||||
| +#include <stdio.h>
 | ||||
| +#include <sys/socket.h>
 | ||||
| +
 | ||||
| +#include <sasl.h>
 | ||||
| +
 | ||||
| +void s_error(const char *hdr, ssize_t ret, ssize_t len, int err);
 | ||||
| +void send_string(int sd, const char *s, unsigned int l);
 | ||||
| +void recv_string(int sd, char *buf, unsigned int *buflen);
 | ||||
| +void saslerr(int why, const char *what);
 | ||||
| +int getpath(void *context __attribute__((unused)), const char **path);
 | ||||
| diff --git a/tests/t_gssapi_cli.c b/tests/t_gssapi_cli.c
 | ||||
| new file mode 100644 | ||||
| index 0000000..c833c05
 | ||||
| --- /dev/null
 | ||||
| +++ b/tests/t_gssapi_cli.c
 | ||||
| @@ -0,0 +1,95 @@
 | ||||
| +/* TBD, add (C) */
 | ||||
| +
 | ||||
| +#include "t_common.h"
 | ||||
| +
 | ||||
| +#include <stdlib.h>
 | ||||
| +#include <stdarg.h>
 | ||||
| +#include <ctype.h>
 | ||||
| +#include <string.h>
 | ||||
| +
 | ||||
| +#ifdef HAVE_UNISTD_H
 | ||||
| +#include <unistd.h>
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#include <arpa/inet.h>
 | ||||
| +#include <saslplug.h>
 | ||||
| +
 | ||||
| +static int setup_socket(void)
 | ||||
| +{
 | ||||
| +    struct sockaddr_in addr;
 | ||||
| +    int sock, ret;
 | ||||
| +
 | ||||
| +    sock = socket(AF_INET, SOCK_STREAM, 0);
 | ||||
| +    if (sock < 0) s_error("socket", 0, 0, errno);
 | ||||
| +
 | ||||
| +    addr.sin_family = AF_INET;
 | ||||
| +    addr.sin_addr.s_addr = inet_addr("127.0.0.9");
 | ||||
| +    addr.sin_port = htons(9000);
 | ||||
| +
 | ||||
| +    ret = connect(sock, (struct sockaddr *)&addr, sizeof(addr));
 | ||||
| +    if (ret != 0) s_error("connect", 0, 0, errno);
 | ||||
| +
 | ||||
| +    return sock;
 | ||||
| +}
 | ||||
| +
 | ||||
| +int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
 | ||||
| +{
 | ||||
| +    sasl_callback_t callbacks[2] = {};
 | ||||
| +    char buf[8192];
 | ||||
| +    const char *chosenmech;
 | ||||
| +    sasl_conn_t *conn;
 | ||||
| +    const char *data;
 | ||||
| +    unsigned int len;
 | ||||
| +    int sd;
 | ||||
| +    int r;
 | ||||
| +
 | ||||
| +    /* initialize the sasl library */
 | ||||
| +    callbacks[0].id = SASL_CB_GETPATH;
 | ||||
| +    callbacks[0].proc = (sasl_callback_ft)&getpath;
 | ||||
| +    callbacks[0].context = NULL;
 | ||||
| +    callbacks[1].id = SASL_CB_LIST_END;
 | ||||
| +    callbacks[1].proc = NULL;
 | ||||
| +    callbacks[1].context = NULL;
 | ||||
| +
 | ||||
| +    r = sasl_client_init(callbacks);
 | ||||
| +    if (r != SASL_OK) exit(-1);
 | ||||
| +
 | ||||
| +    r = sasl_client_new("test", "host.realm.test", NULL, NULL, NULL, 0, &conn);
 | ||||
| +    if (r != SASL_OK) {
 | ||||
| +        saslerr(r, "allocating connection state");
 | ||||
| +        exit(-1);
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    r = sasl_client_start(conn, "GSSAPI", NULL, &data, &len, &chosenmech);
 | ||||
| +    if (r != SASL_OK && r != SASL_CONTINUE) {
 | ||||
| +	saslerr(r, "starting SASL negotiation");
 | ||||
| +	printf("\n%s\n", sasl_errdetail(conn));
 | ||||
| +	exit(-1);
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    sd = setup_socket();
 | ||||
| +
 | ||||
| +    while (r == SASL_CONTINUE) {
 | ||||
| +        send_string(sd, data, len);
 | ||||
| +        len = 8192;
 | ||||
| +        recv_string(sd, buf, &len);
 | ||||
| +
 | ||||
| +	r = sasl_client_step(conn, buf, len, NULL, &data, &len);
 | ||||
| +	if (r != SASL_OK && r != SASL_CONTINUE) {
 | ||||
| +	    saslerr(r, "performing SASL negotiation");
 | ||||
| +	    printf("\n%s\n", sasl_errdetail(conn));
 | ||||
| +	    exit(-1);
 | ||||
| +        }
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    if (r != SASL_OK) exit(-1);
 | ||||
| +
 | ||||
| +    if (len > 0) {
 | ||||
| +        send_string(sd, data, len);
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    fprintf(stdout, "DONE\n");
 | ||||
| +    fflush(stdout);
 | ||||
| +    return 0;
 | ||||
| +}
 | ||||
| +
 | ||||
| diff --git a/tests/t_gssapi_srv.c b/tests/t_gssapi_srv.c
 | ||||
| new file mode 100644 | ||||
| index 0000000..29f538d
 | ||||
| --- /dev/null
 | ||||
| +++ b/tests/t_gssapi_srv.c
 | ||||
| @@ -0,0 +1,111 @@
 | ||||
| +/* TBD, add (C) */
 | ||||
| +
 | ||||
| +#include "t_common.h"
 | ||||
| +
 | ||||
| +#include <stdlib.h>
 | ||||
| +#include <stdarg.h>
 | ||||
| +#include <ctype.h>
 | ||||
| +#include <string.h>
 | ||||
| +
 | ||||
| +#ifdef HAVE_UNISTD_H
 | ||||
| +#include <unistd.h>
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#include <arpa/inet.h>
 | ||||
| +#include <saslplug.h>
 | ||||
| +
 | ||||
| +static int setup_socket(void)
 | ||||
| +{
 | ||||
| +    struct sockaddr_in addr;
 | ||||
| +    int sock, ret, sd;
 | ||||
| +
 | ||||
| +    sock = socket(AF_INET, SOCK_STREAM, 0);
 | ||||
| +    if (sock < 0) s_error("socket", 0, 0, errno);
 | ||||
| +
 | ||||
| +    addr.sin_family = AF_INET;
 | ||||
| +    addr.sin_addr.s_addr = inet_addr("127.0.0.9");
 | ||||
| +    addr.sin_port = htons(9000);
 | ||||
| +
 | ||||
| +    ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr));
 | ||||
| +    if (ret != 0) s_error("bind", 0, 0, errno);
 | ||||
| +
 | ||||
| +    ret = listen(sock, 1);
 | ||||
| +    if (ret != 0) s_error("listen", 0, 0, errno);
 | ||||
| +
 | ||||
| +    /* signal we are ready */
 | ||||
| +    fprintf(stdout, "READY\n");
 | ||||
| +    fflush(stdout);
 | ||||
| +
 | ||||
| +    /* block until the client connects */
 | ||||
| +    sd = accept(sock, NULL, NULL);
 | ||||
| +    if (sd < 0) s_error("accept", 0, 0, errno);
 | ||||
| +
 | ||||
| +    close(sock);
 | ||||
| +    return sd;
 | ||||
| +}
 | ||||
| +
 | ||||
| +int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
 | ||||
| +{
 | ||||
| +    sasl_callback_t callbacks[2] = {};
 | ||||
| +    char buf[8192];
 | ||||
| +    sasl_conn_t *conn;
 | ||||
| +    const char *data;
 | ||||
| +    unsigned int len;
 | ||||
| +    int sd;
 | ||||
| +    int r;
 | ||||
| +
 | ||||
| +    /* initialize the sasl library */
 | ||||
| +    callbacks[0].id = SASL_CB_GETPATH;
 | ||||
| +    callbacks[0].proc = (sasl_callback_ft)&getpath;
 | ||||
| +    callbacks[0].context = NULL;
 | ||||
| +    callbacks[1].id = SASL_CB_LIST_END;
 | ||||
| +    callbacks[1].proc = NULL;
 | ||||
| +    callbacks[1].context = NULL;
 | ||||
| +
 | ||||
| +    r = sasl_server_init(callbacks, "t_gssapi_srv");
 | ||||
| +    if (r != SASL_OK) exit(-1);
 | ||||
| +
 | ||||
| +    r = sasl_server_new("test", "host.realm.test", NULL, NULL, NULL,
 | ||||
| +                        callbacks, 0, &conn);
 | ||||
| +    if (r != SASL_OK) {
 | ||||
| +        saslerr(r, "allocating connection state");
 | ||||
| +        exit(-1);
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    sd = setup_socket();
 | ||||
| +
 | ||||
| +    len = 8192;
 | ||||
| +    recv_string(sd, buf, &len);
 | ||||
| +
 | ||||
| +    r = sasl_server_start(conn, "GSSAPI", buf, len, &data, &len);
 | ||||
| +    if (r != SASL_OK && r != SASL_CONTINUE) {
 | ||||
| +	saslerr(r, "starting SASL negotiation");
 | ||||
| +	printf("\n%s\n", sasl_errdetail(conn));
 | ||||
| +	exit(-1);
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    while (r == SASL_CONTINUE) {
 | ||||
| +        send_string(sd, data, len);
 | ||||
| +        len = 8192;
 | ||||
| +        recv_string(sd, buf, &len);
 | ||||
| +
 | ||||
| +	r = sasl_server_step(conn, buf, len, &data, &len);
 | ||||
| +	if (r != SASL_OK && r != SASL_CONTINUE) {
 | ||||
| +	    saslerr(r, "performing SASL negotiation");
 | ||||
| +	    printf("\n%s\n", sasl_errdetail(conn));
 | ||||
| +	    exit(-1);
 | ||||
| +	}
 | ||||
| +
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    if (r != SASL_OK) exit(-1);
 | ||||
| +
 | ||||
| +    if (len > 0) {
 | ||||
| +        send_string(sd, data, len);
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    fprintf(stdout, "DONE\n");
 | ||||
| +    fflush(stdout);
 | ||||
| +    return 0;
 | ||||
| +}
 | ||||
| +
 | ||||
| -- 
 | ||||
| 2.18.2 | ||||
| 
 | ||||
							
								
								
									
										411
									
								
								SOURCES/cyrus-sasl-2.1.27-Add-basic-test-plain-auth.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										411
									
								
								SOURCES/cyrus-sasl-2.1.27-Add-basic-test-plain-auth.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,411 @@ | ||||
| diff -Nru cyrus-sasl-2.1.27/tests/runtests.py cyrus-sasl-2.1.27-beldmit/tests/runtests.py
 | ||||
| --- cyrus-sasl-2.1.27/tests/runtests.py	2020-12-23 14:31:35.564537485 +0100
 | ||||
| +++ cyrus-sasl-2.1.27-beldmit/tests/runtests.py	2020-12-23 14:30:46.933219377 +0100
 | ||||
| @@ -313,6 +313,99 @@
 | ||||
|   | ||||
|      return err | ||||
|   | ||||
| +def setup_plain(testdir):
 | ||||
| +    """ Create sasldb file """
 | ||||
| +    sasldbfile = os.path.join(testdir, 'testsasldb.db')
 | ||||
| +
 | ||||
| +    sasldbenv = {'SASL_PATH': os.path.join(testdir, '../../plugins/.libs'),
 | ||||
| +                 'LD_LIBRARY_PATH' : os.path.join(testdir, '../../lib/.libs')}
 | ||||
| +
 | ||||
| +    passwdprog = os.path.join(testdir, '../../utils/saslpasswd2')
 | ||||
| +
 | ||||
| +    echo = subprocess.Popen(('echo', '1234567'), stdout=subprocess.PIPE)
 | ||||
| +    subprocess.check_call([
 | ||||
| +        passwdprog, "-f", sasldbfile, "-c", "test",
 | ||||
| +        "-u", "host.realm.test", "-p"
 | ||||
| +        ], stdin=echo.stdout, env=sasldbenv, timeout=5)
 | ||||
| +
 | ||||
| +    return (sasldbfile, sasldbenv)
 | ||||
| +
 | ||||
| +def plain_test(sasldbfile, sasldbenv):
 | ||||
| +    try:
 | ||||
| +        srv = subprocess.Popen(["../tests/t_gssapi_srv", "-P", sasldbfile],
 | ||||
| +                               stdout=subprocess.PIPE,
 | ||||
| +                               stderr=subprocess.PIPE, env=sasldbenv)
 | ||||
| +        srv.stdout.readline() # Wait for srv to say it is ready
 | ||||
| +        cli = subprocess.Popen(["../tests/t_gssapi_cli", "-P", "1234567"],
 | ||||
| +                               stdout=subprocess.PIPE,
 | ||||
| +                               stderr=subprocess.PIPE, env=sasldbenv)
 | ||||
| +        try:
 | ||||
| +            cli.wait(timeout=5)
 | ||||
| +            srv.wait(timeout=5)
 | ||||
| +        except Exception as e:
 | ||||
| +            print("Failed on {}".format(e));
 | ||||
| +            cli.kill()
 | ||||
| +            srv.kill()
 | ||||
| +        if cli.returncode != 0 or srv.returncode != 0:
 | ||||
| +            raise Exception("CLI ({}): {} --> SRV ({}): {}".format(
 | ||||
| +                cli.returncode, cli.stderr.read().decode('utf-8'),
 | ||||
| +                srv.returncode, srv.stderr.read().decode('utf-8')))
 | ||||
| +    except Exception as e:
 | ||||
| +        print("FAIL: {}".format(e))
 | ||||
| +        return 1
 | ||||
| +
 | ||||
| +    print("PASS: PLAIN CLI({}) SRV({})".format(
 | ||||
| +        cli.stdout.read().decode('utf-8').strip(),
 | ||||
| +        srv.stdout.read().decode('utf-8').strip()))
 | ||||
| +    return 0
 | ||||
| +
 | ||||
| +def plain_mismatch_test(sasldbfile, sasldbenv):
 | ||||
| +    result = "FAIL"
 | ||||
| +    try:
 | ||||
| +        srv = subprocess.Popen(["../tests/t_gssapi_srv", "-P", sasldbfile],
 | ||||
| +                               stdout=subprocess.PIPE,
 | ||||
| +                               stderr=subprocess.PIPE, env=sasldbenv)
 | ||||
| +        srv.stdout.readline() # Wait for srv to say it is ready
 | ||||
| +        bindings = base64.b64encode("CLI CBS".encode('utf-8'))
 | ||||
| +        cli = subprocess.Popen(["../tests/t_gssapi_cli", "-P", "12345678"],
 | ||||
| +                               stdout=subprocess.PIPE,
 | ||||
| +                               stderr=subprocess.PIPE, env=sasldbenv)
 | ||||
| +        try:
 | ||||
| +            cli.wait(timeout=5)
 | ||||
| +            srv.wait(timeout=5)
 | ||||
| +        except Exception as e:
 | ||||
| +            print("Failed on {}".format(e));
 | ||||
| +            cli.kill()
 | ||||
| +            srv.kill()
 | ||||
| +        if cli.returncode != 0 or srv.returncode != 0:
 | ||||
| +            cli_err = cli.stderr.read().decode('utf-8').strip()
 | ||||
| +            srv_err = srv.stderr.read().decode('utf-8').strip()
 | ||||
| +            if "authentication failure" in srv_err:
 | ||||
| +                result = "PASS"
 | ||||
| +            raise Exception("CLI ({}): {} --> SRV ({}): {}".format(
 | ||||
| +                cli.returncode, cli_err, srv.returncode, srv_err))
 | ||||
| +    except Exception as e:
 | ||||
| +        print("{}: {}".format(result, e))
 | ||||
| +        return 0
 | ||||
| +
 | ||||
| +    print("FAIL: This test should fail [CLI({}) SRV({})]".format(
 | ||||
| +        cli.stdout.read().decode('utf-8').strip(),
 | ||||
| +        srv.stdout.read().decode('utf-8').strip()))
 | ||||
| +    return 1
 | ||||
| +
 | ||||
| +def plain_tests(testdir):
 | ||||
| +    err = 0
 | ||||
| +    sasldbfile, sasldbenv = setup_plain(testdir)
 | ||||
| +    #print("DB file: {}, ENV: {}".format(sasldbfile, sasldbenv))
 | ||||
| +    print('SASLDB PLAIN:')
 | ||||
| +    print('    ', end='')
 | ||||
| +    err += plain_test(sasldbfile, sasldbenv)
 | ||||
| +
 | ||||
| +    print('SASLDB PLAIN PASSWORD MISMATCH:')
 | ||||
| +    print('    ', end='')
 | ||||
| +    err += plain_mismatch_test(sasldbfile, sasldbenv)
 | ||||
| +
 | ||||
| +    return err
 | ||||
|   | ||||
|  if __name__ == "__main__": | ||||
|   | ||||
| @@ -329,5 +422,9 @@
 | ||||
|   | ||||
|      err = gssapi_tests(T) | ||||
|      if err != 0: | ||||
| -        print('{} test(s) FAILED'.format(err))
 | ||||
| +        print('{} GSSAPI test(s) FAILED'.format(err))
 | ||||
| +
 | ||||
| +    err = plain_tests(T)
 | ||||
| +    if err != 0:
 | ||||
| +        print('{} PLAIN test(s) FAILED'.format(err))
 | ||||
|          sys.exit(-1) | ||||
| diff -Nru cyrus-sasl-2.1.27/tests/t_gssapi_cli.c cyrus-sasl-2.1.27-beldmit/tests/t_gssapi_cli.c
 | ||||
| --- cyrus-sasl-2.1.27/tests/t_gssapi_cli.c	2020-12-23 14:31:35.564537485 +0100
 | ||||
| +++ cyrus-sasl-2.1.27-beldmit/tests/t_gssapi_cli.c	2021-01-06 11:26:15.460662537 +0100
 | ||||
| @@ -16,6 +16,8 @@
 | ||||
|  #include <saslplug.h> | ||||
|  #include <saslutil.h> | ||||
|   | ||||
| +const char *testpass = NULL;
 | ||||
| +
 | ||||
|  static int setup_socket(void) | ||||
|  { | ||||
|      struct sockaddr_in addr; | ||||
| @@ -34,9 +36,60 @@
 | ||||
|      return sock; | ||||
|  } | ||||
|   | ||||
| +static int get_user(void *context __attribute__((unused)),
 | ||||
| +                  int id,
 | ||||
| +                  const char **result,
 | ||||
| +                  unsigned *len)
 | ||||
| +{
 | ||||
| +    const char *testuser = "test@host.realm.test";
 | ||||
| +
 | ||||
| +    if (! result)
 | ||||
| +        return SASL_BADPARAM;
 | ||||
| +
 | ||||
| +    switch (id) {
 | ||||
| +    case SASL_CB_USER:
 | ||||
| +    case SASL_CB_AUTHNAME:
 | ||||
| +        *result = testuser;
 | ||||
| +        break;
 | ||||
| +    default:
 | ||||
| +        return SASL_BADPARAM;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    if (len) *len = strlen(*result);
 | ||||
| +
 | ||||
| +    return SASL_OK;
 | ||||
| +}
 | ||||
| +
 | ||||
| +static int get_pass(sasl_conn_t *conn __attribute__((unused)),
 | ||||
| +          void *context __attribute__((unused)),
 | ||||
| +          int id,
 | ||||
| +          sasl_secret_t **psecret)
 | ||||
| +{
 | ||||
| +    size_t len;
 | ||||
| +    static sasl_secret_t *x;
 | ||||
| +
 | ||||
| +    /* paranoia check */
 | ||||
| +    if (! conn || ! psecret || id != SASL_CB_PASS)
 | ||||
| +        return SASL_BADPARAM;
 | ||||
| +
 | ||||
| +    len = strlen(testpass);
 | ||||
| +
 | ||||
| +    x = (sasl_secret_t *) realloc(x, sizeof(sasl_secret_t) + len);
 | ||||
| +
 | ||||
| +    if (!x) {
 | ||||
| +        return SASL_NOMEM;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    x->len = len;
 | ||||
| +    strcpy((char *)x->data, testpass);
 | ||||
| +
 | ||||
| +    *psecret = x;
 | ||||
| +    return SASL_OK;
 | ||||
| +}
 | ||||
| +
 | ||||
|  int main(int argc, char *argv[]) | ||||
|  { | ||||
| -    sasl_callback_t callbacks[2] = {};
 | ||||
| +    sasl_callback_t callbacks[4] = {};
 | ||||
|      char buf[8192]; | ||||
|      const char *chosenmech; | ||||
|      sasl_conn_t *conn; | ||||
| @@ -49,8 +102,9 @@
 | ||||
|      const char *sasl_mech = "GSSAPI"; | ||||
|      bool spnego = false; | ||||
|      bool zeromaxssf = false; | ||||
| +    bool plain = false;
 | ||||
|   | ||||
| -    while ((c = getopt(argc, argv, "c:zN")) != EOF) {
 | ||||
| +    while ((c = getopt(argc, argv, "c:zNP:")) != EOF) {
 | ||||
|          switch (c) { | ||||
|          case 'c': | ||||
|              parse_cb(&cb, cb_buf, 256, optarg); | ||||
| @@ -61,6 +115,10 @@
 | ||||
|          case 'N': | ||||
|              spnego = true; | ||||
|              break; | ||||
| +        case 'P':
 | ||||
| +            plain = true;
 | ||||
| +            testpass = optarg;
 | ||||
| +            break;
 | ||||
|          default: | ||||
|              break; | ||||
|          } | ||||
| @@ -73,6 +131,12 @@
 | ||||
|      callbacks[1].id = SASL_CB_LIST_END; | ||||
|      callbacks[1].proc = NULL; | ||||
|      callbacks[1].context = NULL; | ||||
| +    callbacks[2].id = SASL_CB_LIST_END;
 | ||||
| +    callbacks[2].proc = NULL;
 | ||||
| +    callbacks[2].context = NULL;
 | ||||
| +    callbacks[3].id = SASL_CB_LIST_END;
 | ||||
| +    callbacks[3].proc = NULL;
 | ||||
| +    callbacks[3].context = NULL;
 | ||||
|   | ||||
|      r = sasl_client_init(callbacks); | ||||
|      if (r != SASL_OK) exit(-1); | ||||
| @@ -91,6 +155,16 @@
 | ||||
|          sasl_mech = "GSS-SPNEGO"; | ||||
|      } | ||||
|   | ||||
| +    if (plain) {
 | ||||
| +        sasl_mech = "PLAIN";
 | ||||
| +
 | ||||
| +        callbacks[1].id = SASL_CB_AUTHNAME;
 | ||||
| +        callbacks[1].proc = (sasl_callback_ft)&get_user;
 | ||||
| +
 | ||||
| +        callbacks[2].id = SASL_CB_PASS;
 | ||||
| +        callbacks[2].proc = (sasl_callback_ft)&get_pass;
 | ||||
| +    }
 | ||||
| +
 | ||||
|      if (zeromaxssf) { | ||||
|          /* set all security properties to 0 including maxssf */ | ||||
|          sasl_security_properties_t secprops = { 0 }; | ||||
| @@ -99,9 +173,9 @@
 | ||||
|   | ||||
|      r = sasl_client_start(conn, sasl_mech, NULL, &data, &len, &chosenmech); | ||||
|      if (r != SASL_OK && r != SASL_CONTINUE) { | ||||
| -	saslerr(r, "starting SASL negotiation");
 | ||||
| -	printf("\n%s\n", sasl_errdetail(conn));
 | ||||
| -	exit(-1);
 | ||||
| +        saslerr(r, "starting SASL negotiation");
 | ||||
| +        printf("\n%s\n", sasl_errdetail(conn));
 | ||||
| +        exit(-1);
 | ||||
|      } | ||||
|   | ||||
|      sd = setup_socket(); | ||||
| @@ -111,11 +185,11 @@
 | ||||
|          len = 8192; | ||||
|          recv_string(sd, buf, &len, false); | ||||
|   | ||||
| -	r = sasl_client_step(conn, buf, len, NULL, &data, &len);
 | ||||
| -	if (r != SASL_OK && r != SASL_CONTINUE) {
 | ||||
| -	    saslerr(r, "performing SASL negotiation");
 | ||||
| -	    printf("\n%s\n", sasl_errdetail(conn));
 | ||||
| -	    exit(-1);
 | ||||
| +        r = sasl_client_step(conn, buf, len, NULL, &data, &len);
 | ||||
| +        if (r != SASL_OK && r != SASL_CONTINUE) {
 | ||||
| +            saslerr(r, "performing SASL negotiation");
 | ||||
| +            printf("\n%s\n", sasl_errdetail(conn));
 | ||||
| +            exit(-1);
 | ||||
|          } | ||||
|      } | ||||
|   | ||||
| diff -Nru cyrus-sasl-2.1.27/tests/t_gssapi_srv.c cyrus-sasl-2.1.27-beldmit/tests/t_gssapi_srv.c
 | ||||
| --- cyrus-sasl-2.1.27/tests/t_gssapi_srv.c	2020-12-23 14:31:35.565537492 +0100
 | ||||
| +++ cyrus-sasl-2.1.27-beldmit/tests/t_gssapi_srv.c	2021-01-06 11:27:48.373257373 +0100
 | ||||
| @@ -1,4 +1,5 @@
 | ||||
| -/* Copyright (C) Simo Sorce <simo@redhat.com>
 | ||||
| +/* Copyright (C) Simo Sorce <simo@redhat.com>,
 | ||||
| + * Dmitry Belyavskiy <dbelyavs@redhat.com>
 | ||||
|   * See COPYING file for License */ | ||||
|   | ||||
|  #include "t_common.h" | ||||
| @@ -15,6 +16,10 @@
 | ||||
|  #include <arpa/inet.h> | ||||
|  #include <saslplug.h> | ||||
|   | ||||
| +const char *sasldb_path = NULL,
 | ||||
| +      *auxprop_plugin = "sasldb",
 | ||||
| +      *pwcheck_method = "auxprop-hashed";
 | ||||
| +
 | ||||
|  static int setup_socket(void) | ||||
|  { | ||||
|      struct sockaddr_in addr; | ||||
| @@ -45,9 +50,38 @@
 | ||||
|      return sd; | ||||
|  } | ||||
|   | ||||
| +static int test_getopt(void *context __attribute__((unused)),
 | ||||
| +                const char *plugin_name __attribute__((unused)),
 | ||||
| +                const char *option,
 | ||||
| +                const char **result,
 | ||||
| +                unsigned *len)
 | ||||
| +{
 | ||||
| +    if (sasldb_path && !strcmp(option, "sasldb_path")) {
 | ||||
| +        *result = sasldb_path;
 | ||||
| +        if (len)
 | ||||
| +            *len = (unsigned) strlen(sasldb_path);
 | ||||
| +        return SASL_OK;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    if (sasldb_path && !strcmp(option, "auxprop_plugin")) {
 | ||||
| +        *result = auxprop_plugin;
 | ||||
| +        if (len)
 | ||||
| +            *len = (unsigned) strlen(auxprop_plugin);
 | ||||
| +        return SASL_OK;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    if (sasldb_path && !strcmp(option, "pwcheck_method")) {
 | ||||
| +        *result = pwcheck_method;
 | ||||
| +        if (len)
 | ||||
| +            *len = (unsigned) strlen(pwcheck_method);
 | ||||
| +        return SASL_OK;
 | ||||
| +    }
 | ||||
| +    return SASL_FAIL;
 | ||||
| +}
 | ||||
| +
 | ||||
|  int main(int argc, char *argv[]) | ||||
|  { | ||||
| -    sasl_callback_t callbacks[2] = {};
 | ||||
| +    sasl_callback_t callbacks[3] = {};
 | ||||
|      char buf[8192]; | ||||
|      sasl_conn_t *conn; | ||||
|      const char *data; | ||||
| @@ -59,8 +93,9 @@
 | ||||
|      const char *sasl_mech = "GSSAPI"; | ||||
|      bool spnego = false; | ||||
|      bool zeromaxssf = false; | ||||
| +    bool plain = false;
 | ||||
|   | ||||
| -    while ((c = getopt(argc, argv, "c:zN")) != EOF) {
 | ||||
| +    while ((c = getopt(argc, argv, "c:zNP:")) != EOF) {
 | ||||
|          switch (c) { | ||||
|          case 'c': | ||||
|              parse_cb(&cb, cb_buf, 256, optarg); | ||||
| @@ -71,6 +106,10 @@
 | ||||
|          case 'N': | ||||
|              spnego = true; | ||||
|              break; | ||||
| +        case 'P':
 | ||||
| +            plain = true;
 | ||||
| +            sasldb_path = optarg;
 | ||||
| +            break;
 | ||||
|          default: | ||||
|              break; | ||||
|          } | ||||
| @@ -81,9 +120,12 @@
 | ||||
|      callbacks[0].id = SASL_CB_GETPATH; | ||||
|      callbacks[0].proc = (sasl_callback_ft)&getpath; | ||||
|      callbacks[0].context = NULL; | ||||
| -    callbacks[1].id = SASL_CB_LIST_END;
 | ||||
| -    callbacks[1].proc = NULL;
 | ||||
| +    callbacks[1].id = SASL_CB_GETOPT;
 | ||||
| +    callbacks[1].proc = (sasl_callback_ft)&test_getopt;
 | ||||
|      callbacks[1].context = NULL; | ||||
| +    callbacks[2].id = SASL_CB_LIST_END;
 | ||||
| +    callbacks[2].proc = NULL;
 | ||||
| +    callbacks[2].context = NULL;
 | ||||
|   | ||||
|      r = sasl_server_init(callbacks, "t_gssapi_srv"); | ||||
|      if (r != SASL_OK) exit(-1); | ||||
| @@ -103,6 +145,10 @@
 | ||||
|          sasl_mech = "GSS-SPNEGO"; | ||||
|      } | ||||
|   | ||||
| +    if (plain) {
 | ||||
| +        sasl_mech = "PLAIN";
 | ||||
| +    }
 | ||||
| +
 | ||||
|      if (zeromaxssf) { | ||||
|          /* set all security properties to 0 including maxssf */ | ||||
|          sasl_security_properties_t secprops = { 0 }; | ||||
| @@ -116,9 +162,9 @@
 | ||||
|   | ||||
|      r = sasl_server_start(conn, sasl_mech, buf, len, &data, &len); | ||||
|      if (r != SASL_OK && r != SASL_CONTINUE) { | ||||
| -	saslerr(r, "starting SASL negotiation");
 | ||||
| -	printf("\n%s\n", sasl_errdetail(conn));
 | ||||
| -	exit(-1);
 | ||||
| +        saslerr(r, "starting SASL negotiation");
 | ||||
| +        printf("\n%s\n", sasl_errdetail(conn));
 | ||||
| +        exit(-1);
 | ||||
|      } | ||||
|   | ||||
|      while (r == SASL_CONTINUE) { | ||||
| @@ -126,12 +172,12 @@
 | ||||
|          len = 8192; | ||||
|          recv_string(sd, buf, &len, true); | ||||
|   | ||||
| -	r = sasl_server_step(conn, buf, len, &data, &len);
 | ||||
| -	if (r != SASL_OK && r != SASL_CONTINUE) {
 | ||||
| -	    saslerr(r, "performing SASL negotiation");
 | ||||
| -	    printf("\n%s\n", sasl_errdetail(conn));
 | ||||
| -	    exit(-1);
 | ||||
| -	}
 | ||||
| +        r = sasl_server_step(conn, buf, len, &data, &len);
 | ||||
| +        if (r != SASL_OK && r != SASL_CONTINUE) {
 | ||||
| +            saslerr(r, "performing SASL negotiation");
 | ||||
| +            printf("\n%s\n", sasl_errdetail(conn));
 | ||||
| +            exit(-1);
 | ||||
| +        }
 | ||||
|      } | ||||
|   | ||||
|      if (r != SASL_OK) exit(-1); | ||||
| @ -0,0 +1,435 @@ | ||||
| From 49e965f41257a0ed299c58a7cf1c120ddf944aaa Mon Sep 17 00:00:00 2001 | ||||
| From: Simo Sorce <simo@redhat.com> | ||||
| Date: Tue, 5 May 2020 14:51:36 -0400 | ||||
| Subject: [PATCH] Add support for setting max ssf 0 to GSS-SPNEGO | ||||
| 
 | ||||
| Bacport form this proposed PR (still open at bacport time): | ||||
| https://github.com/cyrusimap/cyrus-sasl/pull/603 | ||||
| 
 | ||||
| Signed-off-by: Simo Sorce <simo@redhat.com> | ||||
| ---
 | ||||
|  m4/sasl2.m4          | 13 +++++++ | ||||
|  plugins/gssapi.c     | 44 ++++++++++++++++++++- | ||||
|  tests/runtests.py    | 91 ++++++++++++++++++++++++++++++++++++++++---- | ||||
|  tests/t_common.c     | 13 ++++--- | ||||
|  tests/t_common.h     |  3 +- | ||||
|  tests/t_gssapi_cli.c | 25 ++++++++++-- | ||||
|  tests/t_gssapi_srv.c | 28 +++++++++++--- | ||||
|  7 files changed, 194 insertions(+), 23 deletions(-) | ||||
| 
 | ||||
| diff --git a/m4/sasl2.m4 b/m4/sasl2.m4
 | ||||
| index 56e0504..6effe99 100644
 | ||||
| --- a/m4/sasl2.m4
 | ||||
| +++ b/m4/sasl2.m4
 | ||||
| @@ -287,6 +287,19 @@ if test "$gssapi" != no; then
 | ||||
|    AC_CHECK_FUNCS(gss_oid_equal) | ||||
|    LIBS="$cmu_save_LIBS" | ||||
|   | ||||
| +  cmu_save_LIBS="$LIBS"
 | ||||
| +  LIBS="$LIBS $GSSAPIBASE_LIBS"
 | ||||
| +  if test "$ac_cv_header_gssapi_gssapi_krb5_h" = "yes"; then
 | ||||
| +    AC_CHECK_DECL(GSS_KRB5_CRED_NO_CI_FLAGS_X,
 | ||||
| +                  [AC_DEFINE(HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X,1,
 | ||||
| +                             [Define if your GSSAPI implementation supports GSS_KRB5_CRED_NO_CI_FLAGS_X])],,
 | ||||
| +                  [
 | ||||
| +                    AC_INCLUDES_DEFAULT
 | ||||
| +                    #include <gssapi/gssapi_krb5.h>
 | ||||
| +                    ])
 | ||||
| +  fi
 | ||||
| +  LIBS="$cmu_save_LIBS"
 | ||||
| +
 | ||||
|    cmu_save_LIBS="$LIBS" | ||||
|    LIBS="$LIBS $GSSAPIBASE_LIBS" | ||||
|    AC_CHECK_FUNCS(gss_get_name_attribute) | ||||
| diff --git a/plugins/gssapi.c b/plugins/gssapi.c
 | ||||
| index 5d900c5..7480316 100644
 | ||||
| --- a/plugins/gssapi.c
 | ||||
| +++ b/plugins/gssapi.c
 | ||||
| @@ -1783,7 +1783,49 @@ static int gssapi_client_mech_step(void *conn_context,
 | ||||
|  		/* We want to try for privacy */ | ||||
|  		req_flags |= GSS_C_CONF_FLAG; | ||||
|  	    } | ||||
| -	}
 | ||||
| +#ifdef HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X
 | ||||
| +        /* The krb5 mechanism automatically adds INTEG and CONF flags even when
 | ||||
| +         * not specified, this has the effect of rendering explicit requests
 | ||||
| +         * of no confidentiality and integrity via setting maxssf 0 moot.
 | ||||
| +         * However to interoperate with Windows machines it needs to be
 | ||||
| +         * possible to unset these flags as Windows machines refuse to allow
 | ||||
| +         * two layers (say TLS and GSSAPI) to both provide these services.
 | ||||
| +         * So if we do not suppress these flags a SASL/GSS-SPNEGO negotiation
 | ||||
| +         * over, say, LDAPS will fail against Windows Servers */
 | ||||
| +	} else if (params->props.max_ssf == 0) {
 | ||||
| +            gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER;
 | ||||
| +            if (client_creds == GSS_C_NO_CREDENTIAL) {
 | ||||
| +                gss_OID_set_desc mechs = { 0 };
 | ||||
| +                gss_OID_set desired_mechs = GSS_C_NO_OID_SET;
 | ||||
| +                if (text->mech_type != GSS_C_NO_OID) {
 | ||||
| +                    mechs.count = 1;
 | ||||
| +                    mechs.elements = text->mech_type;
 | ||||
| +                    desired_mechs = &mechs;
 | ||||
| +                }
 | ||||
| +
 | ||||
| +                maj_stat = gss_acquire_cred(&min_stat, GSS_C_NO_NAME,
 | ||||
| +                                            GSS_C_INDEFINITE, desired_mechs,
 | ||||
| +                                            GSS_C_INITIATE,
 | ||||
| +                                            &text->client_creds, NULL, NULL);
 | ||||
| +                if (GSS_ERROR(maj_stat)) {
 | ||||
| +                    sasl_gss_seterror(text->utils, maj_stat, min_stat);
 | ||||
| +                    sasl_gss_free_context_contents(text);
 | ||||
| +                    return SASL_FAIL;
 | ||||
| +                }
 | ||||
| +                client_creds = text->client_creds;
 | ||||
| +            }
 | ||||
| +
 | ||||
| +            maj_stat = gss_set_cred_option(&min_stat, &client_creds,
 | ||||
| +                                           (gss_OID)GSS_KRB5_CRED_NO_CI_FLAGS_X,
 | ||||
| +                                            &empty_buffer);
 | ||||
| +            if (GSS_ERROR(maj_stat)) {
 | ||||
| +                sasl_gss_seterror(text->utils, maj_stat, min_stat);
 | ||||
| +                sasl_gss_free_context_contents(text);
 | ||||
| +                return SASL_FAIL;
 | ||||
| +            }
 | ||||
| +#endif
 | ||||
| +        }
 | ||||
| +
 | ||||
|   | ||||
|  	if (params->props.security_flags & SASL_SEC_PASS_CREDENTIALS) { | ||||
|  	    req_flags = req_flags |  GSS_C_DELEG_FLAG; | ||||
| diff --git a/tests/runtests.py b/tests/runtests.py
 | ||||
| index fc9cf24..4106401 100755
 | ||||
| --- a/tests/runtests.py
 | ||||
| +++ b/tests/runtests.py
 | ||||
| @@ -6,6 +6,7 @@ import os
 | ||||
|  import shutil | ||||
|  import signal | ||||
|  import subprocess | ||||
| +import sys
 | ||||
|  import time | ||||
|  from string import Template | ||||
|   | ||||
| @@ -149,11 +150,12 @@ def gssapi_basic_test(kenv):
 | ||||
|                  srv.returncode, srv.stderr.read().decode('utf-8'))) | ||||
|      except Exception as e: | ||||
|          print("FAIL: {}".format(e)) | ||||
| -        return
 | ||||
| +        return 1
 | ||||
|   | ||||
|      print("PASS: CLI({}) SRV({})".format( | ||||
|          cli.stdout.read().decode('utf-8').strip(), | ||||
|          srv.stdout.read().decode('utf-8').strip())) | ||||
| +    return 0
 | ||||
|   | ||||
|  def gssapi_channel_binding_test(kenv): | ||||
|      try: | ||||
| @@ -178,11 +180,12 @@ def gssapi_channel_binding_test(kenv):
 | ||||
|                  srv.returncode, srv.stderr.read().decode('utf-8'))) | ||||
|      except Exception as e: | ||||
|          print("FAIL: {}".format(e)) | ||||
| -        return
 | ||||
| +        return 1
 | ||||
|   | ||||
|      print("PASS: CLI({}) SRV({})".format( | ||||
|          cli.stdout.read().decode('utf-8').strip(), | ||||
|          srv.stdout.read().decode('utf-8').strip())) | ||||
| +    return 0
 | ||||
|   | ||||
|  def gssapi_channel_binding_mismatch_test(kenv): | ||||
|      result = "FAIL" | ||||
| @@ -212,11 +215,70 @@ def gssapi_channel_binding_mismatch_test(kenv):
 | ||||
|                  cli.returncode, cli_err, srv.returncode, srv_err)) | ||||
|      except Exception as e: | ||||
|          print("{}: {}".format(result, e)) | ||||
| -        return
 | ||||
| +        return 0
 | ||||
|   | ||||
|      print("FAIL: This test should fail [CLI({}) SRV({})]".format( | ||||
|          cli.stdout.read().decode('utf-8').strip(), | ||||
|          srv.stdout.read().decode('utf-8').strip())) | ||||
| +    return 1
 | ||||
| +
 | ||||
| +def gss_spnego_basic_test(kenv):
 | ||||
| +    try:
 | ||||
| +        srv = subprocess.Popen(["../tests/t_gssapi_srv", "-N"],
 | ||||
| +                               stdout=subprocess.PIPE,
 | ||||
| +                               stderr=subprocess.PIPE, env=kenv)
 | ||||
| +        srv.stdout.readline() # Wait for srv to say it is ready
 | ||||
| +        cli = subprocess.Popen(["../tests/t_gssapi_cli", "-N"],
 | ||||
| +                               stdout=subprocess.PIPE,
 | ||||
| +                               stderr=subprocess.PIPE, env=kenv)
 | ||||
| +        try:
 | ||||
| +            cli.wait(timeout=5)
 | ||||
| +            srv.wait(timeout=5)
 | ||||
| +        except Exception as e:
 | ||||
| +            print("Failed on {}".format(e));
 | ||||
| +            cli.kill()
 | ||||
| +            srv.kill()
 | ||||
| +        if cli.returncode != 0 or srv.returncode != 0:
 | ||||
| +            raise Exception("CLI ({}): {} --> SRV ({}): {}".format(
 | ||||
| +                cli.returncode, cli.stderr.read().decode('utf-8'),
 | ||||
| +                srv.returncode, srv.stderr.read().decode('utf-8')))
 | ||||
| +    except Exception as e:
 | ||||
| +        print("FAIL: {}".format(e))
 | ||||
| +        return 1
 | ||||
| +
 | ||||
| +    print("PASS: CLI({}) SRV({})".format(
 | ||||
| +        cli.stdout.read().decode('utf-8').strip(),
 | ||||
| +        srv.stdout.read().decode('utf-8').strip()))
 | ||||
| +    return 0
 | ||||
| +
 | ||||
| +def gss_spnego_zeromaxssf_test(kenv):
 | ||||
| +    try:
 | ||||
| +        srv = subprocess.Popen(["../tests/t_gssapi_srv", "-N", "-z"],
 | ||||
| +                               stdout=subprocess.PIPE,
 | ||||
| +                               stderr=subprocess.PIPE, env=kenv)
 | ||||
| +        srv.stdout.readline() # Wait for srv to say it is ready
 | ||||
| +        cli = subprocess.Popen(["../tests/t_gssapi_cli", "-N", "-z"],
 | ||||
| +                               stdout=subprocess.PIPE,
 | ||||
| +                               stderr=subprocess.PIPE, env=kenv)
 | ||||
| +        try:
 | ||||
| +            cli.wait(timeout=5)
 | ||||
| +            srv.wait(timeout=5)
 | ||||
| +        except Exception as e:
 | ||||
| +            print("Failed on {}".format(e));
 | ||||
| +            cli.kill()
 | ||||
| +            srv.kill()
 | ||||
| +        if cli.returncode != 0 or srv.returncode != 0:
 | ||||
| +            raise Exception("CLI ({}): {} --> SRV ({}): {}".format(
 | ||||
| +                cli.returncode, cli.stderr.read().decode('utf-8'),
 | ||||
| +                srv.returncode, srv.stderr.read().decode('utf-8')))
 | ||||
| +    except Exception as e:
 | ||||
| +        print("FAIL: {}".format(e))
 | ||||
| +        return 1
 | ||||
| +
 | ||||
| +    print("PASS: CLI({}) SRV({})".format(
 | ||||
| +        cli.stdout.read().decode('utf-8').strip(),
 | ||||
| +        srv.stdout.read().decode('utf-8').strip()))
 | ||||
| +    return 0
 | ||||
|   | ||||
|  def gssapi_tests(testdir): | ||||
|      """ SASL/GSSAPI Tests """ | ||||
| @@ -225,20 +287,32 @@ def gssapi_tests(testdir):
 | ||||
|      #print("KDC: {}, ENV: {}".format(kdc, kenv)) | ||||
|      kenv['KRB5_TRACE'] = os.path.join(testdir, 'trace.log') | ||||
|   | ||||
| +    err = 0
 | ||||
| +
 | ||||
|      print('GSSAPI BASIC:') | ||||
|      print('    ', end='') | ||||
| -    gssapi_basic_test(kenv)
 | ||||
| +    err += gssapi_basic_test(kenv)
 | ||||
|   | ||||
|      print('GSSAPI CHANNEL BINDING:') | ||||
|      print('    ', end='') | ||||
| -    gssapi_channel_binding_test(kenv)
 | ||||
| +    err += gssapi_channel_binding_test(kenv)
 | ||||
|   | ||||
|      print('GSSAPI CHANNEL BINDING MISMTACH:') | ||||
|      print('    ', end='') | ||||
| -    gssapi_channel_binding_mismatch_test(kenv)
 | ||||
| +    err += gssapi_channel_binding_mismatch_test(kenv)
 | ||||
| +
 | ||||
| +    print('GSS-SPNEGO BASIC:')
 | ||||
| +    print('    ', end='')
 | ||||
| +    err += gss_spnego_basic_test(kenv)
 | ||||
| +
 | ||||
| +    print('GSS-SPNEGO 0 MAXSSF:')
 | ||||
| +    print('    ', end='')
 | ||||
| +    err += gss_spnego_zeromaxssf_test(kenv)
 | ||||
|   | ||||
|      os.killpg(kdc.pid, signal.SIGTERM) | ||||
|   | ||||
| +    return err
 | ||||
| +
 | ||||
|   | ||||
|  if __name__ == "__main__": | ||||
|   | ||||
| @@ -253,4 +327,7 @@ if __name__ == "__main__":
 | ||||
|          shutil.rmtree(T) | ||||
|      os.makedirs(T) | ||||
|   | ||||
| -    gssapi_tests(T)
 | ||||
| +    err = gssapi_tests(T)
 | ||||
| +    if err != 0:
 | ||||
| +        print('{} test(s) FAILED'.format(err))
 | ||||
| +        sys.exit(-1)
 | ||||
| diff --git a/tests/t_common.c b/tests/t_common.c
 | ||||
| index 478e6a1..f56098e 100644
 | ||||
| --- a/tests/t_common.c
 | ||||
| +++ b/tests/t_common.c
 | ||||
| @@ -23,20 +23,21 @@ void send_string(int sd, const char *s, unsigned int l)
 | ||||
|      if (ret != l) s_error("send data", ret, l, errno); | ||||
|  } | ||||
|   | ||||
| -void recv_string(int sd, char *buf, unsigned int *buflen)
 | ||||
| +void recv_string(int sd, char *buf, unsigned int *buflen, bool allow_eof)
 | ||||
|  { | ||||
| +    unsigned int bufsize = *buflen;
 | ||||
|      unsigned int l; | ||||
|      ssize_t ret; | ||||
|   | ||||
| +    *buflen = 0;
 | ||||
| +
 | ||||
|      ret = recv(sd, &l, sizeof(l), MSG_WAITALL); | ||||
| +    if (allow_eof && ret == 0) return;
 | ||||
|      if (ret != sizeof(l)) s_error("recv size", ret, sizeof(l), errno); | ||||
|   | ||||
| -    if (l == 0) {
 | ||||
| -        *buflen = 0;
 | ||||
| -        return;
 | ||||
| -    }
 | ||||
| +    if (l == 0) return;
 | ||||
|   | ||||
| -    if (*buflen < l) s_error("recv len", l, *buflen, E2BIG);
 | ||||
| +    if (bufsize < l) s_error("recv len", l, bufsize, E2BIG);
 | ||||
|   | ||||
|      ret = recv(sd, buf, l, 0); | ||||
|      if (ret != l) s_error("recv data", ret, l, errno); | ||||
| diff --git a/tests/t_common.h b/tests/t_common.h
 | ||||
| index a10def1..be24a53 100644
 | ||||
| --- a/tests/t_common.h
 | ||||
| +++ b/tests/t_common.h
 | ||||
| @@ -4,6 +4,7 @@
 | ||||
|  #include "config.h" | ||||
|   | ||||
|  #include <errno.h> | ||||
| +#include <stdbool.h>
 | ||||
|  #include <stdio.h> | ||||
|  #include <sys/socket.h> | ||||
|   | ||||
| @@ -12,7 +13,7 @@
 | ||||
|   | ||||
|  void s_error(const char *hdr, ssize_t ret, ssize_t len, int err); | ||||
|  void send_string(int sd, const char *s, unsigned int l); | ||||
| -void recv_string(int sd, char *buf, unsigned int *buflen);
 | ||||
| +void recv_string(int sd, char *buf, unsigned int *buflen, bool allow_eof);
 | ||||
|  void saslerr(int why, const char *what); | ||||
|  int getpath(void *context __attribute__((unused)), const char **path); | ||||
|  void parse_cb(sasl_channel_binding_t *cb, char *buf, unsigned max, char *in); | ||||
| diff --git a/tests/t_gssapi_cli.c b/tests/t_gssapi_cli.c
 | ||||
| index a44a3f5..d9eafe1 100644
 | ||||
| --- a/tests/t_gssapi_cli.c
 | ||||
| +++ b/tests/t_gssapi_cli.c
 | ||||
| @@ -46,12 +46,21 @@ int main(int argc, char *argv[])
 | ||||
|      char cb_buf[256]; | ||||
|      int sd; | ||||
|      int c, r; | ||||
| +    const char *sasl_mech = "GSSAPI";
 | ||||
| +    bool spnego = false;
 | ||||
| +    bool zeromaxssf = false;
 | ||||
|   | ||||
| -    while ((c = getopt(argc, argv, "c:")) != EOF) {
 | ||||
| +    while ((c = getopt(argc, argv, "c:zN")) != EOF) {
 | ||||
|          switch (c) { | ||||
|          case 'c': | ||||
|              parse_cb(&cb, cb_buf, 256, optarg); | ||||
|              break; | ||||
| +        case 'z':
 | ||||
| +            zeromaxssf = true;
 | ||||
| +            break;
 | ||||
| +        case 'N':
 | ||||
| +            spnego = true;
 | ||||
| +            break;
 | ||||
|          default: | ||||
|              break; | ||||
|          } | ||||
| @@ -78,7 +87,17 @@ int main(int argc, char *argv[])
 | ||||
|          sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb); | ||||
|      } | ||||
|   | ||||
| -    r = sasl_client_start(conn, "GSSAPI", NULL, &data, &len, &chosenmech);
 | ||||
| +    if (spnego) {
 | ||||
| +        sasl_mech = "GSS-SPNEGO";
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    if (zeromaxssf) {
 | ||||
| +        /* set all security properties to 0 including maxssf */
 | ||||
| +        sasl_security_properties_t secprops = { 0 };
 | ||||
| +        sasl_setprop(conn, SASL_SEC_PROPS, &secprops);
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    r = sasl_client_start(conn, sasl_mech, NULL, &data, &len, &chosenmech);
 | ||||
|      if (r != SASL_OK && r != SASL_CONTINUE) { | ||||
|  	saslerr(r, "starting SASL negotiation"); | ||||
|  	printf("\n%s\n", sasl_errdetail(conn)); | ||||
| @@ -90,7 +109,7 @@ int main(int argc, char *argv[])
 | ||||
|      while (r == SASL_CONTINUE) { | ||||
|          send_string(sd, data, len); | ||||
|          len = 8192; | ||||
| -        recv_string(sd, buf, &len);
 | ||||
| +        recv_string(sd, buf, &len, false);
 | ||||
|   | ||||
|  	r = sasl_client_step(conn, buf, len, NULL, &data, &len); | ||||
|  	if (r != SASL_OK && r != SASL_CONTINUE) { | ||||
| diff --git a/tests/t_gssapi_srv.c b/tests/t_gssapi_srv.c
 | ||||
| index ef1217f..448a218 100644
 | ||||
| --- a/tests/t_gssapi_srv.c
 | ||||
| +++ b/tests/t_gssapi_srv.c
 | ||||
| @@ -56,12 +56,21 @@ int main(int argc, char *argv[])
 | ||||
|      unsigned char cb_buf[256]; | ||||
|      int sd; | ||||
|      int c, r; | ||||
| +    const char *sasl_mech = "GSSAPI";
 | ||||
| +    bool spnego = false;
 | ||||
| +    bool zeromaxssf = false;
 | ||||
|   | ||||
| -    while ((c = getopt(argc, argv, "c:")) != EOF) {
 | ||||
| +    while ((c = getopt(argc, argv, "c:zN")) != EOF) {
 | ||||
|          switch (c) { | ||||
|          case 'c': | ||||
|              parse_cb(&cb, cb_buf, 256, optarg); | ||||
|              break; | ||||
| +        case 'z':
 | ||||
| +            zeromaxssf = true;
 | ||||
| +            break;
 | ||||
| +        case 'N':
 | ||||
| +            spnego = true;
 | ||||
| +            break;
 | ||||
|          default: | ||||
|              break; | ||||
|          } | ||||
| @@ -90,12 +99,22 @@ int main(int argc, char *argv[])
 | ||||
|          sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb); | ||||
|      } | ||||
|   | ||||
| +    if (spnego) {
 | ||||
| +        sasl_mech = "GSS-SPNEGO";
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    if (zeromaxssf) {
 | ||||
| +        /* set all security properties to 0 including maxssf */
 | ||||
| +        sasl_security_properties_t secprops = { 0 };
 | ||||
| +        sasl_setprop(conn, SASL_SEC_PROPS, &secprops);
 | ||||
| +    }
 | ||||
| +
 | ||||
|      sd = setup_socket(); | ||||
|   | ||||
|      len = 8192; | ||||
| -    recv_string(sd, buf, &len);
 | ||||
| +    recv_string(sd, buf, &len, false);
 | ||||
|   | ||||
| -    r = sasl_server_start(conn, "GSSAPI", buf, len, &data, &len);
 | ||||
| +    r = sasl_server_start(conn, sasl_mech, buf, len, &data, &len);
 | ||||
|      if (r != SASL_OK && r != SASL_CONTINUE) { | ||||
|  	saslerr(r, "starting SASL negotiation"); | ||||
|  	printf("\n%s\n", sasl_errdetail(conn)); | ||||
| @@ -105,7 +124,7 @@ int main(int argc, char *argv[])
 | ||||
|      while (r == SASL_CONTINUE) { | ||||
|          send_string(sd, data, len); | ||||
|          len = 8192; | ||||
| -        recv_string(sd, buf, &len);
 | ||||
| +        recv_string(sd, buf, &len, true);
 | ||||
|   | ||||
|  	r = sasl_server_step(conn, buf, len, &data, &len); | ||||
|  	if (r != SASL_OK && r != SASL_CONTINUE) { | ||||
| @@ -113,7 +132,6 @@ int main(int argc, char *argv[])
 | ||||
|  	    printf("\n%s\n", sasl_errdetail(conn)); | ||||
|  	    exit(-1); | ||||
|  	} | ||||
| -
 | ||||
|      } | ||||
|   | ||||
|      if (r != SASL_OK) exit(-1); | ||||
| -- 
 | ||||
| 2.18.2 | ||||
| 
 | ||||
| @ -0,0 +1,42 @@ | ||||
| From ec070b2e83a4ee698c08d6d68c205aea4d90b0bb Mon Sep 17 00:00:00 2001 | ||||
| From: Simo Sorce <simo@redhat.com> | ||||
| Date: Tue, 5 May 2020 14:31:10 -0400 | ||||
| Subject: [PATCH] Emit debug log only in case of errors | ||||
| 
 | ||||
| Backport of commit id: | ||||
| ccc5e547d4b40ee2b182a9945f8f6cc10b4fdf48 | ||||
| 
 | ||||
| Signed-off-by: Simo Sorce <simo@redhat.com> | ||||
| ---
 | ||||
|  plugins/gssapi.c | 7 +++---- | ||||
|  1 file changed, 3 insertions(+), 4 deletions(-) | ||||
| 
 | ||||
| diff --git a/plugins/gssapi.c b/plugins/gssapi.c
 | ||||
| index 7480316..6bcd78e 100644
 | ||||
| --- a/plugins/gssapi.c
 | ||||
| +++ b/plugins/gssapi.c
 | ||||
| @@ -1444,9 +1444,6 @@ gssapi_server_mech_step(void *conn_context,
 | ||||
|   | ||||
|      if (text == NULL) return SASL_BADPROT; | ||||
|   | ||||
| -    params->utils->log(params->utils->conn, SASL_LOG_DEBUG,
 | ||||
| -		       "GSSAPI server step %d\n", text->state);
 | ||||
| -
 | ||||
|      switch (text->state) { | ||||
|   | ||||
|      case SASL_GSSAPI_STATE_AUTHNEG: | ||||
| @@ -1496,8 +1493,10 @@ gssapi_server_mech_step(void *conn_context,
 | ||||
|  	} | ||||
|   | ||||
|  	oparams->doneflag = 1; | ||||
| +    } else {
 | ||||
| +        params->utils->log(params->utils->conn, SASL_LOG_DEBUG,
 | ||||
| +		           "GSSAPI server step failed: %d\n", text->state);
 | ||||
|      } | ||||
| -    
 | ||||
|      return ret; | ||||
|  } | ||||
|   | ||||
| -- 
 | ||||
| 2.18.2 | ||||
| 
 | ||||
							
								
								
									
										569
									
								
								SOURCES/cyrus-sasl-2.1.27-Migration-from-BerkeleyDB.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										569
									
								
								SOURCES/cyrus-sasl-2.1.27-Migration-from-BerkeleyDB.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,569 @@ | ||||
| diff -up cyrus-sasl-2.1.27/configure.ac.frombdb cyrus-sasl-2.1.27/configure.ac
 | ||||
| --- cyrus-sasl-2.1.27/configure.ac.frombdb	2021-06-04 13:02:07.790112263 +0200
 | ||||
| +++ cyrus-sasl-2.1.27/configure.ac	2021-06-04 13:02:07.798112327 +0200
 | ||||
| @@ -1091,6 +1091,9 @@ AC_SUBST(SASL_STATIC_SRCS)
 | ||||
|  AC_SUBST(SASL_STATIC_OBJS) | ||||
|  AC_SUBST(SASL_STATIC_LIBS) | ||||
|   | ||||
| +CYRUS_BERKELEY_DB_STATIC_LIB()
 | ||||
| +AC_SUBST(BDB_STATIC_LIBADD)
 | ||||
| +
 | ||||
|  AC_ARG_WITH(plugindir, [  --with-plugindir=DIR    set the directory where plugins will | ||||
|                            be found [[LIBDIR/sasl2]] ], | ||||
|    plugindir=$withval, | ||||
| diff -up cyrus-sasl-2.1.27/m4/berkdb.m4.frombdb cyrus-sasl-2.1.27/m4/berkdb.m4
 | ||||
| --- cyrus-sasl-2.1.27/m4/berkdb.m4.frombdb	2016-01-29 18:35:35.000000000 +0100
 | ||||
| +++ cyrus-sasl-2.1.27/m4/berkdb.m4	2021-06-04 13:02:07.798112327 +0200
 | ||||
| @@ -286,3 +286,10 @@ AC_DEFUN([CYRUS_BERKELEY_DB_CHK],
 | ||||
|   | ||||
|  	CPPFLAGS=$cmu_save_CPPFLAGS | ||||
|  ]) | ||||
| +
 | ||||
| +AC_DEFUN([CYRUS_BERKELEY_DB_STATIC_LIB],
 | ||||
| +[
 | ||||
| +BDB_STATIC_LIBADD="/dev/null -lpthread"
 | ||||
| +AC_CHECK_FILE([/usr/lib64/libdb-5.3.a],[BDB_STATIC_LIBADD="/usr/lib64/libdb-5.3.a -lpthread "],[])
 | ||||
| +AC_CHECK_FILE([/usr/lib/libdb-5.3.a],[BDB_STATIC_LIBADD="/usr/lib/libdb-5.3.a -lpthread"],[])
 | ||||
| +])
 | ||||
| diff -up cyrus-sasl-2.1.27/m4/sasldb.m4.frombdb cyrus-sasl-2.1.27/m4/sasldb.m4
 | ||||
| --- cyrus-sasl-2.1.27/m4/sasldb.m4.frombdb	2017-07-13 20:45:19.000000000 +0200
 | ||||
| +++ cyrus-sasl-2.1.27/m4/sasldb.m4	2021-06-04 13:02:07.798112327 +0200
 | ||||
| @@ -111,7 +111,7 @@ AC_MSG_RESULT($dblib)
 | ||||
|  SASL_DB_BACKEND="db_${dblib}.lo" | ||||
|  SASL_DB_BACKEND_STATIC="db_${dblib}.o allockey.o" | ||||
|  SASL_DB_BACKEND_STATIC_SRCS="\$(top_srcdir)/sasldb/db_${dblib}.c \$(top_srcdir)/sasldb/allockey.c" | ||||
| -SASL_DB_UTILS="saslpasswd2 sasldblistusers2"
 | ||||
| +SASL_DB_UTILS="cyrusbdb2current saslpasswd2 sasldblistusers2"
 | ||||
|  SASL_DB_MANS="saslpasswd2.8 sasldblistusers2.8" | ||||
|   | ||||
|  case "$dblib" in | ||||
| diff -up cyrus-sasl-2.1.27/sasldb/db_gdbm.c.frombdb cyrus-sasl-2.1.27/sasldb/db_gdbm.c
 | ||||
| --- cyrus-sasl-2.1.27/sasldb/db_gdbm.c.frombdb	2017-07-13 14:34:03.000000000 +0200
 | ||||
| +++ cyrus-sasl-2.1.27/sasldb/db_gdbm.c	2021-06-04 13:04:24.098206887 +0200
 | ||||
| @@ -67,6 +67,7 @@ int _sasldb_getdata(const sasl_utils_t *
 | ||||
|    void *cntxt; | ||||
|    sasl_getopt_t *getopt; | ||||
|    const char *path = SASL_DB_PATH; | ||||
| +  int fetch_errno = 0;
 | ||||
|   | ||||
|    if (!utils) return SASL_BADPARAM; | ||||
|    if (!authid || !propName || !realm || !out || !max_out) { | ||||
| @@ -99,6 +100,9 @@ int _sasldb_getdata(const sasl_utils_t *
 | ||||
|    } | ||||
|    db = gdbm_open((char *)path, 0, GDBM_READER, S_IRUSR | S_IWUSR, NULL); | ||||
|    if (! db) { | ||||
| +      utils->log(conn, SASL_LOG_ERR,
 | ||||
| +		 "SASL error opening password file. "
 | ||||
| +		 "Have you performed the migration from db2 using cyrusbdb2current?\n");
 | ||||
|        utils->seterror(cntxt, 0, "Could not open %s: gdbm_errno=%d", | ||||
|  		      path, gdbm_errno); | ||||
|        result = SASL_FAIL; | ||||
| @@ -107,9 +111,10 @@ int _sasldb_getdata(const sasl_utils_t *
 | ||||
|    gkey.dptr = key; | ||||
|    gkey.dsize = key_len; | ||||
|    gvalue = gdbm_fetch(db, gkey); | ||||
| +  fetch_errno = gdbm_errno;
 | ||||
|    gdbm_close(db); | ||||
|    if (! gvalue.dptr) { | ||||
| -      if (gdbm_errno == GDBM_ITEM_NOT_FOUND) {
 | ||||
| +      if (fetch_errno == GDBM_ITEM_NOT_FOUND) {
 | ||||
|            utils->seterror(conn, SASL_NOLOG, | ||||
|  			  "user: %s@%s property: %s not found in %s", | ||||
|  			  authid, realm, propName, path); | ||||
| @@ -186,7 +191,8 @@ int _sasldb_putdata(const sasl_utils_t *
 | ||||
|    if (! db) { | ||||
|        utils->log(conn, SASL_LOG_ERR, | ||||
|  		 "SASL error opening password file. " | ||||
| -		 "Do you have write permissions?\n");
 | ||||
| +		 "Do you have write permissions?\n"
 | ||||
| +		 "Have you performed the migration from db2 using cyrusbdb2current?\n");
 | ||||
|        utils->seterror(conn, 0, "Could not open %s for write: gdbm_errno=%d", | ||||
|                       path, gdbm_errno); | ||||
|        result = SASL_FAIL; | ||||
| @@ -298,6 +304,9 @@ sasldb_handle _sasldb_getkeyhandle(const
 | ||||
|      db = gdbm_open((char *)path, 0, GDBM_READER, S_IRUSR | S_IWUSR, NULL); | ||||
|   | ||||
|      if(!db) { | ||||
| +        utils->log(conn, SASL_LOG_ERR,
 | ||||
| +		 "SASL error opening password file. "
 | ||||
| +		 "Have you performed the migration from db2 using cyrusbdb2current?\n");
 | ||||
|          utils->seterror(conn, 0, "Could not open %s: gdbm_errno=%d", | ||||
|  			 path, gdbm_errno); | ||||
|  	return NULL; | ||||
| diff -up cyrus-sasl-2.1.27/utils/cyrusbdb2current.8.frombdb cyrus-sasl-2.1.27/utils/cyrusbdb2current.8
 | ||||
| --- cyrus-sasl-2.1.27/utils/cyrusbdb2current.8.frombdb	2021-06-04 13:02:07.798112327 +0200
 | ||||
| +++ cyrus-sasl-2.1.27/utils/cyrusbdb2current.8	2021-06-04 13:02:07.798112327 +0200
 | ||||
| @@ -0,0 +1,159 @@
 | ||||
| +.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40)
 | ||||
| +.\"
 | ||||
| +.\" Standard preamble:
 | ||||
| +.\" ========================================================================
 | ||||
| +.de Sp \" Vertical space (when we can't use .PP)
 | ||||
| +.if t .sp .5v
 | ||||
| +.if n .sp
 | ||||
| +..
 | ||||
| +.de Vb \" Begin verbatim text
 | ||||
| +.ft CW
 | ||||
| +.nf
 | ||||
| +.ne \\$1
 | ||||
| +..
 | ||||
| +.de Ve \" End verbatim text
 | ||||
| +.ft R
 | ||||
| +.fi
 | ||||
| +..
 | ||||
| +.\" Set up some character translations and predefined strings.  \*(-- will
 | ||||
| +.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
 | ||||
| +.\" double quote, and \*(R" will give a right double quote.  \*(C+ will
 | ||||
| +.\" give a nicer C++.  Capital omega is used to do unbreakable dashes and
 | ||||
| +.\" therefore won't be available.  \*(C` and \*(C' expand to `' in nroff,
 | ||||
| +.\" nothing in troff, for use with C<>.
 | ||||
| +.tr \(*W-
 | ||||
| +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
 | ||||
| +.ie n \{\
 | ||||
| +.    ds -- \(*W-
 | ||||
| +.    ds PI pi
 | ||||
| +.    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
 | ||||
| +.    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
 | ||||
| +.    ds L" ""
 | ||||
| +.    ds R" ""
 | ||||
| +.    ds C` ""
 | ||||
| +.    ds C' ""
 | ||||
| +'br\}
 | ||||
| +.el\{\
 | ||||
| +.    ds -- \|\(em\|
 | ||||
| +.    ds PI \(*p
 | ||||
| +.    ds L" ``
 | ||||
| +.    ds R" ''
 | ||||
| +.    ds C`
 | ||||
| +.    ds C'
 | ||||
| +'br\}
 | ||||
| +.\"
 | ||||
| +.\" Escape single quotes in literal strings from groff's Unicode transform.
 | ||||
| +.ie \n(.g .ds Aq \(aq
 | ||||
| +.el       .ds Aq '
 | ||||
| +.\"
 | ||||
| +.\" If the F register is >0, we'll generate index entries on stderr for
 | ||||
| +.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
 | ||||
| +.\" entries marked with X<> in POD.  Of course, you'll have to process the
 | ||||
| +.\" output yourself in some meaningful fashion.
 | ||||
| +.\"
 | ||||
| +.\" Avoid warning from groff about undefined register 'F'.
 | ||||
| +.de IX
 | ||||
| +..
 | ||||
| +.nr rF 0
 | ||||
| +.if \n(.g .if rF .nr rF 1
 | ||||
| +.if (\n(rF:(\n(.g==0)) \{\
 | ||||
| +.    if \nF \{\
 | ||||
| +.        de IX
 | ||||
| +.        tm Index:\\$1\t\\n%\t"\\$2"
 | ||||
| +..
 | ||||
| +.        if !\nF==2 \{\
 | ||||
| +.            nr % 0
 | ||||
| +.            nr F 2
 | ||||
| +.        \}
 | ||||
| +.    \}
 | ||||
| +.\}
 | ||||
| +.rr rF
 | ||||
| +.\"
 | ||||
| +.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
 | ||||
| +.\" Fear.  Run.  Save yourself.  No user-serviceable parts.
 | ||||
| +.    \" fudge factors for nroff and troff
 | ||||
| +.if n \{\
 | ||||
| +.    ds #H 0
 | ||||
| +.    ds #V .8m
 | ||||
| +.    ds #F .3m
 | ||||
| +.    ds #[ \f1
 | ||||
| +.    ds #] \fP
 | ||||
| +.\}
 | ||||
| +.if t \{\
 | ||||
| +.    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
 | ||||
| +.    ds #V .6m
 | ||||
| +.    ds #F 0
 | ||||
| +.    ds #[ \&
 | ||||
| +.    ds #] \&
 | ||||
| +.\}
 | ||||
| +.    \" simple accents for nroff and troff
 | ||||
| +.if n \{\
 | ||||
| +.    ds ' \&
 | ||||
| +.    ds ` \&
 | ||||
| +.    ds ^ \&
 | ||||
| +.    ds , \&
 | ||||
| +.    ds ~ ~
 | ||||
| +.    ds /
 | ||||
| +.\}
 | ||||
| +.if t \{\
 | ||||
| +.    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
 | ||||
| +.    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
 | ||||
| +.    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
 | ||||
| +.    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
 | ||||
| +.    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
 | ||||
| +.    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
 | ||||
| +.\}
 | ||||
| +.    \" troff and (daisy-wheel) nroff accents
 | ||||
| +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
 | ||||
| +.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
 | ||||
| +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
 | ||||
| +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
 | ||||
| +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
 | ||||
| +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
 | ||||
| +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
 | ||||
| +.ds ae a\h'-(\w'a'u*4/10)'e
 | ||||
| +.ds Ae A\h'-(\w'A'u*4/10)'E
 | ||||
| +.    \" corrections for vroff
 | ||||
| +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
 | ||||
| +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
 | ||||
| +.    \" for low resolution devices (crt and lpr)
 | ||||
| +.if \n(.H>23 .if \n(.V>19 \
 | ||||
| +\{\
 | ||||
| +.    ds : e
 | ||||
| +.    ds 8 ss
 | ||||
| +.    ds o a
 | ||||
| +.    ds d- d\h'-1'\(ga
 | ||||
| +.    ds D- D\h'-1'\(hy
 | ||||
| +.    ds th \o'bp'
 | ||||
| +.    ds Th \o'LP'
 | ||||
| +.    ds ae ae
 | ||||
| +.    ds Ae AE
 | ||||
| +.\}
 | ||||
| +.rm #[ #] #H #V #F C
 | ||||
| +.\" ========================================================================
 | ||||
| +.\"
 | ||||
| +.IX Title "CYRUSBDB2CURRENT 1"
 | ||||
| +.TH CYRUSBDB2CURRENT 1 "2021-04-28" "perl v5.30.3" "User Contributed Perl Documentation"
 | ||||
| +.\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 | ||||
| +.\" way too many mistakes in technical documents.
 | ||||
| +.if n .ad l
 | ||||
| +.nh
 | ||||
| +.SH "NAME"
 | ||||
| +cyrusbdb2current \- command\-line utility converting the SASLDB database from
 | ||||
| +BerkeleyDB to the database format currently used bys sasldb.
 | ||||
| +.SH "SYNOPSIS"
 | ||||
| +.IX Header "SYNOPSIS"
 | ||||
| +cyrusbdb2current <sasldb_old_path> <sasldb_new_path>
 | ||||
| +.SH "DESCRIPTION"
 | ||||
| +.IX Header "DESCRIPTION"
 | ||||
| +\&\fBcyrusbdb2current\fR converts the current sasldb database from BerkeleyDB format to the
 | ||||
| +currently used database format. It is \fB\s-1STRONGLY RECOMMENDED\s0\fR to make a backup
 | ||||
| +of the current database before the conversion.
 | ||||
| +.PP
 | ||||
| +We expect that the old path is \fB/etc/sasldb2\fR and the new one is
 | ||||
| +\&\fB/etc/sasl2/sasldb2\fR
 | ||||
| +.SH "SEE ALSO"
 | ||||
| +.IX Header "SEE ALSO"
 | ||||
| +\&\fBsaslpasswd2\fR\|(8)
 | ||||
| +.PP
 | ||||
| +rfc4422 \- Simple Authentication and Security Layer (\s-1SASL\s0)
 | ||||
| diff -up cyrus-sasl-2.1.27/utils/cyrusbdb2current.c.frombdb cyrus-sasl-2.1.27/utils/cyrusbdb2current.c
 | ||||
| --- cyrus-sasl-2.1.27/utils/cyrusbdb2current.c.frombdb	2021-06-04 13:02:07.798112327 +0200
 | ||||
| +++ cyrus-sasl-2.1.27/utils/cyrusbdb2current.c	2021-06-04 13:02:07.798112327 +0200
 | ||||
| @@ -0,0 +1,282 @@
 | ||||
| +#include <config.h>
 | ||||
| +
 | ||||
| +#include <stdio.h>
 | ||||
| +#include <stdlib.h>
 | ||||
| +
 | ||||
| +#include <sasl.h>
 | ||||
| +#include <saslplug.h>
 | ||||
| +#include "../sasldb/sasldb.h"
 | ||||
| +
 | ||||
| +/* Cheating to make the utils work out right */
 | ||||
| +extern const sasl_utils_t *sasl_global_utils;
 | ||||
| +sasl_conn_t *globalconn;
 | ||||
| +
 | ||||
| +typedef void *listcb_t(const char *, const char *, const char *,
 | ||||
| +		       const char *, unsigned);
 | ||||
| +
 | ||||
| +void listusers_cb(const char *authid, const char *realm,
 | ||||
| +		  const char *propName, const char *secret,
 | ||||
| +		  unsigned seclen)
 | ||||
| +{
 | ||||
| +    if (!authid || !propName || !realm) {
 | ||||
| +	fprintf(stderr,"userlist callback has bad param");
 | ||||
| +	return;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    /* the entries that just say the mechanism exists */
 | ||||
| +    if (strlen(authid)==0) return;
 | ||||
| +
 | ||||
| +    printf("Converting: %s@%s (%s)...",authid,realm,propName);
 | ||||
| +
 | ||||
| +    _sasldb_putdata(sasl_global_utils, globalconn,
 | ||||
| +		    authid, realm, propName,
 | ||||
| +		    secret, seclen);
 | ||||
| +
 | ||||
| +    printf("ok\n");
 | ||||
| +}
 | ||||
| +
 | ||||
| +/*
 | ||||
| + * List all users in database
 | ||||
| + */
 | ||||
| +
 | ||||
| +#include <db.h>
 | ||||
| +
 | ||||
| +#define DB_VERSION_FULL ((DB_VERSION_MAJOR << 24) | (DB_VERSION_MINOR << 16) | DB_VERSION_PATCH)
 | ||||
| +/*
 | ||||
| + * Open the database
 | ||||
| + *
 | ||||
| + */
 | ||||
| +static int berkeleydb_open(const char *path,DB **mbdb)
 | ||||
| +{
 | ||||
| +    int ret;
 | ||||
| +
 | ||||
| +#if DB_VERSION_FULL < 0x03000000
 | ||||
| +    ret = db_open(path, DB_HASH, DB_CREATE, 0664, NULL, NULL, mbdb);
 | ||||
| +#else /* DB_VERSION_FULL < 0x03000000 */
 | ||||
| +    ret = db_create(mbdb, NULL, 0);
 | ||||
| +    if (ret == 0 && *mbdb != NULL)
 | ||||
| +    {
 | ||||
| +#if DB_VERSION_FULL >= 0x04010000
 | ||||
| +	ret = (*mbdb)->open(*mbdb, NULL, path, NULL, DB_HASH, DB_CREATE, 0664);
 | ||||
| +#else
 | ||||
| +	ret = (*mbdb)->open(*mbdb, path, NULL, DB_HASH, DB_CREATE, 0664);
 | ||||
| +#endif
 | ||||
| +	if (ret != 0)
 | ||||
| +	{
 | ||||
| +	    (void) (*mbdb)->close(*mbdb, 0);
 | ||||
| +	    *mbdb = NULL;
 | ||||
| +	}
 | ||||
| +    }
 | ||||
| +#endif /* DB_VERSION_FULL < 0x03000000 */
 | ||||
| +
 | ||||
| +    if (ret != 0) {
 | ||||
| +	fprintf(stderr,"Error opening password file %s\n", path);
 | ||||
| +	return SASL_FAIL;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    return SASL_OK;
 | ||||
| +}
 | ||||
| +
 | ||||
| +/*
 | ||||
| + * Close the database
 | ||||
| + *
 | ||||
| + */
 | ||||
| +
 | ||||
| +static void berkeleydb_close(DB *mbdb)
 | ||||
| +{
 | ||||
| +    int ret;
 | ||||
| +    
 | ||||
| +    ret = mbdb->close(mbdb, 0);
 | ||||
| +    if (ret!=0) {
 | ||||
| +	fprintf(stderr,"error closing sasldb: %s",
 | ||||
| +		db_strerror(ret));
 | ||||
| +    }
 | ||||
| +}
 | ||||
| +
 | ||||
| +int listusers(const char *path, listcb_t *cb)
 | ||||
| +{
 | ||||
| +    int result;
 | ||||
| +    DB *mbdb = NULL;
 | ||||
| +    DBC *cursor;
 | ||||
| +    DBT key, data;
 | ||||
| +
 | ||||
| +    /* open the db */
 | ||||
| +    result=berkeleydb_open(path, &mbdb);
 | ||||
| +    if (result!=SASL_OK) goto cleanup;
 | ||||
| +
 | ||||
| +    /* make cursor */
 | ||||
| +#if DB_VERSION_FULL < 0x03060000
 | ||||
| +    result = mbdb->cursor(mbdb, NULL,&cursor); 
 | ||||
| +#else
 | ||||
| +    result = mbdb->cursor(mbdb, NULL,&cursor, 0); 
 | ||||
| +#endif /* DB_VERSION_FULL < 0x03060000 */
 | ||||
| +
 | ||||
| +    if (result!=0) {
 | ||||
| +	fprintf(stderr,"Making cursor failure: %s\n",db_strerror(result));
 | ||||
| +      result = SASL_FAIL;
 | ||||
| +      goto cleanup;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    memset(&key,0, sizeof(key));
 | ||||
| +    memset(&data,0,sizeof(data));
 | ||||
| +
 | ||||
| +    /* loop thru */
 | ||||
| +    result = cursor->c_get(cursor, &key, &data,
 | ||||
| +			   DB_FIRST);
 | ||||
| +
 | ||||
| +    while (result != DB_NOTFOUND)
 | ||||
| +    {
 | ||||
| +	char *authid;
 | ||||
| +	char *realm;
 | ||||
| +	char *tmp;
 | ||||
| +	unsigned int len;
 | ||||
| +	char prop[1024];
 | ||||
| +	int numnulls = 0;
 | ||||
| +	unsigned int lup;
 | ||||
| +
 | ||||
| +	/* make sure there are exactly 2 null's */
 | ||||
| +	for (lup=0;lup<key.size;lup++)
 | ||||
| +	    if (((char *)key.data)[lup]=='\0')
 | ||||
| +		numnulls++;
 | ||||
| +
 | ||||
| +	if (numnulls != 2) {
 | ||||
| +	    fprintf(stderr,"warning: probable database corruption\n");
 | ||||
| +	    result = cursor->c_get(cursor, &key, &data, DB_NEXT);
 | ||||
| +	    continue;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	authid = key.data;
 | ||||
| +	realm  = authid + strlen(authid)+1;
 | ||||
| +	tmp    = realm + strlen(realm)+1;
 | ||||
| +	len = key.size - (tmp - authid);
 | ||||
| +
 | ||||
| +	/* make sure we have enough space of prop */
 | ||||
| +	if (len >=sizeof(prop)) {
 | ||||
| +	    fprintf(stderr,"warning: absurdly long prop name\n");
 | ||||
| +	    result = cursor->c_get(cursor, &key, &data, DB_NEXT);
 | ||||
| +	    continue;
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	memcpy(prop, tmp, key.size - (tmp - ((char *)key.data)));
 | ||||
| +	prop[key.size - (tmp - ((char *)key.data))] = '\0';
 | ||||
| +
 | ||||
| +	if (*authid) {
 | ||||
| +	    /* don't check return values */
 | ||||
| +	    cb(authid,realm,prop,data.data,data.size);
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	result = cursor->c_get(cursor, &key, &data, DB_NEXT);
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    if (result != DB_NOTFOUND) {
 | ||||
| +	fprintf(stderr,"failure: %s\n",db_strerror(result));
 | ||||
| +	result = SASL_FAIL;
 | ||||
| +	goto cleanup;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    result = cursor->c_close(cursor);
 | ||||
| +    if (result != 0) {
 | ||||
| +        result = SASL_FAIL;
 | ||||
| +        goto cleanup;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    result = SASL_OK;
 | ||||
| +
 | ||||
| + cleanup:
 | ||||
| +
 | ||||
| +    if (mbdb != NULL) berkeleydb_close(mbdb);
 | ||||
| +    return result;
 | ||||
| +}
 | ||||
| +
 | ||||
| +
 | ||||
| +char *db = NULL, *db_new=NULL;
 | ||||
| +
 | ||||
| +int good_getopt(void *context __attribute__((unused)), 
 | ||||
| +		const char *plugin_name __attribute__((unused)), 
 | ||||
| +		const char *option,
 | ||||
| +		const char **result,
 | ||||
| +		unsigned *len)
 | ||||
| +{
 | ||||
| +    if (db_new && !strcmp(option, "sasldb_path")) {
 | ||||
| +	*result = db_new;
 | ||||
| +	if (len)
 | ||||
| +	    *len = strlen(db_new);
 | ||||
| +	return SASL_OK;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    return SASL_FAIL;
 | ||||
| +}
 | ||||
| +
 | ||||
| +static struct sasl_callback goodsasl_cb[] = {
 | ||||
| +    { SASL_CB_GETOPT, (int (*)(void))&good_getopt, NULL },
 | ||||
| +    { SASL_CB_LIST_END, NULL, NULL }
 | ||||
| +};
 | ||||
| +
 | ||||
| +int main(int argc, char **argv)
 | ||||
| +{
 | ||||
| +    int result;
 | ||||
| +    FILE *f;
 | ||||
| +
 | ||||
| +    if (argc != 3) {
 | ||||
| +	fprintf(stderr, "Usage: cyrusbdb2current old_sasldb new_sasldb\n");
 | ||||
| +	fprintf(stderr, "old_sasldb is presumably /etc/sasldb2\n");
 | ||||
| +       	fprintf(stderr, "new_sasldb is presumably /etc/sasl2/sasldb2\n");
 | ||||
| +	return 1;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    db = argv[1];
 | ||||
| +    db_new = argv[2];
 | ||||
| +
 | ||||
| +    if (strcmp(db, db_new) == 0) {
 | ||||
| +	fprintf(stderr, "Old and new files should be different\n");
 | ||||
| +	return 1;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +
 | ||||
| +    f = fopen(db_new, "rb");
 | ||||
| +    if (f != NULL) {
 | ||||
| +	fprintf(stderr, "The specified target file %s already exists\n", db_new);
 | ||||
| +	fclose(f);
 | ||||
| +	return 1;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    result = sasl_server_init(goodsasl_cb, "dbconverter");
 | ||||
| +    if (result != SASL_OK) {
 | ||||
| +	fprintf(stderr, "couldn't init saslv2\n");
 | ||||
| +	return 1;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    result = sasl_server_new("sasldb",
 | ||||
| +			     "localhost",
 | ||||
| +			     NULL,
 | ||||
| +			     NULL,
 | ||||
| +			     NULL,
 | ||||
| +			     NULL,
 | ||||
| +			     0,
 | ||||
| +			     &globalconn);
 | ||||
| +    if (result != SASL_OK) {
 | ||||
| +	fprintf(stderr, "couldn't create globalconn\n");
 | ||||
| +	return 1;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    if(_sasl_check_db(sasl_global_utils,globalconn) != SASL_OK) {
 | ||||
| +	fprintf(stderr, "target DB %s is not OK\n", db_new);
 | ||||
| +	return 1;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    printf("\nThis program will take the sasldb file specified on the\n"
 | ||||
| +           "command line and convert it to a new sasldb specified\n"
 | ||||
| +           "on the command line. It is STRONGLY RECOMMENDED that you\n"
 | ||||
| +           "backup sasldb before allowing this program to run\n\n"
 | ||||
| +	   "We are going to convert %s and our output will be in %s\n\n"
 | ||||
| +           "Press return to continue\n", db, db_new);
 | ||||
| +
 | ||||
| +    getchar();
 | ||||
| +
 | ||||
| +    listusers(db, (listcb_t *) &listusers_cb);
 | ||||
| +
 | ||||
| +    sasl_dispose(&globalconn);
 | ||||
| +    sasl_done();
 | ||||
| +
 | ||||
| +    exit(0);
 | ||||
| +}
 | ||||
| diff -up cyrus-sasl-2.1.27/utils/Makefile.am.frombdb cyrus-sasl-2.1.27/utils/Makefile.am
 | ||||
| --- cyrus-sasl-2.1.27/utils/Makefile.am.frombdb	2018-10-05 16:40:16.000000000 +0200
 | ||||
| +++ cyrus-sasl-2.1.27/utils/Makefile.am	2021-06-04 13:02:07.798112327 +0200
 | ||||
| @@ -46,14 +46,14 @@ all_sasl_libs = ../lib/libsasl2.la $(SAS
 | ||||
|  all_sasl_static_libs = ../lib/.libs/libsasl2.a $(SASL_DB_LIB) $(LIB_SOCKET) $(GSSAPIBASE_LIBS) $(GSSAPI_LIBS) $(SASL_KRB_LIB) $(LIB_DES) $(PLAIN_LIBS) $(SRP_LIBS) $(LIB_MYSQL) $(LIB_PGSQL) $(LIB_SQLITE) | ||||
|   | ||||
|  sbin_PROGRAMS = @SASL_DB_UTILS@ @SMTPTEST_PROGRAM@ pluginviewer | ||||
| -EXTRA_PROGRAMS = saslpasswd2 sasldblistusers2 testsuite testsuitestatic smtptest pluginviewer
 | ||||
| +EXTRA_PROGRAMS = saslpasswd2 sasldblistusers2 testsuite testsuitestatic smtptest pluginviewer cyrusbdb2current
 | ||||
|   | ||||
|  noinst_PROGRAMS = dbconverter-2 | ||||
|   | ||||
|  if NO_SASL_DB_MANS | ||||
|  man_MANS =  | ||||
|  else | ||||
| -man_MANS = saslpasswd2.8 sasldblistusers2.8 pluginviewer.8
 | ||||
| +man_MANS = saslpasswd2.8 sasldblistusers2.8 pluginviewer.8 cyrusbdb2current.8
 | ||||
|  endif | ||||
|   | ||||
|  saslpasswd2_LDADD = ../sasldb/libsasldb.la $(all_sasl_libs) | ||||
| @@ -63,6 +63,7 @@ sasldblistusers2_SOURCES = sasldblistuse
 | ||||
|  dbconverter_2_LDADD = ../sasldb/libsasldb.la $(all_sasl_libs) | ||||
|  pluginviewer_LDADD = $(all_sasl_libs) | ||||
|  pluginviewer_SOURCES = pluginviewer.c | ||||
| +cyrusbdb2current_LDADD = ../sasldb/libsasldb.la @BDB_STATIC_LIBADD@ $(all_sasl_libs)
 | ||||
|   | ||||
|  testsuite_LDADD = $(all_sasl_libs) @DMALLOC_LIBS@ | ||||
|   | ||||
							
								
								
									
										56
									
								
								SOURCES/cyrus-sasl-2.1.27-coverity.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								SOURCES/cyrus-sasl-2.1.27-coverity.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,56 @@ | ||||
| diff -up cyrus-sasl-2.1.27/include/makemd5.c.coverity cyrus-sasl-2.1.27/include/makemd5.c
 | ||||
| --- cyrus-sasl-2.1.27/include/makemd5.c.coverity	2021-04-12 15:10:25.421431535 +0200
 | ||||
| +++ cyrus-sasl-2.1.27/include/makemd5.c	2021-04-12 15:56:46.752827737 +0200
 | ||||
| @@ -107,7 +107,6 @@ my_strupr(char *s)
 | ||||
|      }	 | ||||
|  } | ||||
|   | ||||
| -
 | ||||
|  #define BITSIZE(TYPE)						\ | ||||
|  {								\ | ||||
|      int b = 0; TYPE x = 1, zero = 0; char *pre = "U";		\ | ||||
| @@ -129,6 +128,8 @@ my_strupr(char *s)
 | ||||
|  static void | ||||
|  try_signed(FILE *f, int len) | ||||
|  { | ||||
| +/* Local macros for not-installed program. No coverity/compiler issues! */
 | ||||
| +#pragma GCC diagnostic ignored "-Wformat-overflow"
 | ||||
|  #ifdef HAVE_INT8_T | ||||
|      BITSIZE(int8_t); | ||||
|  #endif | ||||
| @@ -149,6 +150,7 @@ try_signed(FILE *f, int len)
 | ||||
|      BITSIZE(long long); | ||||
|  #endif | ||||
|      fprintf(f, "/* There is no %d bit type */\n", len); | ||||
| +#pragma GCC pop
 | ||||
|  } | ||||
|   | ||||
|  static void | ||||
| diff -up cyrus-sasl-2.1.27/saslauthd/lak.c.coverity cyrus-sasl-2.1.27/saslauthd/lak.c
 | ||||
| --- cyrus-sasl-2.1.27/saslauthd/lak.c.coverity	2018-11-08 18:29:57.000000000 +0100
 | ||||
| +++ cyrus-sasl-2.1.27/saslauthd/lak.c	2021-04-12 15:10:25.433431630 +0200
 | ||||
| @@ -337,9 +337,9 @@ static int lak_config_read(
 | ||||
|           EMPTY(conf->group_search_base) ) | ||||
|          strlcpy(conf->group_search_base, conf->search_base, LAK_DN_LEN); | ||||
|           | ||||
| -	fclose(infile);
 | ||||
| +    fclose(infile);
 | ||||
|   | ||||
| -	return LAK_OK;
 | ||||
| +    return LAK_OK;
 | ||||
|  } | ||||
|   | ||||
|  static int lak_config_int( | ||||
| diff -up cyrus-sasl-2.1.27/saslauthd/saslauthd-main.c.coverity cyrus-sasl-2.1.27/saslauthd/saslauthd-main.c
 | ||||
| --- cyrus-sasl-2.1.27/saslauthd/saslauthd-main.c.coverity	2018-01-19 15:13:40.000000000 +0100
 | ||||
| +++ cyrus-sasl-2.1.27/saslauthd/saslauthd-main.c	2021-04-12 15:10:25.433431630 +0200
 | ||||
| @@ -833,7 +833,8 @@ void detach_tty() {
 | ||||
|      } | ||||
|       | ||||
|      logger(L_INFO, L_FUNC, "master pid is: %lu", (unsigned long)master_pid); | ||||
| -    
 | ||||
| +    /* null_fd expected to be more than 2, so it is closed after dups, no leaks occur */
 | ||||
| +    /* coverity[leaked_handle : FALSE]*/
 | ||||
|      return; | ||||
|  } | ||||
|   | ||||
							
								
								
									
										73
									
								
								SOURCES/cyrus-sasl-2.1.27-legacy-init.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								SOURCES/cyrus-sasl-2.1.27-legacy-init.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,73 @@ | ||||
| From 4edb8ce82ac530f473a8728bae01d9fc8535c9cb Mon Sep 17 00:00:00 2001 | ||||
| From: Simo Sorce <simo@redhat.com> | ||||
| Date: Mon, 21 Jun 2021 14:24:18 -0400 | ||||
| Subject: [PATCH] Gracefully handle failed initializations | ||||
| 
 | ||||
| In OpenSSL 3.0 these algorithms have been moved to the legacy provider | ||||
| which is not enabled by default. This means allocation can and do fail. | ||||
| Handle failed allocations by returning an actual error instead of | ||||
| crashing later with a NULL context. | ||||
| 
 | ||||
| Signed-off-by: Simo Sorce <simo@redhat.com> | ||||
| ---
 | ||||
|  plugins/digestmd5.c | 16 ++++++++++++++-- | ||||
|  1 file changed, 14 insertions(+), 2 deletions(-) | ||||
| 
 | ||||
| diff --git a/plugins/digestmd5.c b/plugins/digestmd5.c
 | ||||
| index c6b54317..b2617536 100644
 | ||||
| --- a/plugins/digestmd5.c
 | ||||
| +++ b/plugins/digestmd5.c
 | ||||
| @@ -254,6 +254,7 @@ typedef struct context {
 | ||||
|      decode_context_t decode_context; | ||||
|   | ||||
|      /* if privacy mode is used use these functions for encode and decode */ | ||||
| +    char *cipher_name;
 | ||||
|      cipher_function_t *cipher_enc; | ||||
|      cipher_function_t *cipher_dec; | ||||
|      cipher_init_t *cipher_init; | ||||
| @@ -2821,6 +2822,7 @@ static int digestmd5_server_mech_step2(server_context_t *stext,
 | ||||
|  	} | ||||
|  	 | ||||
|  	if (cptr->name) { | ||||
| +	    text->cipher_name = cptr->name;
 | ||||
|  	    text->cipher_enc = cptr->cipher_enc; | ||||
|  	    text->cipher_dec = cptr->cipher_dec; | ||||
|  	    text->cipher_init = cptr->cipher_init; | ||||
| @@ -2964,7 +2966,10 @@ static int digestmd5_server_mech_step2(server_context_t *stext,
 | ||||
|  	if (text->cipher_init) { | ||||
|  	    if (text->cipher_init(text, enckey, deckey) != SASL_OK) { | ||||
|  		sparams->utils->seterror(sparams->utils->conn, 0, | ||||
| -					 "couldn't init cipher");
 | ||||
| +					 "couldn't init cipher '%s'",
 | ||||
| +                                         text->cipher_name);
 | ||||
| +                result = SASL_FAIL;
 | ||||
| +                goto FreeAllMem;
 | ||||
|  	    } | ||||
|  	} | ||||
|      } | ||||
| @@ -3515,6 +3520,7 @@ static int make_client_response(context_t *text,
 | ||||
|  	oparams->mech_ssf = ctext->cipher->ssf; | ||||
|   | ||||
|  	nbits = ctext->cipher->n; | ||||
| +	text->cipher_name = ctext->cipher->name;
 | ||||
|  	text->cipher_enc = ctext->cipher->cipher_enc; | ||||
|  	text->cipher_dec = ctext->cipher->cipher_dec; | ||||
|  	text->cipher_free = ctext->cipher->cipher_free; | ||||
| @@ -3739,7 +3745,13 @@ static int make_client_response(context_t *text,
 | ||||
|  	 | ||||
|  	/* initialize cipher if need be */ | ||||
|  	if (text->cipher_init) { | ||||
| -	    text->cipher_init(text, enckey, deckey);
 | ||||
| +	    if (text->cipher_init(text, enckey, deckey) != SASL_OK) {
 | ||||
| +	        params->utils->seterror(params->utils->conn, 0,
 | ||||
| +		         "internal error: failed to init cipher '%s'",
 | ||||
| +                         text->cipher_name);
 | ||||
| +                result = SASL_FAIL;
 | ||||
| +                goto FreeAllocatedMem;
 | ||||
| +            }
 | ||||
|  	} | ||||
|      } | ||||
|       | ||||
| -- 
 | ||||
| 2.31.1 | ||||
| 
 | ||||
							
								
								
									
										51
									
								
								SOURCES/cyrus-sasl-2.1.27-nostrncpy.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								SOURCES/cyrus-sasl-2.1.27-nostrncpy.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,51 @@ | ||||
| diff --git a/plugins/gssapi.c b/plugins/gssapi.c
 | ||||
| index 5d900c5e..4688bb9a 100644
 | ||||
| --- a/plugins/gssapi.c
 | ||||
| +++ b/plugins/gssapi.c
 | ||||
| @@ -1567,7 +1567,6 @@ int gssapiv2_server_plug_init(
 | ||||
|  { | ||||
|  #ifdef HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY | ||||
|      const char *keytab = NULL; | ||||
| -    char keytab_path[1024];
 | ||||
|      unsigned int rl; | ||||
|  #endif | ||||
|       | ||||
| @@ -1589,15 +1588,7 @@ int gssapiv2_server_plug_init(
 | ||||
|  	    return SASL_FAIL; | ||||
|  	} | ||||
|  	 | ||||
| -	if(strlen(keytab) > 1024) {
 | ||||
| -	    utils->log(NULL, SASL_LOG_ERR,
 | ||||
| -		       "path to keytab is > 1024 characters");
 | ||||
| -	    return SASL_BUFOVER;
 | ||||
| -	}
 | ||||
| -	
 | ||||
| -	strncpy(keytab_path, keytab, 1024);
 | ||||
| -	
 | ||||
| -	gsskrb5_register_acceptor_identity(keytab_path);
 | ||||
| +	gsskrb5_register_acceptor_identity(keytab);
 | ||||
|      } | ||||
|  #endif | ||||
|       | ||||
| diff --git a/plugins/ntlm.c b/plugins/ntlm.c
 | ||||
| index aeb3ac34..8a7d9065 100644
 | ||||
| --- a/plugins/ntlm.c
 | ||||
| +++ b/plugins/ntlm.c
 | ||||
| @@ -375,10 +375,15 @@ static unsigned char *P16_lm(unsigned char *P16, sasl_secret_t *passwd,
 | ||||
|  			     unsigned *buflen __attribute__((unused)), | ||||
|  			     int *result) | ||||
|  { | ||||
| -    char P14[14];
 | ||||
| +    char P14[14] = { 0 };
 | ||||
| +    int Plen;
 | ||||
|      unsigned char S8[] = { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 }; | ||||
|   | ||||
| -    strncpy(P14, (const char *) passwd->data, sizeof(P14));
 | ||||
| +    Plen = sizeof(P14);
 | ||||
| +    if (passwd->len < Plen) {
 | ||||
| +        Plen = passwd->len;
 | ||||
| +    }
 | ||||
| +    memcpy(P14, (const char *) passwd->data, Plen);
 | ||||
|      ucase(P14, sizeof(P14)); | ||||
|   | ||||
|      E(P16, (unsigned char *) P14, sizeof(P14), S8, sizeof(S8)); | ||||
							
								
								
									
										25
									
								
								SOURCES/cyrus-sasl-cve-2019-19906.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								SOURCES/cyrus-sasl-cve-2019-19906.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | ||||
| From dcc9f51cbd4ed622cfb0f9b1c141eb2ffe3b12f1 Mon Sep 17 00:00:00 2001 | ||||
| From: Quanah Gibson-Mount <quanah@symas.com> | ||||
| Date: Tue, 18 Feb 2020 19:05:12 +0000 | ||||
| Subject: [PATCH] Fix #587 | ||||
| 
 | ||||
| Off by one error in common.c, CVE-2019-19906. | ||||
| 
 | ||||
| Thanks to Stephan Zeisberg for reporting | ||||
| ---
 | ||||
|  lib/common.c | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
| 
 | ||||
| diff --git a/lib/common.c b/lib/common.c
 | ||||
| index bc3bf1df..9969d6aa 100644
 | ||||
| --- a/lib/common.c
 | ||||
| +++ b/lib/common.c
 | ||||
| @@ -190,7 +190,7 @@ int _sasl_add_string(char **out, size_t *alloclen,
 | ||||
|   | ||||
|    if (add==NULL) add = "(null)"; | ||||
|   | ||||
| -  addlen=strlen(add); /* only compute once */
 | ||||
| +  addlen=strlen(add)+1; /* only compute once */
 | ||||
|    if (_buf_alloc(out, alloclen, (*outlen)+addlen)!=SASL_OK) | ||||
|      return SASL_NOMEM; | ||||
|   | ||||
							
								
								
									
										156
									
								
								SOURCES/cyrus-sasl-pr559-RC4-openssl.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								SOURCES/cyrus-sasl-pr559-RC4-openssl.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,156 @@ | ||||
| From 8aa9ae816ddf66921b4a8a0f422517e6f2e55ac6 Mon Sep 17 00:00:00 2001 | ||||
| From: Simo Sorce <simo@redhat.com> | ||||
| Date: Wed, 27 Mar 2019 14:29:08 -0400 | ||||
| Subject: [PATCH] Use Openssl RC4 when available | ||||
| 
 | ||||
| Signed-off-by: Simo Sorce <simo@redhat.com> | ||||
| ---
 | ||||
|  configure.ac        |   5 +-- | ||||
|  plugins/digestmd5.c | 107 +++++++++++++++++++++++++++++++++++++++++++- | ||||
|  2 files changed, 108 insertions(+), 4 deletions(-) | ||||
| 
 | ||||
| diff --git a/configure.ac b/configure.ac
 | ||||
| index 388f5d02..cfdee4a2 100644
 | ||||
| --- a/configure.ac
 | ||||
| +++ b/configure.ac
 | ||||
| @@ -1103,13 +1103,12 @@ AC_ARG_WITH(configdir, [   --with-configdir=DIR    set the directory where confi
 | ||||
|    configdir='${plugindir}:${sysconfdir}/sasl2') | ||||
|  AC_SUBST(configdir) | ||||
|   | ||||
| -dnl look for rc4 libraries. we accept the CMU one or one from openSSL
 | ||||
| -AC_ARG_WITH(rc4, [  --with-rc4              use internal rc4 routines [[yes]] ],
 | ||||
| +AC_ARG_WITH(rc4, [  --with-rc4              use rc4 routines [[yes]] ],
 | ||||
|  	with_rc4=$withval, | ||||
|  	with_rc4=yes) | ||||
|   | ||||
|  if test "$with_rc4" != no; then | ||||
| -    AC_DEFINE(WITH_RC4,[],[Use internal RC4 implementation?])
 | ||||
| +    AC_DEFINE(WITH_RC4,[],[Use RC4])
 | ||||
|  fi | ||||
|   | ||||
|  building_for_macosx=no | ||||
| diff --git a/plugins/digestmd5.c b/plugins/digestmd5.c
 | ||||
| index df35093d..c6b54317 100644
 | ||||
| --- a/plugins/digestmd5.c
 | ||||
| +++ b/plugins/digestmd5.c
 | ||||
| @@ -1117,6 +1117,111 @@ static void free_des(context_t *text)
 | ||||
|  #endif /* WITH_DES */ | ||||
|   | ||||
|  #ifdef WITH_RC4 | ||||
| +#ifdef HAVE_OPENSSL
 | ||||
| +#include <openssl/evp.h>
 | ||||
| +
 | ||||
| +static void free_rc4(context_t *text)
 | ||||
| +{
 | ||||
| +    if (text->cipher_enc_context) {
 | ||||
| +        EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *)text->cipher_enc_context);
 | ||||
| +        text->cipher_enc_context = NULL;
 | ||||
| +    }
 | ||||
| +    if (text->cipher_dec_context) {
 | ||||
| +        EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *)text->cipher_dec_context);
 | ||||
| +        text->cipher_dec_context = NULL;
 | ||||
| +    }
 | ||||
| +}
 | ||||
| +
 | ||||
| +static int init_rc4(context_t *text,
 | ||||
| +		    unsigned char enckey[16],
 | ||||
| +		    unsigned char deckey[16])
 | ||||
| +{
 | ||||
| +    EVP_CIPHER_CTX *ctx;
 | ||||
| +    int rc;
 | ||||
| +
 | ||||
| +    ctx = EVP_CIPHER_CTX_new();
 | ||||
| +    if (ctx == NULL) return SASL_NOMEM;
 | ||||
| +
 | ||||
| +    rc = EVP_EncryptInit_ex(ctx, EVP_rc4(), NULL, enckey, NULL);
 | ||||
| +    if (rc != 1) return SASL_FAIL;
 | ||||
| +
 | ||||
| +    text->cipher_enc_context = (void *)ctx;
 | ||||
| +
 | ||||
| +    ctx = EVP_CIPHER_CTX_new();
 | ||||
| +    if (ctx == NULL) return SASL_NOMEM;
 | ||||
| +
 | ||||
| +    rc = EVP_DecryptInit_ex(ctx, EVP_rc4(), NULL, deckey, NULL);
 | ||||
| +    if (rc != 1) return SASL_FAIL;
 | ||||
| +
 | ||||
| +    text->cipher_dec_context = (void *)ctx;
 | ||||
| +
 | ||||
| +    return SASL_OK;
 | ||||
| +}
 | ||||
| +
 | ||||
| +static int dec_rc4(context_t *text,
 | ||||
| +		   const char *input,
 | ||||
| +		   unsigned inputlen,
 | ||||
| +		   unsigned char digest[16] __attribute__((unused)),
 | ||||
| +		   char *output,
 | ||||
| +		   unsigned *outputlen)
 | ||||
| +{
 | ||||
| +    int len;
 | ||||
| +    int rc;
 | ||||
| +
 | ||||
| +    /* decrypt the text part & HMAC */
 | ||||
| +    rc = EVP_DecryptUpdate((EVP_CIPHER_CTX *)text->cipher_dec_context,
 | ||||
| +                           (unsigned char *)output, &len,
 | ||||
| +                           (const unsigned char *)input, inputlen);
 | ||||
| +    if (rc != 1) return SASL_FAIL;
 | ||||
| +
 | ||||
| +    *outputlen = len;
 | ||||
| +
 | ||||
| +    rc = EVP_DecryptFinal_ex((EVP_CIPHER_CTX *)text->cipher_dec_context,
 | ||||
| +                             (unsigned char *)output + len, &len);
 | ||||
| +    if (rc != 1) return SASL_FAIL;
 | ||||
| +
 | ||||
| +    *outputlen += len;
 | ||||
| +
 | ||||
| +    /* subtract the HMAC to get the text length */
 | ||||
| +    *outputlen -= 10;
 | ||||
| +
 | ||||
| +    return SASL_OK;
 | ||||
| +}
 | ||||
| +
 | ||||
| +static int enc_rc4(context_t *text,
 | ||||
| +		   const char *input,
 | ||||
| +		   unsigned inputlen,
 | ||||
| +		   unsigned char digest[16],
 | ||||
| +		   char *output,
 | ||||
| +		   unsigned *outputlen)
 | ||||
| +{
 | ||||
| +    int len;
 | ||||
| +    int rc;
 | ||||
| +    /* encrypt the text part */
 | ||||
| +    rc = EVP_EncryptUpdate((EVP_CIPHER_CTX *)text->cipher_enc_context,
 | ||||
| +                           (unsigned char *)output, &len,
 | ||||
| +                           (const unsigned char *)input, inputlen);
 | ||||
| +    if (rc != 1) return SASL_FAIL;
 | ||||
| +
 | ||||
| +    *outputlen = len;
 | ||||
| +
 | ||||
| +    /* encrypt the `MAC part */
 | ||||
| +    rc = EVP_EncryptUpdate((EVP_CIPHER_CTX *)text->cipher_enc_context,
 | ||||
| +                           (unsigned char *)output + *outputlen, &len,
 | ||||
| +                           digest, 10);
 | ||||
| +    if (rc != 1) return SASL_FAIL;
 | ||||
| +
 | ||||
| +    *outputlen += len;
 | ||||
| +
 | ||||
| +    rc = EVP_EncryptFinal_ex((EVP_CIPHER_CTX *)text->cipher_enc_context,
 | ||||
| +                             (unsigned char *)output + *outputlen, &len);
 | ||||
| +    if (rc != 1) return SASL_FAIL;
 | ||||
| +
 | ||||
| +    *outputlen += len;
 | ||||
| +
 | ||||
| +    return SASL_OK;
 | ||||
| +}
 | ||||
| +#else
 | ||||
|  /* quick generic implementation of RC4 */ | ||||
|  struct rc4_context_s { | ||||
|      unsigned char sbox[256]; | ||||
| @@ -1296,7 +1401,7 @@ static int enc_rc4(context_t *text,
 | ||||
|       | ||||
|      return SASL_OK; | ||||
|  } | ||||
| -
 | ||||
| +#endif /* HAVE_OPENSSL */
 | ||||
|  #endif /* WITH_RC4 */ | ||||
|   | ||||
|  struct digest_cipher available_ciphers[] = | ||||
							
								
								
									
										41
									
								
								SOURCES/make-no-dlcompatorsrp-tarball.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										41
									
								
								SOURCES/make-no-dlcompatorsrp-tarball.sh
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,41 @@ | ||||
| #!/bin/bash -e | ||||
| # | ||||
| #  See https://github.com/cyrusimap/cyrus-sasl/releases for unmodified sources. | ||||
| # | ||||
| 
 | ||||
| tmppath=`mktemp -d ${TMPDIR:-/tmp}/make-no-dlcompat-tarball-XXXXXX` | ||||
| if test -z "$tmppath" ; then | ||||
| 	echo Error creating temporary directory. | ||||
| 	exit 1 | ||||
| fi | ||||
| trap "rm -fr $tmppath" EXIT | ||||
| 
 | ||||
| initialdir=`pwd` | ||||
| 
 | ||||
| for tarball in ${initialdir}/cyrus-sasl-*.tar.{gz,bz2} ; do | ||||
| 	if ! test -s "$tarball" ; then | ||||
| 		continue | ||||
| 	fi | ||||
| 	rm -fr $tmppath/* | ||||
| 	pushd $tmppath > /dev/null | ||||
| 	case "$tarball" in | ||||
| 	*nodlcompat*) | ||||
| 		: Do nothing. | ||||
| 		;; | ||||
| 	*.gz) | ||||
| 		gzip  -dc "$tarball" | tar xf - | ||||
| 		rm -fr cyrus-sasl-*/dlcompat* | ||||
| 		rm -fr cyrus-sasl-*/plugins/srp* | ||||
| 		tar cf - * | gzip  -9c > \ | ||||
| 		$initialdir/`basename $tarball .tar.gz`-nodlcompatorsrp.tar.gz | ||||
| 		;; | ||||
| 	*.bz2) | ||||
| 		bzip2 -dc "$tarball" | tar xf - | ||||
| 		rm -fr cyrus-sasl-*/dlcompat* | ||||
| 		rm -fr cyrus-sasl-*/plugins/srp* | ||||
| 		tar cf - * | bzip2 -9c > \ | ||||
| 		$initialdir/`basename $tarball .tar.bz2`-nodlcompatorsrp.tar.bz2 | ||||
| 		;; | ||||
| 	esac | ||||
| 	popd > /dev/null | ||||
| done | ||||
							
								
								
									
										99
									
								
								SOURCES/sasl-mechlist.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								SOURCES/sasl-mechlist.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,99 @@ | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| #include "sasl.h" | ||||
| 
 | ||||
| static int | ||||
| my_getopt(void *context, const char *plugin_name, | ||||
| 	  const char *option, const char **result, unsigned *len) | ||||
| { | ||||
| 	if (result) { | ||||
| 		*result = NULL; | ||||
| #if 0 | ||||
| 		fprintf(stderr, "Getopt plugin=%s%s%s/option=%s%s%s -> ", | ||||
| 			plugin_name ? "\"" : "", | ||||
| 			plugin_name ? plugin_name : "(null)", | ||||
| 			plugin_name ? "\"" : "", | ||||
| 			option ? "\"" : "", | ||||
| 			option ? option : "(null)", | ||||
| 			option ? "\"" : ""); | ||||
| 		fprintf(stderr, "'%s'.\n", *result ? *result : ""); | ||||
| #endif | ||||
| 	} | ||||
| 	if (len) { | ||||
| 		*len = 0; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| main(int argc, char **argv) | ||||
| { | ||||
| 	int ret, i; | ||||
| 	const char *mechs, **globals; | ||||
| 	sasl_callback_t callbacks[] = { | ||||
| 		{SASL_CB_GETOPT, my_getopt, NULL}, | ||||
| 		{SASL_CB_LIST_END}, | ||||
| 	}; | ||||
| 	sasl_conn_t *connection; | ||||
| 	char hostname[512]; | ||||
| 
 | ||||
| 	if ((argc > 1) && (argv[1][0] == '-')) { | ||||
| 		fprintf(stderr, "Usage: %s [appname [hostname] ]\n", argv[0]); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	ret = sasl_server_init(callbacks, argc > 1 ? argv[1] : "sasl-mechlist"); | ||||
| 	if (ret != SASL_OK) { | ||||
| 		fprintf(stderr, "Error in sasl_server_init(): %s\n", | ||||
| 			sasl_errstring(ret, NULL, NULL)); | ||||
| 	} | ||||
| 
 | ||||
| 	connection = NULL; | ||||
| 	strcpy(hostname, "localhost"); | ||||
| 	gethostname(hostname, sizeof(hostname)); | ||||
| 	ret = sasl_server_new(argc > 2 ? argv[2] : "host", | ||||
| 			      hostname, | ||||
| 			      NULL, | ||||
| 			      NULL, | ||||
| 			      NULL, | ||||
| 			      callbacks, | ||||
| 			      0, | ||||
| 			      &connection); | ||||
| 	if (ret != SASL_OK) { | ||||
| 		fprintf(stderr, "Error in sasl_server_new(): %s\n", | ||||
| 			sasl_errstring(ret, NULL, NULL)); | ||||
| 	} | ||||
| 
 | ||||
| 	ret = sasl_listmech(connection, | ||||
| 			    getenv("USER") ? getenv("USER") : "root", | ||||
| 			    "Available mechanisms: ", | ||||
| 			    ",", | ||||
| 			    "\n", | ||||
| 			    &mechs, | ||||
| 			    NULL, | ||||
| 			    NULL); | ||||
| 	if (ret != SASL_OK) { | ||||
| 		fprintf(stderr, "Error in sasl_listmechs(): %s\n", | ||||
| 			sasl_errstring(ret, NULL, NULL)); | ||||
| 	} else { | ||||
| 		fprintf(stdout, "%s", mechs); | ||||
| 	} | ||||
| 
 | ||||
| 	globals = sasl_global_listmech(); | ||||
| 	for (i = 0; (globals != NULL) && (globals[i] != NULL); i++) { | ||||
| 		if (i == 0) { | ||||
| 			fprintf(stdout, "Library supports: "); | ||||
| 		} | ||||
| 		fprintf(stdout, "%s", globals[i]); | ||||
| 		if (globals[i + 1] != NULL) { | ||||
| 			fprintf(stdout, ","); | ||||
| 		} else { | ||||
| 			fprintf(stdout, "\n"); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
							
								
								
									
										12
									
								
								SOURCES/saslauthd.service
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								SOURCES/saslauthd.service
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| [Unit] | ||||
| Description=SASL authentication daemon. | ||||
| 
 | ||||
| [Service] | ||||
| Type=forking | ||||
| PIDFile=/run/saslauthd/saslauthd.pid | ||||
| EnvironmentFile=/etc/sysconfig/saslauthd | ||||
| ExecStart=/usr/sbin/saslauthd -m $SOCKETDIR -a $MECH $FLAGS | ||||
| RuntimeDirectory=saslauthd | ||||
| 
 | ||||
| [Install] | ||||
| WantedBy=multi-user.target | ||||
							
								
								
									
										11
									
								
								SOURCES/saslauthd.sysconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								SOURCES/saslauthd.sysconfig
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| # Directory in which to place saslauthd's listening socket, pid file, and so | ||||
| # on.  This directory must already exist. | ||||
| SOCKETDIR=/run/saslauthd | ||||
| 
 | ||||
| # Mechanism to use when checking passwords.  Run "saslauthd -v" to get a list | ||||
| # of which mechanism your installation was compiled with the ablity to use. | ||||
| MECH=pam | ||||
| 
 | ||||
| # Additional flags to pass to saslauthd on the command line.  See saslauthd(8) | ||||
| # for the list of accepted flags. | ||||
| FLAGS= | ||||
							
								
								
									
										1188
									
								
								SPECS/cyrus-sasl.spec
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1188
									
								
								SPECS/cyrus-sasl.spec
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
		Reference in New Issue
	
	Block a user