From d949b305c016607cb18df9cda0c3b2d54ba21b6b Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Mon, 4 May 2020 22:38:02 +0200 Subject: [PATCH] Fix STARTTLS pretests, improve XMPP handshakes There was a empty variable in determine_optimal_proto() which prevented to save STARTTLS_OPTIMAL_PROTO. This is fixed. The buffers and return codes for XMPP in starttls_io() were under not every circumstances correct. This fixes those cases and making that in general more robust (hopefully). (There's still code commented out which I'll leave it for now). When openssl did not support -starttls xmpp-server there was a copy and paste error saying that -xmpphost option was not supported. --- testssl.sh | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/testssl.sh b/testssl.sh index ba67b8e..4915eae 100755 --- a/testssl.sh +++ b/testssl.sh @@ -5038,8 +5038,9 @@ run_prototest_openssl() { # arg1: protocol # arg2: available (yes) or not (no) add_proto_offered() { + # the ":" is mandatory here (and @ other places), otherwise e.g. tls1 will match tls1_2 if [[ "$PROTOS_OFFERED" =~ $1: ]]; then - # the ":" is mandatory here (and @ other places), otherwise e.g. tls1 will match tls1_2 + # we got that protcol already : else PROTOS_OFFERED+="${1}:$2 " @@ -10231,12 +10232,13 @@ run_alpn() { return $ret } -# arg1: string to send -# arg2: possible success strings a egrep pattern, needed! -# arg3: wait in seconds +# arg1: send string +# arg2: success string: an egrep pattern +# arg3: number of loops we should read from the buffer (optional, otherwise STARTTLS_SLEEP) starttls_io() { - local waitsleep=$STARTTLS_SLEEP + local nr_waits=$STARTTLS_SLEEP local buffer="" + local -i i [[ -n "$3" ]] && waitsleep=$3 [[ -z "$2" ]] && echo "FIXME $((LINENO))" @@ -10244,27 +10246,31 @@ starttls_io() { # If there's a sending part it's IO. Postgres sends via socket and replies via # strings "S". So there's no I part of IO ;-) if [[ -n "$1" ]]; then - debugme echo -en "C: \"$1\"" + debugme echo -en "C: $1" echo -en "$1" >&5 fi + if [[ "$2" == JUSTSEND ]]; then + debugme echo -e "\n (only sent)\n" + dd of=/dev/null bs=512 count=1 <&5 2>/dev/null & + return 0 + fi # This seems a bit dangerous but works. No blockings yet. "if=nonblock" doesn't work on BSDs buffer="$(dd bs=512 count=1 <&5 2>/dev/null)" - [[ "$DEBUG" -ge 2 ]] && echo -en "\nS: " && echo $buffer - for ((i=1; i < $waitsleep; i++ )); do + for ((i=1; i < $nr_waits; i++ )); do + [[ "$DEBUG" -ge 2 ]] && echo -en "\nS: " && echo $buffer if [[ "$buffer" =~ $2 ]]; then debugme echo " ---> reply matched \"$2\"" # the fd sometimes still seem to contain chars which confuses the following TLS handshake, trying to empty: - dd of=/dev/null bs=512 count=1 <&5 2>/dev/null + # dd of=/dev/null bs=512 count=1 <&5 2>/dev/null return 0 else # no match yet, more reading from fd helps. buffer+=$(dd bs=512 count=1 <&5 2>/dev/null) fi - sleep 0.5 done - return 0 + return 1 } @@ -10413,8 +10419,9 @@ starttls_xmpp_dialog() { namespace="jabber:client" [[ "$STARTTLS_PROTOCOL" == xmpp-server ]] && namespace="jabber:server" - starttls_io "" 'starttls(.*)features' 1 && + starttls_io "" 'starttls(.*)features' 1 && starttls_io "" '" 'JUSTSEND' 2 local ret=$? debugme echo "=== finished xmpp STARTTLS dialog with ${ret} ===" return $ret @@ -19640,7 +19647,7 @@ determine_optimal_proto() { $OPENSSL s_client $(s_client_options "$STARTTLS_OPTIMAL_PROTO $BUGS -connect "$NODEIP:$PORT" $PROXY -msg $STARTTLS $SNI") $TMPFILE 2>>$ERRFILE if sclient_auth $? $TMPFILE; then all_failed=false - add_proto_offered "${proto/-/}" yes + add_proto_offered "${STARTTLS_OPTIMAL_PROTO/-/}" yes break fi done @@ -19747,7 +19754,7 @@ determine_optimal_proto() { } -# arg1 (optional): ftp smtp, lmtp, pop3, imap, xmpp, telnet, ldap, postgres, mysql, irc, nntp (maybe with trailing s) +# arg1 (optional): ftp smtp, lmtp, pop3, imap, xmpp, xmpp-server, telnet, ldap, postgres, mysql, irc, nntp (maybe with trailing s) # determine_service() { local ua @@ -19816,7 +19823,7 @@ determine_service() { fi fi if [[ "$protocol" == xmpp-server ]] && ! "$HAS_XMPP_SERVER"; then - fatal "Your $OPENSSL does not support the \"-xmpphost\" option" $ERR_OSSLBIN + fatal "Your $OPENSSL does not support the \"-starttls xmpp-server\" option" $ERR_OSSLBIN fi elif [[ "$protocol" == postgres ]]; then # Check if openssl version supports postgres. @@ -19850,7 +19857,7 @@ determine_service() { outln ;; *) outln - fatal "momentarily only ftp, smtp, lmtp, pop3, imap, xmpp, telnet, ldap, nntp, postgres and mysql allowed" $ERR_CMDLINE + fatal "momentarily only ftp, smtp, lmtp, pop3, imap, xmpp, xmpp-server, telnet, ldap, nntp, postgres and mysql allowed" $ERR_CMDLINE ;; esac fi