#!/bin/bash
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-

[ -f /usr/local/bin/usr_local_tput.bash ] && \
    . /usr/local/bin/usr_local_tput.bash

. /usr/local/bin/proxy_curl_lib.bash
[ -z "$TIMEOUT" ] && TIMEOUT=30
TIMEOUT3=`expr 3 \* $TIMEOUT`

SSLSCAN_ARGS="-4 --show-certificate --bugs --timeout $TIMEOUT"
[ $SSL_VER = 3 ] && SSLSCAN_ARGS="$SSLSCAN_ARGS  --tls13" || \
	SSLSCAN_ARGS="$SSLSCAN_ARGS --tls12"
# -cipher 'ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH'  -debug

# no timeout -no_tls1_1 -no_tls1_2
OPENSSL_ARGS="-4 -showcerts -bugs -status -state -no_ign_eof"
[ $SSL_VER = 3 ] && OPENSSL_ARGS="$OPENSSL_ARGS -tls1_3" || \
	OPENSSL_ARGS="$OPENSSL_ARGS -tls1_2"
# --no-colour ?--show-certificate  ?--show-client-cas ?--show-ciphers ?--tlsall

TESTSSL_ARGS="-4 --server-defaults --protocols --grease  --server-preference --heartbleed --ccs-injection --renegotiation  --breach --tls-fallback --drown  --assume-http --connect-timeout $TIMEOUT3 --openssl-timeout $TIMEOUT3 --standard --vulnerable --ssl-native --phone-out --nodns none"

ANALYZE_ARGS="--timeout $TIMEOUT --all-ciphers --verbose"

NMAP_ARGS="--script ssl-enum-ciphers -v --script-trace"
# no  --cert-status -> ocsp
CURL_ARGS="--silent -vvv --head --connect-timeout $TIMEOUT"
CURL_HTTP_ARGS="$CURL_ARGS --fail --location --http2 --proto-redir https --proto-default https  --proto =https"
# [ -d /usr/local/share/ca-certificates/mozilla ] && \
#    CURL_ARGS="$CURL_ARGS --capath usr/local/share/ca-certificates/mozilla"

[ $SSL_VER = 3 ] && CURL_ARGS="$CURL_ARGS --tlsv1.3" || \
	CURL_ARGS="$CURL_ARGS --tlsv1.2"
NOW=`date +%s`
DATE () {
    local elt=$1
    shift
    # DEBUG=1
    $elt $( expr `date +%s` - $NOW )s $*
    return 0
}

ssltest_proxies () {

	PROXY_SCHEME=`echo $SSLTEST_HTTPS_PROXY|sed -e 's@/@@g'  -e 's/:/ /g'| cut -f 1 -d ' '`
	PROXY_HOST=`echo $SSLTEST_HTTPS_PROXY|sed -e 's@/@@g'  -e 's/:/ /g'| cut -f 2 -d ' '`
	PROXY_PORT=`echo $SSLTEST_HTTPS_PROXY|sed -e 's@/@@g'  -e 's/:/ /g'| cut -f 3 -d ' '`

	# SocksPolicy Accept in /etc/tor/torrc - required and works with sslscan
	TESTSSL_ENVS="env MAX_OSSL_FAIL=10 DNS_VIA_PROXY=true PROXY_WAIT=$TIMEOUT"
	if [ -n "$SSLTEST_HTTP_PROXY" ] ; then
	    PROXY_HOST_PORT=`echo "$SSLTEST_HTTPS_PROXY" | sed -e 's@.*/@@'`
	    OPENSSL_ARGS="$OPENSSL_ARGS -proxy $PROXY_HOST_PORT"
	elif [ -n "$SSLTEST_HTTPS_PROXY" ] ; then
	    # WTF HTTP CONNECT failed: 502 Bad Gateway (tor protocol violation)
	    PROXY_HOST_PORT=`echo "$SSLTEST_HTTPS_PROXY" | sed -e 's@.*/@@'`
	    OPENSSL_ARGS="$OPENSSL_ARGS -proxy $PROXY_HOST_PORT"
	fi

	# Make sure a firewall is not between you and your scanning target!
	# `sed -e 's@.*/@@' <<< $SSLTEST_HTTPS_PROXY`
	# timesout 3x
	# TESTSSL_ARGS="$TESTSSL_ARGS --proxy=auto"

	# use torsocks instead of
	# ANALYZE_ARGS="ANALYZE_ARGS --starttls http_proxy:${PROXY_HOST}:$PROXY_PORT"
	CURL_ARGS="$CURL_ARGS -x socks5h://${SOCKS_HOST}:$SOCKS_PORT"
#?	NMAP_ARGS="$NMAP_ARGS -x socks4://${SOCKS_HOST}:$SOCKS_PORT"

    # no proxy args and no _proxy strings
    SSLSCAN_ENVS="$TORSOCKS "
    ANALYZE_ENVS="$TORSOCKS "
    # proxy timesout
    TESTSSL_ENVS="sudo -u $BOX_BYPASS_PROXY_GROUP $TESTSSL_ENVS"
    NMAP_ENVS="sudo -u $BOX_BYPASS_PROXY_GROUP "
    CURL_ENVS=" "
    return 0
}

ssltest_nmap () {
    local elt=$1
    local site=$2
    local outfile=$3
    [ -f "$outfile" ] || return 1
    local eltfile=`sed -e "s/.out/_$elt.out/" <<< $outfile`
    local exe=nmap

    DATE DBUG $elt "$NMAP_ENVS $exe $NMAP_ELTS $site" $eltfile
    INFO $elt "$NMAP_ENVS $exe $NMAP_ELTS $site"    >> $eltfile
    $NMAP_ENVS $exe $NMAP_ELTS $site >> $eltfile 2>&1
    retval=$?
    if grep -q '(1 host up)' $eltfile ; then
	if grep -q TLS_AKE_WITH_AES_256_GCM_SHA384  $eltfile ; then
    	    INFO "$elt TLS_AKE_WITH_AES_256_GCM_SHA384 = $eltfile" | tee -a $eltfile
	else
    	    INFO "$elt CA=$cacert = $eltfile" | tee -a $eltfile
	fi
    elif [ $retval -ne 0 ] ; then
    	ERROR "$elt retval=$retval timeout=$TIMEOUT CA=$cacert = $eltfile" | tee -a $eltfile
    else
	WARN $elt "NO '(1 host up)' in" $eltfile
    fi

    return 0
}

## ssltest_nmap
## no good for 1.3
ssltest_sslscan () {
    local elt=$1
    local site=$2
    local outfile=$3
    [ -f "$outfile" ] || return 1
    local eltfile=`sed -e "s/.out/_$elt.out/" <<< $outfile`
    local exe=sslscan
    [ -n "$SSL_VER" ] || { WARN no SSL_VER ; return 2 ; }

    DATE DBUG "$SSLSCAN_ENVS $exe $SSLSCAN_ELTS $site" $eltfile
    INFO "$SSLSCAN_ENVS $exe $SSLSCAN_ELTS $site"    >> $eltfile
    $SSLSCAN_ENVS $exe $SSLSCAN_ELTS $site:$SSL_PORT >> $eltfile 2>&1
    retval=$?

    # ECDHE-RSA-AES256-SHA pop.zoho.eu tls1.2
    if [ $retval -ne 0 ] ; then
	ERROR "$elt failed retval=$retval CA=$cacert = $eltfile" | tee -a $eltfile
    elif grep ERROR $eltfile ; then
	ERROR "$elt ERROR CA=$cacert = $eltfile" | tee -a $eltfile
	retval=-1
    elif grep EROR: $eltfile ; then
	ERROR "$elt EROR: CA=$cacert = $eltfile" | tee -a $eltfile
	retval=-2
    elif grep "Certificate information cannot be retrieved." $eltfile ; then
	WARN "$elt 'Certificate information cannot be retrieved' = $eltfile" | tee -a $eltfile

    elif grep "TLSv1.$SSL_VER.*disabled" $eltfile ; then
	ERROR "$elt TLSv1.$SSL_VER disabled = $eltfile" | tee -a $eltfile
	retval=-3
    elif ! grep '^\(Subject\|Altnames\).*'"$site" $eltfile ; then
	# *.zoho.eu
	WARN "$elt not 'Subject\|Altnames' = $eltfile" | tee -a $eltfile
    elif ! grep -q Accepted $eltfile ; then
	WARN "$elt not Accepted CA=$cacert = $eltfile" | tee -a $eltfile
    elif [ $SSL_VER = 3 ] && ! grep -q TLS_AES_256_GCM_SHA384 $eltfile ; then
	WARN "$elt not TLS_AES_256_GCM_SHA384 CA=$cacert = $eltfile" | tee -a $eltfile
    else
	DATE INFO "$elt Accepted CA=$cacert = $eltfile " | tee -a $eltfile
    fi
    return $retval
}

## ssltest_openssl
ssltest_openssl () {
    local elt=$1
    local site=$2
    local exe=openssl
    local outfile=$3
    [ -f "$outfile" ] || return 1
    local eltfile=`sed -e "s/.out/_$elt.out/" <<< $outfile`
    local total_s=`expr 2 \* $TIMEOUT`
    [ -n "$SSL_VER" ] || { WARN no SSL_VER ; return 2 ; }

    #  -msg -msgfile $TMPDIR/$$.$site.s_client.msg
    DATE DBUG "$elt s_client $OPENSSL_ELTS" $site $eltfile
    INFO "$exe s_client $OPENSSL_ELTS timeout=$total_s" $site >> $eltfile
    timeout $total_s $exe s_client $OPENSSL_ELTS $site < /dev/null >> $eltfile 2>&1
    retval=$?

    if [ $retval -eq 124 ] ; then
    	WARN "$elt failed timeout=$TIMEOUT CA=$cacert = $eltfile" | tee -a $eltfile
    elif [ $retval -eq 1 ] ; then
	num=`grep ':SSL alert number' $eltfile | sed -e 's/.*:SSL alert number //'`
	if [ $? -eq 0 ] && [ -n "$num" ] ; then
	    ERROR "$elt failed retval=$retval SSL alert #$num ${SSL_ALERT_CODES[$num]} CA=$cacert = $eltfile" | tee -a $eltfile
	else
	    ERROR "$elt failed retval=$retval err=${OPENSSL_X509_V[$retval]} CA=$cacert = $eltfile" | tee -a $eltfile
	    cat $eltfile
	fi
    elif grep ':error:' $eltfile ; then
	a=`grep ':error:' $eltfile | sed -e 's/^[0-9]*:[^:]*:[^:]*:[^:]*:[^:]*://' -e 's/:.*//' |head -1 `
    	ERROR "$elt :error: $a CA=$cacert = $eltfile" | tee -a $eltfile
    elif grep 'Cipher is (NONE)\|SSL handshake has read 0 bytes' $eltfile ; then
        ERROR "$elt s_client Cipher is (NONE) CA=$cacert = $eltfile" | tee -a $eltfile
    elif [ $retval -ne 0 ] ; then
    	ERROR "$elt failed retval=$retval err=${OPENSSL_X509_V[$retval]} CA=$cacert = $eltfile" | tee -a $eltfile
    elif grep 'HTTP CONNECT failed:' $eltfile ; then
    	WARN "$elt failed HTTP CONNECT failed CA=$cacert = $eltfile" | tee -a $eltfile
    elif grep 'unable to get local issuer certificate' $eltfile ; then
        WARN "$elt s_client unable to get local issuer certificate CA=$cacert = $eltfile" | tee -a $eltfile
    elif grep 'Verification error: certificate has expired' $eltfile ; then
        WARN "$elt s_client Verification error: certificate has expired = $eltfile | tee -a $eltfile" | tee -a $eltfile
    elif ! grep -q '^depth=0 CN.*'$site $eltfile  ; then
        WARN "$elt s_client CN NOT $site = $eltfile" | tee -a $eltfile

    elif grep 'OSCP response: no response' $eltfile ; then
        WARN "$elt s_client OSCP response: no response = $eltfile | tee -a $eltfile" | tee -a $eltfile
    elif grep 'New, TLSv1.$SSL_VER, Cipher is TLS' $eltfile ; then
        DATE INFO "$elt TLSv1.$SSL_VER, Cipher is TLS CA=$cacert = $eltfile " | tee -a $eltfile
    else
        DATE INFO "$elt client CA=$cacert = $eltfile " | tee -a $eltfile
    fi
    return $retval
}

## ssltest_testssl
ssltest_testssl () {
    local elt=$1
    local site=$2
    local exe=/usr/local/bin/$elt.sh
    local outfile=$3
    [ -f "$outfile" ] || return 1
    local eltfile=`sed -e "s/.out/_$elt.out/" <<< $outfile`
    local total_s=`expr 2 \* $TIMEOUT3`
    [ -n "$SSL_VER" ] || { WARN no SSL_VER ; return 2 ; }

    DATE DBUG $elt timeout $total_s "`basename $exe` $TESTSSL_ELTS $site:$SSL_PORT" $eltfile
    INFO DBUG $elt timeout $total_s "`basename $exe` $TESTSSL_ELTS $site:$SSL_PORT" >> $eltfile 2>&1
    #  TLS 1.2    offered (OK)
    #  TLS 1.3    offered (OK)
    # You should not proceed as no protocol was detected. If you still really really want to, say "YES" -->
    echo YES | timeout $total_s env $TESTSSL_ENVS $exe $TESTSSL_ELTS $site:$SSL_PORT >>$eltfile 2>&1
    retval=$?

    subdir=`grep 'DEBUG (level 1): see files in' $eltfile | sed -e 's/.* //' -e "s/[$'].*//"`
    if [ -n "$subdir" ] ; then
	subdir="${subdir::19}"
	if [ -d "$subdir" ] ; then
	    DBUG found \"$subdir\"
	    cat "$subdir"/*parse*txt >>  $eltfile
	fi
    fi
    if grep "Protocol.*TLSv1.$SSL_VER" $eltfile ; then
	# timesout after success
        DATE INFO "$elt $site Protocol : TLSv1.$SSL_VER CA=$cacert =$eltfile" | tee -a $eltfile
	retval=0
    elif grep 'TLS 1.$SSL_VER *.*offered.*(OK)' $eltfile ; then
        DATE INFO "$elt $site TLS 1.$SSL_VER offered  CA=$cacert =$eltfile" | tee -a $eltfile
	retval=0
    elif [ $retval -eq 124 ] ; then
    	WARN $elt $site "timedout timeout=$total_s CA=$cacert = $eltfile" | tee -a $eltfile
    elif grep 'TLS 1.$SSL_VER.*not offered and downgraded to a weaker protocol' $eltfile ; then
        DATE ERROR "$elt $site TLS 1.$SSL_VER NOT offered  CA=$cacert =$eltfile" | tee -a $eltfile
	retval=`expr 256 - 1`
    elif grep -q 't seem to be a TLS/SSL enabled server' $eltfile ; then
        DATE ERROR "$elt $site doesnt seem to be a TLS/SSL enabled server: CA=$cacert =$eltfile" | tee -a $eltfile
	retval=`expr 256 - 2`
    elif grep -q 'Client problem, No server cerificate could be retrieved' $eltfile ; then
        WARN  "$elt $site Client problem: CA=$cacert =$eltfile" | tee -a $eltfile
	retval=`expr 256 - 3`
    elif grep 'Fixme: something weird happened' $eltfile ; then
        WARN  "$elt $site Fixme: something weird happened CA=$cacert =$eltfile" | tee -a $eltfile
	retval=`expr 256 - 4`
    elif grep 'Oops: TCP connect problem' $eltfile ; then
        WARN  "$elt $site Oops: TCP connect problem CA=$cacert =$eltfile" | tee -a $eltfile
	retval=`expr 256 - 5`
    elif [ $retval -gt 5 ] ; then
	# returns 5
    	WARN "$elt failed retval=$retval CA=$cacert = $eltfile" | tee -a $eltfile
    elif grep ': unable to\| error:' $eltfile ; then
        ERROR "$elt.bash unable to / error: CA=$cacert = $eltfile" | tee -a $eltfile
	retval=`expr 256 - 6`
    elif grep 'unexpected error' $eltfile ; then
        ERROR "$elt.bash unexpected error CA=$cacert = $eltfile" | tee -a $eltfile
	retval=`expr 256 - 7`
    elif [ "$retval" -eq 1 ] ; then
        DATE ERROR "$elt.bash error retval=$retval: CA=$cacert = $eltfile " | tee -a $eltfile
    elif grep -q "Negotiated protocol.*TLSv1.$SSL_VER" $eltfile ; then
	# TLS_AES_256_GCM_SHA384
        DATE INFO "$elt.bash TLSv1.$SSL_VER retval=$retval: CA=$cacert = $eltfile " | tee -a $eltfile
    elif [ "$retval" -ne 0 ] ; then
	# 5 is success
        DATE WARN "$elt.bash error retval=$retval: CA=$cacert = $eltfile " | tee -a $eltfile
    else
        DATE INFO "$elt.bash no error retval=$retval: CA=$cacert = $eltfile " | tee -a $eltfile
    fi

    if grep ' VULNERABLE ' $eltfile ; then
        WARN "$elt.bash VULNERABLE: CA=$cacert = $eltfile " | tee -a $eltfile
    fi
    grep 'Overall Grade' $eltfile
    return $retval
}

## ssltest_analyze_ssl  $elt $site
ssltest_analyze_ssl () {
    local elt=$1
    local site=$2
    local exe=/usr/local/bin/analyze-ssl.pl.bash
    local outfile=$3
    [ -f "$outfile" ] || return 1
    local eltfile=`sed -e "s/.out/_$elt.out/" <<< $outfile`
    local total_s=`expr 2 \* $TIMEOUT`
    [ -n "$SSL_VER" ] || { WARN no SSL_VER ; return 2 ; }

    DATE DBUG $elt "timeout $total_s $ANALYZE_ENVS `basename $exe` $ANALYZE_ELTS $site:$SSL_PORT" $eltfile
    INFO "timeout $total_s $ANALYZE_ENVS `basename $exe` $ANALYZE_ELTS $site:$SSL_PORT" >> $eltfile
    timeout  $total_s $ANALYZE_ENVS $exe $ANALYZE_ELTS $site:$SSL_PORT >> $eltfile 2>&1
    retval=$?

    if [ ! -s $eltfile ] ; then
	ERROR "$elt failed empty $eltfile" | tee -a $eltfile
	retval=`expr 256 - 1`
    elif grep "successful connect with TLSv1_$SSL_VER" $eltfile && \
	 grep 'all certificates verified' $eltfile ; then
	# succeeds but timesout
	DATE INFO "$elt successful connect with TLSv1_$SSL_VER retval=$retval error = $eltfile" | tee -a $eltfile
    elif [ $retval -eq 124 ] ; then
    	WARN "$elt timedout timeout=$total_s CA=$cacert = $eltfile" | tee -a $eltfile
    elif [ $retval -ne 0 ] ; then
	ERROR "$elt failed retval=$retval = $eltfile" | tee -a $eltfile
    elif grep ERROR: $eltfile ; then
	ERROR "$elt failed ERROR: = $eltfile" | tee -a $eltfile
	retval=`expr 256 - 3`
    elif grep 'certificate verify - name does not match'  $eltfile ; then
	ERROR "$elt failed name does not match = $eltfile" | tee -a $eltfile
	retval=`expr 256 - 4`
    elif ! grep 'certificate verified : ok'  $eltfile ; then
	ERROR "$elt failed NO certificate verified = $eltfile" | tee -a $eltfile
	retval=`expr 256 - 5`
    elif grep 'certificate verified : FAIL'  $eltfile ; then
	ERROR "$elt certificate verified : FAIL = $eltfile" | tee -a $eltfile
	retval=`expr 256 - 6`
    elif grep 'handshake failed with HIGH' $eltfile ; then
	WARN "$elt failed handshake failed with HIGH = $eltfile" | tee -a $eltfile
	retval=`expr 256 - 7`
    elif grep '^ \! ' $eltfile ; then
	ERROR "$elt failed \! = $eltfile" | tee -a $eltfile
	retval=`expr 256 - 8`
    else
	DATE INFO "$elt no error = $eltfile" | tee -a $eltfile
    fi
    return $retval
}

## ssltest_curl
ssltest_curl () {
    local elt=$1
    local site=$2
    local exe="/usr/local/bin/s$elt.bash -- "
    local outfile=$3
    [ -f "$outfile" ] || { WARN no outfile ; return 1 ; }
    local eltfile=`sed -e "s/.out/_$elt.out/" <<< $outfile`
    local total_s=`expr 2 \* $TIMEOUT`
    local prot
    [ -n "$SSL_VER" ] || { WARN no SSL_VER ; return 2 ; }
    [ -n "$SSL_PORT" ] || { WARN no SSL_PORT ; return 3 ; }

    exe=curl
    if [ "$SSL_PORT" = 443 ] ; then
	prot=https
    elif [ "$SSL_PORT" = 995 ] ; then
	prot=pop3s
	exe=curl
	CURL_ELTS="$CURL_ELTS -l"
    elif [ "$SSL_PORT" = 587 ] ; then
	prot=smtps
	exe=curl
	# CURL_ELTS="$CURL_ELTS"
    else
	ERROR $elt unrecognized port protocol $SSL_PORT
	return 3
    fi
    DATE DBUG $elt $CURL_ENVS "`basename $exe` $CURL_ELTS ${prot}://$site:$SSL_PORT" $eltfile
    INFO $elt "$CURL_ENVS `basename $exe` $CURL_ELTS ${prot}://$site:$SSL_PORT" >> $eltfile
    $CURL_ENVS $exe $CURL_ELTS ${prot}://$site:$SSL_PORT >> $eltfile 2>&1
    retval=$?
    # grep '= /tmp/scurl'
    ERRF=$eltfile

    if [ $SSL_VER -eq 3 ] && ! grep "SSL connection using TLSv1.$SSL_VER" $ERRF ; then
    	ERROR "$elt NO SSL connection using TLSv1.$SSL_VER CA=$cacert = $ERRF" | tee -a $eltfile
	retval=`expr 256 - 1`
	cat $eltfile
    elif ! grep -q "SSL connection using TLSv1.[3$SSL_VER]" $ERRF ; then
    	ERROR "$elt NO SSL connection using TLSv1.$SSL_VER CA=$cacert = $ERRF" | tee -a $eltfile
	retval=`expr 256 - 1`
	cat $eltfile
    elif [ $retval -eq 77 ] || grep -q 'CURLE_SSL_CACERT_BADFILE' $ERRF ; then
    	ERROR "$elt retval=$retval ${CURLE[$retval]}  CAFILE=$CAFILE = $ERRF" | tee -a $eltfile
    elif [ $retval -eq 28 ] || grep -q 'CURLE_OPERATION_TIMEDOUT' $ERRF ; then
    	WARN "$elt retval=$retval CURLE_OPERATION_TIMEDOUT ${CURLE[$retval]}  CAFILE=$CAFILE = $ERRF" | tee -a $eltfile

    elif [ $retval -eq 91 ] || grep -q 'CURLE_SSL_INVALIDCERTSTATUS' $ERRF ; then
    	WARN "$elt retval=$retval ${CURLE[$retval]}  CAFILE=$CAFILE = $ERRF" | tee -a $eltfile

    elif [ $retval -eq 28 ] || grep 'Connection timed out' $ERRF ; then
    	WARN "$elt retval=$retval ${CURLE[$retval]}  CAFILE=$CAFILE = $ERRF" | tee -a $eltfile

    elif [ $retval -eq 22 ] || grep -q 'curl: (22) The requested URL returned error:' $ERRF; then
	# on 22 - change to HTTP code
	code=`grep 'curl: (22) The requested URL returned error:' $ERRF | sed -s 's/.*returned error: //'`
	if [ "$code" = 416 ] ; then
    	    INFO "$elt retval=$retval ${CURLE[$retval]} code=$code CA=$cacert = $ERRF" | tee -a $eltfile
	    retval=$code
	elif [ -n "$code" ] && [ "$code" -ge 400 ] ; then
	    # 403 Cloudflare
    	    ERROR "$elt retval=$retval ${CURLE[$retval]} code=$code CA=$cacert = $ERRF" | tee -a $eltfile
	    retval=$code
	else
    	    WARN "$elt retval=$retval ${CURLE[$retval]} code=$code CA=$cacert = $ERRF" | tee -a $eltfile
	fi

    elif [ $retval -ne 0 ] ; then
	# curl: (3) URL using bad/illegal format or missing URL - worked
    	WARN "$elt retval=$retval ${CURLE[$retval]} CA=$cacert = $ERRF" | tee -a $eltfile

    elif ! grep "subject: CN=$site" $ERRF ; then
    	ERROR "$elt NO subject: CN=$site CA=$cacert = $ERRF" | tee -a $eltfile
	retval=`expr 256 - 2`
    elif grep "503 - Forwarding failure" $ERRF ; then
    	WARN "$elt 503 - Forwarding failure CA=$cacert = $ERRF" | tee -a $eltfile
	retval=`expr 256 - 3`
    elif grep 'we are not connected'  $eltfile ; then
    	WARN  "$elt CA=$cacert = $ERRF" | tee -a $eltfile
	retval=0
    else
    	INFO  "$elt CA=$cacert = $ERRF" | tee -a $eltfile
	retval=0
    fi
    # TLSv1.3 (IN), TLS handshake, Finished
    return $retval
}

## ssllabs_analyze
ssltest_analyze () {
    local elt=$1
    local site=$2
    local exe="/usr/local/bin/scurl.bash -- "
    local outfile=$3
    [ -f "$outfile" ] || return 1
    local eltfile=`sed -e "s/.out/_$elt.html/" <<< $outfile`
    local total_s=`expr 2 \* $TIMEOUT`
    local url="https://www.ssllabs.com/ssltest/analyze.html?d=$site"
    [ -n "$SSL_VER" ] || { WARN no SSL_VER ; return 2 ; }
    umask 0022

    DATE DBUG "$elt $CURL_ELTS SSL_PORT=$SSL_PORT $url" $eltfile
    INFO "<\!-- $CURL_ENVS $elt $CURL_ELTS $url -->" >> $eltfile
    $CURL_ENVS $exe $CURL_ELTS $url  >> $eltfile 2>&1
    retval=$?
    if [ $retval -ne 0 ] ; then
        DATE WARN "$elt retval=$retval $url" $eltfile >> $outfile
    else
        DATE INFO "$elt retval=$retval $url" $eltfile >> $outfile
    fi
    return $retval
}

## ssltest_ssllabs
ssltest_ssllabs() {
    local elt=$1
    local site=$2
    local outfile=$3
    [ -f "$outfile" ] || return 1
    local site_ip=$4
    local eltfile=`sed -e "s/.out/_$elt.html/" <<< $outfile`
    local host=www.ssllabs.com
    local url="ssltest/analyze.html?d=$site&s=$site_ip"
    local exe="/usr/local/bin/scurl.bash -- "
    [ -n "$SSL_VER" ] || { WARN no SSL_VER ; return 2 ; }
    umask 0022

    DATE DBUG "$elt $CURL_ELTS $url" $eltfile
    INFO "<\!-- $CURL_ENVS $elt $CURL_ELTS $url -->" >> $eltfile
    $CURL_ENVS $exe $CURL_ELTS $url  >> $eltfile 2>&1
    retval=$?
    if [ $retval -ne 0 ] ; then
        DATE WARN "$elt retval=$retval $url" $eltfile | tee -a $eltfile
    elif grep -A 2 ">TLS 1.$SSL_VER<" $eltfile | grep 'No' ; then
        DATE ERROR "$elt retval=$retval $url" $eltfile | tee -a $eltfile
	retval=`expr 256 - 1`
    elif grep -A 2 ">TLS 1.$SSL_VER<" $eltfile | grep 'Yes' ; then
        DATE INFO "$elt retval=$retval $url" $eltfile | tee -a $eltfile
	retval=0
    else
        DATE WARN "$elt retval=$retval $url" $eltfile | tee -a $eltfile
    fi
    return $retval
}

## ssltest_http2_alt_svc
ssltest_http2_alt_svc() {
    local elt=$1
    local site=$2
    local outfile=$3
    [ -f "$outfile" ] || return 1
    local eltfile=`sed -e "s/.out/_$elt.html/" <<< $outfile`
    local exe="/usr/local/bin/scurl.bash -- "
    local host=www.integralblue.com
    local url=1.1.1.1/fun-stuff/dns-over-tor/
    [ -n "$SSL_VER" ] || { WARN no SSL_VER ; return 2 ; }
    umask 0022

    if [ -n "$socks_proxy" ] ; then
        export socks_proxy=`sed -e 's/socks[a-z0-9]*:/socks5h:/' <<< $socks_proxy`
        $exe --head --http2  -x $socks_proxy https://$host/$url > $eltfile 2>&1
      else
        $exe --head --http2 https://$host/$url > $eltfile 2>&1
    fi

    #? grep '^HTTP/2 301' $eltfile || exit 1
    grep '^HTTP/2 ' $eltfile || return 11
    grep 'alt-svc:' $eltfile || return 12
    onion=`grep 'alt-svc:' $eltfile | sed -e 's/.*h2=.//' -e 's/";.*//'` # || exit 3

    if [ -n "$socks_proxy" ] ; then
        $exe --head -x $socks_proxy https://$onion/$url >> $eltfile 2>&1
	retval=$?
    else
        $exe --head https://$onion/$url >> $eltfile 2>&1
	retval=$?
    fi
    if [ $retval -eq 0 ] ; then
	DATE INFO $elt https://$host/$url | tee -a $eltfile
    else
	DATE WARN $elt https://$host/$url | tee -a $eltfile
    fi
    return $?
}
