From 797d0f96959415bf620ef2ac7bb9349a4db08e0f Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Thu, 26 Oct 2023 14:52:53 +0200 Subject: [PATCH] Catch the case of empty SNI host to prevent OpenSSL error --- CHANGES | 3 + gatherinfo.sh | 172 -------------------------------------------------- test.sh | 41 ++++++++++-- xio-openssl.c | 5 +- 4 files changed, 40 insertions(+), 181 deletions(-) delete mode 100755 gatherinfo.sh diff --git a/CHANGES b/CHANGES index 70ae71e..4122c3d 100644 --- a/CHANGES +++ b/CHANGES @@ -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 diff --git a/gatherinfo.sh b/gatherinfo.sh deleted file mode 100755 index 7c59eab..0000000 --- a/gatherinfo.sh +++ /dev/null @@ -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" diff --git a/test.sh b/test.sh index 22ff300..fec51b1 100755 --- a/test.sh +++ b/test.sh @@ -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; 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 diff --git a/xio-openssl.c b/xio-openssl.c index 5ffc1d1..026489f 100644 --- a/xio-openssl.c +++ b/xio-openssl.c @@ -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;