Catch the case of empty SNI host to prevent OpenSSL error

This commit is contained in:
Gerhard Rieger 2023-10-26 14:52:53 +02:00
parent 43eb003245
commit 797d0f9695
4 changed files with 40 additions and 181 deletions

View file

@ -25,6 +25,9 @@ Corrections:
but remembers the failure and allows further processing.
Thanks to Luke Jones for reporting this issue.
Now catching the case of empty SNI host to prevent OpenSSL error.
This is related to Red Hat issue 2081414.
Coding:
Introduced groups_t instead of uint32_t, for more flexibility

View file

@ -1,172 +0,0 @@
#! /bin/sh
# source: gatherinfo.sh
# Copyright Gerhard Rieger and contributors (see file CHANGES)
# Published under the GNU General Public License V.2, see file COPYING
#set -vx
# use this script after successful porting
# provide the platform name as argument with no dots, e.g. HPUX-11-0
# it generates the files:
# Config/Makefile.PLATFORM
# Config/config.PLATFORM.h
# Config/socat.PLATFORM.out
#
# Config/config.PLATFORM.log
# Config/compile.PLATFORM.log
# Config/test.PLATFORM.log
VERBOSE=
LOGGING=
INTERACTIVE=
CONFOPTS=
PLATFORM=
OUTPUT='>/dev/null'
# how to echo special characters?
if [ `echo "x\c"` = "x" ]; then E=""
elif [ `echo -e "x\c"` = "x" ]; then E="-e"
fi
while [ -n "$1" ]; do
case "$1" in
-v) VERBOSE=1; shift;; # tell about progress
-d) LOGGING=1; shift;; # show complete output
-i) INTERACTIVE=1; shift;; # diff and ask before overriding old files
-*) CONFOPTS="$CONFOPTS $1"; shift;;
*) PLATFORM="$1"; break;;
esac
done
#if [ -z "$PLATFORM" ]; then
# echo "please specify a configuration name, e.g. `uname -s`-`uname -r|tr '.' '-'`!" >&2; exit 1;
#fi
if [ $# -eq 0 ]; then
echo $E "usage: $0 [-v] [-i] [configure options ...] platform" >&2
echo $E "\t-v\t\tverbose (print actual command)" >&2
echo $E "\t-d\t\tdump command outputs" >&2
echo $E "\t-i\t\tinteractive (ask before overwriting something)" >&2
echo $E "\tconfigure options\toptions for configure script, e.g. --disable-ip6" >&2
echo $E "\tplatform\tdescribe your OS, e.g. `uname -s`-`uname -r|tr '.' '-'`" >&2
exit 1
fi
case "$PLATFORM" in
*.*) echo "platform name must not contain '.'" >&2; exit 1;;
esac
# now, lets begin!
if [ -f Makefile ]; then
COMMAND="make distclean"
[ "$VERBOSE" ] && echo "$COMMAND"
$COMMAND >/dev/null 2>&1 || echo "*** failed: $COMMAND" 1>&2
fi
# implicitly generates Makefile, config.h, config.log
COMMAND="./configure $CONFOPTS"
LOGFILE="compile.log"
[ "$VERBOSE" ] && echo "$COMMAND"
if [ "$LOGGING" ]; then
{ $COMMAND; echo "$?" >socat.rc; } 2>&1 |tee $LOGFILE;
if [ `cat socat.rc` -ne 0 ]; then echo "*** failed: $COMMAND" 1>&2; exit 1; fi
else
$COMMAND >$LOGFILE 2>&1 || { echo "*** failed: $COMMAND" 1>&2; exit 1; }
fi
COMMAND="make -k"
LOGFILE="compile.log"
[ "$VERBOSE" ] && echo "$COMMAND"
if [ "$LOGGING" ]; then
{ $COMMAND; echo "$?" >socat.rc; } 2>&1 |tee -a $LOGFILE;
if [ `cat socat.rc` -ne 0 ]; then echo "*** failed: $COMMAND" 1>&2; exit 1; fi
else
$COMMAND >>$LOGFILE 2>&1 || { echo "*** failed: $COMMAND" 1>&2; exit 1; }
fi
# generates socat.out
COMMAND="make info"
[ "$VERBOSE" ] && echo "$COMMAND"
$COMMAND >/dev/null || echo "*** failed: $COMMAND" 1>&2
COMMAND="./test.sh"
LOGFILE="test.log"
[ "$VERBOSE" ] && echo "$COMMAND"
if [ "$LOGGING" ]; then
{ $COMMAND; echo "$?" >socat.rc; } 2>&1 |tee $LOGFILE;
if [ `cat socat.rc` -ne 0 ]; then
echo "*** failed: $COMMAND" 1>&2
if [ `cat socat.rc` -ge 128 ]; then
exit 1
fi
fi
else
$COMMAND >$LOGFILE 2>&1 || echo "*** failed: $COMMAND" 1>&2
fi
FILES=
b=Makefile; e=; f=$b; p=Config/$b.$PLATFORM
if [ "$INTERACTIVE" -a -f $p ]; then
if ! diff $p $f; then
cp -pi $f $p
fi
else
cp -p $f $p
fi
FILES="$p"
b=config; e=h; f=$b.$e; p=Config/$b.$PLATFORM.$e
if [ "$INTERACTIVE" -a -f $p ]; then
if ! diff $p $f; then
cp -pi $f $p
fi
else
cp -p $f $p
fi
FILES="$FILES $p"
b=socat; e=out; f=$b.$e; p=Config/$b.$PLATFORM.$e
if [ "$INTERACTIVE" -a -f $p ]; then
if ! diff $p $f; then
cp -pi $f $p
fi
else
cp -p $f $p
fi
FILES="$FILES $p"
b=config; e=log; f=$b.$e; p=Config/$b.$PLATFORM.$e
if [ "$INTERACTIVE" -a -f $p ]; then
if ! diff $p $f; then
cp -pi $f $p
fi
else
cp -p $f $p
fi
FILES="$FILES $p"
b=compile; e=log; f=$b.$e; p=Config/$b.$PLATFORM.$e
if [ "$INTERACTIVE" -a -f $p ]; then
if ! diff $p $f; then
cp -pi $f $p
fi
else
cp -p $f $p
fi
FILES="$FILES $p"
b=test; e=log; f=$b.$e; p=Config/$b.$PLATFORM.$e
if [ "$INTERACTIVE" -a -f $p ]; then
if ! diff $p $f; then
cp -pi $f $p
fi
else
cp -p $f $p
fi
FILES="$FILES $p"
echo "output files:"
echo "$FILES"

41
test.sh
View file

@ -11178,6 +11178,12 @@ esac
N=$((N+1))
# Does Socat have -d0 option?
opt_d0=
if $SOCAT -h |grep -e -d0 >/dev/null; then
opt_d0="-d0"
fi
# socat up to 1.7.2.1 did only shutdown() but not close() an accept() socket
# that was rejected due to range, tcpwrap, lowport, or sourceport option.
# This file descriptor leak could be used for a denial of service attack.
@ -11202,7 +11208,7 @@ if [ $RLIMIT_NOFILE -gt 1024 ]; then
RLIMIT_NOFILE="$(ulimit -n)"
fi
newport tcp4
CMD0="$TRACE $SOCAT -d0 $opts TCP-LISTEN:$PORT,$REUSEADDR,range=$LOCALHOST:255.255.255.255 PIPE"
CMD0="$TRACE $SOCAT $opt_d0 $opts TCP-LISTEN:$PORT,$REUSEADDR,range=$LOCALHOST:255.255.255.255 PIPE"
CMD1="$TRACE $SOCAT $opts -t 0 /dev/null TCP:$SECONDADDR:$PORT,bind=$SECONDADDR"
CMD2="$TRACE $SOCAT $opts - TCP:$LOCALHOST:$PORT,bind=$LOCALHOST"
printf "test $F_n $TEST... " $N
@ -14997,7 +15003,7 @@ pid2=$!
sleep 2
cpids="$(childpids $pid0 </dev/null)"
kill $pid1 $pid2 $cpids $pid0 2>/dev/null; wait
if echo -e "$da 2\n$da 1" |diff - $tf >$tdiff; then
if $ECHO "$da 2\n$da 1" |diff - $tf >$tdiff; then
$PRINTF "$OK\n"
if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
@ -15039,19 +15045,29 @@ TEST="$NAME: Option -S can turn off logging of SIGTERM"
# Start Socat with option -S 0x0000, kill it with SIGTERM
# When no logging entry regarding this signal is there, the test succeeded
if ! eval $NUMCOND; then :;
elif ! $SOCAT -h | grep -e " -S\>" >/dev/null; then
$PRINTF "test $F_n $TEST... ${YELLOW}Option -S not available${NORMAL}\n" $N
numCANT=$((numCANT+1))
listCANT="$listCANT $N"
elif ! F=$(testfeats PIPE); then
$PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
numCANT=$((numCANT+1))
listCANT="$listCANT $N"
elif ! A=$(testaddrs PIPE); then
$PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
numCANT=$((numCANT+1))
listCANT="$listCANT $N"
else
tf="$td/test$N.stdout"
te="$td/test$N.stderr"
tdiff="$td/test$N.diff"
da="test$N $(date) $RANDOM"
newport tcp4 # or whatever proto, or drop this line
CMD0="$TRACE $SOCAT $opts -S 0x0000 PIPE PIPE"
printf "test $F_n $TEST... " $N
$CMD0 >/dev/null 2>"${te}0" &
pid0=$!
relsleep 1 # give process time to start
kill -TERM $pid0 2>/dev/null; wait
if ! grep -q "exiting on signal" ${te}0; then
if ! grep "exiting on signal" ${te}0 >/dev/null; then
$PRINTF "$OK\n"
if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
@ -15079,19 +15095,30 @@ TEST="$NAME: Option -S can turn on logging of signal 31"
# Start Socat with option -S 0x80000000, kill it with -31
# When a logging entry regarding this signal is there, the test succeeded
if ! eval $NUMCOND; then :;
elif ! $SOCAT -h | grep -e " -S\>" >/dev/null; then
$PRINTF "test $F_n $TEST... ${YELLOW}Option -S not available${NORMAL}\n" $N
numCANT=$((numCANT+1))
listCANT="$listCANT $N"
elif ! F=$(testfeats PIPE); then
$PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
numCANT=$((numCANT+1))
listCANT="$listCANT $N"
elif ! A=$(testaddrs PIPE); then
$PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
numCANT=$((numCANT+1))
listCANT="$listCANT $N"
else
tf="$td/test$N.stdout"
te="$td/test$N.stderr"
tdiff="$td/test$N.diff"
da="test$N $(date) $RANDOM"
newport tcp4 # or whatever proto, or drop this line
CMD0="$TRACE $SOCAT $opts -S 0x80000000 PIPE PIPE"
printf "test $F_n $TEST... " $N
$CMD0 >/dev/null 2>"${te}0" &
pid0=$!
relsleep 1 # give process time to start
kill -31 $pid0 2>/dev/null; wait
if grep -q "exiting on signal" ${te}0; then
if grep "exiting on signal" ${te}0 >/dev/null; then
$PRINTF "$OK\n"
if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
if [ "$DEBUG" ]; then cat "${te}0" >&2; fi

View file

@ -448,8 +448,9 @@ int _xioopen_openssl_connect(struct single *xfd,
#if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
if (!no_sni) {
/*Warn1("_xioopen_openssl_connect(): calling SSL_set_tlsext_host_name(snihost=\"%s\")", snihost?snihost:"NULL");*/
if (!SSL_set_tlsext_host_name(ssl, snihost)) {
if (snihost == NULL || strlen(snihost) == 0) {
Warn("refusing to set empty SNI host name");
} else if (!SSL_set_tlsext_host_name(ssl, snihost)) {
Error1("Failed to set SNI host \"%s\"", snihost);
sycSSL_free(xfd->para.openssl.ssl);
xfd->para.openssl.ssl = NULL;