stunnel-5.61
This commit is contained in:
Родитель
e3f8472f8d
Коммит
689968d14f
|
@ -20,6 +20,7 @@
|
|||
--prefix=/opt/openssl-mingw64 mingw64 shared enable-capieng
|
||||
sed -i 's/"\$(OPENSSLDIR)/"..\/config/' Makefile
|
||||
sed -i 's/"\$(ENGINESDIR)/"..\/engines/' Makefile
|
||||
sed -i 's/"\$(MODULESDIR)/"..\/ossl-modules/' Makefile
|
||||
make
|
||||
sudo make install
|
||||
sudo cp ms/applink.c /opt/openssl-mingw64/include/openssl/
|
||||
|
@ -54,6 +55,7 @@
|
|||
--prefix=/opt/openssl-mingw mingw shared enable-capieng
|
||||
sed -i 's/"\$(OPENSSLDIR)/"..\/config/' Makefile
|
||||
sed -i 's/"\$(ENGINESDIR)/"..\/engines/' Makefile
|
||||
sed -i 's/"\$(MODULESDIR)/"..\/ossl-modules/' Makefile
|
||||
make
|
||||
sudo make install
|
||||
sudo cp ms/applink.c /opt/openssl-mingw/include/openssl/
|
||||
|
|
|
@ -16,7 +16,7 @@ doc_DATA += INSTALL.W32.md INSTALL.WCE.md INSTALL.FIPS.md
|
|||
|
||||
EXTRA_DIST = .travis.yml $(doc_DATA)
|
||||
|
||||
distcleancheck_listfiles = find -type f -exec sh -c 'test -f $(srcdir)/{} || echo {}' ';'
|
||||
distcleancheck_listfiles = find . -type f -exec sh -c 'test -f $(srcdir)/{} || echo {}' ';'
|
||||
|
||||
distclean-local:
|
||||
rm -rf autom4te.cache
|
||||
|
|
|
@ -370,7 +370,7 @@ doc_DATA = README.md TODO.md COPYING.md AUTHORS.md NEWS.md PORTS.md \
|
|||
BUGS.md COPYRIGHT.md CREDITS.md INSTALL.W32.md INSTALL.WCE.md \
|
||||
INSTALL.FIPS.md
|
||||
EXTRA_DIST = .travis.yml $(doc_DATA)
|
||||
distcleancheck_listfiles = find -type f -exec sh -c 'test -f $(srcdir)/{} || echo {}' ';'
|
||||
distcleancheck_listfiles = find . -type f -exec sh -c 'test -f $(srcdir)/{} || echo {}' ';'
|
||||
all: all-recursive
|
||||
|
||||
.SUFFIXES:
|
||||
|
|
26
NEWS.md
26
NEWS.md
|
@ -1,6 +1,31 @@
|
|||
# stunnel change log
|
||||
|
||||
|
||||
### Version 5.61, 2021.12.22, urgency: LOW
|
||||
* New features sponsored by the University of Maryland
|
||||
- Added new "protocol = capwin" and "protocol = capwinctrl"
|
||||
configuration file options.
|
||||
* New features for the Windows platform
|
||||
- Added client mode allowing authenticated users to view
|
||||
logs, reconfigure and terminate running stunnel services.
|
||||
- Added support for multiple GUI and service instances
|
||||
distinguised by the location of stunnel.conf.
|
||||
- Improved log window scrolling.
|
||||
- Added a new 'Pause auto-scroll' GUI checkbox.
|
||||
- Double click on the icon tray replaced with single click.
|
||||
- OpenSSL DLLs updated to version 3.0.1.
|
||||
* Other new features
|
||||
- Rewritten the testing framework in python (thx to
|
||||
Peter Pentchev for inspiration and initial framework).
|
||||
- Added support for missing SSL_set_options() values.
|
||||
- Updated stunnel.spec to support RHEL8.
|
||||
* Bugfixes
|
||||
- Fixed OpenSSL 3.0 build.
|
||||
- Fixed reloading configuration with
|
||||
"systemctl reload stunnel.service".
|
||||
- Fixed incorrect messages logged for OpenSSL errors.
|
||||
- Fixed printing IPv6 socket option defaults on FreeBSD.
|
||||
|
||||
### Version 5.60, 2021.08.16, urgency: LOW
|
||||
* New features
|
||||
- New 'sessionResume' service-level option to allow
|
||||
|
@ -13,7 +38,6 @@
|
|||
- Enforced minimum WIN32 log window size.
|
||||
- Fixed support for password-protected private keys with
|
||||
OpenSSL 3.0 (thx to Dmitry Belyavskiy).
|
||||
- Added missing TLS options supported in OpenSSL 1.1.1k.
|
||||
|
||||
### Version 5.59, 2021.04.05, urgency: HIGH
|
||||
* Security bugfixes
|
||||
|
|
19
TODO.md
19
TODO.md
|
@ -7,16 +7,17 @@ A sponsor could allocate my time to get them faster.
|
|||
|
||||
* Add client certificate autoselection based on the list of accepted issuers:
|
||||
SSL_CTX_set_client_cert_cb(), SSL_get_client_CA_list().
|
||||
* Add an Apparmor profile.
|
||||
* Optional line-buffering of the log file.
|
||||
* Log rotation on Windows.
|
||||
* Configuration file option to limit the number of concurrent connections.
|
||||
* Command-line server control interface on both Unix and Windows.
|
||||
* Separate GUI process running as the current user on Windows.
|
||||
* An Android GUI.
|
||||
* OCSP stapling (tlsext_status).
|
||||
* Indirect CRL support (RFC 3280, section 5).
|
||||
* Add an Apparmor profile.
|
||||
* Log rotation on Windows.
|
||||
* Configuration file option to limit the number of concurrent connections.
|
||||
* Command-line server control interface on Unix.
|
||||
* An Android GUI.
|
||||
* MSI installer for Windows.
|
||||
* Add 'leastconn' failover strategy to order defined 'connect' targets
|
||||
by the number of active connections.
|
||||
* Optional line-buffering of the log file.
|
||||
|
||||
### Low priority features
|
||||
These features will unlikely ever be supported.
|
||||
|
@ -27,10 +28,6 @@ These features will unlikely ever be supported.
|
|||
* Logging to NT EventLog on Windows.
|
||||
* Internationalization of logged messages (i18n).
|
||||
* Generic scripting engine instead or static protocol.c.
|
||||
* Add 'leastconn' failover strategy to order defined 'connect' targets
|
||||
by the number of active connections.
|
||||
* Add '-status' command line option reporting the number of clients
|
||||
connected to each service.
|
||||
|
||||
### Rejected features
|
||||
Features I will not support, unless convinced otherwise by a wealthy sponsor.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for stunnel 5.60.
|
||||
# Generated by GNU Autoconf 2.69 for stunnel 5.61.
|
||||
#
|
||||
#
|
||||
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
||||
|
@ -587,8 +587,8 @@ MAKEFLAGS=
|
|||
# Identity of this package.
|
||||
PACKAGE_NAME='stunnel'
|
||||
PACKAGE_TARNAME='stunnel'
|
||||
PACKAGE_VERSION='5.60'
|
||||
PACKAGE_STRING='stunnel 5.60'
|
||||
PACKAGE_VERSION='5.61'
|
||||
PACKAGE_STRING='stunnel 5.61'
|
||||
PACKAGE_BUGREPORT=''
|
||||
PACKAGE_URL=''
|
||||
|
||||
|
@ -1338,7 +1338,7 @@ if test "$ac_init_help" = "long"; then
|
|||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures stunnel 5.60 to adapt to many kinds of systems.
|
||||
\`configure' configures stunnel 5.61 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
|
@ -1409,7 +1409,7 @@ fi
|
|||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of stunnel 5.60:";;
|
||||
short | recursive ) echo "Configuration of stunnel 5.61:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
|
@ -1528,7 +1528,7 @@ fi
|
|||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
stunnel configure 5.60
|
||||
stunnel configure 5.61
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
|
@ -2134,7 +2134,7 @@ cat >config.log <<_ACEOF
|
|||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by stunnel $as_me 5.60, which was
|
||||
It was created by stunnel $as_me 5.61, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
|
@ -2998,7 +2998,7 @@ fi
|
|||
|
||||
# Define the identity of the package.
|
||||
PACKAGE='stunnel'
|
||||
VERSION='5.60'
|
||||
VERSION='5.61'
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
|
@ -3207,197 +3207,7 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
|||
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
if test -n "$ac_tool_prefix"; then
|
||||
# Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
|
||||
set dummy ${ac_tool_prefix}gcc; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_prog_CC+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
if test -n "$CC"; then
|
||||
ac_cv_prog_CC="$CC" # Let the user override the test.
|
||||
else
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_prog_CC="${ac_tool_prefix}gcc"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
fi
|
||||
fi
|
||||
CC=$ac_cv_prog_CC
|
||||
if test -n "$CC"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
|
||||
$as_echo "$CC" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
if test -z "$ac_cv_prog_CC"; then
|
||||
ac_ct_CC=$CC
|
||||
# Extract the first word of "gcc", so it can be a program name with args.
|
||||
set dummy gcc; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_prog_ac_ct_CC+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
if test -n "$ac_ct_CC"; then
|
||||
ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
|
||||
else
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_prog_ac_ct_CC="gcc"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
fi
|
||||
fi
|
||||
ac_ct_CC=$ac_cv_prog_ac_ct_CC
|
||||
if test -n "$ac_ct_CC"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
|
||||
$as_echo "$ac_ct_CC" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
if test "x$ac_ct_CC" = x; then
|
||||
CC=""
|
||||
else
|
||||
case $cross_compiling:$ac_tool_warned in
|
||||
yes:)
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
|
||||
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
|
||||
ac_tool_warned=yes ;;
|
||||
esac
|
||||
CC=$ac_ct_CC
|
||||
fi
|
||||
else
|
||||
CC="$ac_cv_prog_CC"
|
||||
fi
|
||||
|
||||
if test -z "$CC"; then
|
||||
if test -n "$ac_tool_prefix"; then
|
||||
# Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
|
||||
set dummy ${ac_tool_prefix}cc; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_prog_CC+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
if test -n "$CC"; then
|
||||
ac_cv_prog_CC="$CC" # Let the user override the test.
|
||||
else
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_prog_CC="${ac_tool_prefix}cc"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
fi
|
||||
fi
|
||||
CC=$ac_cv_prog_CC
|
||||
if test -n "$CC"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
|
||||
$as_echo "$CC" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
fi
|
||||
if test -z "$CC"; then
|
||||
# Extract the first word of "cc", so it can be a program name with args.
|
||||
set dummy cc; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_prog_CC+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
if test -n "$CC"; then
|
||||
ac_cv_prog_CC="$CC" # Let the user override the test.
|
||||
else
|
||||
ac_prog_rejected=no
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
|
||||
ac_prog_rejected=yes
|
||||
continue
|
||||
fi
|
||||
ac_cv_prog_CC="cc"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
if test $ac_prog_rejected = yes; then
|
||||
# We found a bogon in the path, so make sure we never use it.
|
||||
set dummy $ac_cv_prog_CC
|
||||
shift
|
||||
if test $# != 0; then
|
||||
# We chose a different compiler from the bogus one.
|
||||
# However, it has the same basename, so the bogon will be chosen
|
||||
# first if we set CC to just the basename; use the full file name.
|
||||
shift
|
||||
ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
CC=$ac_cv_prog_CC
|
||||
if test -n "$CC"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
|
||||
$as_echo "$CC" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
if test -z "$CC"; then
|
||||
if test -n "$ac_tool_prefix"; then
|
||||
for ac_prog in cl.exe
|
||||
for ac_prog in gcc clang cl cc
|
||||
do
|
||||
# Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
|
||||
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
|
||||
|
@ -3441,7 +3251,7 @@ fi
|
|||
fi
|
||||
if test -z "$CC"; then
|
||||
ac_ct_CC=$CC
|
||||
for ac_prog in cl.exe
|
||||
for ac_prog in gcc clang cl cc
|
||||
do
|
||||
# Extract the first word of "$ac_prog", so it can be a program name with args.
|
||||
set dummy $ac_prog; ac_word=$2
|
||||
|
@ -3496,8 +3306,6 @@ esac
|
|||
fi
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
|
||||
test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
|
||||
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
|
||||
|
@ -15972,8 +15780,8 @@ $as_echo_n "checking whether to enable FIPS support... " >&6; }
|
|||
if test "${enable_fips+set}" = set; then :
|
||||
enableval=$enable_fips;
|
||||
case "$enableval" in
|
||||
yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
use_fips="yes"
|
||||
|
||||
$as_echo "#define USE_FIPS 1" >>confdefs.h
|
||||
|
@ -16903,7 +16711,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
|||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by stunnel $as_me 5.60, which was
|
||||
This file was extended by stunnel $as_me 5.61, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
|
@ -16969,7 +16777,7 @@ _ACEOF
|
|||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
stunnel config.status 5.60
|
||||
stunnel config.status 5.61
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT([stunnel],[5.60])
|
||||
AC_INIT([stunnel],[5.61])
|
||||
AC_MSG_NOTICE([**************************************** initialization])
|
||||
AC_CONFIG_AUX_DIR(auto)
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
@ -28,7 +28,7 @@ case "$host_os" in
|
|||
;;
|
||||
esac
|
||||
|
||||
AC_PROG_CC
|
||||
AC_PROG_CC([gcc clang cl cc])
|
||||
AM_PROG_CC_C_O
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_MAKE_SET
|
||||
|
@ -299,7 +299,7 @@ AC_ARG_ENABLE(fips,
|
|||
[ --disable-fips disable OpenSSL FIPS support],
|
||||
[
|
||||
case "$enableval" in
|
||||
yes) AC_MSG_RESULT([no])
|
||||
yes) AC_MSG_RESULT([yes])
|
||||
use_fips="yes"
|
||||
AC_DEFINE([USE_FIPS], [1],
|
||||
[Define to 1 to enable OpenSSL FIPS support])
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
.\" ========================================================================
|
||||
.\"
|
||||
.IX Title "stunnel 8"
|
||||
.TH stunnel 8 "2021.05.30" "5.60" "stunnel TLS Proxy"
|
||||
.TH stunnel 8 "2021.12.22" "5.61" "stunnel TLS Proxy"
|
||||
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
||||
.\" way too many mistakes in technical documents.
|
||||
.if n .ad l
|
||||
|
@ -700,6 +700,14 @@ Currently supported protocols:
|
|||
.IX Item "cifs"
|
||||
Proprietary (undocummented) extension of \s-1CIFS\s0 protocol implemented in Samba.
|
||||
Support for this extension was dropped in Samba 3.0.0.
|
||||
.IP "\fIcapwin\fR" 4
|
||||
.IX Item "capwin"
|
||||
http://www.capwin.org/ application support
|
||||
.IP "\fIcapwinctrl\fR" 4
|
||||
.IX Item "capwinctrl"
|
||||
http://www.capwin.org/ application support
|
||||
.Sp
|
||||
This protocol is only supported in client mode.
|
||||
.IP "\fIconnect\fR" 4
|
||||
.IX Item "connect"
|
||||
Based on \s-1RFC 2817\s0 \- \fIUpgrading to \s-1TLS\s0 Within \s-1HTTP/1.1\s0\fR, section 5.2 \- \fIRequesting a Tunnel with \s-1CONNECT\s0\fR
|
||||
|
|
|
@ -824,6 +824,20 @@
|
|||
|
||||
<p>Proprietary (undocummented) extension of CIFS protocol implemented in Samba. Support for this extension was dropped in Samba 3.0.0.</p>
|
||||
|
||||
</dd>
|
||||
<dt id="capwin"><i>capwin</i></dt>
|
||||
<dd>
|
||||
|
||||
<p>http://www.capwin.org/ application support</p>
|
||||
|
||||
</dd>
|
||||
<dt id="capwinctrl"><i>capwinctrl</i></dt>
|
||||
<dd>
|
||||
|
||||
<p>http://www.capwin.org/ application support</p>
|
||||
|
||||
<p>This protocol is only supported in client mode.</p>
|
||||
|
||||
</dd>
|
||||
<dt id="connect"><i>connect</i></dt>
|
||||
<dd>
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
.\" ========================================================================
|
||||
.\"
|
||||
.IX Title "stunnel 8"
|
||||
.TH stunnel 8 "2021.05.30" "5.60" "stunnel TLS Proxy"
|
||||
.TH stunnel 8 "2021.12.22" "5.61" "stunnel TLS Proxy"
|
||||
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
||||
.\" way too many mistakes in technical documents.
|
||||
.if n .ad l
|
||||
|
@ -719,6 +719,14 @@ Aktualnie wspierane protokoły:
|
|||
.IX Item "cifs"
|
||||
Nieudokumentowane rozszerzenie protokołu \s-1CIFS\s0 wspierane przez serwer Samba.
|
||||
Wsparcie dla tego rozszerzenia zostało zarzucone w wersji 3.0.0 serwera Samba.
|
||||
.IP "\fIcapwin\fR" 4
|
||||
.IX Item "capwin"
|
||||
Wsparcie dla aplikacji http://www.capwin.org/
|
||||
.IP "\fIcapwinctrl\fR" 4
|
||||
.IX Item "capwinctrl"
|
||||
Wsparcie dla aplikacji http://www.capwin.org/
|
||||
.Sp
|
||||
Ten protokół jest wspierany wyłącznie w trybie klienckim.
|
||||
.IP "\fIconnect\fR" 4
|
||||
.IX Item "connect"
|
||||
Negocjacja \s-1RFC 2817\s0 \- \fIUpgrading to \s-1TLS\s0 Within \s-1HTTP/1.1\s0\fR, rozdział 5.2 \- \fIRequesting a Tunnel with \s-1CONNECT\s0\fR
|
||||
|
|
|
@ -822,6 +822,20 @@
|
|||
|
||||
<p>Nieudokumentowane rozszerzenie protokołu CIFS wspierane przez serwer Samba. Wsparcie dla tego rozszerzenia zostało zarzucone w wersji 3.0.0 serwera Samba.</p>
|
||||
|
||||
</dd>
|
||||
<dt id="capwin"><i>capwin</i></dt>
|
||||
<dd>
|
||||
|
||||
<p>Wsparcie dla aplikacji http://www.capwin.org/</p>
|
||||
|
||||
</dd>
|
||||
<dt id="capwinctrl"><i>capwinctrl</i></dt>
|
||||
<dd>
|
||||
|
||||
<p>Wsparcie dla aplikacji http://www.capwin.org/</p>
|
||||
|
||||
<p>Ten protokół jest wspierany wyłącznie w trybie klienckim.</p>
|
||||
|
||||
</dd>
|
||||
<dt id="connect"><i>connect</i></dt>
|
||||
<dd>
|
||||
|
|
|
@ -756,6 +756,16 @@ Aktualnie wspierane protokoły:
|
|||
Nieudokumentowane rozszerzenie protokołu CIFS wspierane przez serwer Samba.
|
||||
Wsparcie dla tego rozszerzenia zostało zarzucone w wersji 3.0.0 serwera Samba.
|
||||
|
||||
=item I<capwin>
|
||||
|
||||
Wsparcie dla aplikacji http://www.capwin.org/
|
||||
|
||||
=item I<capwinctrl>
|
||||
|
||||
Wsparcie dla aplikacji http://www.capwin.org/
|
||||
|
||||
Ten protokół jest wspierany wyłącznie w trybie klienckim.
|
||||
|
||||
=item I<connect>
|
||||
|
||||
Negocjacja RFC 2817 - I<Upgrading to TLS Within HTTP/1.1>, rozdział 5.2 - I<Requesting a Tunnel with CONNECT>
|
||||
|
|
|
@ -739,6 +739,16 @@ Currently supported protocols:
|
|||
Proprietary (undocummented) extension of CIFS protocol implemented in Samba.
|
||||
Support for this extension was dropped in Samba 3.0.0.
|
||||
|
||||
=item I<capwin>
|
||||
|
||||
http://www.capwin.org/ application support
|
||||
|
||||
=item I<capwinctrl>
|
||||
|
||||
http://www.capwin.org/ application support
|
||||
|
||||
This protocol is only supported in client mode.
|
||||
|
||||
=item I<connect>
|
||||
|
||||
Based on RFC 2817 - I<Upgrading to TLS Within HTTP/1.1>, section 5.2 - I<Requesting a Tunnel with CONNECT>
|
||||
|
|
|
@ -29,7 +29,7 @@ CLEANFILES = stunnel3
|
|||
# Red Hat "by design" bug #82369
|
||||
stunnel_CPPFLAGS = -I$(SYSROOT)/usr/kerberos/include
|
||||
|
||||
# Additional preprocesor definitions
|
||||
# Additional preprocessor definitions
|
||||
stunnel_CPPFLAGS += -I$(SSLDIR)/include
|
||||
stunnel_CPPFLAGS += -DLIBDIR='"$(pkglibdir)"'
|
||||
stunnel_CPPFLAGS += -DCONFDIR='"$(sysconfdir)/stunnel"'
|
||||
|
|
|
@ -391,7 +391,7 @@ CLEANFILES = stunnel3
|
|||
|
||||
# Red Hat "by design" bug #82369
|
||||
|
||||
# Additional preprocesor definitions
|
||||
# Additional preprocessor definitions
|
||||
stunnel_CPPFLAGS = -I$(SYSROOT)/usr/kerberos/include \
|
||||
-I$(SSLDIR)/include -DLIBDIR='"$(pkglibdir)"' \
|
||||
-DCONFDIR='"$(sysconfdir)/stunnel"'
|
||||
|
|
64
src/client.c
64
src/client.c
|
@ -307,6 +307,10 @@ NOEXPORT void client_run(CLI *c) {
|
|||
"Connection %s: %llu byte(s) sent to TLS, %llu byte(s) sent to socket",
|
||||
rst ? "reset" : "closed",
|
||||
(unsigned long long)c->ssl_bytes, (unsigned long long)c->sock_bytes);
|
||||
#ifdef USE_WIN32
|
||||
if(capwin_hwnd && err==1 && InterlockedExchange(&capwin_connectivity, 0))
|
||||
PostMessage(capwin_hwnd, WM_CAPWIN_NET_DOWN, 0, 0);
|
||||
#endif
|
||||
|
||||
/* cleanup temporary (e.g. IDENT) socket */
|
||||
if(c->fd!=INVALID_SOCKET)
|
||||
|
@ -413,15 +417,19 @@ NOEXPORT void local_start(CLI *c) {
|
|||
addr_len=sizeof(SOCKADDR_UNION);
|
||||
c->local_rfd.is_socket=!getpeername(c->local_rfd.fd, &addr.sa, &addr_len);
|
||||
if(c->local_rfd.is_socket) {
|
||||
/* store the retrieved peer address */
|
||||
memcpy(&c->peer_addr.sa, &addr.sa, (size_t)addr_len);
|
||||
c->peer_addr_len=addr_len;
|
||||
if(socket_options_set(c->opt, c->local_rfd.fd, 1))
|
||||
if(
|
||||
#ifdef HAVE_STRUCT_SOCKADDR_UN
|
||||
addr.sa.sa_family!=AF_UNIX &&
|
||||
#endif
|
||||
socket_options_set(c->opt, c->local_rfd.fd, 1)) {
|
||||
s_log(LOG_WARNING, "Failed to set local socket options");
|
||||
} else {
|
||||
if(get_last_socket_error()!=S_ENOTSOCK) {
|
||||
sockerror("getpeerbyname (local_rfd)");
|
||||
throw_exception(c, 1);
|
||||
}
|
||||
} else if(get_last_socket_error()!=S_ENOTSOCK) {
|
||||
sockerror("getpeerbyname (local_rfd)");
|
||||
throw_exception(c, 1);
|
||||
}
|
||||
|
||||
/* check if local_wfd is a socket and get peer address */
|
||||
|
@ -431,17 +439,21 @@ NOEXPORT void local_start(CLI *c) {
|
|||
addr_len=sizeof(SOCKADDR_UNION);
|
||||
c->local_wfd.is_socket=!getpeername(c->local_wfd.fd, &addr.sa, &addr_len);
|
||||
if(c->local_wfd.is_socket) {
|
||||
if(!c->local_rfd.is_socket) { /* already retrieved */
|
||||
if(!c->local_rfd.is_socket) { /* not retrieved from rfd? */
|
||||
/* store the retrieved peer address */
|
||||
memcpy(&c->peer_addr.sa, &addr.sa, (size_t)addr_len);
|
||||
c->peer_addr_len=addr_len;
|
||||
}
|
||||
if(socket_options_set(c->opt, c->local_wfd.fd, 1))
|
||||
if(
|
||||
#ifdef HAVE_STRUCT_SOCKADDR_UN
|
||||
addr.sa.sa_family!=AF_UNIX &&
|
||||
#endif
|
||||
socket_options_set(c->opt, c->local_wfd.fd, 1)) {
|
||||
s_log(LOG_WARNING, "Failed to set local socket options");
|
||||
} else {
|
||||
if(get_last_socket_error()!=S_ENOTSOCK) {
|
||||
sockerror("getpeerbyname (local_wfd)");
|
||||
throw_exception(c, 1);
|
||||
}
|
||||
} else if(get_last_socket_error()!=S_ENOTSOCK) {
|
||||
sockerror("getpeerbyname (local_wfd)");
|
||||
throw_exception(c, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -565,10 +577,7 @@ NOEXPORT void ssl_start(CLI *c) {
|
|||
CRYPTO_THREAD_write_lock(stunnel_locks[LOCK_SSL]);
|
||||
#endif /* OpenSSL version < 1.1.0 */
|
||||
|
||||
if(c->opt->option.client)
|
||||
i=SSL_connect(c->ssl);
|
||||
else
|
||||
i=SSL_accept(c->ssl);
|
||||
i=c->opt->option.client ? SSL_connect(c->ssl) : SSL_accept(c->ssl);
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
if(unsafe_openssl)
|
||||
|
@ -609,11 +618,10 @@ NOEXPORT void ssl_start(CLI *c) {
|
|||
#endif
|
||||
continue;
|
||||
}
|
||||
sockerror(c->opt->option.client ? "SSL_connect" : "SSL_accept");
|
||||
throw_exception(c, 1);
|
||||
}
|
||||
if(c->opt->option.client)
|
||||
sslerror("SSL_connect");
|
||||
else
|
||||
sslerror("SSL_accept");
|
||||
sslerror(c->opt->option.client ? "SSL_connect" : "SSL_accept");
|
||||
throw_exception(c, 1);
|
||||
}
|
||||
print_cipher(c);
|
||||
|
@ -774,16 +782,22 @@ NOEXPORT void transfer(CLI *c) {
|
|||
s_poll_init(c->fds, 0); /* initialize the structure */
|
||||
/* for plain socket open data strem = open file descriptor */
|
||||
/* make sure to add each open socket to receive exceptions! */
|
||||
if(sock_open_rd) /* only poll if the read file descriptor is open */
|
||||
s_poll_add(c->fds, c->sock_rfd->fd, c->sock_ptr<BUFFSIZE, 0);
|
||||
if(sock_open_wr) /* only poll if the write file descriptor is open */
|
||||
s_poll_add(c->fds, c->sock_wfd->fd, 0, c->ssl_ptr>0);
|
||||
if(c->sock_rfd->fd==c->sock_wfd->fd) {
|
||||
if(sock_open_rd || sock_open_wr)
|
||||
s_poll_add(c->fds, c->sock_rfd->fd,
|
||||
sock_open_rd && c->sock_ptr<BUFFSIZE,
|
||||
sock_open_wr && c->ssl_ptr>0);
|
||||
} else {
|
||||
if(sock_open_rd) /* only poll if the read file descriptor is open */
|
||||
s_poll_add(c->fds, c->sock_rfd->fd, c->sock_ptr<BUFFSIZE, 0);
|
||||
if(sock_open_wr) /* only poll if the write file descriptor is open */
|
||||
s_poll_add(c->fds, c->sock_wfd->fd, 0, c->ssl_ptr>0);
|
||||
}
|
||||
/* poll TLS file descriptors unless TLS shutdown was completed */
|
||||
if(SSL_get_shutdown(c->ssl)!=
|
||||
(SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN)) {
|
||||
s_poll_add(c->fds, c->ssl_rfd->fd,
|
||||
read_wants_read || write_wants_read || shutdown_wants_read, 0);
|
||||
s_poll_add(c->fds, c->ssl_wfd->fd, 0,
|
||||
read_wants_read || write_wants_read || shutdown_wants_read,
|
||||
read_wants_write || write_wants_write || shutdown_wants_write);
|
||||
}
|
||||
|
||||
|
|
|
@ -104,6 +104,7 @@ typedef __int64 ssize_t;
|
|||
typedef int ssize_t;
|
||||
#endif /* _WIN64 */
|
||||
#endif /* !__MINGW32__ */
|
||||
#define PRIX64 "I64X"
|
||||
#define USE_IPv6
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#define _CRT_NONSTDC_NO_DEPRECATE
|
||||
|
@ -242,6 +243,7 @@ typedef int ssize_t;
|
|||
#include <ws2tcpip.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
|
||||
#include <process.h> /* _beginthread */
|
||||
#include <shlobj.h> /* SHGetFolderPath */
|
||||
|
@ -411,6 +413,9 @@ extern char *sys_errlist[];
|
|||
|
||||
/**************************************** OpenSSL headers */
|
||||
|
||||
/* TODO: remove this after migrating to the OpenSSL 3.0 API */
|
||||
#define OPENSSL_SUPPRESS_DEPRECATED
|
||||
|
||||
#define OPENSSL_THREAD_DEFINES
|
||||
#include <openssl/opensslconf.h>
|
||||
/* opensslv.h requires prior opensslconf.h to include -fips in version string */
|
||||
|
@ -530,6 +535,8 @@ STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void);
|
|||
#define offsetof(T, F) ((unsigned)((char *)&((T *)0L)->F - (char *)0L))
|
||||
#endif
|
||||
|
||||
#define is_prefix(a, b) (strncasecmp((a), (b), strlen(b))==0)
|
||||
|
||||
#endif /* defined COMMON_H */
|
||||
|
||||
/* end of common.h */
|
||||
|
|
26
src/ctx.c
26
src/ctx.c
|
@ -139,10 +139,16 @@ typedef long SSL_OPTIONS_TYPE;
|
|||
int context_init(SERVICE_OPTIONS *section) { /* init TLS context */
|
||||
/* create a new TLS context */
|
||||
#if OPENSSL_VERSION_NUMBER>=0x10100000L
|
||||
if(section->option.client)
|
||||
section->ctx=SSL_CTX_new(TLS_client_method());
|
||||
else /* server mode */
|
||||
section->ctx=SSL_CTX_new(TLS_server_method());
|
||||
#if OPENSSL_VERSION_NUMBER>=0x30000000L
|
||||
section->ctx=SSL_CTX_new_ex(NULL,
|
||||
EVP_default_properties_is_fips_enabled(NULL) ?
|
||||
"fips=yes" : "provider!=fips",
|
||||
section->option.client ?
|
||||
TLS_client_method() : TLS_server_method());
|
||||
#else /* OPENSSL_VERSION_NUMBER<0x30000000L */
|
||||
section->ctx=SSL_CTX_new(section->option.client ?
|
||||
TLS_client_method() : TLS_server_method());
|
||||
#endif /* OPENSSL_VERSION_NUMBER>=0x30000000L */
|
||||
if(!SSL_CTX_set_min_proto_version(section->ctx,
|
||||
section->min_proto_version)) {
|
||||
s_log(LOG_ERR, "Failed to set the minimum protocol version 0x%X",
|
||||
|
@ -233,11 +239,12 @@ int context_init(SERVICE_OPTIONS *section) { /* init TLS context */
|
|||
|
||||
/* TLS options: log the configured values */
|
||||
#if OPENSSL_VERSION_NUMBER>=0x009080dfL
|
||||
s_log(LOG_DEBUG, "TLS options: 0x%08lX (+0x%08lX, -0x%08lX)",
|
||||
s_log(LOG_DEBUG,
|
||||
"TLS options: 0x%" PRIX64 " (+0x%" PRIX64 ", -0x%" PRIX64 ")",
|
||||
SSL_CTX_get_options(section->ctx),
|
||||
section->ssl_options_set, section->ssl_options_clear);
|
||||
#else /* OpenSSL older than 0.9.8m */
|
||||
s_log(LOG_DEBUG, "TLS options: 0x%08lX (+0x%08lX)",
|
||||
s_log(LOG_DEBUG, "TLS options: 0x%" PRIX64 " (+0x%" PRIX64 ")",
|
||||
SSL_CTX_get_options(section->ctx), section->ssl_options_set);
|
||||
#endif /* OpenSSL 0.9.8m or later */
|
||||
|
||||
|
@ -320,7 +327,8 @@ int context_init(SERVICE_OPTIONS *section) { /* init TLS context */
|
|||
dh_init(section); /* ignore the result (errors are not critical) */
|
||||
#endif /* OPENSSL_NO_DH */
|
||||
#ifndef OPENSSL_NO_ECDH
|
||||
ecdh_init(section); /* ignore the result (errors are not critical) */
|
||||
if(ecdh_init(section))
|
||||
return 1; /* FAILED */
|
||||
#endif /* OPENSSL_NO_ECDH */
|
||||
|
||||
return 0; /* OK */
|
||||
|
@ -519,9 +527,7 @@ NOEXPORT int SSL_CTX_set1_groups_list(SSL_CTX *ctx, char *list) {
|
|||
NOEXPORT int ecdh_init(SERVICE_OPTIONS *section) {
|
||||
s_log(LOG_DEBUG, "ECDH initialization");
|
||||
if(!SSL_CTX_set1_groups_list(section->ctx, section->curves)) {
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
|
||||
sslerror("SSL_CTX_set1_groups_list");
|
||||
#endif /* OpenSSL version >= 1.1.1 */
|
||||
s_log(LOG_ERR, "Invalid groups list in 'curves'");
|
||||
return 1; /* FAILED */
|
||||
}
|
||||
s_log(LOG_DEBUG, "ECDH initialized with curves %s", section->curves);
|
||||
|
|
|
@ -5,32 +5,32 @@
|
|||
DH *get_dh2048(void)
|
||||
{
|
||||
static unsigned char dhp_2048[] = {
|
||||
0x91, 0xC2, 0x73, 0x35, 0xC8, 0x30, 0xC4, 0xD8, 0xF4, 0xB5,
|
||||
0x3E, 0xCD, 0xC7, 0x3C, 0xD3, 0x5A, 0x4D, 0xBA, 0x5C, 0x38,
|
||||
0xB2, 0x7B, 0x5B, 0xCA, 0xFB, 0xF8, 0x9B, 0xC9, 0x98, 0x00,
|
||||
0x79, 0xDC, 0xA6, 0xFF, 0xE6, 0xB3, 0x61, 0x0E, 0xFB, 0x1B,
|
||||
0xC0, 0x95, 0xDE, 0xA4, 0xB6, 0x1B, 0xA6, 0x9B, 0x76, 0x8E,
|
||||
0x7B, 0x84, 0x03, 0xB7, 0x2F, 0x6A, 0x5D, 0x35, 0xE3, 0x04,
|
||||
0x1A, 0x14, 0x47, 0x27, 0xDC, 0x57, 0x74, 0x81, 0x1B, 0x91,
|
||||
0x42, 0x87, 0x34, 0xCE, 0x41, 0x96, 0xC8, 0x38, 0xB4, 0xBB,
|
||||
0x95, 0x41, 0x7A, 0x5F, 0x18, 0x1F, 0xA5, 0x2C, 0x3F, 0xAD,
|
||||
0xEA, 0xC7, 0xD7, 0x0C, 0x25, 0x13, 0xBA, 0x0A, 0x84, 0x57,
|
||||
0x7E, 0xD1, 0xE5, 0x9C, 0x0F, 0x62, 0xAA, 0x47, 0x94, 0x75,
|
||||
0xFA, 0x36, 0x0A, 0xF6, 0xEE, 0xFD, 0x95, 0x40, 0x36, 0x79,
|
||||
0xD0, 0x35, 0x7A, 0x6D, 0x46, 0xDA, 0xBD, 0xFA, 0xCF, 0xE2,
|
||||
0x01, 0xEC, 0x49, 0x43, 0x2A, 0x46, 0xC6, 0xA7, 0xBC, 0xC3,
|
||||
0x1A, 0xA7, 0x6F, 0x54, 0xA6, 0x10, 0x54, 0xDA, 0x5F, 0x21,
|
||||
0x95, 0x3F, 0xF4, 0x77, 0x99, 0x90, 0xE9, 0xD0, 0x0A, 0xB4,
|
||||
0x09, 0x10, 0xAC, 0xE7, 0x1D, 0x38, 0x21, 0x14, 0xF5, 0xC9,
|
||||
0xC9, 0xFA, 0xCA, 0xA7, 0x61, 0x1D, 0x13, 0xB5, 0x84, 0xA2,
|
||||
0x10, 0x6B, 0xF8, 0x85, 0xB1, 0x1C, 0x1C, 0x1A, 0x67, 0x98,
|
||||
0xDC, 0x67, 0xA4, 0xE8, 0x52, 0xC1, 0x05, 0xBA, 0x08, 0x9D,
|
||||
0xDD, 0xAC, 0x56, 0x72, 0x7B, 0x33, 0x25, 0x37, 0xCA, 0x85,
|
||||
0xAA, 0xB8, 0xB1, 0x60, 0x6D, 0x07, 0x1C, 0xC6, 0xD8, 0x73,
|
||||
0x76, 0xB2, 0xB3, 0xFC, 0x2A, 0x0F, 0xF8, 0x5F, 0x7D, 0x2B,
|
||||
0x56, 0x30, 0xB8, 0x00, 0x3B, 0x21, 0x6B, 0xAB, 0x30, 0xEA,
|
||||
0x7C, 0x62, 0xA4, 0xD2, 0x3B, 0xE2, 0x2F, 0x98, 0xA0, 0xF4,
|
||||
0x59, 0x31, 0xB5, 0x83, 0x6A, 0x93
|
||||
0xEA, 0xAB, 0xD1, 0x12, 0x96, 0x57, 0xE6, 0x1C, 0xCB, 0x63,
|
||||
0xF1, 0xE1, 0x48, 0x10, 0xB7, 0x95, 0x7E, 0xC8, 0x45, 0x7A,
|
||||
0xCC, 0x4D, 0xDC, 0xA0, 0xEC, 0x46, 0xB3, 0xFF, 0xAE, 0x60,
|
||||
0x0C, 0xE9, 0xA8, 0x43, 0xA0, 0x1C, 0x9F, 0x96, 0x09, 0x14,
|
||||
0x4C, 0x63, 0x65, 0x7D, 0x9A, 0x0D, 0x69, 0x42, 0x62, 0xFA,
|
||||
0x4C, 0x3C, 0x0C, 0xD2, 0xC2, 0xF6, 0xA3, 0x57, 0x99, 0x8C,
|
||||
0x4A, 0x24, 0x57, 0x97, 0x21, 0x05, 0x6A, 0x7C, 0xF2, 0xE7,
|
||||
0x69, 0xF2, 0x0A, 0x5F, 0xDF, 0xBD, 0x83, 0x43, 0x1F, 0x6C,
|
||||
0xDA, 0x21, 0xF5, 0x02, 0x9D, 0x9F, 0x03, 0xA4, 0x6C, 0x6F,
|
||||
0x8E, 0x5F, 0xE7, 0xD6, 0xBC, 0x93, 0x0E, 0x5A, 0x55, 0x88,
|
||||
0xED, 0x96, 0x5D, 0x3B, 0x39, 0x80, 0xB0, 0xDA, 0xDF, 0x24,
|
||||
0xFC, 0xAC, 0xB9, 0xE1, 0xEE, 0xB6, 0xA6, 0x28, 0x84, 0x79,
|
||||
0x34, 0xDC, 0xBC, 0x8F, 0x39, 0x52, 0x20, 0x6F, 0xAC, 0x57,
|
||||
0x76, 0xA3, 0x3A, 0x05, 0x28, 0xAD, 0x7F, 0x1C, 0xC1, 0x93,
|
||||
0x54, 0x75, 0x58, 0x4F, 0x59, 0x79, 0x0D, 0x6F, 0xFE, 0x91,
|
||||
0x38, 0x7E, 0x6D, 0xEF, 0xB4, 0xCC, 0x10, 0x79, 0x73, 0x04,
|
||||
0x07, 0x1E, 0xB2, 0x4E, 0x87, 0xA6, 0xA1, 0x7B, 0xCA, 0xFB,
|
||||
0x5B, 0xF8, 0xFD, 0xC6, 0xDF, 0x32, 0x1F, 0x35, 0x44, 0xB8,
|
||||
0x70, 0x98, 0xE0, 0x5B, 0xFD, 0x80, 0x76, 0x29, 0x78, 0xFB,
|
||||
0xEE, 0xB4, 0xAC, 0xFB, 0x6C, 0x44, 0xCF, 0x94, 0x58, 0x13,
|
||||
0xA6, 0xD3, 0xBD, 0x26, 0x91, 0xA6, 0x4B, 0xFC, 0x5A, 0x04,
|
||||
0x6C, 0x1C, 0xB8, 0x2E, 0x17, 0x22, 0x9D, 0xD4, 0xA3, 0x79,
|
||||
0x9A, 0xCB, 0x93, 0x7F, 0x0F, 0x55, 0x0A, 0x4D, 0xFC, 0x48,
|
||||
0x23, 0xA2, 0xCE, 0x9C, 0xE9, 0x1C, 0x62, 0x36, 0x89, 0x7E,
|
||||
0xB4, 0xAC, 0xEB, 0xBA, 0xF1, 0xB5, 0x04, 0x80, 0x9B, 0xEE,
|
||||
0xE3, 0x47, 0x29, 0x49, 0xB9, 0x1B
|
||||
};
|
||||
static unsigned char dhg_2048[] = {
|
||||
0x02
|
||||
|
@ -52,4 +52,4 @@ DH *get_dh2048(void)
|
|||
return dh;
|
||||
}
|
||||
#endif /* OPENSSL_NO_DH */
|
||||
/* built for stunnel 5.60 */
|
||||
/* built for stunnel 5.61 */
|
||||
|
|
32
src/mingw.mk
32
src/mingw.mk
|
@ -14,19 +14,37 @@
|
|||
bindir = ../bin/$(win32_arch)
|
||||
objdir = ../obj/$(win32_arch)
|
||||
|
||||
win32_ssl_dir = /opt/openssl-$(win32_mingw)
|
||||
ifeq ($(win32_ssl_dir),)
|
||||
win32_ssl_dir := /opt/openssl-$(win32_mingw)
|
||||
endif
|
||||
win32_cppflags = -I$(win32_ssl_dir)/include
|
||||
win32_cflags = -g -mthreads -O2
|
||||
#win32_cflags += -fstack-protector
|
||||
win32_cflags += -Wall -Wextra -Wpedantic -Wformat=2 -Wconversion -Wno-long-long
|
||||
win32_cflags += -fstack-protector
|
||||
win32_cflags += -Wall -Wextra -Wpedantic -Wconversion -Wno-long-long -ansi
|
||||
win32_cflags += -D_FORTIFY_SOURCE=2 -DUNICODE -D_UNICODE
|
||||
win32_ldflags = -g -mthreads
|
||||
#win32_ldflags += -fstack-protector
|
||||
# -fstack-protector is broken (at least in x86_64-w64-mingw32-gcc 8.2.0)
|
||||
win32_ldflags = -g -mthreads -pipe
|
||||
win32_ldflags += -fstack-protector
|
||||
win32_ldflags += -Wl,--dynamicbase,--nxcompat,--no-seh,--tsaware,--no-insert-timestamp
|
||||
ifeq ($(win32_arch),win64)
|
||||
win32_ldflags += -Wl,--high-entropy-va
|
||||
else
|
||||
win32_ldflags += -Wl,--large-address-aware
|
||||
endif
|
||||
|
||||
# -fstack-protector was broken in x86_64-w64-mingw32-gcc 8.2.0
|
||||
|
||||
# compiling with -D_FORTIFY_SOURCE=2 may require linking with -lssp
|
||||
win32_common_libs = -lws2_32 -lkernel32 -lssp
|
||||
win32_ssl_libs = -L$(win32_ssl_dir)/lib -lcrypto -lssl
|
||||
ifneq (,$(wildcard $(win32_ssl_dir)/lib64/libcrypto.dll.a))
|
||||
# use OpenSSL 3.x.x mingw-generated library stubs if available
|
||||
win32_ssl_libs = -L$(win32_ssl_dir)/lib64 -lcrypto -lssl
|
||||
else ifneq (,$(wildcard $(win32_ssl_dir)/lib/libcrypto.dll.a))
|
||||
# use OpenSSL 1.x.x mingw-generated library stubs if available
|
||||
win32_ssl_libs = -L$(win32_ssl_dir)/lib -lcrypto -lssl
|
||||
else
|
||||
# directly import libeay32.dll and ssleay32.dll otherwise
|
||||
win32_ssl_libs = -L$(win32_ssl_dir)/bin -llibeay32 -lssleay32
|
||||
endif
|
||||
win32_gui_libs = $(win32_common_libs) -lgdi32 -lpsapi $(win32_ssl_libs)
|
||||
win32_cli_libs = $(win32_common_libs) $(win32_ssl_libs)
|
||||
|
||||
|
|
|
@ -71,7 +71,12 @@ void s_poll_init(s_poll_set *fds, int main_thread) {
|
|||
fds->allocated=4; /* prealloc 4 file descriptors */
|
||||
s_poll_realloc(fds);
|
||||
fds->main_thread=main_thread;
|
||||
#ifdef USE_TERMINATE_PIPE
|
||||
s_poll_add(fds, main_thread ? signal_pipe[0] : terminate_pipe[0], 1, 0);
|
||||
#else
|
||||
if(main_thread)
|
||||
s_poll_add(fds, signal_pipe[0], 1, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void s_poll_add(s_poll_set *fds, SOCKET fd, int rd, int wr) {
|
||||
|
@ -375,13 +380,11 @@ void s_poll_init(s_poll_set *fds, int main_thread) {
|
|||
FD_ZERO(fds->ixfds);
|
||||
fds->max=0; /* no file descriptors */
|
||||
fds->main_thread=main_thread;
|
||||
#ifdef USE_WIN32
|
||||
/* there seems to be a deadlock in the Windows select() function when
|
||||
* waiting for the same terminate_pipe socket in multiple threads */
|
||||
#ifdef USE_TERMINATE_PIPE
|
||||
s_poll_add(fds, main_thread ? signal_pipe[0] : terminate_pipe[0], 1, 0);
|
||||
#else
|
||||
if(main_thread)
|
||||
s_poll_add(fds, signal_pipe[0], 1, 0);
|
||||
#else
|
||||
s_poll_add(fds, main_thread ? signal_pipe[0] : terminate_pipe[0], 1, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -512,6 +515,7 @@ void s_poll_sleep(int sec, int msec) {
|
|||
|
||||
#ifndef USE_UCONTEXT
|
||||
NOEXPORT void check_terminate(s_poll_set *fds) {
|
||||
#ifdef USE_TERMINATE_PIPE
|
||||
if(!fds->main_thread && s_poll_canread(fds, terminate_pipe[0])) {
|
||||
#ifdef USE_PTHREAD
|
||||
pthread_exit(NULL);
|
||||
|
@ -531,6 +535,9 @@ NOEXPORT void check_terminate(s_poll_set *fds) {
|
|||
exit(0);
|
||||
#endif /* USE_FORK */
|
||||
}
|
||||
#else /* USE_TERMINATE_PIPE */
|
||||
(void)fds; /* squash the unused parameter warning */
|
||||
#endif /* USE_TERMINATE_PIPE */
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -681,39 +688,53 @@ void s_write(CLI *c, SOCKET fd, const void *buf, size_t len) {
|
|||
}
|
||||
}
|
||||
|
||||
void s_read(CLI *c, SOCKET fd, void *ptr, size_t len) {
|
||||
size_t s_read_eof(CLI *c, SOCKET fd, void *ptr, size_t len) {
|
||||
/* simulate a blocking read */
|
||||
ssize_t num;
|
||||
/* return a value < len on EOF */
|
||||
size_t total=0;
|
||||
|
||||
while(len>0) {
|
||||
ssize_t num;
|
||||
|
||||
s_poll_init(c->fds, 0);
|
||||
s_poll_add(c->fds, fd, 1, 0); /* read */
|
||||
switch(s_poll_wait(c->fds, c->opt->timeout_busy, 0)) {
|
||||
case -1:
|
||||
sockerror("s_read: s_poll_wait");
|
||||
sockerror("s_read_eof: s_poll_wait");
|
||||
throw_exception(c, 1); /* error */
|
||||
case 0:
|
||||
s_log(LOG_INFO, "s_read: s_poll_wait:"
|
||||
s_log(LOG_INFO, "s_read_eof: s_poll_wait:"
|
||||
" TIMEOUTbusy exceeded: sending reset");
|
||||
throw_exception(c, 1); /* timeout */
|
||||
case 1:
|
||||
break; /* OK */
|
||||
default:
|
||||
s_log(LOG_ERR, "s_read: s_poll_wait: unknown result");
|
||||
s_log(LOG_ERR, "s_read_eof: s_poll_wait: unknown result");
|
||||
throw_exception(c, 1); /* error */
|
||||
}
|
||||
num=readsocket(fd, ptr, len);
|
||||
switch(num) {
|
||||
case -1: /* error */
|
||||
sockerror("readsocket (s_read)");
|
||||
throw_exception(c, 1);
|
||||
case 0: /* EOF */
|
||||
s_log(LOG_ERR, "Unexpected socket close (s_read)");
|
||||
|
||||
num=readsocket(fd, (char *)ptr+total, len);
|
||||
if(num<0) { /* error */
|
||||
sockerror("readsocket (s_read_eof)");
|
||||
throw_exception(c, 1);
|
||||
}
|
||||
ptr=(uint8_t *)ptr+num;
|
||||
if(num==0) { /* EOF */
|
||||
s_log(LOG_DEBUG, "Socket closed (s_read_eof)");
|
||||
break;
|
||||
}
|
||||
total+=(size_t)num;
|
||||
len-=(size_t)num;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
void s_read(CLI *c, SOCKET fd, void *ptr, size_t len) {
|
||||
/* simulate a blocking read */
|
||||
/* throw an exception on EOF */
|
||||
if(s_read_eof(c, fd, ptr, len)!=len) {
|
||||
s_log(LOG_ERR, "Unexpected socket close (s_read)");
|
||||
throw_exception(c, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void fd_putline(CLI *c, SOCKET fd, const char *line) {
|
||||
|
@ -804,11 +825,14 @@ void s_ssl_write(CLI *c, const void *buf, int len) {
|
|||
}
|
||||
}
|
||||
|
||||
void s_ssl_read(CLI *c, void *ptr, int len) {
|
||||
size_t s_ssl_read_eof(CLI *c, void *ptr, int len) {
|
||||
/* simulate a blocking SSL_read */
|
||||
int num;
|
||||
/* return a value < len on EOF */
|
||||
size_t total=0;
|
||||
|
||||
while(len>0) {
|
||||
int num;
|
||||
|
||||
if(!SSL_pending(c->ssl)) {
|
||||
s_poll_init(c->fds, 0);
|
||||
s_poll_add(c->fds, c->ssl_rfd->fd, 1, 0); /* read */
|
||||
|
@ -827,18 +851,29 @@ void s_ssl_read(CLI *c, void *ptr, int len) {
|
|||
throw_exception(c, 1); /* error */
|
||||
}
|
||||
}
|
||||
num=SSL_read(c->ssl, ptr, len);
|
||||
switch(num) {
|
||||
case -1: /* error */
|
||||
sockerror("SSL_read (s_ssl_read)");
|
||||
throw_exception(c, 1);
|
||||
case 0: /* EOF */
|
||||
s_log(LOG_ERR, "Unexpected socket close (s_ssl_read)");
|
||||
|
||||
num=SSL_read(c->ssl, (char *)ptr+total, len);
|
||||
if(num<0) { /* error */
|
||||
sockerror("SSL_read (s_ssl_read_eof)");
|
||||
throw_exception(c, 1);
|
||||
}
|
||||
ptr=(uint8_t *)ptr+num;
|
||||
if(num==0) { /* EOF */
|
||||
s_log(LOG_DEBUG, "Socket close (s_ssl_read_eof)");
|
||||
break;
|
||||
}
|
||||
total+=(size_t)num;
|
||||
len-=num;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
void s_ssl_read(CLI *c, void *ptr, int len) {
|
||||
/* simulate a blocking SSL_read */
|
||||
/* throw an exception on EOF */
|
||||
if(s_ssl_read_eof(c, ptr, len)!=(size_t)len) {
|
||||
s_log(LOG_ERR, "Unexpected socket close (s_ssl_read)");
|
||||
throw_exception(c, 1);
|
||||
}
|
||||
}
|
||||
|
||||
char *ssl_getstring(CLI *c) { /* get null-terminated string */
|
||||
|
|
272
src/options.c
272
src/options.c
|
@ -108,92 +108,83 @@ typedef struct {
|
|||
} SSL_OPTION;
|
||||
|
||||
static const SSL_OPTION ssl_opts[] = {
|
||||
{"MICROSOFT_SESS_ID_BUG", SSL_OP_MICROSOFT_SESS_ID_BUG},
|
||||
{"NETSCAPE_CHALLENGE_BUG", SSL_OP_NETSCAPE_CHALLENGE_BUG},
|
||||
#ifdef SSL_OP_LEGACY_SERVER_CONNECT
|
||||
{"LEGACY_SERVER_CONNECT", SSL_OP_LEGACY_SERVER_CONNECT},
|
||||
#endif
|
||||
{"NETSCAPE_REUSE_CIPHER_CHANGE_BUG",
|
||||
SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG},
|
||||
#ifdef SSL_OP_TLSEXT_PADDING
|
||||
{"TLSEXT_PADDING", SSL_OP_TLSEXT_PADDING},
|
||||
#endif
|
||||
{"MICROSOFT_BIG_SSLV3_BUFFER", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER},
|
||||
#ifdef SSL_OP_SAFARI_ECDHE_ECDSA_BUG
|
||||
{"SAFARI_ECDHE_ECDSA_BUG", SSL_OP_SAFARI_ECDHE_ECDSA_BUG},
|
||||
#endif
|
||||
{"SSLEAY_080_CLIENT_DH_BUG", SSL_OP_SSLEAY_080_CLIENT_DH_BUG},
|
||||
{"TLS_D5_BUG", SSL_OP_TLS_D5_BUG},
|
||||
{"TLS_BLOCK_PADDING_BUG", SSL_OP_TLS_BLOCK_PADDING_BUG},
|
||||
#ifdef SSL_OP_MSIE_SSLV2_RSA_PADDING
|
||||
{"MSIE_SSLV2_RSA_PADDING", SSL_OP_MSIE_SSLV2_RSA_PADDING},
|
||||
#endif
|
||||
{"SSLREF2_REUSE_CERT_TYPE_BUG", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG},
|
||||
#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
|
||||
{"DONT_INSERT_EMPTY_FRAGMENTS", SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS},
|
||||
#endif
|
||||
#ifdef SSL_OP_ALL
|
||||
{"ALL", SSL_OP_ALL},
|
||||
#ifdef SSL_OP_NO_QUERY_MTU
|
||||
{"NO_QUERY_MTU", SSL_OP_NO_QUERY_MTU},
|
||||
#endif
|
||||
#ifdef SSL_OP_COOKIE_EXCHANGE
|
||||
{"COOKIE_EXCHANGE", SSL_OP_COOKIE_EXCHANGE},
|
||||
#ifdef SSL_OP_ALLOW_CLIENT_RENEGOTIATION
|
||||
{"ALLOW_CLIENT_RENEGOTIATION", SSL_OP_ALLOW_CLIENT_RENEGOTIATION},
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_TICKET
|
||||
{"NO_TICKET", SSL_OP_NO_TICKET},
|
||||
#ifdef SSL_OP_ALLOW_NO_DHE_KEX
|
||||
{"ALLOW_NO_DHE_KEX", SSL_OP_ALLOW_NO_DHE_KEX},
|
||||
#endif
|
||||
#ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
|
||||
{"ALLOW_UNSAFE_LEGACY_RENEGOTIATION", SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION},
|
||||
#endif
|
||||
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
|
||||
{"CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE},
|
||||
#endif
|
||||
#ifdef SSL_OP_CISCO_ANYCONNECT
|
||||
{"CISCO_ANYCONNECT", SSL_OP_CISCO_ANYCONNECT},
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
|
||||
{"NO_SESSION_RESUMPTION_ON_RENEGOTIATION",
|
||||
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION},
|
||||
#ifdef SSL_OP_CLEANSE_PLAINTEXT
|
||||
{"CLEANSE_PLAINTEXT", SSL_OP_CLEANSE_PLAINTEXT},
|
||||
#endif
|
||||
#ifdef SSL_OP_COOKIE_EXCHANGE
|
||||
{"COOKIE_EXCHANGE", SSL_OP_COOKIE_EXCHANGE},
|
||||
#endif
|
||||
#ifdef SSL_OP_CRYPTOPRO_TLSEXT_BUG
|
||||
{"CRYPTOPRO_TLSEXT_BUG", SSL_OP_CRYPTOPRO_TLSEXT_BUG},
|
||||
#endif
|
||||
#ifdef SSL_OP_DISABLE_TLSEXT_CA_NAMES
|
||||
{"DISABLE_TLSEXT_CA_NAMES", SSL_OP_DISABLE_TLSEXT_CA_NAMES},
|
||||
#endif
|
||||
#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
|
||||
{"DONT_INSERT_EMPTY_FRAGMENTS", SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS},
|
||||
#endif
|
||||
#ifdef SSL_OP_ENABLE_KTLS
|
||||
{"ENABLE_KTLS", SSL_OP_ENABLE_KTLS},
|
||||
#endif
|
||||
#ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT
|
||||
{"ENABLE_MIDDLEBOX_COMPAT", SSL_OP_ENABLE_MIDDLEBOX_COMPAT},
|
||||
#endif
|
||||
#ifdef SSL_OP_EPHEMERAL_RSA
|
||||
{"EPHEMERAL_RSA", SSL_OP_EPHEMERAL_RSA},
|
||||
#endif
|
||||
#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF
|
||||
{"IGNORE_UNEXPECTED_EOF", SSL_OP_IGNORE_UNEXPECTED_EOF},
|
||||
#endif
|
||||
#ifdef SSL_OP_LEGACY_SERVER_CONNECT
|
||||
{"LEGACY_SERVER_CONNECT", SSL_OP_LEGACY_SERVER_CONNECT},
|
||||
#endif
|
||||
#ifdef SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
|
||||
{"MICROSOFT_BIG_SSLV3_BUFFER", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER},
|
||||
#endif
|
||||
#ifdef SSL_OP_MICROSOFT_SESS_ID_BUG
|
||||
{"MICROSOFT_SESS_ID_BUG", SSL_OP_MICROSOFT_SESS_ID_BUG},
|
||||
#endif
|
||||
#ifdef SSL_OP_MSIE_SSLV2_RSA_PADDING
|
||||
{"MSIE_SSLV2_RSA_PADDING", SSL_OP_MSIE_SSLV2_RSA_PADDING},
|
||||
#endif
|
||||
#ifdef SSL_OP_NETSCAPE_CA_DN_BUG
|
||||
{"NETSCAPE_CA_DN_BUG", SSL_OP_NETSCAPE_CA_DN_BUG},
|
||||
#endif
|
||||
#ifdef SSL_OP_NETSCAPE_CHALLENGE_BUG
|
||||
{"NETSCAPE_CHALLENGE_BUG", SSL_OP_NETSCAPE_CHALLENGE_BUG},
|
||||
#endif
|
||||
#ifdef SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
|
||||
{"NETSCAPE_DEMO_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG},
|
||||
#endif
|
||||
#ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
|
||||
{"NETSCAPE_REUSE_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG},
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_ANTI_REPLAY
|
||||
{"NO_ANTI_REPLAY", SSL_OP_NO_ANTI_REPLAY},
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_COMPRESSION
|
||||
{"NO_COMPRESSION", SSL_OP_NO_COMPRESSION},
|
||||
#endif
|
||||
#ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
|
||||
{"ALLOW_UNSAFE_LEGACY_RENEGOTIATION",
|
||||
SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION},
|
||||
#endif
|
||||
#ifdef SSL_OP_SINGLE_ECDH_USE
|
||||
{"SINGLE_ECDH_USE", SSL_OP_SINGLE_ECDH_USE},
|
||||
#endif
|
||||
{"SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE},
|
||||
{"EPHEMERAL_RSA", SSL_OP_EPHEMERAL_RSA},
|
||||
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
|
||||
{"CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE},
|
||||
#endif
|
||||
{"TLS_ROLLBACK_BUG", SSL_OP_TLS_ROLLBACK_BUG},
|
||||
{"NO_SSLv2", SSL_OP_NO_SSLv2},
|
||||
{"NO_SSLv3", SSL_OP_NO_SSLv3},
|
||||
{"NO_TLSv1", SSL_OP_NO_TLSv1},
|
||||
#ifdef SSL_OP_NO_TLSv1_1
|
||||
{"NO_TLSv1.1", SSL_OP_NO_TLSv1_1},
|
||||
#else /* ignore if unsupported by OpenSSL */
|
||||
{"NO_TLSv1.1", 0},
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_TLSv1_2
|
||||
{"NO_TLSv1.2", SSL_OP_NO_TLSv1_2},
|
||||
#else /* ignore if unsupported by OpenSSL */
|
||||
{"NO_TLSv1.2", 0},
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_TLSv1_3
|
||||
{"NO_TLSv1.3", SSL_OP_NO_TLSv1_3},
|
||||
{"NO_TLSv1_3", SSL_OP_NO_TLSv1_3}, /* keep compatibility with our typo */
|
||||
#else /* ignore if unsupported by OpenSSL */
|
||||
{"NO_TLSv1.3", 0},
|
||||
{"NO_TLSv1_3", 0}, /* keep compatibility with our typo */
|
||||
#endif
|
||||
{"PKCS1_CHECK_1", SSL_OP_PKCS1_CHECK_1},
|
||||
{"PKCS1_CHECK_2", SSL_OP_PKCS1_CHECK_2},
|
||||
{"NETSCAPE_CA_DN_BUG", SSL_OP_NETSCAPE_CA_DN_BUG},
|
||||
#ifdef SSL_OP_NON_EXPORT_FIRST
|
||||
{"NON_EXPORT_FIRST", SSL_OP_NON_EXPORT_FIRST},
|
||||
#endif
|
||||
{"NETSCAPE_DEMO_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG},
|
||||
#ifdef SSL_OP_CRYPTOPRO_TLSEXT_BUG
|
||||
{"CRYPTOPRO_TLSEXT_BUG", SSL_OP_CRYPTOPRO_TLSEXT_BUG},
|
||||
#ifdef SSL_OP_NO_DTLS_MASK
|
||||
{"NO_DTLS_MASK", SSL_OP_NO_DTLS_MASK},
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_DTLSv1
|
||||
{"NO_DTLSv1", SSL_OP_NO_DTLSv1},
|
||||
|
@ -201,50 +192,80 @@ static const SSL_OPTION ssl_opts[] = {
|
|||
#ifdef SSL_OP_NO_DTLSv1_2
|
||||
{"NO_DTLSv1_2", SSL_OP_NO_DTLSv1_2},
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_SSL_MASK
|
||||
{"NO_SSL_MASK", SSL_OP_NO_SSL_MASK},
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_DTLS_MASK
|
||||
{"NO_DTLS_MASK", SSL_OP_NO_DTLS_MASK},
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_ENCRYPT_THEN_MAC
|
||||
{"NO_ENCRYPT_THEN_MAC", SSL_OP_NO_ENCRYPT_THEN_MAC},
|
||||
#endif
|
||||
#ifdef SSL_OP_ALLOW_NO_DHE_KEX
|
||||
{"ALLOW_NO_DHE_KEX", SSL_OP_ALLOW_NO_DHE_KEX},
|
||||
#ifdef SSL_OP_NO_EXTENDED_MASTER_SECRET
|
||||
{"NO_EXTENDED_MASTER_SECRET", SSL_OP_NO_EXTENDED_MASTER_SECRET},
|
||||
#endif
|
||||
#ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT
|
||||
{"ENABLE_MIDDLEBOX_COMPAT", SSL_OP_ENABLE_MIDDLEBOX_COMPAT},
|
||||
#ifdef SSL_OP_NO_QUERY_MTU
|
||||
{"NO_QUERY_MTU", SSL_OP_NO_QUERY_MTU},
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_RENEGOTIATION
|
||||
{"NO_RENEGOTIATION", SSL_OP_NO_RENEGOTIATION},
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
|
||||
{"NO_SESSION_RESUMPTION_ON_RENEGOTIATION", SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION},
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_SSL_MASK
|
||||
{"NO_SSL_MASK", SSL_OP_NO_SSL_MASK},
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_SSLv2
|
||||
{"NO_SSLv2", SSL_OP_NO_SSLv2},
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_SSLv3
|
||||
{"NO_SSLv3", SSL_OP_NO_SSLv3},
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_TICKET
|
||||
{"NO_TICKET", SSL_OP_NO_TICKET},
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_TLSv1
|
||||
{"NO_TLSv1", SSL_OP_NO_TLSv1},
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_TLSv1_1
|
||||
{"NO_TLSv1_1", SSL_OP_NO_TLSv1_1},
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_TLSv1_2
|
||||
{"NO_TLSv1_2", SSL_OP_NO_TLSv1_2},
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_TLSv1_3
|
||||
{"NO_TLSv1_3", SSL_OP_NO_TLSv1_3},
|
||||
#endif
|
||||
#ifdef SSL_OP_PKCS1_CHECK_1
|
||||
{"PKCS1_CHECK_1", SSL_OP_PKCS1_CHECK_1},
|
||||
#endif
|
||||
#ifdef SSL_OP_PKCS1_CHECK_2
|
||||
{"PKCS1_CHECK_2", SSL_OP_PKCS1_CHECK_2},
|
||||
#endif
|
||||
#ifdef SSL_OP_PRIORITIZE_CHACHA
|
||||
{"PRIORITIZE_CHACHA", SSL_OP_PRIORITIZE_CHACHA},
|
||||
#endif
|
||||
#ifdef SSL_OP_ALLOW_CLIENT_RENEGOTIATION
|
||||
{"ALLOW_CLIENT_RENEGOTIATION", SSL_OP_ALLOW_CLIENT_RENEGOTIATION},
|
||||
#ifdef SSL_OP_SAFARI_ECDHE_ECDSA_BUG
|
||||
{"SAFARI_ECDHE_ECDSA_BUG", SSL_OP_SAFARI_ECDHE_ECDSA_BUG},
|
||||
#endif
|
||||
#ifdef SSL_OP_BIT
|
||||
{"BIT", SSL_OP_BIT},
|
||||
#ifdef SSL_OP_SINGLE_DH_USE
|
||||
{"SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE},
|
||||
#endif
|
||||
#ifdef SSL_OP_CLEANSE_PLAINTEXT
|
||||
{"CLEANSE_PLAINTEXT", SSL_OP_CLEANSE_PLAINTEXT},
|
||||
#ifdef SSL_OP_SINGLE_ECDH_USE
|
||||
{"SINGLE_ECDH_USE", SSL_OP_SINGLE_ECDH_USE},
|
||||
#endif
|
||||
#ifdef SSL_OP_DISABLE_TLSEXT_CA_NAMES
|
||||
{"DISABLE_TLSEXT_CA_NAMES", SSL_OP_DISABLE_TLSEXT_CA_NAMES},
|
||||
#ifdef SSL_OP_SSLEAY_080_CLIENT_DH_BUG
|
||||
{"SSLEAY_080_CLIENT_DH_BUG", SSL_OP_SSLEAY_080_CLIENT_DH_BUG},
|
||||
#endif
|
||||
#ifdef SSL_OP_ENABLE_KTLS
|
||||
{"ENABLE_KTLS", SSL_OP_ENABLE_KTLS},
|
||||
#ifdef SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
|
||||
{"SSLREF2_REUSE_CERT_TYPE_BUG", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG},
|
||||
#endif
|
||||
#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF
|
||||
{"IGNORE_UNEXPECTED_EOF", SSL_OP_IGNORE_UNEXPECTED_EOF},
|
||||
#ifdef SSL_OP_TLS_BLOCK_PADDING_BUG
|
||||
{"TLS_BLOCK_PADDING_BUG", SSL_OP_TLS_BLOCK_PADDING_BUG},
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_ANTI_REPLAY
|
||||
{"NO_ANTI_REPLAY", SSL_OP_NO_ANTI_REPLAY},
|
||||
#ifdef SSL_OP_TLS_D5_BUG
|
||||
{"TLS_D5_BUG", SSL_OP_TLS_D5_BUG},
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_EXTENDED_MASTER_SECRET
|
||||
{"NO_EXTENDED_MASTER_SECRET", SSL_OP_NO_EXTENDED_MASTER_SECRET},
|
||||
#ifdef SSL_OP_TLSEXT_PADDING
|
||||
{"TLSEXT_PADDING", SSL_OP_TLSEXT_PADDING},
|
||||
#endif
|
||||
#ifdef SSL_OP_TLS_ROLLBACK_BUG
|
||||
{"TLS_ROLLBACK_BUG", SSL_OP_TLS_ROLLBACK_BUG},
|
||||
#endif
|
||||
{NULL, 0}
|
||||
};
|
||||
|
@ -288,7 +309,7 @@ NOEXPORT char **arg_dup(char **);
|
|||
NOEXPORT void arg_free(char **arg);
|
||||
#endif
|
||||
|
||||
char *configuration_file=NULL;
|
||||
static char *configuration_file=NULL;
|
||||
|
||||
GLOBAL_OPTIONS global_options;
|
||||
SERVICE_OPTIONS service_options;
|
||||
|
@ -682,6 +703,9 @@ void service_free(SERVICE_OPTIONS *section) {
|
|||
|
||||
NOEXPORT char *parse_global_option(CMD cmd, GLOBAL_OPTIONS *options, char *opt, char *arg) {
|
||||
void *tmp;
|
||||
#ifdef USE_FIPS
|
||||
static int fips_default=-1;
|
||||
#endif /* USE_FIPS */
|
||||
|
||||
if(cmd==CMD_PRINT_DEFAULTS || cmd==CMD_PRINT_HELP) {
|
||||
s_log(LOG_NOTICE, " ");
|
||||
|
@ -871,11 +895,14 @@ NOEXPORT char *parse_global_option(CMD cmd, GLOBAL_OPTIONS *options, char *opt,
|
|||
switch(cmd) {
|
||||
case CMD_SET_DEFAULTS:
|
||||
#ifdef USE_FIPS
|
||||
if(fips_default==-1) { /* not initialized */
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
options->option.fips=0;
|
||||
fips_default=EVP_default_properties_is_fips_enabled(NULL);
|
||||
#else /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
|
||||
options->option.fips=FIPS_mode()?1:0;
|
||||
fips_default=FIPS_mode();
|
||||
#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
|
||||
}
|
||||
options->option.fips=fips_default?1:0;
|
||||
#endif /* USE_FIPS */
|
||||
break;
|
||||
case CMD_SET_COPY: /* not used for global options */
|
||||
|
@ -893,10 +920,8 @@ NOEXPORT char *parse_global_option(CMD cmd, GLOBAL_OPTIONS *options, char *opt,
|
|||
#endif /* USE_FIPS */
|
||||
} else if(!strcasecmp(arg, "no")) {
|
||||
#ifdef USE_FIPS
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
if(FIPS_mode())
|
||||
if(fips_default)
|
||||
return "Failed to override system-wide FIPS mode";
|
||||
#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
|
||||
options->option.fips=0;
|
||||
#endif /* USE_FIPS */
|
||||
} else {
|
||||
|
@ -907,13 +932,8 @@ NOEXPORT char *parse_global_option(CMD cmd, GLOBAL_OPTIONS *options, char *opt,
|
|||
break;
|
||||
case CMD_PRINT_DEFAULTS:
|
||||
#ifdef USE_FIPS
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
if(fips_available())
|
||||
s_log(LOG_NOTICE, "%-22s = %s", "fips", "no");
|
||||
#else /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
|
||||
if(fips_available())
|
||||
s_log(LOG_NOTICE, "%-22s = %s", "fips", FIPS_mode()?"yes":"no");
|
||||
#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
|
||||
s_log(LOG_NOTICE, "%-22s = %s", "fips", fips_default?"yes":"no");
|
||||
#endif /* USE_FIPS */
|
||||
break;
|
||||
case CMD_PRINT_HELP:
|
||||
|
@ -4417,13 +4437,6 @@ NOEXPORT void socket_options_free(SOCK_OPT *opt) {
|
|||
|
||||
NOEXPORT int socket_options_print(void) {
|
||||
SOCK_OPT *opt, *ptr;
|
||||
SOCKET fd;
|
||||
socklen_t optlen;
|
||||
OPT_UNION val;
|
||||
char *ta, *tl, *tr, *td;
|
||||
|
||||
fd=socket(AF_INET, SOCK_STREAM, 0);
|
||||
opt=socket_options_init();
|
||||
|
||||
s_log(LOG_NOTICE, " ");
|
||||
s_log(LOG_NOTICE, "Socket option defaults:");
|
||||
|
@ -4431,8 +4444,21 @@ NOEXPORT int socket_options_print(void) {
|
|||
" Option Name | Accept | Local | Remote |OS default");
|
||||
s_log(LOG_NOTICE,
|
||||
" --------------------+----------+----------+----------+----------");
|
||||
|
||||
opt=socket_options_init();
|
||||
for(ptr=opt; ptr->opt_str; ++ptr) {
|
||||
SOCKET fd;
|
||||
socklen_t optlen;
|
||||
OPT_UNION val;
|
||||
char *ta, *tl, *tr, *td;
|
||||
|
||||
/* get OS default value */
|
||||
#if defined(AF_INET6) && defined(IPPROTO_IPV6)
|
||||
if(ptr->opt_level==IPPROTO_IPV6)
|
||||
fd=socket(AF_INET6, SOCK_STREAM, 0);
|
||||
else
|
||||
#endif
|
||||
fd=socket(AF_INET, SOCK_STREAM, 0);
|
||||
optlen=sizeof val;
|
||||
if(getsockopt(fd, ptr->opt_level,
|
||||
ptr->opt_name, (void *)&val, &optlen)) {
|
||||
|
@ -4449,17 +4475,19 @@ NOEXPORT int socket_options_print(void) {
|
|||
}
|
||||
} else
|
||||
td=socket_option_text(ptr->opt_type, &val);
|
||||
closesocket(fd);
|
||||
|
||||
/* get stunnel default values */
|
||||
ta=socket_option_text(ptr->opt_type, ptr->opt_val[0]);
|
||||
tl=socket_option_text(ptr->opt_type, ptr->opt_val[1]);
|
||||
tr=socket_option_text(ptr->opt_type, ptr->opt_val[2]);
|
||||
/* print collected data and fee the memory */
|
||||
|
||||
/* print collected data and free the allocated memory */
|
||||
s_log(LOG_NOTICE, " %-20s|%10s|%10s|%10s|%10s",
|
||||
ptr->opt_str, ta, tl, tr, td);
|
||||
str_free(ta); str_free(tl); str_free(tr); str_free(td);
|
||||
}
|
||||
socket_options_free(opt);
|
||||
closesocket(fd);
|
||||
return 0; /* OK */
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
prefix=.
|
||||
DEFS = -DPACKAGE_NAME=\"stunnel\" \
|
||||
-DPACKAGE_TARNAME=\"stunnel\" \
|
||||
-DPACKAGE_VERSION=\"5.60\" \
|
||||
-DPACKAGE_STRING=\"stunnel\ 5.60\" \
|
||||
-DPACKAGE_VERSION=\"5.61\" \
|
||||
-DPACKAGE_STRING=\"stunnel\ 5.61\" \
|
||||
-DPACKAGE_BUGREPORT=\"\" \
|
||||
-DPACKAGE=\"stunnel\" \
|
||||
-DVERSION=\"5.60\" \
|
||||
-DVERSION=\"5.61\" \
|
||||
-DSTDC_HEADERS=1 \
|
||||
-DHAVE_SYS_TYPES_H=1 \
|
||||
-DHAVE_SYS_STAT_H=1 \
|
||||
|
|
270
src/protocol.c
270
src/protocol.c
|
@ -38,7 +38,7 @@
|
|||
#include "common.h"
|
||||
#include "prototypes.h"
|
||||
|
||||
#define is_prefix(a, b) (strncasecmp((a), (b), strlen(b))==0)
|
||||
#define CAPWIN_BUFFER_SIZE 100
|
||||
|
||||
/* protocol-specific function prototypes */
|
||||
NOEXPORT char *socks_client(CLI *, SERVICE_OPTIONS *, const PHASE);
|
||||
|
@ -71,9 +71,19 @@ NOEXPORT char *connect_client(CLI *, SERVICE_OPTIONS *, const PHASE);
|
|||
NOEXPORT void ntlm(CLI *, SERVICE_OPTIONS *);
|
||||
NOEXPORT char *ntlm1();
|
||||
NOEXPORT char *ntlm3(char *, char *, char *, char *);
|
||||
NOEXPORT void crypt_DES(DES_cblock, DES_cblock, DES_cblock);
|
||||
NOEXPORT void crypt_DES(DES_cblock, DES_cblock, unsigned char[7]);
|
||||
#endif
|
||||
NOEXPORT char *base64(int, const char *, int);
|
||||
NOEXPORT char *capwin_server(CLI *, SERVICE_OPTIONS *, const PHASE);
|
||||
NOEXPORT char *capwin_client(CLI *, SERVICE_OPTIONS *, const PHASE);
|
||||
NOEXPORT char *capwinctrl_client(CLI *, SERVICE_OPTIONS *, const PHASE);
|
||||
|
||||
/* global state */
|
||||
NOEXPORT char capwin_auth[CAPWIN_BUFFER_SIZE]={0};
|
||||
#ifdef USE_WIN32
|
||||
HWND capwin_hwnd=NULL;
|
||||
LONG capwin_connectivity=0;
|
||||
#endif
|
||||
|
||||
/**************************************** framework */
|
||||
|
||||
|
@ -122,6 +132,14 @@ char *protocol(CLI *c, SERVICE_OPTIONS *opt, const PHASE phase) {
|
|||
return opt->option.client ?
|
||||
connect_client(c, opt, phase) :
|
||||
connect_server(c, opt, phase);
|
||||
if(!strcasecmp(opt->protocol, "capwin"))
|
||||
return opt->option.client ?
|
||||
capwin_client(c, opt, phase) :
|
||||
capwin_server(c, opt, phase);
|
||||
if(!strcasecmp(opt->protocol, "capwinctrl"))
|
||||
return opt->option.client ?
|
||||
capwinctrl_client(c, opt, phase) :
|
||||
"The 'capwinctrl' protocol is not supported in the server mode";
|
||||
return "Protocol not supported";
|
||||
}
|
||||
|
||||
|
@ -652,7 +670,7 @@ NOEXPORT char *cifs_server(CLI *c, SERVICE_OPTIONS *opt, const PHASE phase) {
|
|||
(void)opt; /* squash the unused parameter warning */
|
||||
if(phase!=PROTOCOL_EARLY)
|
||||
return NULL;
|
||||
s_read(c, c->local_rfd.fd, buffer, 4) ;/* NetBIOS header */
|
||||
s_read(c, c->local_rfd.fd, buffer, 4); /* NetBIOS header */
|
||||
len=(uint16_t)(((uint16_t)(buffer[2])<<8)|buffer[3]);
|
||||
if(len>sizeof buffer-4) {
|
||||
s_log(LOG_ERR, "Received block too long");
|
||||
|
@ -1601,4 +1619,250 @@ NOEXPORT char *base64(int encode, const char *in, int len) {
|
|||
return out;
|
||||
}
|
||||
|
||||
/**************************************** capwin authentication support */
|
||||
|
||||
NOEXPORT int capwin_decode(const char *src,
|
||||
char **cmd, char **user, char **pass, char **ctrl) {
|
||||
char *us1, *us2, *us3, *fs;
|
||||
|
||||
us1=strchr(src, '\x1f');
|
||||
if(!us1) {
|
||||
s_log(LOG_ERR, "CapWIN: Malformed credentials (1)");
|
||||
return 1; /* FAILED */
|
||||
}
|
||||
us2=strchr(us1 + 1, '\x1f');
|
||||
if(!us2) {
|
||||
s_log(LOG_ERR, "CapWIN: Malformed credentials (2)");
|
||||
return 1; /* FAILED */
|
||||
}
|
||||
us3=strchr(us2 + 1, '\x1f');
|
||||
if(!us3) {
|
||||
s_log(LOG_ERR, "CapWIN: Malformed credentials (3)");
|
||||
return 1; /* FAILED */
|
||||
}
|
||||
fs=strchr(us3 + 1, '\x1c');
|
||||
if(!fs) {
|
||||
s_log(LOG_ERR, "CapWIN: Malformed credentials (4)");
|
||||
return 1; /* FAILED */
|
||||
}
|
||||
if(cmd) {
|
||||
size_t len=(size_t)(us1 - src);
|
||||
*cmd=str_alloc(len + 1);
|
||||
memcpy(*cmd, src, len);
|
||||
}
|
||||
if(user) {
|
||||
size_t len=(size_t)(us2 - us1) - 1;
|
||||
*user=str_alloc(len + 1);
|
||||
memcpy(*user, us1 + 1, len);
|
||||
}
|
||||
if(pass) {
|
||||
size_t len=(size_t)(us3 - us2) - 1;
|
||||
*pass=str_alloc(len + 1);
|
||||
memcpy(*pass, us2 + 1, len);
|
||||
}
|
||||
if(ctrl) {
|
||||
size_t len=(size_t)(fs - us3) - 1;
|
||||
*ctrl=str_alloc(len + 1);
|
||||
memcpy(*ctrl, us3 + 1, len);
|
||||
}
|
||||
return 0; /* SUCCESS */
|
||||
}
|
||||
|
||||
NOEXPORT int ldap_auth(CLI *c, const char *dn, const char *pass) {
|
||||
size_t dn_len, pass_len, req_len;
|
||||
SOCKADDR_UNION addr;
|
||||
int i;
|
||||
unsigned char *req, resp[22];
|
||||
const unsigned char resp_ok[22]=
|
||||
"\x30\x84\x00\x00\x00\x10\x02\x01\x01\x61\x84"
|
||||
"\x00\x00\x00\x07\x0a\x01\x00\x04\x00\x04\x00";
|
||||
|
||||
/* reject parameters too long for simple encoding */
|
||||
dn_len=strlen(dn);
|
||||
pass_len=strlen(pass);
|
||||
req_len=dn_len + pass_len + 14;
|
||||
if(req_len > 120) {
|
||||
s_log(LOG_ERR, "LDAP: Request too long");
|
||||
return 1; /* FAILED */
|
||||
}
|
||||
|
||||
/* connect the configured LDAP server */
|
||||
if(!name2addr(&addr, c->opt->protocol_host, 0)) {
|
||||
s_log(LOG_ERR, "LDAP: Failed to resolve protocolHost");
|
||||
return 1; /* FAILED */
|
||||
}
|
||||
c->fd=s_socket(addr.sa.sa_family, SOCK_STREAM, 0, 1, "LDAP socket");
|
||||
if(c->fd==INVALID_SOCKET)
|
||||
return 1; /* FAILED */
|
||||
s_log(LOG_DEBUG, "LDAP: Connecting the server");
|
||||
if(s_connect(c, &addr, addr_len(&addr))) {
|
||||
closesocket(c->fd);
|
||||
c->fd=INVALID_SOCKET; /* avoid double close on cleanup */
|
||||
return 1; /* FAILED */
|
||||
}
|
||||
|
||||
/* send BindRequest */
|
||||
req=str_alloc(req_len);
|
||||
i=0;
|
||||
req[i++]=0x30; /* SEQUENCE */
|
||||
req[i++]=(unsigned char)(dn_len + pass_len + 12);
|
||||
req[i++]=0x02; /* INTEGER */
|
||||
req[i++]=0x01; /* length */
|
||||
req[i++]=0x01; /* MessageID */
|
||||
req[i++]=0x60; /* [APPLICATION 0]: BindRequest */
|
||||
req[i++]=(unsigned char)(dn_len + pass_len + 7);
|
||||
req[i++]=0x02; /* INTEGER */
|
||||
req[i++]=0x01; /* length */
|
||||
req[i++]=0x03; /* LDAP protocol version */
|
||||
req[i++]=0x04; /* OCTET STRING */
|
||||
req[i++]=(unsigned char)dn_len;
|
||||
memcpy(req + i, dn, dn_len);
|
||||
i+=(int)dn_len;
|
||||
req[i++]=0x80; /* [IMPLICIT 0]: simple authentication */
|
||||
req[i++]=(unsigned char)pass_len;
|
||||
memcpy(req + i, pass, pass_len);
|
||||
s_log(LOG_DEBUG, "LDAP: Sending BindRequest");
|
||||
s_write(c, c->fd, req, req_len);
|
||||
str_free(req);
|
||||
|
||||
/* receive BindResponse */
|
||||
s_log(LOG_DEBUG, "LDAP: Waiting for BindResponse");
|
||||
s_read(c, c->fd, resp, sizeof resp);
|
||||
closesocket(c->fd);
|
||||
c->fd=INVALID_SOCKET; /* avoid double close on cleanup */
|
||||
return memcmp(resp, resp_ok, sizeof resp);
|
||||
}
|
||||
|
||||
NOEXPORT char *ldap_escape_dn(const char *src) {
|
||||
int i=0, j=0;
|
||||
char *dst=str_alloc(2 * strlen(src) + 1);
|
||||
|
||||
while(src[i]) {
|
||||
if(strchr("+;,\\\"<>#", src[i]))
|
||||
dst[j++]='\\';
|
||||
dst[j++]=src[i++];
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
NOEXPORT char *capwin_server(CLI *c, SERVICE_OPTIONS *opt, const PHASE phase) {
|
||||
char *buffer, *user, *pass, *esc_user, *dn;
|
||||
const char *success="BINGO", *failure="FAILED";
|
||||
int i;
|
||||
|
||||
(void)opt; /* squash the unused parameter warning */
|
||||
switch(phase) {
|
||||
case PROTOCOL_MIDDLE: /* TLS is established */
|
||||
buffer=str_alloc(CAPWIN_BUFFER_SIZE);
|
||||
for(i=0; i<CAPWIN_BUFFER_SIZE - 1; ++i) {
|
||||
s_ssl_read(c, buffer+i, 1);
|
||||
if(buffer[i] == '\x1c')
|
||||
break;
|
||||
}
|
||||
if(capwin_decode(buffer, NULL, &user, &pass, NULL)) {
|
||||
/* malformed request: reset instead of sending "FAILED" */
|
||||
str_free(buffer);
|
||||
throw_exception(c, 1);
|
||||
}
|
||||
str_free(buffer);
|
||||
esc_user=ldap_escape_dn(user);
|
||||
str_free(user);
|
||||
dn=str_printf("uid=%s,ou=people,O=CAPWIN,C=US", esc_user);
|
||||
str_free(esc_user);
|
||||
if(ldap_auth(c, dn, pass)) {
|
||||
str_free(dn);
|
||||
str_free(pass);
|
||||
s_log(LOG_ERR, "CapWIN: Authentication failed");
|
||||
s_ssl_write(c, failure, (int)strlen(failure));
|
||||
throw_exception(c, 2); /* don't reset */
|
||||
}
|
||||
str_free(dn);
|
||||
str_free(pass);
|
||||
s_log(LOG_NOTICE, "CapWIN: Authentication succeeded");
|
||||
break;
|
||||
case PROTOCOL_LATE: /* remote host is connected */
|
||||
s_ssl_write(c, success, (int)strlen(success));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NOEXPORT char *capwin_client(CLI *c, SERVICE_OPTIONS *opt, const PHASE phase) {
|
||||
char *cmd, *user, *pass, *ctrl, *req, resp[5];
|
||||
|
||||
(void)opt; /* squash the unused parameter warning */
|
||||
if(phase!=PROTOCOL_LATE)
|
||||
return NULL;
|
||||
|
||||
/* we extract the username and the password to work around a bug in the
|
||||
* original server-side code that required unused units to be empty */
|
||||
/* otherwise, we could simply forward capwin_auth directly */
|
||||
if(!capwin_auth[0]) {
|
||||
s_log(LOG_ERR, "CapWIN: No credentials set");
|
||||
throw_exception(c, 1);
|
||||
}
|
||||
if(capwin_decode(capwin_auth, &cmd, &user, &pass, &ctrl))
|
||||
throw_exception(c, 1);
|
||||
if(strcmp(cmd, "AUTH")) {
|
||||
s_log(LOG_ERR, "CapWIN: Invalid authentication request");
|
||||
str_free(cmd);
|
||||
str_free(user);
|
||||
str_free(pass);
|
||||
str_free(ctrl);
|
||||
throw_exception(c, 1);
|
||||
}
|
||||
str_free(cmd);
|
||||
req=str_printf("\x1f%s\x1f%s\x1f\x1c", user, pass);
|
||||
str_free(user);
|
||||
str_free(pass);
|
||||
#ifdef USE_WIN32
|
||||
capwin_hwnd=(HWND)(uintptr_t)atoi(ctrl);
|
||||
#endif
|
||||
str_free(ctrl);
|
||||
|
||||
s_log(LOG_DEBUG, "CapWIN: Sending credentials");
|
||||
s_ssl_write(c, req, (int)strlen(req));
|
||||
str_free(req);
|
||||
|
||||
s_log(LOG_DEBUG, "CapWIN: Waiting for response");
|
||||
s_ssl_read(c, resp, sizeof resp);
|
||||
#ifdef USE_WIN32
|
||||
/* we received a response, so network is up */
|
||||
if(!InterlockedExchange(&capwin_connectivity, 1))
|
||||
PostMessage(capwin_hwnd, WM_CAPWIN_NET_UP, 0, 0);
|
||||
#endif
|
||||
if(memcmp(resp, "BINGO", sizeof resp)) {
|
||||
s_log(LOG_ERR, "CapWIN: Authentication failed");
|
||||
#ifdef USE_WIN32
|
||||
PostMessage(capwin_hwnd, WM_CAPWIN_AUTH_FAIL, 0, 0);
|
||||
#endif
|
||||
throw_exception(c, 1);
|
||||
}
|
||||
s_log(LOG_NOTICE, "CapWIN: Authentication succeeded");
|
||||
#ifdef USE_WIN32
|
||||
PostMessage(capwin_hwnd, WM_CAPWIN_AUTH_OK, 0, 0);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NOEXPORT char *capwinctrl_client(CLI *c, SERVICE_OPTIONS *opt, const PHASE phase) {
|
||||
switch(phase) {
|
||||
case PROTOCOL_CHECK:
|
||||
opt->option.protocol_endpoint=1;
|
||||
break;
|
||||
case PROTOCOL_EARLY:
|
||||
s_log(LOG_DEBUG, "CapWIN: Setting credentials");
|
||||
memset(capwin_auth, 0, CAPWIN_BUFFER_SIZE);
|
||||
s_read_eof(c, c->local_rfd.fd, capwin_auth, CAPWIN_BUFFER_SIZE - 1);
|
||||
s_log(LOG_NOTICE, "CapWIN: Credentials set");
|
||||
/* skip connecting a remote host */
|
||||
throw_exception(c, 2); /* don't reset */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* end of protocol.c */
|
||||
|
|
|
@ -44,6 +44,14 @@
|
|||
#define USE_OS_THREADS
|
||||
#endif
|
||||
|
||||
#ifdef USE_OS_THREADS
|
||||
#ifndef USE_WIN32
|
||||
/* FIXME: waiting for a single terminate_pipe socket
|
||||
* from multiple threads causes a deadlock on WIN32 */
|
||||
#define USE_TERMINATE_PIPE
|
||||
#endif /* USE_WIN32 */
|
||||
#endif /* USE_OS_THREADS */
|
||||
|
||||
/**************************************** forward declarations */
|
||||
|
||||
typedef struct tls_data_struct TLS_DATA;
|
||||
|
@ -246,9 +254,9 @@ typedef struct service_options_struct {
|
|||
#if OPENSSL_VERSION_NUMBER>=0x10100000L
|
||||
int security_level;
|
||||
#endif /* OpenSSL 1.1.0 or later */
|
||||
long unsigned ssl_options_set;
|
||||
uint64_t ssl_options_set;
|
||||
#if OPENSSL_VERSION_NUMBER>=0x009080dfL
|
||||
long unsigned ssl_options_clear;
|
||||
uint64_t ssl_options_clear;
|
||||
#endif /* OpenSSL 0.9.8m or later */
|
||||
#if OPENSSL_VERSION_NUMBER>=0x10100000L
|
||||
int min_proto_version, max_proto_version;
|
||||
|
@ -486,7 +494,6 @@ void stunnel_info(int);
|
|||
|
||||
/**************************************** prototypes for options.c */
|
||||
|
||||
extern char *configuration_file;
|
||||
extern unsigned number_of_sections;
|
||||
|
||||
int options_cmdline(char *, char *);
|
||||
|
@ -633,6 +640,7 @@ void throw_exception(CLI *, int) NORETURN;
|
|||
int get_socket_error(const SOCKET);
|
||||
int s_connect(CLI *, SOCKADDR_UNION *, socklen_t);
|
||||
void s_write(CLI *, SOCKET fd, const void *, size_t);
|
||||
size_t s_read_eof(CLI *, SOCKET fd, void *, size_t);
|
||||
void s_read(CLI *, SOCKET fd, void *, size_t);
|
||||
void fd_putline(CLI *, SOCKET, const char *);
|
||||
char *fd_getline(CLI *, SOCKET);
|
||||
|
@ -644,6 +652,7 @@ void fd_printf(CLI *, SOCKET, const char *, ...)
|
|||
;
|
||||
#endif
|
||||
void s_ssl_write(CLI *, const void *, int);
|
||||
size_t s_ssl_read_eof(CLI *, void *, int);
|
||||
void s_ssl_read(CLI *, void *, int);
|
||||
char *ssl_getstring(CLI *c);
|
||||
char *ssl_getline(CLI *c);
|
||||
|
@ -664,6 +673,11 @@ typedef enum {
|
|||
PROTOCOL_LATE
|
||||
} PHASE;
|
||||
|
||||
#ifdef USE_WIN32
|
||||
extern HWND capwin_hwnd;
|
||||
extern LONG capwin_connectivity;
|
||||
#endif
|
||||
|
||||
char *protocol(CLI *, SERVICE_OPTIONS *opt, const PHASE);
|
||||
|
||||
/**************************************** prototypes for resolver.c */
|
||||
|
|
|
@ -350,8 +350,10 @@ char *s_ntop(SOCKADDR_UNION *addr, socklen_t addrlen) {
|
|||
if(err) {
|
||||
s_log(LOG_ERR, "getnameinfo: %s", s_gai_strerror(err));
|
||||
retval=str_dup("unresolvable address");
|
||||
} else
|
||||
retval=str_printf("%s:%s", host, port);
|
||||
} else if(!*port && !*host)
|
||||
retval=str_dup("unnamed socket");
|
||||
else
|
||||
retval=str_printf("%s%s%s", host, *host && *port ? ":" : "", port);
|
||||
str_free(host);
|
||||
str_free(port);
|
||||
return retval;
|
||||
|
|
|
@ -3,7 +3,13 @@
|
|||
#define WM_VALID_CONFIG (WM_APP+0)
|
||||
#define WM_INVALID_CONFIG (WM_APP+1)
|
||||
#define WM_NEW_CHAIN (WM_APP+2)
|
||||
#define WM_CLIENTS (WM_APP+3)
|
||||
#define WM_TERMINATE (WM_APP+3)
|
||||
|
||||
#define WM_CAPWIN_DESTROY (WM_APP+0x67)
|
||||
#define WM_CAPWIN_NET_DOWN (WM_APP+0x68)
|
||||
#define WM_CAPWIN_NET_UP (WM_APP+0x69)
|
||||
#define WM_CAPWIN_AUTH_OK (WM_APP+0x70)
|
||||
#define WM_CAPWIN_AUTH_FAIL (WM_APP+0x71)
|
||||
|
||||
#define IDI_STUNNEL_MAIN 10
|
||||
#define IDI_STUNNEL_ACTIVE 11
|
||||
|
@ -13,6 +19,7 @@
|
|||
#define IDE_EDIT 20
|
||||
#define IDE_PASSEDIT 21
|
||||
#define IDE_PINEDIT 22
|
||||
#define IDE_PAUSE 23
|
||||
|
||||
#define IDM_TRAYMENU 30
|
||||
#define IDM_MAINMENU 31
|
||||
|
|
|
@ -44,7 +44,7 @@ BEGIN
|
|||
MENUITEM "Reopen &Log File", IDM_REOPEN_LOG, GRAYED
|
||||
MENUITEM "Co&nnections", IDM_CONNECTIONS
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "E&xit", IDM_EXIT
|
||||
MENUITEM "&Terminate", IDM_EXIT
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&Close", IDM_CLOSE
|
||||
END
|
||||
|
@ -58,9 +58,9 @@ BEGIN
|
|||
MENUITEM "&Reload Configuration", IDM_RELOAD_CONFIG
|
||||
END
|
||||
#ifdef _WIN32_WCE
|
||||
POPUP "&Save Peer Certs"
|
||||
POPUP "&Save Peer Cert", GRAYED
|
||||
#else
|
||||
POPUP "&Save Peer Certificate"
|
||||
POPUP "&Save Peer Certificate", GRAYED
|
||||
#endif
|
||||
BEGIN
|
||||
MENUITEM "dummy", 0, GRAYED
|
||||
|
@ -86,7 +86,7 @@ BEGIN
|
|||
MENUITEM "&Edit Configuration", IDM_EDIT_CONFIG
|
||||
MENUITEM "&Reload Configuration", IDM_RELOAD_CONFIG
|
||||
MENUITEM SEPARATOR
|
||||
POPUP "&Save Peer Certificate"
|
||||
POPUP "&Save Peer Certificate", GRAYED
|
||||
BEGIN
|
||||
MENUITEM "dummy", 0, GRAYED
|
||||
END
|
||||
|
@ -95,7 +95,7 @@ BEGIN
|
|||
MENUITEM "&Manual", IDM_MANPAGE
|
||||
MENUITEM "&About", IDM_ABOUT
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "E&xit", IDM_EXIT
|
||||
MENUITEM "&Terminate", IDM_EXIT
|
||||
END
|
||||
END
|
||||
|
||||
|
|
29
src/ssl.c
29
src/ssl.c
|
@ -70,7 +70,11 @@ NOEXPORT STACK_OF(SSL_COMP) *comp_methods[STUNNEL_COMPS];
|
|||
int fips_available() { /* either FIPS provider or container is available */
|
||||
#ifdef USE_FIPS
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
return OSSL_PROVIDER_available(NULL, "fips");
|
||||
static OSSL_PROVIDER *fips=NULL;
|
||||
|
||||
if(!fips)
|
||||
fips=OSSL_PROVIDER_try_load(NULL, "fips", 1);
|
||||
return fips && OSSL_PROVIDER_available(NULL, "fips");
|
||||
#else /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
|
||||
/* checking for OPENSSL_FIPS would be less precise, because it only
|
||||
* depends on the compiled, and not on the running OpenSSL version */
|
||||
|
@ -195,24 +199,27 @@ NOEXPORT void cb_free_addr(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
|
|||
int ssl_configure(GLOBAL_OPTIONS *global) { /* configure global TLS settings */
|
||||
#ifdef USE_FIPS
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
static OSSL_PROVIDER *prov=NULL;
|
||||
|
||||
if(global->option.fips) {
|
||||
if(!prov) { /* need to load */
|
||||
if(!EVP_default_properties_is_fips_enabled(NULL)) {
|
||||
if(!fips_available()) {
|
||||
s_log(LOG_ERR, "FIPS provider not available");
|
||||
sslerror("FIPS PROVIDER");
|
||||
return 1;
|
||||
}
|
||||
prov=OSSL_PROVIDER_load(NULL, "fips");
|
||||
if(!prov) {
|
||||
sslerror("OSSL_PROVIDER_load");
|
||||
if(!EVP_default_properties_enable_fips(NULL, 1) ||
|
||||
!EVP_default_properties_is_fips_enabled(NULL)) {
|
||||
s_log(LOG_ERR, "Enabling FIPS provider failed");
|
||||
return 1;
|
||||
}
|
||||
s_log(LOG_NOTICE, "FIPS provider enabled");
|
||||
}
|
||||
} else {
|
||||
if(prov) { /* need to unload */
|
||||
OSSL_PROVIDER_unload(prov);
|
||||
prov=NULL;
|
||||
if(EVP_default_properties_is_fips_enabled(NULL)) {
|
||||
if(!EVP_default_properties_enable_fips(NULL, 0) ||
|
||||
EVP_default_properties_is_fips_enabled(NULL)) {
|
||||
s_log(LOG_ERR, "Disabling FIPS provider failed");
|
||||
return 1;
|
||||
}
|
||||
s_log(LOG_NOTICE, "FIPS provider disabled");
|
||||
}
|
||||
}
|
||||
#else /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
|
||||
|
|
|
@ -112,7 +112,7 @@ void thread_id_init(void) {
|
|||
#if OPENSSL_VERSION_NUMBER>=0x10000000L && OPENSSL_VERSION_NUMBER<0x10100000L
|
||||
CRYPTO_THREADID_set_callback(threadid_func);
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER<0x10000000L || !defined(OPENSSL_NO_DEPRECATED)
|
||||
#if OPENSSL_VERSION_NUMBER<0x10000000L
|
||||
CRYPTO_set_id_callback(stunnel_thread_id);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -68,6 +68,7 @@ struct sockaddr_un {
|
|||
};
|
||||
#endif
|
||||
|
||||
NOEXPORT void terminate_threads();
|
||||
#if !defined(USE_WIN32) && !defined(USE_OS2)
|
||||
NOEXPORT void pid_status_nohang(const char *);
|
||||
NOEXPORT void status_info(int, int, const char *);
|
||||
|
@ -90,7 +91,9 @@ NOEXPORT char *signal_name(int);
|
|||
/**************************************** global variables */
|
||||
|
||||
SOCKET signal_pipe[2]={INVALID_SOCKET, INVALID_SOCKET};
|
||||
#ifdef USE_TERMINATE_PIPE
|
||||
SOCKET terminate_pipe[2]={INVALID_SOCKET, INVALID_SOCKET};
|
||||
#endif /* USE_TERMINATE_PIPE */
|
||||
|
||||
#ifndef USE_FORK
|
||||
int max_clients=0;
|
||||
|
@ -133,9 +136,11 @@ void main_init() { /* one-time initialization */
|
|||
if(pipe_init(signal_pipe, "signal_pipe"))
|
||||
fatal("Signal pipe initialization failed: "
|
||||
"check your personal firewall");
|
||||
#ifdef USE_TERMINATE_PIPE
|
||||
if(pipe_init(terminate_pipe, "terminate_pipe"))
|
||||
fatal("Terminate pipe initialization failed: "
|
||||
"check your personal firewall");
|
||||
#endif /* USE_TERMINATE_PIPE */
|
||||
stunnel_info(LOG_NOTICE);
|
||||
if(systemd_fds>0)
|
||||
s_log(LOG_INFO, "Systemd socket activation: %d descriptors received",
|
||||
|
@ -234,14 +239,26 @@ int drop_privileges(int critical) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void main_cleanup() {
|
||||
terminate_threads();
|
||||
unbind_ports();
|
||||
s_poll_free(fds);
|
||||
fds=NULL;
|
||||
#if 0
|
||||
str_stats(); /* main thread allocation tracking */
|
||||
#endif
|
||||
log_flush(LOG_MODE_BUFFER); /* no more logs */
|
||||
log_close(SINK_SYSLOG|SINK_OUTFILE);
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || defined(__clang__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-result"
|
||||
#endif /* __GNUC__>=4.6 */
|
||||
#endif /* __GNUC__ */
|
||||
void main_cleanup() {
|
||||
#ifdef USE_OS_THREADS
|
||||
NOEXPORT void terminate_threads() {
|
||||
#ifdef USE_TERMINATE_PIPE
|
||||
CLI *c;
|
||||
unsigned i, threads;
|
||||
THREAD_ID *thread_list;
|
||||
|
@ -263,7 +280,7 @@ void main_cleanup() {
|
|||
CRYPTO_THREAD_unlock(stunnel_locks[LOCK_THREAD_LIST]);
|
||||
|
||||
if(threads) {
|
||||
s_log(LOG_NOTICE, "Terminating %u service thread(s)", threads);
|
||||
s_log(LOG_INFO, "Terminating %u service thread(s)", threads);
|
||||
writesocket(terminate_pipe[1], "", 1);
|
||||
for(i=0; i<threads; ++i) { /* join client threads */
|
||||
#ifdef USE_PTHREAD
|
||||
|
@ -277,20 +294,11 @@ void main_cleanup() {
|
|||
ioerror("CloseHandle");
|
||||
#endif
|
||||
}
|
||||
s_log(LOG_NOTICE, "Service threads terminated");
|
||||
s_log(LOG_INFO, "Service threads terminated");
|
||||
}
|
||||
|
||||
str_free(thread_list);
|
||||
#endif /* USE_OS_THREADS */
|
||||
|
||||
unbind_ports();
|
||||
s_poll_free(fds);
|
||||
fds=NULL;
|
||||
#if 0
|
||||
str_stats(); /* main thread allocation tracking */
|
||||
#endif
|
||||
log_flush(LOG_MODE_BUFFER); /* no more logs */
|
||||
log_close(SINK_SYSLOG|SINK_OUTFILE);
|
||||
#endif /* USE_TERMINATE_PIPE */
|
||||
}
|
||||
#ifdef __GNUC__
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||
|
@ -884,18 +892,20 @@ NOEXPORT void reload_config() {
|
|||
NOEXPORT int process_connections() {
|
||||
#ifndef USE_FORK
|
||||
CLI *c;
|
||||
int n=0;
|
||||
|
||||
s_log(LOG_NOTICE, "Active connections:");
|
||||
s_log(LOG_EMERG, "Active connections:");
|
||||
CRYPTO_THREAD_write_lock(stunnel_locks[LOCK_THREAD_LIST]);
|
||||
for(c=thread_head; c; c=c->thread_next) {
|
||||
s_log(LOG_NOTICE, "Service [%s]: "
|
||||
s_log(LOG_EMERG, "Active connection %d: Service [%s], "
|
||||
"%llu byte(s) sent to TLS, "
|
||||
"%llu byte(s) sent to socket",
|
||||
c->opt->servname,
|
||||
++n, c->opt->servname,
|
||||
(unsigned long long)c->ssl_bytes,
|
||||
(unsigned long long)c->sock_bytes);
|
||||
}
|
||||
CRYPTO_THREAD_unlock(stunnel_locks[LOCK_THREAD_LIST]);
|
||||
s_log(LOG_EMERG, "Listed %d active connection(s)", n);
|
||||
#endif /* USE_FORK */
|
||||
return 0; /* continue execution */
|
||||
}
|
||||
|
|
|
@ -65,8 +65,12 @@ int main(int argc, char *argv[]) {
|
|||
#endif
|
||||
_tputenv(str_tprintf(TEXT("OPENSSL_ENGINES=%s\\engines"),
|
||||
stunnel_exe_path));
|
||||
_tputenv(str_tprintf(TEXT("OPENSSL_MODULES=%s\\ossl-modules"),
|
||||
stunnel_exe_path));
|
||||
_tputenv(str_tprintf(TEXT("OPENSSL_CONF=%s\\config\\openssl.cnf"),
|
||||
stunnel_exe_path));
|
||||
|
||||
if(WSAStartup(MAKEWORD(1, 1), &wsa_state))
|
||||
if(WSAStartup(MAKEWORD(2, 2), &wsa_state))
|
||||
return 1;
|
||||
resolver_init();
|
||||
main_init();
|
||||
|
|
1562
src/ui_win_gui.c
1562
src/ui_win_gui.c
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -65,7 +65,7 @@
|
|||
|
||||
/* START CUSTOMIZE */
|
||||
#define VERSION_MAJOR 5
|
||||
#define VERSION_MINOR 60
|
||||
#define VERSION_MINOR 61
|
||||
/* END CUSTOMIZE */
|
||||
|
||||
/* all the following macros are ABSOLUTELY NECESSARY to have proper string
|
||||
|
|
|
@ -3,10 +3,15 @@
|
|||
|
||||
SUBDIRS = certs
|
||||
|
||||
EXTRA_DIST = make_test test_library recipes execute execute_read execute_write http_request server.py
|
||||
EXTRA_DIST = maketest.py plugin_collection.py reader.py error.py plugins
|
||||
|
||||
# try to find a supported python version (>= 3.7) that works
|
||||
check-local:
|
||||
$(srcdir)/make_test
|
||||
for v in $$(seq 20 -1 7); do command -v python3.$$v && break; done || ( echo "Python 3.7 or later not found" && false )
|
||||
for v in $$(seq 20 -1 7); do command -v python3.$$v && python3.$$v $(srcdir)/maketest.py --debug=10 && break; done
|
||||
|
||||
distclean-local:
|
||||
rm -f logs/*.log
|
||||
rm -f certs/*.pem
|
||||
rm -f certs/*.p12
|
||||
rm -f certs/*.txt
|
||||
|
|
|
@ -309,7 +309,7 @@ top_build_prefix = @top_build_prefix@
|
|||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
SUBDIRS = certs
|
||||
EXTRA_DIST = make_test test_library recipes execute execute_read execute_write http_request server.py
|
||||
EXTRA_DIST = maketest.py plugin_collection.py reader.py error.py plugins
|
||||
all: all-recursive
|
||||
|
||||
.SUFFIXES:
|
||||
|
@ -628,11 +628,16 @@ uninstall-am:
|
|||
.PRECIOUS: Makefile
|
||||
|
||||
|
||||
# try to find a supported python version (>= 3.7) that works
|
||||
check-local:
|
||||
$(srcdir)/make_test
|
||||
for v in $$(seq 20 -1 7); do command -v python3.$$v && break; done || ( echo "Python 3.7 or later not found" && false )
|
||||
for v in $$(seq 20 -1 7); do command -v python3.$$v && python3.$$v $(srcdir)/maketest.py --debug=10 && break; done
|
||||
|
||||
distclean-local:
|
||||
rm -f logs/*.log
|
||||
rm -f certs/*.pem
|
||||
rm -f certs/*.p12
|
||||
rm -f certs/*.txt
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDwTCCAqmgAwIBAgIUAgntZn82DgFlMtCp03CIJSTafIUwDQYJKoZIhvcNAQEL
|
||||
BQAwaDELMAkGA1UEBhMCUEwxGzAZBgNVBAoMElN0dW5uZWwgRGV2ZWxvcGVyczEQ
|
||||
MA4GA1UECwwHUm9vdCBDQTELMAkGA1UEAwwCQ0ExHTAbBgkqhkiG9w0BCQEWDkNB
|
||||
QGV4YW1wbGUuY29tMB4XDTIxMDMxODEyNTQxOFoXDTI1MDMxODEyNTQxOFowaDEL
|
||||
MAkGA1UEBhMCUEwxGzAZBgNVBAoMElN0dW5uZWwgRGV2ZWxvcGVyczEQMA4GA1UE
|
||||
CwwHUm9vdCBDQTELMAkGA1UEAwwCQ0ExHTAbBgkqhkiG9w0BCQEWDkNBQGV4YW1w
|
||||
bGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy6NMBiYDSCxb
|
||||
vjzY//qWDqx8v6SXDWPLfiT8/tHuH/oBcnfsfp9nGygvctjPNg0pl6+IFVi5UdhC
|
||||
RoRQBFmsSgiDJtmSuvO+Rtb+aG4RMNJOQpeKvOgu+xxxRSOYOyL2l+dOsrSIAnOB
|
||||
yZ+YMc7GTnx9cl5f/GtifMBVGKUSsODqa6SOVg6BVgn+ftmyKa5s2Gh8mWz2+7Cr
|
||||
eN4L2IoV3H3x0NhYzUoWCyCwXgLU0y5p2Pzp2w6SVDgy1PjxNYXGzE2BvhXj+ASJ
|
||||
gFAfYV99sofXdTJMxbjXG/rpY2ymYk/Z66vNZw94p1AdL7byAvYDopCtzVNb338f
|
||||
lp1aiBpHMwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQXfp8c
|
||||
sA5qErTdb/lD30wQEcCICjAfBgNVHSMEGDAWgBQXfp8csA5qErTdb/lD30wQEcCI
|
||||
CjAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggEBAG8U/a5founQWwWj
|
||||
4t77YlwmJL6/+GVNbAYq/q2i9Iit5NrWydLzwxIAyQoVUrw0rkllvfnJFlh7Bpiz
|
||||
hGvTcq+DW4se+D3gAL1IB3PBMaRJ4oGAoB+7xw9k/sI/b96W1nGcBIA3sKw3F00e
|
||||
GSLvZkRLwnzEFaDkNVA/Ux2F/Swo0Yx+8JwDlH6cVSZZpiTtZZe/Zk475u13hpVH
|
||||
o1CWauP3lji72XWV94ohRtUHMWuOTJR6QkL+ekypBIoS/kU/PUH2iqxiv4eTBNFV
|
||||
S15UAMPlV1Cq0GOSczPcrfyLav4DAQLb37FKIK6wfy609hHDga2w0DDFEKZ3+Sco
|
||||
JTR4BB4=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,13 +0,0 @@
|
|||
-----BEGIN X509 CRL-----
|
||||
MIIB7TCB1gIBATANBgkqhkiG9w0BAQsFADBoMQswCQYDVQQGEwJQTDEbMBkGA1UE
|
||||
CgwSU3R1bm5lbCBEZXZlbG9wZXJzMRAwDgYDVQQLDAdSb290IENBMQswCQYDVQQD
|
||||
DAJDQTEdMBsGCSqGSIb3DQEJARYOQ0FAZXhhbXBsZS5jb20XDTIxMDMxODEyNTQx
|
||||
OFoXDTI1MDMxODEyNTQxOFowFTATAgIQABcNMjEwMzE4MTI1NDE4WqAjMCEwHwYD
|
||||
VR0jBBgwFoAUF36fHLAOahK03W/5Q99MEBHAiAowDQYJKoZIhvcNAQELBQADggEB
|
||||
ALfCOE8XUACUlLHCuhfbddnInp2ZRrUjJcZxjjlgDiUbQGvTcBFxT6hoPa0iIiND
|
||||
ijgzieMr4aoOycpYKi3kcn7YBdntCZ4JZul4BiyU1Y4jyWw38jNmtxQ81UKoSmJM
|
||||
fee02LykPWAWm3IUvy3QRYoZl+bs3yQHW5E8IEQvqJW2jlTeIpnK+jKLJd/aR3Af
|
||||
yxwqV1ALkkDbQ4qsvACswsbq2TfVkXnsot6BAmkT1dsvHtmeGbtOFQJPCujIlHoy
|
||||
Gi2jTuaf4a03wMZz9hIxh5auXExNbhS2HKqX+rZiSLg/H4tGj5Z5BWayZxWqlIG3
|
||||
2LIZhzCROn6arv/2Xpme+es=
|
||||
-----END X509 CRL-----
|
|
@ -2,10 +2,6 @@
|
|||
# by Michal Trojnara 1998-2021
|
||||
|
||||
EXTRA_DIST = maketestcert.sh openssltest.cnf
|
||||
EXTRA_DIST += CACertCRL.pem CACert.pem
|
||||
EXTRA_DIST += server_cert.pem server_cert.p12 client_cert.pem
|
||||
EXTRA_DIST += revoked_cert.pem stunnel.pem PeerCerts.pem
|
||||
EXTRA_DIST += psk1.txt psk2.txt secrets.txt
|
||||
|
||||
check-local:
|
||||
$(srcdir)/maketestcert.sh
|
||||
|
|
|
@ -248,10 +248,7 @@ target_alias = @target_alias@
|
|||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
EXTRA_DIST = maketestcert.sh openssltest.cnf CACertCRL.pem CACert.pem \
|
||||
server_cert.pem server_cert.p12 client_cert.pem \
|
||||
revoked_cert.pem stunnel.pem PeerCerts.pem psk1.txt psk2.txt \
|
||||
secrets.txt
|
||||
EXTRA_DIST = maketestcert.sh openssltest.cnf
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDoDCCAoigAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwaDELMAkGA1UEBhMCUEwx
|
||||
GzAZBgNVBAoMElN0dW5uZWwgRGV2ZWxvcGVyczEQMA4GA1UECwwHUm9vdCBDQTEL
|
||||
MAkGA1UEAwwCQ0ExHTAbBgkqhkiG9w0BCQEWDkNBQGV4YW1wbGUuY29tMB4XDTIx
|
||||
MDMxODEyNTQxOFoXDTI1MDMxODEyNTQxOFowbzELMAkGA1UEBhMCUEwxGzAZBgNV
|
||||
BAoMElN0dW5uZWwgRGV2ZWxvcGVyczEPMA0GA1UECwwGY2xpZW50MQ8wDQYDVQQD
|
||||
DAZjbGllbnQxITAfBgkqhkiG9w0BCQEWEmNsaWVudEBleGFtcGxlLmNvbTCCASIw
|
||||
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN5Oew1AT5Ll2hMhOJ8Z+7s5Bai2
|
||||
OggPA6veuTYZSgNZFap004BLg3J5mohgV5Itf0qsx6m10JdF5qDGh44cVIM7OYY+
|
||||
f0XPrjvhzxps0TZmSc7Gb4Kd99evEo/A0PRsQHSC4aYZr/CKMAkWun4HWunxBPV4
|
||||
XFVMtlPFgibncXM9SoyEhqIn93cvYrbcAGPFBMudJePVwYwIDhAlLGrMOHgExUtt
|
||||
cgZOpUBCW8ImzwPumEqxNveybmMLwECxMC5hjBXniiOzs3hWxN4Ih3yQWtls7wdN
|
||||
2D0GdwyIGjUa4AIl0BL2B1BLp5dGPgm//2PVrukZmCKxWSBcOIkQz1FF7ysCAwEA
|
||||
AaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQUlCst2zML4i8FXy1qi/1+uUd13Rgw
|
||||
HwYDVR0jBBgwFoAUF36fHLAOahK03W/5Q99MEBHAiAowDQYJKoZIhvcNAQELBQAD
|
||||
ggEBABafr4e69w/j1/SkD3mtGDphfttJ3XfwySPE47pXN8jaWrvQmRa1Q11x1R+c
|
||||
oJBGyI/Vg65IAUfbDqAqi7Gropsa+3fF5Zm2yLXtxYkWa15/Bn/6XDOWMwhIuGdM
|
||||
2OHWa4qmnAzjseE/CPCB+YM4x2Fgqa9hn8rOmteIBZ6KC3rWR4+9gmqcjt1ZNiQ4
|
||||
1GSiUDBSjmTsPlyb5TLQ2MrowYLYtJjGOLVx3ZaN7plDmh9om+4AeuIkEsLwmB+P
|
||||
SrUGhEqo4MnaPdj/XKQCwVG7DqAd4BReSc4ZzFegycU98z4ALzJ5qy2bT05yEkCO
|
||||
UxDcwNGhr3pOLKb/9860qeY5bi0=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDoDCCAoigAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwaDELMAkGA1UEBhMCUEwx
|
||||
GzAZBgNVBAoMElN0dW5uZWwgRGV2ZWxvcGVyczEQMA4GA1UECwwHUm9vdCBDQTEL
|
||||
MAkGA1UEAwwCQ0ExHTAbBgkqhkiG9w0BCQEWDkNBQGV4YW1wbGUuY29tMB4XDTIx
|
||||
MDMxODEyNTQxOFoXDTI1MDMxODEyNTQxOFowbzELMAkGA1UEBhMCUEwxGzAZBgNV
|
||||
BAoMElN0dW5uZWwgRGV2ZWxvcGVyczEPMA0GA1UECwwGc2VydmVyMQ8wDQYDVQQD
|
||||
DAZzZXJ2ZXIxITAfBgkqhkiG9w0BCQEWEnNlcnZlckBleGFtcGxlLmNvbTCCASIw
|
||||
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALNK+CxahWSi4zH4SQgMJjPjiiI+
|
||||
zG6JTpibWV9Lxuc21b2XRlx9I8xOITsDb3JiKacO6Lg+hWg+EymuyFAE/h5ASmNZ
|
||||
e9pCEmsvCM8XGYyGw18cxOoNK8v+DzAR4XySF6BOcaeaFnInTcbYUnhK0YDSn0P6
|
||||
lyv8Ol76xR/C+y4AvuyoYCjVOzvxY2g3HdjlyA7RwVS9ekYgS5nd0s/qdO91gQ+4
|
||||
imb67HW76bF5LmiCAfZ0XKqHFyvHO5D57QifLq3Kwe6IorTrTSFH/fWre/A/JIji
|
||||
Bt63dGSlxCnfNzQIJYJjJYdU7tz7cKMnpp0avxSCeFZYw8RsAr1L8JunLtsCAwEA
|
||||
AaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQU7L61jETM7BttdLW3uOPJuRqs9uUw
|
||||
HwYDVR0jBBgwFoAUF36fHLAOahK03W/5Q99MEBHAiAowDQYJKoZIhvcNAQELBQAD
|
||||
ggEBAFfZkSmuYMjMfEBzBUudunL2vOeQUsQcH6KROsYaq+lN09aazMKBX8j+VMTL
|
||||
6ZSlVxeM5BCXdD3GvpFb+R4ED8EcrRWKbAiqUJz1tAyjLRyHW2GWqfFpOn5yNonK
|
||||
vsUtZSL+v87V26PGuRs5dQizGkstS2gKx3zFqaKwWdCQE5ldDwT+kDkghvALoGXw
|
||||
IuFt7+QbZjLQvQ/YdCUXjBVdzICVO5WgEePAZ4IO8r20jrda2aP5OFVmUcc+iA8P
|
||||
Rn6jCOfdnNyBDWwm+oEf1WecYxTr0Ly0d3QcOxpAUeQTgT6tZawpllGLkwfrUZFV
|
||||
09YKu45BurR5WZzok/9zyflPv80=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,49 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDoDCCAoigAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwaDELMAkGA1UEBhMCUEwx
|
||||
GzAZBgNVBAoMElN0dW5uZWwgRGV2ZWxvcGVyczEQMA4GA1UECwwHUm9vdCBDQTEL
|
||||
MAkGA1UEAwwCQ0ExHTAbBgkqhkiG9w0BCQEWDkNBQGV4YW1wbGUuY29tMB4XDTIx
|
||||
MDMxODEyNTQxOFoXDTI1MDMxODEyNTQxOFowbzELMAkGA1UEBhMCUEwxGzAZBgNV
|
||||
BAoMElN0dW5uZWwgRGV2ZWxvcGVyczEPMA0GA1UECwwGY2xpZW50MQ8wDQYDVQQD
|
||||
DAZjbGllbnQxITAfBgkqhkiG9w0BCQEWEmNsaWVudEBleGFtcGxlLmNvbTCCASIw
|
||||
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN5Oew1AT5Ll2hMhOJ8Z+7s5Bai2
|
||||
OggPA6veuTYZSgNZFap004BLg3J5mohgV5Itf0qsx6m10JdF5qDGh44cVIM7OYY+
|
||||
f0XPrjvhzxps0TZmSc7Gb4Kd99evEo/A0PRsQHSC4aYZr/CKMAkWun4HWunxBPV4
|
||||
XFVMtlPFgibncXM9SoyEhqIn93cvYrbcAGPFBMudJePVwYwIDhAlLGrMOHgExUtt
|
||||
cgZOpUBCW8ImzwPumEqxNveybmMLwECxMC5hjBXniiOzs3hWxN4Ih3yQWtls7wdN
|
||||
2D0GdwyIGjUa4AIl0BL2B1BLp5dGPgm//2PVrukZmCKxWSBcOIkQz1FF7ysCAwEA
|
||||
AaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQUlCst2zML4i8FXy1qi/1+uUd13Rgw
|
||||
HwYDVR0jBBgwFoAUF36fHLAOahK03W/5Q99MEBHAiAowDQYJKoZIhvcNAQELBQAD
|
||||
ggEBABafr4e69w/j1/SkD3mtGDphfttJ3XfwySPE47pXN8jaWrvQmRa1Q11x1R+c
|
||||
oJBGyI/Vg65IAUfbDqAqi7Gropsa+3fF5Zm2yLXtxYkWa15/Bn/6XDOWMwhIuGdM
|
||||
2OHWa4qmnAzjseE/CPCB+YM4x2Fgqa9hn8rOmteIBZ6KC3rWR4+9gmqcjt1ZNiQ4
|
||||
1GSiUDBSjmTsPlyb5TLQ2MrowYLYtJjGOLVx3ZaN7plDmh9om+4AeuIkEsLwmB+P
|
||||
SrUGhEqo4MnaPdj/XKQCwVG7DqAd4BReSc4ZzFegycU98z4ALzJ5qy2bT05yEkCO
|
||||
UxDcwNGhr3pOLKb/9860qeY5bi0=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEA3k57DUBPkuXaEyE4nxn7uzkFqLY6CA8Dq965NhlKA1kVqnTT
|
||||
gEuDcnmaiGBXki1/SqzHqbXQl0XmoMaHjhxUgzs5hj5/Rc+uO+HPGmzRNmZJzsZv
|
||||
gp33168Sj8DQ9GxAdILhphmv8IowCRa6fgda6fEE9XhcVUy2U8WCJudxcz1KjISG
|
||||
oif3dy9ittwAY8UEy50l49XBjAgOECUsasw4eATFS21yBk6lQEJbwibPA+6YSrE2
|
||||
97JuYwvAQLEwLmGMFeeKI7OzeFbE3giHfJBa2WzvB03YPQZ3DIgaNRrgAiXQEvYH
|
||||
UEunl0Y+Cb//Y9Wu6RmYIrFZIFw4iRDPUUXvKwIDAQABAoIBADuklLEOcwr3bhW5
|
||||
0QYmo3osp08HbPRiitqey9Qu3sOdMAnmhCQknmSlKYezSWtnl4JCbuMia49aarDx
|
||||
8sZ25Vm8FwfkVqM1QArC35y4Wz0cHmtCpAJIPYl5aCJ3Wdhp/rUDtGSq+aAwgwi9
|
||||
N1W+xW6Ego8VNriP907sa6niaHbBF7N5qNls6YrHlevQUUlpEO+ADgIlpfl2ICWs
|
||||
5cTVhFuqz0yECwoX0CeRGUb8EhcLnd1xMwOd4+olWUHSuhXTUTTUaTYIrEhy6tFD
|
||||
ua2prlRRbmzmB/l53aCCRSthpDfkPSPC4CL02jDQerIo5E5YHNP0AWUL+PQzLQQ8
|
||||
tRa197ECgYEA/YEXe6K+06MExN39JFnWCJLqs41zMrYwJ+W3hm0A9VZbbWy/2/xz
|
||||
ZDLnpEc4qiH8fPLM+hllPc07RlZYY47ni/RpVHfs98mYGOifmXmUfR1QKETv5FhD
|
||||
n7R/PoKynjQQwhPyrnfPDSz/wkejyv80v2AxgzNgj9dFfrGGjt/IpPMCgYEA4H7C
|
||||
3dju8UDlJJb0xSe7UrJe/6Yw0iRy4FSMYIgmIBk+X/1DPDvBCxqG6/OUdNPE3ydG
|
||||
wWCRIZ4UkLLU5+22q2gn6jAfvtNfpwUy9VvKq26Df15/Ir0eK+onyYvXgxx6hP23
|
||||
kPXh727aENpblwuA9eG8kqfO9YPKdcUrghnEeukCgYEAuvkIqe7KEmxtKwqUF8iO
|
||||
vXom01GjwqZvdC3RI7un9kvAWT/ZblaPgTqucRL6rzkr8bhfCKPMcT2611D+Fkgj
|
||||
ba1SNrPROp0cqlqAxIDQzUregST/TorvLY7CPwfE2DyMk6iE2LuTIiOra87M9v8u
|
||||
F2zKd/tf4BelsSEcnqpdYZMCgYAieVTTXIzU33JQvB26aO+LM3kDKTI2EwLRECq+
|
||||
aCnyo+3AL9QzW7m5SsmNUkpp5ltFKXLkH0AqOWxPDCdFtmtmxwfaHqnBVBRMQbAh
|
||||
nYbx7HalCI3dd806USrq+F6P87+czJlz2U5oxk0WaXHHMC0NlSywGLTfXu2oSC72
|
||||
O57AgQKBgGJhmy4BYJ7IVLJ035SS+j/XqmwpXFTsQKjZ4jQuzlWyjLlIQNVWPk2W
|
||||
Ci28ttyHZUDA9V/eTTZ24QW/apxV57WKsJEj5t7qDA3UblnozCKRq4ShkF6t8YEX
|
||||
f5xUTwYrlnao1UCvMXHLCvGYDw5yCqLZQ3fO2qjSmLPcK6wslEQp
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1 +0,0 @@
|
|||
test1:6UoHxibiMes9DaN8P0aDsM0tRbEBCflRoDaTVYefMHc26BFX7I
|
|
@ -1 +0,0 @@
|
|||
test2:3RbLUm5d40p9AUCLXgnr6Y3VrlKziUlZdHr6LqHjCgLUJaexa4
|
|
@ -1,49 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDozCCAougAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwaDELMAkGA1UEBhMCUEwx
|
||||
GzAZBgNVBAoMElN0dW5uZWwgRGV2ZWxvcGVyczEQMA4GA1UECwwHUm9vdCBDQTEL
|
||||
MAkGA1UEAwwCQ0ExHTAbBgkqhkiG9w0BCQEWDkNBQGV4YW1wbGUuY29tMB4XDTIx
|
||||
MDMxODEyNTQxOFoXDTI1MDMxODEyNTQxOFowcjELMAkGA1UEBhMCUEwxGzAZBgNV
|
||||
BAoMElN0dW5uZWwgRGV2ZWxvcGVyczEQMA4GA1UECwwHcmV2b2tlZDEQMA4GA1UE
|
||||
AwwHcmV2b2tlZDEiMCAGCSqGSIb3DQEJARYTcmV2b2tlZEBleGFtcGxlLmNvbTCC
|
||||
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOZFiyZkmA1XgVhbjKSTMa/w
|
||||
Qt4MATQCC6XoBdFGjsWyYJJVMu62Ifx6+t7TgDz4rVlf1rgwupVeJ9IUEfL8nEC0
|
||||
VZPLkqN659I4Hs1SEE8cemClGkxDVOs8voO/KYourjKVOZA6rt3vNHI/8Uh1a6eY
|
||||
wo9mZ/tdya3QsrUmZHIj8Vs3KT92QPTNxyrQlkaVRuHaTFluyEBI3VNiq9e/VGVJ
|
||||
hikNiXqspuyt85LU6S2xj3/HVrVyxmXuSbp5urqe7XTL9/SBRFyAB11gmvyCpCwz
|
||||
AD4uOaqyTPa3E2G8a4UWEU/yTHminzNpnMFMYQQnwK7KqQZvtEDFctoswL8JTDcC
|
||||
AwEAAaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQU3bD2NyKFlGcdzmf9tbQyiZ7s
|
||||
B7YwHwYDVR0jBBgwFoAUF36fHLAOahK03W/5Q99MEBHAiAowDQYJKoZIhvcNAQEL
|
||||
BQADggEBAIbPe0ttoLFmo43XFMeD3460yaGtf3EBj2hGHbwhgHppSteyJ++zymJ7
|
||||
1A5OqcLWm9DrTtQp6VkhLHYLL54uYrL+0QcR9GBJlhfqTbOTlzdkHDC3/8u9xmgS
|
||||
+qlI4EUGtzeaj2dTU+8IvihFx4wk+QhMeafr8pouVwt+VdmlW6XbZt5+QiZtVwYT
|
||||
d3hwLSuHb+g1Trt4ryWbNGia/SrTmFfH54jJ8+2WrxEDcv6TAqqGm0L224vImcbA
|
||||
EoMJIC8Wi0p+lnGyVtyvghyTYgct7asTQgsoNNyB6PL12DKIrIwecchY/KF5nz12
|
||||
b6CaxuIkQiLOqlqUxwqxdg4xRnlFdqA=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEA5kWLJmSYDVeBWFuMpJMxr/BC3gwBNAILpegF0UaOxbJgklUy
|
||||
7rYh/Hr63tOAPPitWV/WuDC6lV4n0hQR8vycQLRVk8uSo3rn0jgezVIQTxx6YKUa
|
||||
TENU6zy+g78pii6uMpU5kDqu3e80cj/xSHVrp5jCj2Zn+13JrdCytSZkciPxWzcp
|
||||
P3ZA9M3HKtCWRpVG4dpMWW7IQEjdU2Kr179UZUmGKQ2Jeqym7K3zktTpLbGPf8dW
|
||||
tXLGZe5Junm6up7tdMv39IFEXIAHXWCa/IKkLDMAPi45qrJM9rcTYbxrhRYRT/JM
|
||||
eaKfM2mcwUxhBCfArsqpBm+0QMVy2izAvwlMNwIDAQABAoIBAEkrxgjAJFTw/mfu
|
||||
R2WwZDSM+yKF3AgDsmHYtaiHbCzD/s3hBts1wtzw0zDlMjWtq5/fxWIoEdIO5kZq
|
||||
HD4DKT+iTiM1p/YMwwdYz+jcb9RDr1twe0fKiXxqg/tnTjLbnHz0UCNVkmVxck/v
|
||||
o6MrtLa/4usgVmBYsBJsY60OcxKVYOeF1yI/ODQCFw9RjglE+HybfTg2cGiR0ggA
|
||||
wPmJq6N2CvTJwzjWDuKI5mGJY0xDXwnvvDbcYpgmHNF+6AgMxW5dbpgSoUQvXRCJ
|
||||
8MTN/hwfDC48UDvQAoRPf/RFK3UX/VRbemzvjYGpqqkDW5hS/CY7y4sgFHwZ0T1R
|
||||
fzbuzHECgYEA+kgbWRLatN68IgnM37A0hIgWbF1PDtqh/e7gnYRPghniDzj9WFi/
|
||||
3/9WwfKCKFzjl68nh9W/FFcN9FyXxHjFoKe7Rg5PTWHtQCWQnOB11o1uvcv0gPNv
|
||||
OnXm8x1O/OM49A+YLo7xUfvSPEqx79GVIoMQHbGTpuovr/Brq8SzSj8CgYEA64hm
|
||||
BHedWUbbHOGsgL8g/7KOou36ndYUflR0xIDdDd1JwoEfhWSil71W4zd3ruJy721p
|
||||
MFZIym2rq8dJF9FCq0IVSwBTwPpxU3s9MvjlLAD5CqhO6KT3lve8BhxdAx189DBT
|
||||
DRUqNZZnioVz8hFvqcwXKW6B2fnnrVyozAB4UAkCgYBY9k56P+BrkAxxUOh4zkos
|
||||
na7Sv+v9DKut9j3y33ffd9HJtWkgARPazAkLkWbAcBwZ65FykACGe1cjd9IebQta
|
||||
SqSfhzCbAebx+ShJCuP36nflkNyNBXqQ3h3EZrOP4jh5UB241uhiSs90zNwosWeA
|
||||
R/PvihJAr1daA2xSNu2/wwKBgF6VgdJdbpTBfZBVl/6Dwm6sd9c6FiB4LfalV9bp
|
||||
oNvGd65iSBQ7W4fwAwpv5eIXEezQVSOSIt0XuY7cEqA76rf3a7GYygl/CS9rGCJ2
|
||||
DSHkqh37hOSsCrlXduxFS5zKpLkzBscELtUiNyZLfUpCckMPsGV0+TRdxQm7YhW6
|
||||
QpZxAoGBAIjBjRZ2sSxdcSMihOVVbgcfvJMCOsPgc155FZBtEtO0JSC+QgGhB2z9
|
||||
XRNu00G97TrKcU68kLdi0rse8Gcb4DN+J0t7eRSsyFmdVE+39V630GIpNLGIslrd
|
||||
lHSepln2sJfSmT4tGjjOG1V/7b4jt/Uo8v7wPQH8YmZLMYO89TW1
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1,2 +0,0 @@
|
|||
test1:6UoHxibiMes9DaN8P0aDsM0tRbEBCflRoDaTVYefMHc26BFX7I
|
||||
test2:1xIL8YDbX2sva8QjG734JzSOJVkWhG6HTEp4v82hiJFvfxa1f4
|
Двоичные данные
tests/certs/server_cert.p12
Двоичные данные
tests/certs/server_cert.p12
Двоичный файл не отображается.
|
@ -1,49 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDoDCCAoigAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwaDELMAkGA1UEBhMCUEwx
|
||||
GzAZBgNVBAoMElN0dW5uZWwgRGV2ZWxvcGVyczEQMA4GA1UECwwHUm9vdCBDQTEL
|
||||
MAkGA1UEAwwCQ0ExHTAbBgkqhkiG9w0BCQEWDkNBQGV4YW1wbGUuY29tMB4XDTIx
|
||||
MDMxODEyNTQxOFoXDTI1MDMxODEyNTQxOFowbzELMAkGA1UEBhMCUEwxGzAZBgNV
|
||||
BAoMElN0dW5uZWwgRGV2ZWxvcGVyczEPMA0GA1UECwwGc2VydmVyMQ8wDQYDVQQD
|
||||
DAZzZXJ2ZXIxITAfBgkqhkiG9w0BCQEWEnNlcnZlckBleGFtcGxlLmNvbTCCASIw
|
||||
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALNK+CxahWSi4zH4SQgMJjPjiiI+
|
||||
zG6JTpibWV9Lxuc21b2XRlx9I8xOITsDb3JiKacO6Lg+hWg+EymuyFAE/h5ASmNZ
|
||||
e9pCEmsvCM8XGYyGw18cxOoNK8v+DzAR4XySF6BOcaeaFnInTcbYUnhK0YDSn0P6
|
||||
lyv8Ol76xR/C+y4AvuyoYCjVOzvxY2g3HdjlyA7RwVS9ekYgS5nd0s/qdO91gQ+4
|
||||
imb67HW76bF5LmiCAfZ0XKqHFyvHO5D57QifLq3Kwe6IorTrTSFH/fWre/A/JIji
|
||||
Bt63dGSlxCnfNzQIJYJjJYdU7tz7cKMnpp0avxSCeFZYw8RsAr1L8JunLtsCAwEA
|
||||
AaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQU7L61jETM7BttdLW3uOPJuRqs9uUw
|
||||
HwYDVR0jBBgwFoAUF36fHLAOahK03W/5Q99MEBHAiAowDQYJKoZIhvcNAQELBQAD
|
||||
ggEBAFfZkSmuYMjMfEBzBUudunL2vOeQUsQcH6KROsYaq+lN09aazMKBX8j+VMTL
|
||||
6ZSlVxeM5BCXdD3GvpFb+R4ED8EcrRWKbAiqUJz1tAyjLRyHW2GWqfFpOn5yNonK
|
||||
vsUtZSL+v87V26PGuRs5dQizGkstS2gKx3zFqaKwWdCQE5ldDwT+kDkghvALoGXw
|
||||
IuFt7+QbZjLQvQ/YdCUXjBVdzICVO5WgEePAZ4IO8r20jrda2aP5OFVmUcc+iA8P
|
||||
Rn6jCOfdnNyBDWwm+oEf1WecYxTr0Ly0d3QcOxpAUeQTgT6tZawpllGLkwfrUZFV
|
||||
09YKu45BurR5WZzok/9zyflPv80=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAs0r4LFqFZKLjMfhJCAwmM+OKIj7MbolOmJtZX0vG5zbVvZdG
|
||||
XH0jzE4hOwNvcmIppw7ouD6FaD4TKa7IUAT+HkBKY1l72kISay8IzxcZjIbDXxzE
|
||||
6g0ry/4PMBHhfJIXoE5xp5oWcidNxthSeErRgNKfQ/qXK/w6XvrFH8L7LgC+7Khg
|
||||
KNU7O/FjaDcd2OXIDtHBVL16RiBLmd3Sz+p073WBD7iKZvrsdbvpsXkuaIIB9nRc
|
||||
qocXK8c7kPntCJ8urcrB7oiitOtNIUf99at78D8kiOIG3rd0ZKXEKd83NAglgmMl
|
||||
h1Tu3PtwoyemnRq/FIJ4VljDxGwCvUvwm6cu2wIDAQABAoIBAB6SbwTpHovNdp4j
|
||||
rxhPMghxCTHTsXo7sYo2GyQzwKPWZtXgQKAuunbw75und05yzJVu5mHcT1U6GHxo
|
||||
EEIMx+QSpFySepr53zglmgPt9W5P4GqMdktOmaQ8GwzgT6m1I5AzMBAbJy6p4wpA
|
||||
Arf+UgD8aSnnRfW7GZzud8R1s+zg7Jc4Xi+2UOvSojw8RHcF8GTmiGrhLAD616Cb
|
||||
Yg5sAO2RhNXJwGP3B2kHJEjE8yN1xoOXf2SVjgNtlD1AriQ3TLNQmR8Ecoq7cCVh
|
||||
wYy3DZdIttqAcjL7IvSUnE8zHmQi+gtaHhVol3Z8KDObwj+b0mYgqqVYYRYf2hFP
|
||||
YM156MkCgYEA27eq4L1RIbx4oxOc3XMyiem8Je6ciOvw0kj9r0lwlL/cfn5WgpeM
|
||||
bpbP7a//kfbipQ/FbAyo3FIVCVJN5CgHlRKdHo9IM0x/1U9mpRnhoGF06PooOFwX
|
||||
skbi6FoRkewcGm1GGEEHJksNCdtVYVzGePcLgGfJEX5zuusfqixd/J8CgYEA0OZk
|
||||
k18K2r+9Vlwa3ZB17j6VPqJFtpbN5MSzFf2weyW2yBN3MZQcysukr8q95x2NFSq4
|
||||
fjX68XPgzKCnDfcfszQbaoXFOL6fxTslYuGvXmEUuiqn1J3yKSoG6/GJklR3pGZp
|
||||
R9bLNZDc/5WJ4jXbxrNOZzJ1+8Bkod6l0ule6EUCgYAscsmE0Ye6NXCKPQt82TMe
|
||||
J0TCv7S3FlQPlmiLr2WxEec/R7uki5gDP0stIG+pTbKoBbrAkwcOGyTaT+YmA9sU
|
||||
00Epz36hshYiRv/S4pt8YHrQLts4G5lHnYOF0cLALG27AuQtP+p8Wq52kgKBwcz8
|
||||
561R+qz4dwZeh/ZN7M/OrQKBgQC6MS/hvquhD5dFmvCDHRhP0k4Ztm7mcIFxbvSk
|
||||
HCqpiJLiv57UfMww4NOXr+AVV9yAykQIkjpp7Tunh2V+aA5EHqR1DGgdzKIBHFeV
|
||||
S8yQFX1w9UYDlwfZMtFaiT1yRIEi8fjShBs5UjX4RCPSkOijsPuntW09h1zqfdVV
|
||||
KJZj9QKBgBgSZFAG7WO/bbOYoB95bxSRLyg111OI0nVkWhkHgj1h5n+Lp4n6HGeQ
|
||||
+R4j4tH0oEzQh7fVhfbtA3cs4/met1K5sNm8fPUFNHEyHNu90sbpTeLnIOzSNjX0
|
||||
J44ybnlrZii1DLw0sAP+XmMdKRZ9FS5+krC4yo/uUrdoNTpQ4z0W
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1,53 +0,0 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC23fBHFVaHSAtS
|
||||
UwzLFCyaq36QXoWqqq0nrZdZpjiu6J6I4w/ulVUHTBWchhKEY+71r000Z3H7ZU7W
|
||||
BoQ7QMmW5LAl2xvYcQjBzPdRRIqT32Jjn6WvEzCATZhL6Ja0OPFo5JmO5ns8RXzf
|
||||
V05odEtZ2hGyVJoFdpupZs1IWDL6A0eJ66uBC/MX6F4uhGI+5CJAbyf7SPJMHOKH
|
||||
EvDrTbRb7g9eF7lkybU5jVqnsTyg72W3Etui4H1t3RHADTzvFIvir+xgsyHGAYQQ
|
||||
WCpc24tQ3eOoFG8P1Xt+Y0Drw8nL0EbJUTvvlGIW+lTGqKsi80h/kbIiPkjphQiE
|
||||
ia/3rnBtAgMBAAECggEBAK/xA3BxAEqyr2nqzAFMDMpXvDMNLpARHP5zD47K1fi7
|
||||
iWTtCnQjq6aUtqpdeM12FQC/RInqCYm2ZE6aAHm+EPckWrJhiP4La0CDg2TmjGpP
|
||||
4Cs3/EJhNSYNAj3ur6kArIyefXw3F1TbCpUcPC1VzvXJUYOB0Jr3DjfD2DkF2y4d
|
||||
fzF3K0kc20dwWeUnPKm/ffN3MS7VBwf+pyUcwAKU/Oq6WWOSWGJxzMSPhFObvF5o
|
||||
ZkT7Q5rPBHdtWOey+oWdcKEBfh4FC/kZst8R5LscZ59vN0ZSFDEL+xNqNXdTKsB3
|
||||
5X7spCFmoDWEiaUkHxsW/OA+uIip1ehw/6QMmYsMbuECgYEA3SOyOeD1ojWpQiI6
|
||||
wuMrE6ldD/jk6aaXS9GC1N0uriguAaAI/NNXL89zEMkENrsqcgOBU9qAMbGu6bZ7
|
||||
4LKZra1aRju0MNBhraI/g5gPsjrtooY3hfg0Sn7/Ei/24Uip22K3nYqQp35PqqxC
|
||||
nbPvwRrwSqpCdpAoFBLgsbmwP8kCgYEA07G3t6Rdo7e6arxhELyIHZRh5cV9nbYm
|
||||
CpTCTFSlhB5XTXBy3PrFDxw1FrbHTJKQ0tOVQ19PcBT9BHrsCdAWbpk7r2UiXk4x
|
||||
hl92DST0oZlbCEAPM/xTaAdSxRmGmxtYxWojyWGSncQeA9l9OLpi5rg/KqD5uGm6
|
||||
qHplar3bZYUCgYEAutRyujWWMVJWyrnynT6h4T2gk2L7u290uaireT3ZN2hY3iSg
|
||||
E0JWkd0ZYOAEAF2G0camV/rtfY6ZsXjsFf2umq4v69B7PxZ+v9yo/nvVHwZsSHhO
|
||||
po/5VcsPowUE9naWkvRHHwG3jtrHYfGhYm1oLOSeiOZpupO2WKdOULkJ8AkCgYEA
|
||||
z2eSGMFX4Pw0DzkLXItqTJjBJY5NWURJlxpSFtjj5UKYxE1ErE6g3QIE3YEsWFBM
|
||||
xdH4rq5ltOlLT6VjNuYB5FALEvfiKUUw7nb+wTgQ2XbXooionIU97nEmXed5YuPz
|
||||
IE+ySi5nqFyqD5l5PygVl/iyIoDeyRgFgeWREXh7yMUCgYAg702QxrhdMVN1dwDL
|
||||
BUMdvUbQ2Ad+AhKxTqn9XBDdMQdWkdR//0+emB+9zfscBgNGMU1SU1hlOM8E6Obd
|
||||
nFol+2hAS5w4q/U/KIsZNY00dcZm/aYG/EjPDYSOo1R8dMF9UAx+5An6iSg8U5Wz
|
||||
8TN3/NjT/FC7biSt+/P3QlnUew==
|
||||
-----END PRIVATE KEY-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEQTCCAymgAwIBAgIUB/R3pMEt+vuJcu2Gd035OJy7blEwDQYJKoZIhvcNAQEL
|
||||
BQAwgacxCzAJBgNVBAYTAlBMMRkwFwYDVQQIDBBNYXpvdmlhIFByb3ZpbmNlMQ8w
|
||||
DQYDVQQHDAZXYXJzYXcxGzAZBgNVBAoMElN0dW5uZWwgRGV2ZWxvcGVyczEXMBUG
|
||||
A1UECwwOUHJvdmlzaW9uYWwgQ0ExEjAQBgNVBAMMCWxvY2FsaG9zdDEiMCAGCSqG
|
||||
SIb3DQEJARYTc3R1bm5lbEBleGFtcGxlLmNvbTAeFw0yMTAzMTgxMjU0MTdaFw0y
|
||||
NTAzMTgxMjU0MTdaMIGnMQswCQYDVQQGEwJQTDEZMBcGA1UECAwQTWF6b3ZpYSBQ
|
||||
cm92aW5jZTEPMA0GA1UEBwwGV2Fyc2F3MRswGQYDVQQKDBJTdHVubmVsIERldmVs
|
||||
b3BlcnMxFzAVBgNVBAsMDlByb3Zpc2lvbmFsIENBMRIwEAYDVQQDDAlsb2NhbGhv
|
||||
c3QxIjAgBgkqhkiG9w0BCQEWE3N0dW5uZWxAZXhhbXBsZS5jb20wggEiMA0GCSqG
|
||||
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC23fBHFVaHSAtSUwzLFCyaq36QXoWqqq0n
|
||||
rZdZpjiu6J6I4w/ulVUHTBWchhKEY+71r000Z3H7ZU7WBoQ7QMmW5LAl2xvYcQjB
|
||||
zPdRRIqT32Jjn6WvEzCATZhL6Ja0OPFo5JmO5ns8RXzfV05odEtZ2hGyVJoFdpup
|
||||
Zs1IWDL6A0eJ66uBC/MX6F4uhGI+5CJAbyf7SPJMHOKHEvDrTbRb7g9eF7lkybU5
|
||||
jVqnsTyg72W3Etui4H1t3RHADTzvFIvir+xgsyHGAYQQWCpc24tQ3eOoFG8P1Xt+
|
||||
Y0Drw8nL0EbJUTvvlGIW+lTGqKsi80h/kbIiPkjphQiEia/3rnBtAgMBAAGjYzBh
|
||||
MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJSgbfs9SkZg/XEeUj6nDyGCHkXn
|
||||
MB8GA1UdIwQYMBaAFJSgbfs9SkZg/XEeUj6nDyGCHkXnMA4GA1UdDwEB/wQEAwIB
|
||||
hjANBgkqhkiG9w0BAQsFAAOCAQEAnYdyJUeOS3XgKQ1Yz/wuJQPrhoN67fSSjdy6
|
||||
jmeXFV7wbs0rgrsiWy/Lg6YTHqNzDQUC6/cvTcrh2KxMwbNcgAJd4VxwyKw4mMwu
|
||||
P4htwmE1wSXfrMdckQZ50QnJ6sdf+9fY/xmYtSj0+KVEkIXIgjf25brxcnj5znxD
|
||||
kSWeZt5FCo4/zwcsYLTd22q0k5ynl6LaaVUVCP3C/f0hlHFUJXAKl4kRF4ZwH1is
|
||||
mLLpIZYPjaqla1Au8c512rRP8Txx02n2TPYD4PQmyzvmXWLa0Fi3d37DjHPe3kS+
|
||||
ihMrfXvmT4DtErI32t6gvdiJpnmMWdRk66GTA/Hkeg2i7dSgZQ==
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,4 @@
|
|||
"""An error occured."""
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("Wrong_connection!")
|
|
@ -1,3 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
printf "%-35s\t%s\n" "test $1" "success"
|
|
@ -1,3 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
cat >> "$1"
|
|
@ -1,3 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
echo "$@" > "$1"
|
|
@ -1,2 +0,0 @@
|
|||
GET / HTTP/1.0
|
||||
|
115
tests/make_test
115
tests/make_test
|
@ -1,115 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
result=0
|
||||
count=0
|
||||
fail=0
|
||||
skip=0
|
||||
|
||||
result_path=$(pwd)
|
||||
cd $(dirname "$0")
|
||||
script_path=$(pwd)
|
||||
cd "${result_path}"
|
||||
result_path="${result_path}/logs"
|
||||
|
||||
autodetection() {
|
||||
|
||||
result=0
|
||||
if [ -n "$(command -v ncat)" ]
|
||||
then # ncat
|
||||
mynetcat="ncat"
|
||||
elif [ -n "$(command -v nc)" ]
|
||||
then # nc
|
||||
mynetcat="nc"
|
||||
else # netcat is required
|
||||
printf "%s\n" "ncat / nc not found in \$PATH"
|
||||
result=1
|
||||
fi
|
||||
|
||||
if uname -r | grep -q Microsoft && test -f /mnt/c/Windows/System32/netstat.exe && ! /mnt/c/Windows/System32/netstat.exe -a -n 2>&1 | grep -q -e "usage" -e "invalid" -e "illegal" -e "command not found"
|
||||
then
|
||||
mynetstat="/mnt/c/Windows/System32/netstat.exe"
|
||||
elif [ -n "$(command -v netstat)" ] && ! netstat -a -n 2>&1 | grep -q -e "usage" -e "invalid" -e "illegal" -e "command not found"
|
||||
then
|
||||
mynetstat="netstat"
|
||||
elif [ -n "$(command -v ss)" ] && ! ss -a -n -l 2>&1 | grep -q -e "usage" -e "invalid" -e "illegal" -e "command not found"
|
||||
then
|
||||
mynetstat="ss"
|
||||
elif [ -n "$(command -v lsof)" ] && ! lsof -i -n -P 2>&1 | grep -q -e "usage" -e "invalid" -e "illegal" -e "command not found"
|
||||
then
|
||||
mynetstat="lsof"
|
||||
else # netstat / ss / lsof is required
|
||||
printf "%s\n" "netstat / ss / lsof not found in \$PATH or some option error"
|
||||
result=1
|
||||
fi
|
||||
|
||||
if [ -n "$(command -v stdbuf)" ]
|
||||
then
|
||||
mybuffer="stdbuf"
|
||||
elif [ -n "$(command -v unbuffer)" ]
|
||||
then
|
||||
mybuffer="unbuffer"
|
||||
else
|
||||
mybuffer=""
|
||||
fi
|
||||
|
||||
if [ -n "$(command -v python3)" ]
|
||||
then
|
||||
mypython=python3
|
||||
elif [ -n "$(command -v python)" ] && python -V | grep -q "Python 3"
|
||||
then
|
||||
mypython=python
|
||||
else
|
||||
mypython=""
|
||||
fi
|
||||
return $result
|
||||
}
|
||||
|
||||
if autodetection
|
||||
then
|
||||
rm -rf "${result_path}"
|
||||
mkdir "${result_path}"
|
||||
cd "${result_path}"
|
||||
date > "results.log"
|
||||
../../src/stunnel -version 2>> "results.log"
|
||||
if [ -n "$(command -v fips-mode-setup)" ]
|
||||
then
|
||||
printf "\n" >> "results.log"
|
||||
fips-mode-setup --check 1>> "results.log"
|
||||
fi
|
||||
printf "\n%s\n" "Testing..." >> "results.log"
|
||||
head -n5 "results.log"
|
||||
if ! grep -q "solaris" "results.log"
|
||||
then
|
||||
for plik in ${script_path}/recipes/*
|
||||
do
|
||||
/bin/sh $plik "$mynetcat" "$mynetstat" "$mybuffer" "$mypython"
|
||||
state=$?
|
||||
if [ "$state" -eq 0 ]
|
||||
then # $state=0
|
||||
count=$((count + 1))
|
||||
elif [ "$state" -eq 125 ]
|
||||
then # $state=125
|
||||
skip=$((skip + 1))
|
||||
else # $state=1
|
||||
fail=$((fail + 1))
|
||||
result=1
|
||||
fi
|
||||
done
|
||||
if [ $count -eq 0 ]
|
||||
then # no test was done
|
||||
result=1
|
||||
fi
|
||||
printf "%s\n" "summary: success $count, skip $skip, fail $fail"
|
||||
printf "%s\n" "summary: success $count, skip $skip, fail $fail" >> "results.log"
|
||||
printf "%s\n" "./make_test finished"
|
||||
cd ..
|
||||
else # skip make test for solaris
|
||||
printf "%s\n" "./make_test skipped"
|
||||
printf "%s\n" "./make_test skipped" >> "results.log"
|
||||
#result=125
|
||||
fi
|
||||
else # netcat not found
|
||||
printf "%s\n" "./make_test skipped"
|
||||
#result=125
|
||||
fi
|
||||
exit $result
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,140 @@
|
|||
"""A plugin structure"""
|
||||
|
||||
import dataclasses
|
||||
import inspect
|
||||
import os
|
||||
import pkgutil
|
||||
|
||||
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class LogEvent():
|
||||
"""The base class for an event."""
|
||||
etype: str
|
||||
level: int
|
||||
log: str
|
||||
|
||||
|
||||
class Plugin():
|
||||
"""Base class that each plugin must inherit from. Within this class
|
||||
you must define the methods that all of your plugins must implement
|
||||
"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
def __init__(self):
|
||||
self.description = 'UNKNOWN'
|
||||
|
||||
async def perform_operation(self, cfg, logger):
|
||||
"""The method that we expect all plugins to implement. This is the
|
||||
method that our framework will call
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class PluginCollection():
|
||||
"""Upon creation, this class will read the plugins package for modules
|
||||
that contain a class definition that is inheriting from the Plugin class
|
||||
"""
|
||||
|
||||
def __init__(self, cfg, logger, plugin_package):
|
||||
"""Constructor that initiates the reading of all available plugins
|
||||
when an instance of the PluginCollection object is created
|
||||
"""
|
||||
self.plugin_package = plugin_package
|
||||
self.cfg = cfg
|
||||
self.logger = logger
|
||||
self.plugins = []
|
||||
self.seen_paths = []
|
||||
|
||||
|
||||
def __await__(self):
|
||||
return self.async_init().__await__()
|
||||
|
||||
|
||||
async def async_init(self):
|
||||
"""Constructor that initiates the reading of all available plugins
|
||||
when an instance of the PluginCollection object is created
|
||||
"""
|
||||
await self.reload_plugins()
|
||||
await self.apply_all_plugins()
|
||||
|
||||
|
||||
async def reload_plugins(self):
|
||||
"""Reset the list of all plugins and initiate the walk over the main
|
||||
provided plugin package to load all available plugins
|
||||
"""
|
||||
await self.cfg.mainq.put(
|
||||
LogEvent(
|
||||
etype="log",
|
||||
level=10,
|
||||
log=f'[plugins] Looking for plugins under package {self.plugin_package}'
|
||||
)
|
||||
)
|
||||
await self.walk_package(self.plugin_package)
|
||||
|
||||
|
||||
async def apply_all_plugins(self):
|
||||
"""Apply all of the plugins
|
||||
"""
|
||||
await self.cfg.mainq.put(
|
||||
LogEvent(
|
||||
etype="log",
|
||||
level=10,
|
||||
log='[plugins] ----- Applying all plugins -----'
|
||||
)
|
||||
)
|
||||
for plugin in self.plugins:
|
||||
await self.cfg.mainq.put(LogEvent(etype="log", level=20, log=""))
|
||||
await self.cfg.mainq.put(
|
||||
LogEvent(
|
||||
etype="log",
|
||||
level=20,
|
||||
log=f'[plugins] >>>>> Applying \'{plugin.description}\' <<<<<'
|
||||
)
|
||||
)
|
||||
await plugin.perform_operation(self.cfg, self.logger)
|
||||
|
||||
async def walk_package(self, package):
|
||||
"""Recursively walk the supplied package to retrieve all plugins
|
||||
"""
|
||||
imported_package = __import__(package, fromlist=['blah'])
|
||||
|
||||
for _, pluginname, ispkg in pkgutil.iter_modules(
|
||||
imported_package.__path__, imported_package.__name__ + '.'
|
||||
):
|
||||
if not ispkg:
|
||||
plugin_module = __import__(pluginname, fromlist=['blah'])
|
||||
clsmembers = inspect.getmembers(plugin_module, inspect.isclass)
|
||||
for (_, cls) in clsmembers:
|
||||
# Only add classes that are a sub class of Plugin, but NOT Plugin itself
|
||||
if issubclass(cls, Plugin) & (cls is not Plugin):
|
||||
await self.cfg.mainq.put(
|
||||
LogEvent(
|
||||
etype="log",
|
||||
level=10,
|
||||
log=f'[plugins] Found plugin class: {cls.__module__}.{cls.__name__}'
|
||||
)
|
||||
)
|
||||
self.plugins.append(cls())
|
||||
|
||||
|
||||
# Now that we have looked at all the modules in the current package, start looking
|
||||
# recursively for additional modules in sub packages
|
||||
all_current_paths = []
|
||||
if isinstance(imported_package.__path__, str):
|
||||
all_current_paths.append(imported_package.__path__)
|
||||
else:
|
||||
all_current_paths.extend(imported_package.__path__)
|
||||
|
||||
for pkg_path in all_current_paths:
|
||||
if pkg_path not in self.seen_paths:
|
||||
self.seen_paths.append(pkg_path)
|
||||
|
||||
# Get all sub directory of the current package path directory
|
||||
child_pkgs = [
|
||||
p for p in os.listdir(pkg_path)
|
||||
if os.path.isdir(os.path.join(pkg_path, p))
|
||||
]
|
||||
|
||||
# For each sub directory, apply the walk_package method recursively
|
||||
for child_pkg in child_pkgs:
|
||||
await self.walk_package(package + '.' + child_pkg)
|
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -0,0 +1,139 @@
|
|||
"""stunnel client tests"""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
from plugin_collection import Plugin
|
||||
from maketest import (
|
||||
Config,
|
||||
StunnelAcceptConnect
|
||||
)
|
||||
|
||||
|
||||
class StunnelTest(StunnelAcceptConnect):
|
||||
"""Base class for stunnel client tests."""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.ssl_server = True
|
||||
self.params.services = ['client']
|
||||
|
||||
|
||||
class CertTest(StunnelTest):
|
||||
""" Checking if the cert option ensures a client certificate.
|
||||
The success is expected because the client presents a certificate.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '011. Test \"cert\" option'
|
||||
self.params.context = 'cert_required'
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_client_cfgfile(
|
||||
self, cfg: Config, ports: list, service: str
|
||||
) -> (pathlib.Path, pathlib.Path):
|
||||
"""Create a configuration file for a stunnel client."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
client = yes
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{ports[0]}
|
||||
cert = {cfg.certdir}/client_cert.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_client.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile, os.devnull
|
||||
|
||||
|
||||
|
||||
class FailureCertTest(StunnelTest):
|
||||
""" Checking if the cert option ensures a client certificate.
|
||||
The failure is expected because the client does not present any certificate.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '012. Test no \"cert\" option'
|
||||
self.params.context = 'cert_required'
|
||||
self.events.count = 1
|
||||
self.events.success = [
|
||||
"Client received unexpected message",
|
||||
"Connection reset by peer"
|
||||
]
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
#"Connection reset by peer",
|
||||
#"Connection lost",
|
||||
#"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_client_cfgfile(
|
||||
self, cfg: Config, ports: list, service: str
|
||||
) -> (pathlib.Path, pathlib.Path):
|
||||
"""Create a configuration file for a stunnel client."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
client = yes
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{ports[0]}
|
||||
;client does not present any certificate
|
||||
;cert = {cfg.certdir}/client_cert.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_client.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile, os.devnull
|
||||
|
||||
|
||||
|
||||
class StunnelClientTest(Plugin):
|
||||
"""Stunnel client tests
|
||||
HTTP client --> stunnel client --> HTTPS server
|
||||
"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.description = 'Existing certificate'
|
||||
|
||||
|
||||
async def perform_operation(self, cfg: Config, logger: logging.Logger) -> None:
|
||||
"""Run tests"""
|
||||
stunnel = CertTest(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
||||
|
||||
stunnel = FailureCertTest(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
|
@ -0,0 +1,133 @@
|
|||
"""stunnel server tests"""
|
||||
|
||||
import logging
|
||||
import pathlib
|
||||
from plugin_collection import Plugin
|
||||
from maketest import (
|
||||
Config,
|
||||
StunnelAcceptConnect
|
||||
)
|
||||
|
||||
|
||||
class StunnelTest(StunnelAcceptConnect):
|
||||
"""Base class for stunnel server tests."""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.ssl_client = True
|
||||
self.params.services = ['server']
|
||||
|
||||
|
||||
class RequireCertTest(StunnelTest):
|
||||
"""Checking if the requireCert option requires a client certificate.
|
||||
The success is expected because the client presents any but incorrect certificate.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '021. Test \"requireCert\" option'
|
||||
self.params.context = 'load_wrong_cert'
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
requireCert = yes
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class FailureRequireCertTest(StunnelTest):
|
||||
"""Checking if the requireCert option requires a client certificate.
|
||||
The failure is expected because the client does not present any certificate.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '022. Failure test \"requireCert\" option'
|
||||
self.events.count = 1
|
||||
self.events.success = [
|
||||
"peer did not return a certificate"
|
||||
]
|
||||
self.events.failure = [
|
||||
#"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
#"Connection reset by peer",
|
||||
#"Connection lost",
|
||||
#"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
requireCert = yes
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class StunnelServerTest(Plugin):
|
||||
"""Stunnel server tests:
|
||||
HTTPS client --> stunnel server --> HTTP server
|
||||
"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.description = 'Require certificate'
|
||||
|
||||
|
||||
async def perform_operation(self, cfg: Config, logger: logging.Logger) -> None:
|
||||
"""Run tests"""
|
||||
stunnel = RequireCertTest(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
||||
|
||||
stunnel = FailureRequireCertTest(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
|
@ -0,0 +1,138 @@
|
|||
"""stunnel server tests"""
|
||||
|
||||
import logging
|
||||
import pathlib
|
||||
from plugin_collection import Plugin
|
||||
from maketest import (
|
||||
Config,
|
||||
StunnelAcceptConnect
|
||||
)
|
||||
|
||||
|
||||
class StunnelTest(StunnelAcceptConnect):
|
||||
"""Base class for stunnel server tests."""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.ssl_client = True
|
||||
self.params.services = ['server']
|
||||
|
||||
|
||||
class VerifyPeer(StunnelTest):
|
||||
"""Checking if the verifyPeer option verifies the peer certificate.
|
||||
The peer certificate is stored in the file specified with CAfile.
|
||||
The success is expected because the client presents the valid certificate.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '031. Test \"verifyPeer\" option'
|
||||
self.params.context = 'load_correct_cert'
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
verifyPeer = yes
|
||||
CAfile = {cfg.certdir}/PeerCerts.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class FailureVerifyPeer(StunnelTest):
|
||||
"""Checking if the verifyPeer option verifies the peer certificate.
|
||||
The valid peer certificate is stored in the file specified with CAfile.
|
||||
The failure is expected because the client presents an incorrect certificate.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '032. Failure test \"verifyPeer\" option'
|
||||
self.params.context = 'load_wrong_cert'
|
||||
self.events.count = 1
|
||||
self.events.success = [
|
||||
"certificate verify failed"
|
||||
]
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
#"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
#"Connection reset by peer",
|
||||
#"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
verifyPeer = yes
|
||||
CAfile = {cfg.certdir}/PeerCerts.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class StunnelServerTest(Plugin):
|
||||
"""Stunnel server tests:
|
||||
HTTPS client --> stunnel server --> HTTP server
|
||||
"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.description = 'Verify peer'
|
||||
|
||||
|
||||
async def perform_operation(self, cfg: Config, logger: logging.Logger) -> None:
|
||||
"""Run tests"""
|
||||
stunnel = VerifyPeer(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
||||
|
||||
stunnel = FailureVerifyPeer(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
|
@ -0,0 +1,138 @@
|
|||
"""stunnel server tests"""
|
||||
|
||||
import logging
|
||||
import pathlib
|
||||
from plugin_collection import Plugin
|
||||
from maketest import (
|
||||
Config,
|
||||
StunnelAcceptConnect
|
||||
)
|
||||
|
||||
|
||||
class StunnelTest(StunnelAcceptConnect):
|
||||
"""Base class for stunnel server tests."""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.ssl_client = True
|
||||
self.params.services = ['server']
|
||||
|
||||
|
||||
class VerifyChain(StunnelTest):
|
||||
"""Checking if the verifyChain option verifies the peer certificate starting from the root CA.
|
||||
The self-signed root CA certificate is stored in the file specified with CAfile.
|
||||
The success is expected because python client presents the valid certificate.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '041. Test \"verifyChain\" option'
|
||||
self.params.context = 'load_correct_cert'
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
verifyChain = yes
|
||||
CAfile = {cfg.certdir}/CACert.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class FailureVerifyChain(StunnelTest):
|
||||
"""Checking if the verifyChain option verifies the peer certificate starting from the root CA.
|
||||
The self-signed root CA certificate is stored in the file specified with CAfile.
|
||||
The failure is expected because python client presents an incorrect certificate.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '042. Failure test \"verifyChain\" option'
|
||||
self.params.context = 'load_wrong_cert'
|
||||
self.events.count = 1
|
||||
self.events.success = [
|
||||
"certificate verify failed"
|
||||
]
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
#"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
#"Connection reset by peer",
|
||||
#"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
verifyChain = yes
|
||||
CAfile = {cfg.certdir}/CACert.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class StunnelServerTest(Plugin):
|
||||
"""Stunnel server tests:
|
||||
HTTPS client --> stunnel server --> HTTP server
|
||||
"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.description = 'Verify chain'
|
||||
|
||||
|
||||
async def perform_operation(self, cfg: Config, logger: logging.Logger) -> None:
|
||||
"""Run tests"""
|
||||
stunnel = VerifyChain(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
||||
|
||||
stunnel = FailureVerifyChain(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
|
@ -0,0 +1,144 @@
|
|||
"""stunnel server tests"""
|
||||
|
||||
import logging
|
||||
import pathlib
|
||||
from plugin_collection import Plugin
|
||||
from maketest import (
|
||||
Config,
|
||||
StunnelAcceptConnect
|
||||
)
|
||||
|
||||
|
||||
class StunnelTest(StunnelAcceptConnect):
|
||||
"""Base class for stunnel server tests."""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.ssl_client = True
|
||||
self.params.services = ['server']
|
||||
|
||||
|
||||
class VerifyCRL(StunnelTest):
|
||||
"""Checking if the CRL is verified.
|
||||
The verifyChain option verifies the peer certificate starting from the root CA.
|
||||
The self-signed root CA certificate is stored in the file specified with CAfile.
|
||||
Certificate Revocation Lists file is stored in the file specified with CRLfile.
|
||||
The success is expected because python client presents the valid certificate.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '051. CRL file with valid certificate'
|
||||
self.params.context = 'load_correct_cert'
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
verifyChain = yes
|
||||
CAfile = {cfg.certdir}/CACert.pem
|
||||
CRLfile = {cfg.certdir}/CACertCRL.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class FailureVerifyCRL(StunnelTest):
|
||||
"""Checking if the CRL is verified.
|
||||
The verifyChain option verifies the peer certificate starting from the root CA.
|
||||
The self-signed root CA certificate is stored in the file specified with CAfile.
|
||||
Certificate Revocation Lists file is stored in the file specified with CRLfile.
|
||||
The failure is expected because the python client presents the revoked certificate.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '052. CRL file with revoked certificate'
|
||||
self.params.context = 'load_revoked_cert'
|
||||
self.events.count = 1
|
||||
self.events.success = [
|
||||
"certificate verify failed"
|
||||
]
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
#"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
#"Connection reset by peer",
|
||||
#"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
verifyChain = yes
|
||||
CAfile = {cfg.certdir}/CACert.pem
|
||||
CRLfile = {cfg.certdir}/CACertCRL.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class StunnelServerTest(Plugin):
|
||||
"""Stunnel server tests:
|
||||
HTTPS client --> stunnel server --> HTTP server
|
||||
"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.description = 'Verify CRL file'
|
||||
|
||||
|
||||
async def perform_operation(self, cfg: Config, logger: logging.Logger) -> None:
|
||||
"""Run tests"""
|
||||
stunnel = VerifyCRL(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
||||
|
||||
stunnel = FailureVerifyCRL(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
|
@ -0,0 +1,176 @@
|
|||
"""stunnel client-server tests"""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
from plugin_collection import Plugin
|
||||
from maketest import (
|
||||
Config,
|
||||
StunnelAcceptConnect
|
||||
)
|
||||
|
||||
|
||||
class StunnelTest(StunnelAcceptConnect):
|
||||
"""Base class for stunnel client-server tests."""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.services = ['server', 'client']
|
||||
|
||||
|
||||
class PSKSecrets(StunnelTest):
|
||||
"""Checking if the PSK authentication works properly.
|
||||
PSK identities and corresponding keys are stored in files specified with PSKsecrets.
|
||||
The success is expected because the client presents the valid PSK.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '061. Test \"PSKsecrets\" option'
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_client_cfgfile(
|
||||
self, cfg: Config, ports: list, service: str
|
||||
) -> (pathlib.Path, pathlib.Path):
|
||||
"""Create a configuration file for a stunnel client."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
client = yes
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{ports[1]}
|
||||
PSKsecrets = {cfg.certdir}/psk1.txt
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_client.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile, os.devnull
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
requireCert = yes
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
PSKsecrets = {cfg.certdir}/secrets.txt
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class FailurePSKSecrets(StunnelTest):
|
||||
"""Checking if the PSK authentication works properly.
|
||||
PSK identities and corresponding keys are stored in files specified with PSKsecrets.
|
||||
The failure is expected because the client presented an incorrect key.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '062. Failure test \"PSKsecrets\" option'
|
||||
self.events.count = 1
|
||||
self.events.success = [
|
||||
"binder does not verify"
|
||||
]
|
||||
self.events.failure = [
|
||||
#"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
#"Connection reset by peer",
|
||||
#"Connection lost",
|
||||
#"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_client_cfgfile(
|
||||
self, cfg: Config, ports: list, service: str
|
||||
) -> (pathlib.Path, pathlib.Path):
|
||||
"""Create a configuration file for a stunnel client."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
client = yes
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{ports[1]}
|
||||
PSKsecrets = {cfg.certdir}/psk2.txt
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_client.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile, os.devnull
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
requireCert = yes
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
PSKsecrets = {cfg.certdir}/secrets.txt
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class StunnelClientServerTest(Plugin):
|
||||
"""Stunnel client-server tests
|
||||
HTTP client --> stunnel client --> stunnel server --> HTTP server
|
||||
"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.description = 'PSK authentication'
|
||||
|
||||
|
||||
async def perform_operation(self, cfg: Config, logger: logging.Logger) -> None:
|
||||
"""Run tests"""
|
||||
stunnel = PSKSecrets(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
||||
|
||||
stunnel = FailurePSKSecrets(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
|
@ -0,0 +1,81 @@
|
|||
"""stunnel server tests"""
|
||||
|
||||
import logging
|
||||
import pathlib
|
||||
from plugin_collection import Plugin
|
||||
from maketest import (
|
||||
Config,
|
||||
StunnelAcceptConnect
|
||||
)
|
||||
|
||||
|
||||
class StunnelTest(StunnelAcceptConnect):
|
||||
"""Base class for stunnel server tests."""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.ssl_client = True
|
||||
self.params.services = ['server']
|
||||
|
||||
|
||||
class Certp12Test(StunnelTest):
|
||||
"""Checking if the file containing certificates used by stunnel to authenticate
|
||||
itself against the remote client may be in the P12 format.
|
||||
The success is expected because the server presents the valid certificate in the P12 format.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '071. Test PKCS#12 certificate'
|
||||
self.params.context = 'load_verify_locations"'
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.p12
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class StunnelServerTest(Plugin):
|
||||
"""Stunnel server tests:
|
||||
HTTPS client --> stunnel server --> HTTP server
|
||||
"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.description = 'Existing PKCS#12 certificate'
|
||||
|
||||
|
||||
async def perform_operation(self, cfg: Config, logger: logging.Logger) -> None:
|
||||
"""Run tests"""
|
||||
stunnel = Certp12Test(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
|
@ -0,0 +1,98 @@
|
|||
"""stunnel client-server tests"""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
from plugin_collection import Plugin
|
||||
from maketest import (
|
||||
Config,
|
||||
StunnelAcceptConnect
|
||||
)
|
||||
|
||||
|
||||
class StunnelTest(StunnelAcceptConnect):
|
||||
"""Base class for stunnel client-server tests."""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.services = ['server', 'client']
|
||||
|
||||
|
||||
class IPv6Test(StunnelTest):
|
||||
""" Checking if IPv6 is supported.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '081. Test IPv6 support'
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_client_cfgfile(
|
||||
self, cfg: Config, ports: list, service: str
|
||||
) -> (pathlib.Path, pathlib.Path):
|
||||
"""Create a configuration file for a stunnel client."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
client = yes
|
||||
accept = 127.0.0.1:0
|
||||
connect = ::1:{ports[1]}
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_client.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile, os.devnull
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
accept = ::1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class StunnelClientTest(Plugin):
|
||||
"""Stunnel client-server tests
|
||||
HTTP client --> stunnel client --> stunnel server --> HTTP server
|
||||
"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.description = 'IPv6 support'
|
||||
|
||||
|
||||
async def perform_operation(self, cfg: Config, logger: logging.Logger) -> None:
|
||||
"""Run tests"""
|
||||
stunnel = IPv6Test(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
|
@ -0,0 +1,82 @@
|
|||
"""stunnel server tests"""
|
||||
|
||||
import logging
|
||||
import pathlib
|
||||
from plugin_collection import Plugin
|
||||
from maketest import (
|
||||
Config,
|
||||
StunnelAcceptConnect
|
||||
)
|
||||
|
||||
|
||||
class StunnelTest(StunnelAcceptConnect):
|
||||
"""Base class for stunnel server tests."""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.ssl_client = True
|
||||
self.params.services = ['server']
|
||||
|
||||
|
||||
class BindingTest(StunnelTest):
|
||||
"""Checking if the service does't refuse to start if binding fails for some addresses:ports.
|
||||
Sample log expected:
|
||||
LOG5[ui]: Binding service [server] to 127.0.0.1:43293: Address already in use (98)
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '091. Binding server'
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:{port}
|
||||
accept = 127.0.0.1:0
|
||||
accept = 127.0.0.1:{port}
|
||||
connect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class StunnelServerTest(Plugin):
|
||||
"""Stunnel server tests:
|
||||
HTTPS client --> stunnel server --> HTTP server
|
||||
"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.description = 'Binding service'
|
||||
|
||||
|
||||
async def perform_operation(self, cfg: Config, logger: logging.Logger) -> None:
|
||||
"""Run tests"""
|
||||
stunnel = BindingTest(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
|
@ -0,0 +1,108 @@
|
|||
"""stunnel client-server tests"""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
from plugin_collection import Plugin
|
||||
from maketest import (
|
||||
Config,
|
||||
StunnelAcceptConnect
|
||||
)
|
||||
|
||||
|
||||
class StunnelTest(StunnelAcceptConnect):
|
||||
"""Base class for stunnel client-server tests."""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.services = ['server', 'client']
|
||||
|
||||
|
||||
class FIPSTest(StunnelTest):
|
||||
""" Checking FIPS mode.
|
||||
The success is expected.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '101. Test FIPS mode'
|
||||
self.events.skip = [
|
||||
"FIPS provider not available",
|
||||
"fips mode not supported",
|
||||
r"FIPS PROVIDER.*could not load the shared library"
|
||||
]
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_client_cfgfile(
|
||||
self, cfg: Config, ports: list, service: str
|
||||
) -> (pathlib.Path, pathlib.Path):
|
||||
"""Create a configuration file for a stunnel client."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
fips = yes
|
||||
|
||||
[{service}]
|
||||
client = yes
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{ports[1]}
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_client.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile, os.devnull
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
fips = yes
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class StunnelClientServerTest(Plugin):
|
||||
"""Stunnel client-server tests
|
||||
HTTP client --> stunnel client --> stunnel server --> HTTP server
|
||||
"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.description = 'FIPS mode'
|
||||
|
||||
|
||||
async def perform_operation(self, cfg: Config, logger: logging.Logger) -> None:
|
||||
"""Run tests"""
|
||||
stunnel = FIPSTest(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
|
@ -0,0 +1,214 @@
|
|||
"""stunnel server tests"""
|
||||
|
||||
import logging
|
||||
import pathlib
|
||||
from plugin_collection import Plugin
|
||||
from maketest import (
|
||||
Config,
|
||||
ExpectedConfigurationFailure
|
||||
)
|
||||
|
||||
|
||||
class StunnelTest(ExpectedConfigurationFailure):
|
||||
"""Base class for stunnel server tests."""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.ssl_client = True
|
||||
self.params.services = ['server']
|
||||
|
||||
|
||||
class FailureCipherFIPS(StunnelTest):
|
||||
"""Checking FIPS mode.
|
||||
The cipher "CAMELLIA256-SHA" (TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA256)
|
||||
is unavailable if FIPS is enabled.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '111. Failure FIPS mode with unavailable cipher'
|
||||
self.events.skip = [
|
||||
"FIPS provider not available",
|
||||
"fips mode not supported",
|
||||
r"FIPS PROVIDER.*could not load the shared library"
|
||||
]
|
||||
self.events.count = 1
|
||||
self.events.success = [
|
||||
"no cipher match"
|
||||
]
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
#"Something went wrong: stunnel 'server' failed",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
fips = yes
|
||||
ciphers = CAMELLIA256-SHA
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class FailureCiphersuitesFIPS(StunnelTest):
|
||||
"""Checking FIPS mode.
|
||||
The ciphersuite "TLS_CHACHA20_POLY1305_SHA256" is unavailable if FIPS is enabled.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '112. Failure FIPS mode with unavailable ciphersuite'
|
||||
self.events.skip = [
|
||||
"FIPS provider not available",
|
||||
"fips mode not supported",
|
||||
r"FIPS PROVIDER.*could not load the shared library"
|
||||
]
|
||||
self.events.count = 1
|
||||
self.events.success = [
|
||||
"disabled for FIPS",
|
||||
"no ciphers available"
|
||||
]
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
fips = yes
|
||||
ciphersuites = TLS_CHACHA20_POLY1305_SHA256
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
|
||||
|
||||
class FailureEllipticCurveFIPS(StunnelTest):
|
||||
""" Checking FIPS mode.
|
||||
The elliptic curve "sect163r1" is unavailable if FIPS is enabled.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '113. Failure FIPS mode with unavailable elliptic curve'
|
||||
self.events.skip = [
|
||||
"FIPS provider not available",
|
||||
"fips mode not supported",
|
||||
r"FIPS PROVIDER.*could not load the shared library"
|
||||
]
|
||||
self.events.count = 1
|
||||
self.events.success = [
|
||||
"no suitable key share",
|
||||
"Invalid groups list in 'curves'"
|
||||
]
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
fips = yes
|
||||
curves = sect163r1
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class StunnelServerTest(Plugin):
|
||||
"""Stunnel server tests:
|
||||
HTTPS client --> stunnel server --> HTTP server
|
||||
"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.description = 'FIPS mode cipher'
|
||||
|
||||
|
||||
async def perform_operation(self, cfg: Config, logger: logging.Logger) -> None:
|
||||
"""Run tests"""
|
||||
stunnel = FailureCipherFIPS(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
||||
|
||||
stunnel = FailureCiphersuitesFIPS(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
||||
|
||||
stunnel = FailureEllipticCurveFIPS(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
|
@ -0,0 +1,196 @@
|
|||
"""stunnel client-server tests"""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
from plugin_collection import Plugin
|
||||
from maketest import (
|
||||
Config,
|
||||
StunnelAcceptConnect
|
||||
)
|
||||
|
||||
|
||||
class StunnelTest(StunnelAcceptConnect):
|
||||
"""Base class for stunnel client-server tests."""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.services = ['server_virtual', 'client']
|
||||
|
||||
|
||||
class SNITest(StunnelTest):
|
||||
"""Use the service as a slave service (a name-based virtual server)
|
||||
for Server Name Indication TLS extension.
|
||||
SERVICE_NAME (server_virtual) specifies the master service that
|
||||
accepts client connections with the accept option.
|
||||
SERVER_NAME_PATTERN (*.mydomain.com) specifies the host name to be redirected.
|
||||
The success is expected because the client presents the sni pattern (sni.mydomain.com)
|
||||
corresponding with SERVER_NAME_PATTERN (*.mydomain.com).
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '121. Test \"sni\" option'
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_client_cfgfile(
|
||||
self, cfg: Config, ports: list, service: str
|
||||
) -> (pathlib.Path, pathlib.Path):
|
||||
"""Create a configuration file for a stunnel client."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
client = yes
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{ports[1]}
|
||||
sni = sni.mydomain.com
|
||||
cert = {cfg.certdir}/client_cert.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_client.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile, os.devnull
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
exec = {cfg.pythondir}
|
||||
execArgs = python3 {cfg.scriptdir}/error.py
|
||||
|
||||
[sni]
|
||||
connect = 127.0.0.1:{port}
|
||||
sni = server_virtual:*.mydomain.com
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
verifyPeer = yes
|
||||
CAfile = {cfg.certdir}/PeerCerts.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class FailureSNITest(StunnelTest):
|
||||
"""Use the service as a slave service (a name-based virtual server)
|
||||
for Server Name Indication TLS extension.
|
||||
SERVICE_NAME (server_virtual) specifies the master service that
|
||||
accepts client connections with the accept option.
|
||||
SERVER_NAME_PATTERN sni.mydomain.com) specifies the host name to be redirected.
|
||||
The success is expected because the client doesn't present any sni pattern.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '122. Failure test \"sni\" option'
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_client_cfgfile(
|
||||
self, cfg: Config, ports: list, service: str
|
||||
) -> (pathlib.Path, pathlib.Path):
|
||||
"""Create a configuration file for a stunnel client."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
client = yes
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{ports[1]}
|
||||
;the client doesn't present any sni pattern
|
||||
;sni = sni.mydomain.com
|
||||
cert = {cfg.certdir}/client_cert.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_client.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile, os.devnull
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
verifyPeer = yes
|
||||
CAfile = {cfg.certdir}/PeerCerts.pem
|
||||
|
||||
[sni]
|
||||
sni = server_virtual:*.mydomain.com
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
exec = {cfg.pythondir}
|
||||
execArgs = python3 {cfg.scriptdir}/error.py
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class StunnelClientServerTest(Plugin):
|
||||
"""Stunnel client-server tests
|
||||
HTTP client --> stunnel client --> stunnel server --> HTTP server
|
||||
"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.description = 'Server Name Indication'
|
||||
|
||||
|
||||
async def perform_operation(self, cfg: Config, logger: logging.Logger) -> None:
|
||||
"""Run tests"""
|
||||
stunnel = SNITest(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
||||
|
||||
stunnel = FailureSNITest(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
|
@ -0,0 +1,351 @@
|
|||
"""stunnel client-server tests"""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
from plugin_collection import Plugin
|
||||
from maketest import (
|
||||
Config,
|
||||
StunnelAcceptConnect
|
||||
)
|
||||
|
||||
|
||||
class StunnelTest(StunnelAcceptConnect):
|
||||
"""Base class for stunnel client-server tests."""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.services = ['server', 'client']
|
||||
self.params.conn_num = 3
|
||||
|
||||
|
||||
class ResumePSK(StunnelTest):
|
||||
"""Checking if the PSK authentication works properly when the session is resumed.
|
||||
We expect exactly 2 "TLS accepted: previous session reused" to be logged
|
||||
by the [server] service because the client presents the valid PSK.
|
||||
PSK identities and corresponding keys are stored in files specified with PSKsecrets.
|
||||
This resumption of the session does not work for the FORK threading model.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '131. Resume session with PSK authentication'
|
||||
self.events.skip = [
|
||||
"FORK"
|
||||
]
|
||||
self.events.count = 2
|
||||
self.events.success = [
|
||||
"TLS accepted: previous session reused"
|
||||
]
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
#"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_client_cfgfile(
|
||||
self, cfg: Config, ports: list, service: str
|
||||
) -> (pathlib.Path, pathlib.Path):
|
||||
"""Create a configuration file for a stunnel client."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
client = yes
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{ports[1]}
|
||||
PSKsecrets = {cfg.certdir}/psk1.txt
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_client.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile, os.devnull
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
PSKsecrets = {cfg.certdir}/secrets.txt
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class ResumeCacheTLSv12(StunnelTest):
|
||||
"""Checking the cache session resumption.
|
||||
We expect exactly 2 "TLS accepted: previous session reused" to be
|
||||
logged by the [server] service.
|
||||
"options = NO_TICKET" turns off ticket support in TLSv1.2 and older.
|
||||
In TLSv1.3, "options = NO_TICKET" switches from using stateful tickets to
|
||||
stateless tickets (traditional cache with session id sent in tickets).
|
||||
https://github.com/openssl/openssl/issues/10280
|
||||
Session cache resumption does not work with the FORK threading model.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '132. Cache session resumption with TLSv1.2'
|
||||
self.events.skip = [
|
||||
"FORK"
|
||||
]
|
||||
self.events.count = 2
|
||||
self.events.success = [
|
||||
"TLS accepted: previous session reused"
|
||||
]
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
#"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_client_cfgfile(
|
||||
self, cfg: Config, ports: list, service: str
|
||||
) -> (pathlib.Path, pathlib.Path):
|
||||
"""Create a configuration file for a stunnel client."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
client = yes
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{ports[1]}
|
||||
cert = {cfg.certdir}/client_cert.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_client.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile, os.devnull
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
sslVersionMax = TLSv1.2
|
||||
options = NO_TICKET
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
verifyPeer = yes
|
||||
CAfile = {cfg.certdir}/PeerCerts.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class SessionResume(StunnelTest):
|
||||
"""Enable the 'sessionResume' service-level option to allow session resumption.
|
||||
This resumption of the session does not work for the FORK threading model.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '133. Test enabled \"sessionResume\" option'
|
||||
self.events.skip = [
|
||||
"FORK"
|
||||
]
|
||||
self.events.count = 2
|
||||
self.events.success = [
|
||||
"TLS accepted: previous session reused"
|
||||
]
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
#"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_client_cfgfile(
|
||||
self, cfg: Config, ports: list, service: str
|
||||
) -> (pathlib.Path, pathlib.Path):
|
||||
"""Create a configuration file for a stunnel client."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
client = yes
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{ports[1]}
|
||||
cert = {cfg.certdir}/client_cert.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_client.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile, os.devnull
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
sessionResume = yes
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
verifyPeer = yes
|
||||
CAfile = {cfg.certdir}/PeerCerts.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class NoSessionResume(StunnelTest):
|
||||
"""Disable the 'sessionResume' service-level option to disallow session resumption.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '134. Test disabled \"sessionResume\" option'
|
||||
self.events.count = 3
|
||||
self.events.success = [
|
||||
"TLS accepted: new session negotiated"
|
||||
]
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_client_cfgfile(
|
||||
self, cfg: Config, ports: list, service: str
|
||||
) -> (pathlib.Path, pathlib.Path):
|
||||
"""Create a configuration file for a stunnel client."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
client = yes
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{ports[1]}
|
||||
cert = {cfg.certdir}/client_cert.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_client.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile, os.devnull
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
sessionResume = no
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
verifyPeer = yes
|
||||
CAfile = {cfg.certdir}/PeerCerts.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class StunnelClientServerTest(Plugin):
|
||||
"""Stunnel client-server tests
|
||||
HTTP client --> stunnel client --> stunnel server --> HTTP server
|
||||
"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.description = 'Resume session'
|
||||
|
||||
|
||||
async def perform_operation(self, cfg: Config, logger: logging.Logger) -> None:
|
||||
"""Run tests"""
|
||||
stunnel = ResumePSK(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
||||
|
||||
stunnel = ResumeCacheTLSv12(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
||||
|
||||
stunnel = SessionResume(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
||||
|
||||
stunnel = NoSessionResume(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
|
@ -0,0 +1,209 @@
|
|||
"""stunnel client-server tests"""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
from plugin_collection import Plugin
|
||||
from maketest import (
|
||||
Config,
|
||||
ClientConnectExec
|
||||
)
|
||||
|
||||
|
||||
class StunnelTest(ClientConnectExec):
|
||||
"""Base class for stunnel client-server tests."""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger, path:pathlib.Path):
|
||||
super().__init__(cfg, logger, path)
|
||||
self.params.services = ['server', 'client']
|
||||
self.params.conn_num = 3
|
||||
self.events.count = 2
|
||||
|
||||
|
||||
class ResumeTicketTLSv12(StunnelTest):
|
||||
"""Checking the stateless session ticket resumption (RFC 4507bis) with TLSv1.2.
|
||||
We expect exactly 2 "TLS accepted: previous session reused" to be logged by the
|
||||
[server] service, because [client] connected 3 times (1 new session, 2 reused sessions).
|
||||
The following options are used to disable session cache:
|
||||
- The "sessionCacheSize = 1" option sets the internal session cache size.
|
||||
- "options = -NO_TICKET" (it is the default with OpenSSL 1.1.1 or later)
|
||||
Stateless session ticket resumption also works with the FORK threading model.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger, path:pathlib.Path):
|
||||
super().__init__(cfg, logger, path)
|
||||
self.params.description = '141. Stateless session ticket resumption with TLSv1.2'
|
||||
self.events.count = 2
|
||||
self.events.success = [
|
||||
"TLS accepted: previous session reused"
|
||||
]
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
#"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
self.path = path
|
||||
|
||||
|
||||
async def prepare_client_cfgfile(
|
||||
self, cfg: Config, ports: list, service: str
|
||||
) -> (pathlib.Path, pathlib.Path):
|
||||
"""Create a configuration file for a stunnel client."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
retry = yes
|
||||
|
||||
[{service}]
|
||||
client = yes
|
||||
exec = {cfg.pythondir}
|
||||
execArgs = python3 {cfg.scriptdir}/reader.py {self.path}
|
||||
connect = 127.0.0.1:{ports[1]}
|
||||
cert = {cfg.certdir}/client_cert.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_client.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile, os.devnull
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
sslVersionMax = TLSv1.2
|
||||
sessionCacheSize = 1
|
||||
options = -NO_TICKET
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
verifyPeer = yes
|
||||
CAfile = {cfg.certdir}/PeerCerts.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class ResumeTicketTLSv13(StunnelTest):
|
||||
"""Checking the stateless session ticket resumption (RFC 4507bis) with TLS 1.3.
|
||||
We expect exactly 2 "TLS accepted: previous session reused" to be logged by the
|
||||
[server] service, because [client] connected 3 times (1 new session, 2 reused sessions).
|
||||
The following options are used to disable session cache:
|
||||
- The "sessionCacheSize = 1" option sets the internal session cache size.
|
||||
- "options = -NO_TICKET" (it is the default with OpenSSL 1.1.1 or later).
|
||||
Stateless session ticket resumption also works with the FORK threading model.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger, path:pathlib.Path):
|
||||
super().__init__(cfg, logger, path)
|
||||
self.params.description = '142. Stateless session ticket resumption with TLSv1.3'
|
||||
self.events.count = 2
|
||||
self.events.success = [
|
||||
"TLS accepted: previous session reused"
|
||||
]
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
#"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
self.path = path
|
||||
|
||||
|
||||
async def prepare_client_cfgfile(
|
||||
self, cfg: Config, ports: list, service: str
|
||||
) -> (pathlib.Path, pathlib.Path):
|
||||
"""Create a configuration file for a stunnel client."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
retry = yes
|
||||
|
||||
[{service}]
|
||||
client = yes
|
||||
exec = {cfg.pythondir}
|
||||
execArgs = python3 {cfg.scriptdir}/reader.py {self.path}
|
||||
connect = 127.0.0.1:{ports[1]}
|
||||
cert = {cfg.certdir}/client_cert.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_client.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile, os.devnull
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
sslVersion = TLSv1.3
|
||||
sessionCacheSize = 1
|
||||
options = -NO_TICKET
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
verifyPeer = yes
|
||||
CAfile = {cfg.certdir}/PeerCerts.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class StunnelClientServerTest(Plugin):
|
||||
"""Stunnel client-server tests
|
||||
HTTP client --> stunnel client --> stunnel server --> HTTP server
|
||||
"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.description = 'Resume session'
|
||||
|
||||
|
||||
async def perform_operation(self, cfg: Config, logger: logging.Logger) -> None:
|
||||
"""Run tests"""
|
||||
path = os.path.join(cfg.tempd, 'unix.sock')
|
||||
stunnel = ResumeTicketTLSv12(cfg, logger, path)
|
||||
await stunnel.test_stunnel(cfg)
|
||||
|
||||
stunnel = ResumeTicketTLSv13(cfg, logger, path)
|
||||
await stunnel.test_stunnel(cfg)
|
|
@ -0,0 +1,145 @@
|
|||
"""stunnel client-server tests"""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
from plugin_collection import Plugin
|
||||
from maketest import (
|
||||
Config,
|
||||
ServerReopen
|
||||
)
|
||||
|
||||
|
||||
class StunnelTest(ServerReopen):
|
||||
"""Base class for stunnel client-server tests."""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger, path:pathlib.Path):
|
||||
super().__init__(cfg, logger, path)
|
||||
self.params.services = ['server', 'client']
|
||||
self.params.conn_num = 4
|
||||
self.events.count = 1
|
||||
|
||||
|
||||
class ResumeTicketSecret(StunnelTest):
|
||||
"""Checking if the reloaded server resume the session with secret keys for
|
||||
the session ticket processing.
|
||||
We expect exactly 2 "TLS accepted: previous session reused" to be logged by the
|
||||
[server] service, because the server holds keys for the session ticket processing.
|
||||
The ticket session resumption also works for the FORK model.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger, path:pathlib.Path):
|
||||
super().__init__(cfg, logger, path)
|
||||
self.params.description = '151. Session resumption with secret keys'
|
||||
self.events.count = 3
|
||||
self.events.success = [
|
||||
"TLS accepted: previous session reused"
|
||||
]
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
#"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
self.path = path
|
||||
|
||||
|
||||
async def prepare_client_cfgfile(
|
||||
self, cfg: Config, ports: list, service: str
|
||||
) -> (pathlib.Path, pathlib.Path):
|
||||
"""Create a configuration file for a stunnel client."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
retry = yes
|
||||
|
||||
[{service}]
|
||||
client = yes
|
||||
exec = {cfg.pythondir}
|
||||
execArgs = python3 {cfg.scriptdir}/reader.py {self.path}
|
||||
connect = 127.0.0.1:{ports[1]}
|
||||
cert = {cfg.certdir}/client_cert.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_client.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile, os.devnull
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
options = -NO_TICKET
|
||||
ticketKeySecret = 6c:42:72:46:57:23:3a:3d:4b:54:2d:7b:55:4b:6e:8f:32:5c:21:6a:2e:6e:47:31:57:20:2f:75:26:7b:4d:25
|
||||
ticketMacSecret = 3f:3c:77:53:32:48:79:76:75:7a:50:33:70:65:47:27:32:79:73:7e:73:2c:21:6c:3a:6f:30:28:4c:5c:27:1f
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
verifyPeer = yes
|
||||
CAfile = {cfg.certdir}/PeerCerts.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
async def prepare_additional_server_cfgfile(
|
||||
self, cfg: Config, ports: list, lport: int
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for new stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_new_server.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
ticketKeySecret = 6c:42:72:46:57:23:3a:3d:4b:54:2d:7b:55:4b:6e:8f:32:5c:21:6a:2e:6e:47:31:57:20:2f:75:26:7b:4d:25
|
||||
ticketMacSecret = 3f:3c:77:53:32:48:79:76:75:7a:50:33:70:65:47:27:32:79:73:7e:73:2c:21:6c:3a:6f:30:28:4c:5c:27:1f
|
||||
|
||||
[server]
|
||||
accept = 127.0.0.1:{ports[1]}
|
||||
connect = 127.0.0.1:{lport}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
verifyPeer = yes
|
||||
CAfile = {cfg.certdir}/PeerCerts.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class StunnelClientServerTest(Plugin):
|
||||
"""Stunnel client-server tests
|
||||
HTTP client --> stunnel client --> stunnel server --> HTTP server
|
||||
"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.description = 'Resume session'
|
||||
|
||||
|
||||
async def perform_operation(self, cfg: Config, logger: logging.Logger) -> None:
|
||||
"""Run tests"""
|
||||
path = os.path.join(cfg.tempd, 'unix.sock')
|
||||
stunnel = ResumeTicketSecret(cfg, logger, path)
|
||||
await stunnel.test_stunnel(cfg)
|
|
@ -0,0 +1,354 @@
|
|||
"""stunnel server tests"""
|
||||
|
||||
import logging
|
||||
import pathlib
|
||||
from plugin_collection import Plugin
|
||||
from maketest import (
|
||||
Config,
|
||||
StunnelAcceptConnect
|
||||
)
|
||||
|
||||
class StunnelTest(StunnelAcceptConnect):
|
||||
"""Base class for stunnel server tests."""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.ssl_client = True
|
||||
self.params.services = ['server']
|
||||
|
||||
|
||||
class RedirectWrongPeerCert(StunnelTest):
|
||||
"""Redirect stunnel server test.
|
||||
The client presents the *wrong* certificate so the connection is redirected.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '161. Redirect connection (wrong peer certificate)'
|
||||
self.params.context = 'load_wrong_cert'
|
||||
self.events.count = 1
|
||||
self.events.success = [
|
||||
"Redirecting connection"
|
||||
]
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
#"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
exec = {cfg.pythondir}
|
||||
execArgs = python3 {cfg.scriptdir}/error.py
|
||||
redirect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
verifyPeer = yes
|
||||
CAfile = {cfg.certdir}/PeerCerts.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class RedirectNoPeerCert(StunnelTest):
|
||||
"""Redirect stunnel server test.
|
||||
The client does not present any certificate so the connection is redirected.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '162. Redirect connection (no peer certificate)'
|
||||
self.events.count = 1
|
||||
self.events.success = [
|
||||
"Redirecting connection"
|
||||
]
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
#"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
exec = {cfg.pythondir}
|
||||
execArgs = python3 {cfg.scriptdir}/error.py
|
||||
redirect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
verifyPeer = yes
|
||||
CAfile = {cfg.certdir}/PeerCerts.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class NoRedirectCorrectPeerCert(StunnelTest):
|
||||
"""No redirect stunnel server test.
|
||||
The client presents the *correct* certificate and the connection is not redirected.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '163. Not redirected connection (valid peer certificate)'
|
||||
self.params.context = 'load_correct_cert'
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
redirect = 127.0.0.1:0
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
verifyPeer = yes
|
||||
CAfile = {cfg.certdir}/PeerCerts.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class RedirectWrongChainCert(StunnelTest):
|
||||
"""Redirect stunnel server test.
|
||||
The client does not present any certificate so the connection is redirected.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '164. Redirect connection (wrong chain)'
|
||||
self.events.count = 1
|
||||
self.events.success = [
|
||||
"Redirecting connection"
|
||||
]
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
#"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
exec = {cfg.pythondir}
|
||||
execArgs = python3 {cfg.scriptdir}/error.py
|
||||
redirect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
verifyChain = yes
|
||||
CAfile = {cfg.certdir}/CACert.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class RedirectNoChainCert(StunnelTest):
|
||||
"""No redirect stunnel server test.
|
||||
The client does not present any certificate so the connection is redirected.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '165. Redirect connection (no chain)'
|
||||
self.events.count = 1
|
||||
self.events.success = [
|
||||
"Redirecting connection"
|
||||
]
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
#"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
exec = {cfg.pythondir}
|
||||
execArgs = python3 {cfg.scriptdir}/error.py
|
||||
redirect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
verifyChain = yes
|
||||
CAfile = {cfg.certdir}/CACert.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class NoRedirectCorrectChainCert(StunnelTest):
|
||||
"""No redirect stunnel server test.
|
||||
The client presents the *correct* certificate and the connection is not redirected.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '166. Not redirected connection (valid chain)'
|
||||
self.params.context = 'load_correct_cert'
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
redirect = 127.0.0.1:0
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
verifyChain = yes
|
||||
CAfile = {cfg.certdir}/CACert.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class RedirectStunnelTest(Plugin):
|
||||
"""Stunnel redirect server tests
|
||||
HTTPS client --> stunnel server --> HTTP server or "Wrong_connection!"
|
||||
"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.description = 'Redirect connection'
|
||||
|
||||
|
||||
async def perform_operation(self, cfg: Config, logger: logging.Logger) -> None:
|
||||
"""Run tests"""
|
||||
stunnel = RedirectWrongPeerCert(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
||||
|
||||
stunnel = RedirectNoPeerCert(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
||||
|
||||
stunnel = NoRedirectCorrectPeerCert(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
||||
|
||||
stunnel = RedirectWrongChainCert(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
||||
|
||||
stunnel = RedirectNoChainCert(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
||||
|
||||
stunnel = NoRedirectCorrectChainCert(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
|
@ -0,0 +1,200 @@
|
|||
"""stunnel server tests"""
|
||||
|
||||
import logging
|
||||
import pathlib
|
||||
from plugin_collection import Plugin
|
||||
from maketest import (
|
||||
Config,
|
||||
StunnelAcceptConnect
|
||||
)
|
||||
|
||||
class StunnelTest(StunnelAcceptConnect):
|
||||
"""Base class for stunnel client-server tests."""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.ssl_client = True
|
||||
self.params.services = ['server']
|
||||
|
||||
|
||||
class RedirectProxyWrongPeerCert(StunnelTest):
|
||||
"""Redirect stunnel server test.
|
||||
The client presents the *wrong* certificate so the connection is redirected.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '171. Redirect proxy connection (wrong peer certificate)'
|
||||
self.params.context = 'load_wrong_cert'
|
||||
self.events.count = 1
|
||||
self.events.success = [
|
||||
"Redirecting connection"
|
||||
]
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
#"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
protocol = proxy
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
exec = {cfg.pythondir}
|
||||
execArgs = python3 {cfg.scriptdir}/error.py
|
||||
redirect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
verifyPeer = yes
|
||||
CAfile = {cfg.certdir}/PeerCerts.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class RedirectProxyNoPeerCert(StunnelTest):
|
||||
"""Redirect stunnel server test.
|
||||
The client does not present any certificate so the connection is redirected.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '172. Redirect proxy connection (no peer certificate)'
|
||||
self.events.count = 1
|
||||
self.events.success = [
|
||||
"Redirecting connection"
|
||||
]
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
#"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
protocol = proxy
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
exec = {cfg.pythondir}
|
||||
execArgs = python3 {cfg.scriptdir}/error.py
|
||||
redirect = 127.0.0.1:{port}
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
verifyPeer = yes
|
||||
CAfile = {cfg.certdir}/PeerCerts.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class NoRedirectProxyCorrectPeerCert(StunnelTest):
|
||||
"""No redirect stunnel server test.
|
||||
The client presents the *correct* certificate and the connection is not redirected.
|
||||
"""
|
||||
|
||||
def __init__(self, cfg: Config, logger: logging.Logger):
|
||||
super().__init__(cfg, logger)
|
||||
self.params.description = '173. Not redirected proxy connection (valid peer certificate)'
|
||||
self.params.context = 'load_correct_cert'
|
||||
self.events.failure = [
|
||||
"peer did not return a certificate",
|
||||
"bad certificate",
|
||||
"certificate verify failed",
|
||||
"unsupported protocol",
|
||||
"TLS accepted: previous session reused",
|
||||
"Redirecting connection",
|
||||
"Connection reset by peer",
|
||||
"Connection lost",
|
||||
"Client received unexpected message",
|
||||
"Server received unexpected message",
|
||||
"Something went wrong",
|
||||
"INTERNAL ERROR"
|
||||
]
|
||||
|
||||
|
||||
async def prepare_server_cfgfile(
|
||||
self, cfg: Config, port: int, service: str
|
||||
) -> pathlib.Path:
|
||||
"""Create a configuration file for a stunnel server."""
|
||||
contents = f"""
|
||||
pid = {cfg.tempd}/stunnel_{service}.pid
|
||||
foreground = yes
|
||||
debug = debug
|
||||
syslog = no
|
||||
|
||||
protocol = proxy
|
||||
|
||||
[{service}]
|
||||
accept = 127.0.0.1:0
|
||||
connect = 127.0.0.1:{port}
|
||||
redirect = 127.0.0.1:0
|
||||
cert = {cfg.certdir}/server_cert.pem
|
||||
verifyPeer = yes
|
||||
CAfile = {cfg.certdir}/PeerCerts.pem
|
||||
"""
|
||||
cfgfile = cfg.tempd / "stunnel_server.conf"
|
||||
cfgfile.write_text(contents, encoding="UTF-8")
|
||||
return cfgfile
|
||||
|
||||
|
||||
class RedirectStunnelTest(Plugin):
|
||||
"""Stunnel redirect server tests
|
||||
HTTPS client --> stunnel server --> HTTP server or "Wrong_connection!"
|
||||
"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.description = 'Redirect PROXY connection'
|
||||
|
||||
|
||||
async def perform_operation(self, cfg: Config, logger: logging.Logger) -> None:
|
||||
"""Run tests"""
|
||||
|
||||
stunnel = RedirectProxyWrongPeerCert(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
||||
|
||||
stunnel = RedirectProxyNoPeerCert(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
||||
|
||||
stunnel = NoRedirectProxyCorrectPeerCert(cfg, logger)
|
||||
await stunnel.test_stunnel(cfg)
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче