From 1241600b8100f46440ad838dece48a3cc39b8880 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Fri, 23 Feb 2024 10:50:55 +0100 Subject: [PATCH] socat-chain.sh, socat-mux.sh, and socat-broker.sh work with older Socat versions --- CHANGES | 3 +++ socat-broker.sh | 24 +++++++++++++++++++----- socat-chain.sh | 8 +++++--- socat-mux.sh | 28 ++++++++++++++++++++-------- test.sh | 11 ++++++++--- 5 files changed, 55 insertions(+), 19 deletions(-) diff --git a/CHANGES b/CHANGES index 1ee9c49..88f5f1e 100644 --- a/CHANGES +++ b/CHANGES @@ -23,6 +23,9 @@ Features: Total inactivity timeout option -T 0 now means 0.0 seconds; up to version 1.8.0.0 it meant no total inactivity timeout. + Changed socat-chain.sh, socat-mux.sh, and socat-broker.sh to work with + older Socat versions. + Porting: Changes for building and testing on NetBSD diff --git a/socat-broker.sh b/socat-broker.sh index ec23774..f8b5abb 100755 --- a/socat-broker.sh +++ b/socat-broker.sh @@ -21,7 +21,7 @@ usage () { $ECHO " is a passive address like TCP4-L or SSL-L" $ECHO " :" $ECHO " -d* -S -t -T are passed to socat" - $ECHO " -V prints the socat command before starting it" + $ECHO " -V Shows executed Socat commands and some infos" $ECHO "For example:" $ECHO " $0 \\" $ECHO " TCP4-L:1234" @@ -60,15 +60,29 @@ if ! [[ "$LISTENER" =~ .*,fork ]] || [[ "$LISTENER" =~ .*,fork, ]]; then fi case "$0" in - */*) SOCAT=${0%/*}/socat ;; - *) SOCAT=socat ;; + */*) if [ -x ${0%/*}/socat ]; then SOCAT=${0%/*}/socat; fi ;; esac +if [ -z "$SOCAT" ]; then SOCAT=socat; fi +[ "$VERBOSE" ] && echo "# $0: Using executable $SOCAT" >&2 +# We need a free UDP port (on loopback) PORT=$($SOCAT -d -d -T 0.000001 UDP4-RECV:0 /dev/null 2>&1 |grep bound |sed 's/.*:\([1-9][0-9]*\)$/\1/') if [ -z "$PORT" ]; then - echo "$0: Failed to determine free UDP port" >&2 - exit 1 + # Probably old Socat version, use a different approach + if type ss >/dev/null 2>&1; then + : + elif type netstat >/dev/null 2>&1; then + alias ss=netstat + else + echo "$0: Failed to determine free UDP port (old Socat version, no ss, no netstat?)" >&2 + exit 1 + fi + PORT= + while [ -z "$PORT" ] || ss -aun |grep -e ":$PORT\>" >/dev/null; do + PORT=$((16384+RANDOM)) + done fi +[ "$VERBOSE" ] && echo "# $0: Using UDP port $PORT" >&2 BCADDR=127.255.255.255 diff --git a/socat-chain.sh b/socat-chain.sh index 865446d..fa8e93e 100755 --- a/socat-chain.sh +++ b/socat-chain.sh @@ -56,7 +56,7 @@ usage () { $ECHO " is typically a client address with protocol like OPENSSL" $ECHO " :" $ECHO " -d* -S -t -T are passed to socat" - $ECHO " -V prints the socat commands before starting them" + $ECHO " -V Shows executed Socat commands and some infos" $ECHO "Example to drive SOCKS over TLS:" $ECHO " $0 \\" $ECHO " TCP4-L:1234,reuseaddr,fork \\" @@ -130,10 +130,12 @@ else fi case "$0" in - */*) SOCAT=${0%/*}/socat ;; - *) SOCAT=socat ;; + */*) if [ -x ${0%/*}/socat ]; then SOCAT=${0%/*}/socat; fi ;; esac +if [ -z "$SOCAT" ]; then SOCAT=socat; fi +[ "$VERBOSE" ] && echo "# $0: Using executable $SOCAT" >&2 +# We need a free TCP port (on loopback) PORT=$($SOCAT -d -d TCP4-L:0,accept-timeout=0.000001 /dev/null 2>&1 |grep listening |sed 's/.*:\([1-9][0-9]*\)$/\1/') if [ -z "$PORT" ]; then echo "$0: Failed to determine free TCP port" >&2 diff --git a/socat-mux.sh b/socat-mux.sh index 7a13f27..1d7e0de 100755 --- a/socat-mux.sh +++ b/socat-mux.sh @@ -28,7 +28,7 @@ usage () { $ECHO "data provided by 10.2.3.4 is sent to ALL clients" $ECHO " :" $ECHO "\t-h\tShow this help text and exit" - $ECHO "\t-V\tShow Socat commands" + $ECHO "\t-V\tShows executed Socat commands and some infos" $ECHO "\t-q\tSuppress most messages" $ECHO "\t-d*\tOptions beginning with -d are passed to Socat processes" $ECHO "\t-l*\tOptions beginning with -l are passed to Socat processes" @@ -67,19 +67,31 @@ if ! [[ "$LISTENER" =~ .*,fork ]] || [[ "$LISTENER" =~ .*,fork, ]]; then fi case "$0" in - */*) SOCAT=${0%/*}/socat ;; - *) SOCAT=socat ;; + */*) if [ -x ${0%/*}/socat ]; then SOCAT=${0%/*}/socat; fi ;; esac +if [ -z "$SOCAT" ]; then SOCAT=socat; fi +[ "$VERBOSE" ] && echo "# $0: Using executable $SOCAT" >&2 +# We need two free UDP ports (on loopback) PORT1=$($SOCAT -d -d -T 0.000001 UDP4-RECV:0 /dev/null 2>&1 |grep bound |sed 's/.*:\([1-9][0-9]*\)$/\1/') PORT2=$($SOCAT -d -d -T 0.000001 UDP4-RECV:0 /dev/null 2>&1 |grep bound |sed 's/.*:\([1-9][0-9]*\)$/\1/') if [ -z "$PORT1" -o -z "$PORT2" ]; then - echo "$0: Failed to determine free UDP ports" >&2 - exit 1 -fi -if [ "$PORT1" = "$PORT2" ]; then # seen on etch - PORT2=$((PORT1+1)) + # Probably old Socat version, use a different approach + if type ss >/dev/null 2>&1; then + : + elif type netstat >/dev/null 2>&1; then + alias ss=netstat + else + echo "$0: Failed to determine free UDP ports (old Socat version, no ss, no netstat?)" >&2 + exit 1 + fi + PORT1= PORT2= + while [ -z "$PORT1" -o -z "$PORT2" -o "$PORT1" = "$PORT2" ] || ss -aun |grep -e ":$PORT1\>" -e ":$PORT2\>" >/dev/null; do + PORT1=$((16384+RANDOM)) + PORT2=$((16384+RANDOM)) + done fi +[ "$VERBOSE" ] && echo "# $0: Using UDP ports $PORT1, $PORT2" >&2 IFADDR=127.0.0.1 BCADDR=127.255.255.255 diff --git a/test.sh b/test.sh index 8b088a4..067f0f5 100755 --- a/test.sh +++ b/test.sh @@ -30,6 +30,11 @@ fi ECHO="echo $E" PRINTF="printf" +GREP_E="grep -E" +GREP_F="grep -F" + +TRUE=$(type -p true) + usage() { $ECHO "Usage: $0 [ ...]" $ECHO "options:" @@ -18025,7 +18030,7 @@ elif [ "$UNAME" = "NetBSD" ]; then $PRINTF "test $F_n $TEST... ${YELLOW}might hang on $UNAME${NORMAL}\n" $N numCANT=$((numCANT+1)) listCANT="$listCANT $N" -elif ! F=$(testfeats STDIO SYSTEM SOCKETPAIR); then +elif ! F=$(testfeats SYCLS STDIO SYSTEM SOCKETPAIR); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N numCANT=$((numCANT+1)) listCANT="$listCANT $N" @@ -19325,7 +19330,7 @@ case "$TESTS" in *%$N%*|*%functions%*|*%scripts%*|*%socat-chain%*|*%listen%*|*%fork%*|*%ip4%*|*%tcp4%*|*%unix%*|*%socks4%*|*%socket%*|*%$NAME%*) TEST="$NAME: test socat-chain.sh with SOCKS4 over UNIX-socket" # Run a socks4 server on UNIX-listen -# Connect with socat-chein.sh; check if data transfer is correct +# Connect with socat-chain.sh; check if data transfer is correct if ! eval $NUMCOND; then : # Remove unneeded checks, adapt lists of the remaining ones elif ! cond=$(checkconds \ @@ -19396,7 +19401,7 @@ case "$TESTS" in *%$N%*|*%functions%*|*%scripts%*|*%socat-chain%*|*%listen%*|*%fork%*|*%ip4%*|*%tcp4%*|*%openssl%*|*%unix%*|*%socket%*|*%pty%*|*%$NAME%*) TEST="$NAME: test socat-chain.sh with SSL over PTY" # Run a socat-chain.sh instance with SSL listening behind a PTY; -# open the PTY with socat-chein.sh using SSL; +# open the PTY with socat-chain.sh using SSL; # check if data transfer is correct if ! eval $NUMCOND; then : # Remove unneeded checks, adapt lists of the remaining ones