From 004cbad07b03480079c2bebc8d2a32d55a1a0d7b Mon Sep 17 00:00:00 2001 From: David Cooper Date: Tue, 14 Feb 2017 16:43:46 -0500 Subject: [PATCH 1/3] run_protocols() bug fix Since the test for TLS 1.2 in `run_protocols()` now uses `tls_sockets()` whenever `$ssl_native` is `true` (i.e., there is no longer a requirement for `$EXPERIMENTAL` to be true as well), the `$EXPERIMENTAL` flag should no longer be checked if the return value is 1. --- testssl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index 4d98c64..5e437ea 100755 --- a/testssl.sh +++ b/testssl.sh @@ -4506,7 +4506,7 @@ run_protocols() { ;; # GCM cipher in TLS 1.2: very good! 1) pr_svrty_mediumln "not offered" - if ! "$using_sockets" || ! "$EXPERIMENTAL" || [[ -z $latest_supported ]]; then + if ! "$using_sockets" || [[ -z $latest_supported ]]; then fileout "tls1_2" "MEDIUM" "TLSv1.2 is not offered" # no GCM, penalty else pr_svrty_criticalln " -- connection failed rather than downgrading to $latest_supported_string" From 2456c808217c847699712fd10860d7659495cd31 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Wed, 15 Feb 2017 11:47:11 -0500 Subject: [PATCH 2/3] Fix early newline In the case that `tls_sockets()` is being used and the server incorrectly fails the connection rather than downgrading, testssl.sh is printing "not offered" on one line and then the error message on the next line, but all the text should appear on one line (as it does when testing TLS 1 and TLS 1.1). --- testssl.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index 8f8de5f..874c139 100755 --- a/testssl.sh +++ b/testssl.sh @@ -4505,8 +4505,9 @@ run_protocols() { add_tls_offered "tls1_2" ;; # GCM cipher in TLS 1.2: very good! 1) - pr_svrty_mediumln "not offered" + pr_svrty_medium "not offered" if ! "$using_sockets" || [[ -z $latest_supported ]]; then + outln fileout "tls1_2" "MEDIUM" "TLSv1.2 is not offered" # no GCM, penalty else pr_svrty_criticalln " -- connection failed rather than downgrading to $latest_supported_string" From c204a0b9429eca35350fd2653c7be11d7636565a Mon Sep 17 00:00:00 2001 From: Dirk Date: Wed, 15 Feb 2017 19:40:06 +0100 Subject: [PATCH 3/3] --proxy=auto takes now the value from https_proxy - made DNS lookups safe (CNAME) and awk'd them almost completely ;-) - invocation of just testssl.sh shows help again --- testssl.sh | 66 +++++++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/testssl.sh b/testssl.sh index eb48614..dc125cb 100755 --- a/testssl.sh +++ b/testssl.sh @@ -6994,7 +6994,7 @@ spdy_pre(){ return 1 fi if [[ -n "$PROXY" ]]; then - [[ -n "$1" ]] && pr_warning " $1 " + [[ -n "$1" ]] && pr_warning "$1" pr_warning "not tested as proxies do not support proxying it" fileout "spdy_npn" "WARN" "SPDY/NPN : not tested as proxies do not support proxying it" return 1 @@ -7033,7 +7033,7 @@ run_spdy() { local -i ret=0 pr_bold " SPDY/NPN " - if ! spdy_pre ; then + if ! spdy_pre; then outln return 0 fi @@ -7071,7 +7071,7 @@ run_http2() { local alpn_finding="" pr_bold " HTTP2/ALPN " - if ! http2_pre ; then + if ! http2_pre; then outln return 0 fi @@ -11138,8 +11138,8 @@ tuning / connect options (most also can be preset via environment variables): --assume-http if protocol check fails it assumes HTTP protocol and enforces HTTP checks --ssl-native fallback to checks with OpenSSL where sockets are normally used --openssl use this openssl binary (default: look in \$PATH, \$RUN_DIR of $PROG_NAME) - --proxy : connect via the specified HTTP proxy - -6 use also IPv6. Works only with supporting OpenSSL version and IPv6 connectivity + --proxy connect via the specified HTTP proxy, auto: autodetermination from \$env (\$http(s)_proxy) + -6 also use IPv6. Works only with supporting OpenSSL version and IPv6 connectivity --ip a) tests the supplied v4 or v6 address instead of resolving host(s) in URI b) arg "one" means: just test the first DNS returns (useful for multiple IPs) -n, --nodns do not try any DNS lookup @@ -11584,9 +11584,9 @@ check_resolver_bins() { } # arg1: a host name. Returned will be 0-n IPv4 addresses +# watch out: $1 can also be a cname! --> all checked get_a_record() { local ip4="" - local cname_temp="" local saved_openssl_conf="$OPENSSL_CONF" "$NODNS" && return 0 # if no DNS lookup was instructed, leave here @@ -11602,25 +11602,20 @@ get_a_record() { fi if [[ -z "$ip4" ]]; then if which dig &> /dev/null ; then - cname_temp=$(dig +short -t CNAME "$1" 2>/dev/null) - if [[ -n "$cname_temp" ]]; then - ip4=$(filter_ip4_address $(dig +short -t a "$cname_temp" 2>/dev/null | sed '/^;;/d')) - else - ip4=$(filter_ip4_address $(dig +short -t a "$1" 2>/dev/null | sed '/^;;/d')) - fi + ip4=$(filter_ip4_address $(dig +short -t a "$1" 2>/dev/null | awk '/^[0-9]/')) fi fi if [[ -z "$ip4" ]]; then which host &> /dev/null && \ - ip4=$(filter_ip4_address $(host -t a "$1" 2>/dev/null | grep -v alias | sed 's/^.*address //')) + ip4=$(filter_ip4_address $(host -t a "$1" 2>/dev/null | awk '/address/ { print $NF }')) fi if [[ -z "$ip4" ]]; then which drill &> /dev/null && \ - ip4=$(filter_ip4_address $(drill a "$1" 2>/dev/null | awk '/^\;\;\sANSWER\sSECTION\:$/,/\;\;\sAUTHORITY\sSECTION\:$/ { print $5,$6 }' | sed '/^\s$/d')) + ip4=$(filter_ip4_address $(drill a "$1" | awk '/ANSWER SECTION/,/AUTHORITY SECTION/ { print $NF }' | awk '/^[0-9]/')) fi if [[ -z "$ip4" ]]; then if which nslookup &>/dev/null; then - ip4=$(filter_ip4_address $(nslookup -querytype=a "$1" 2>/dev/null | awk '/^Name/,/EOF/ { print $0 }' | grep -v Name)) + ip4=$(filter_ip4_address $(nslookup -querytype=a "$1" 2>/dev/null | awk '/^Name/ { getline; print $NF }')) fi fi OPENSSL_CONF="$saved_openssl_conf" # see https://github.com/drwetter/testssl.sh/issues/134 @@ -11628,6 +11623,7 @@ get_a_record() { } # arg1: a host name. Returned will be 0-n IPv6 addresses +# watch out: $1 can also be a cname! --> all checked get_aaaa_record() { local ip6="" local saved_openssl_conf="$OPENSSL_CONF" @@ -11637,20 +11633,20 @@ get_aaaa_record() { if [[ -z "$ip6" ]]; then if [[ "$NODE" == *.local ]]; then if which avahi-resolve &>/dev/null; then - ip6=$(filter_ip6_address $(avahi-resolve -6 -n "$NODE" 2>/dev/null | awk '{ print $2 }')) + ip6=$(filter_ip6_address $(avahi-resolve -6 -n "$1" 2>/dev/null | awk '{ print $2 }')) elif which dig &>/dev/null; then ip6=$(filter_ip6_address $(dig @ff02::fb -p 5353 -t aaaa +short +notcp "$NODE")) else fatal "Local hostname given but no 'avahi-resolve' or 'dig' avaliable." -3 fi elif which host &> /dev/null ; then - ip6=$(filter_ip6_address $(host -t aaaa "$NODE" | grep -v alias | grep -v "no AAAA record" | sed 's/^.*address //')) + ip6=$(filter_ip6_address $(host -t aaaa "$1" | awk '/address/ { print $NF }')) elif which dig &> /dev/null; then - ip6=$(filter_ip6_address $(dig +short -t aaaa "$NODE" 2>/dev/null)) + ip6=$(filter_ip6_address $(dig +short -t aaaa "$1" 2>/dev/null | awk '/^[0-9]/')) elif which drill &> /dev/null; then - ip6=$(filter_ip6_address $(drill aaaa "$NODE" 2>/dev/null | awk '/^\;\;\sANSWER\sSECTION\:$/,/^\;\;\sAUTHORITY\sSECTION\:$/ { print $5,$6 }' | sed '/^\s$/d')) + ip6=$(filter_ip6_address $(drill aaaa "$1" | awk '/ANSWER SECTION/,/AUTHORITY SECTION/ { print $NF }' | awk '/^[0-9]/')) elif which nslookup &>/dev/null; then - ip6=$(filter_ip6_address $(nslookup -type=aaaa "$NODE" 2>/dev/null | grep -A10 Name | grep -v Name)) + ip6=$(filter_ip6_address $(nslookup -type=aaaa "$1" 2>/dev/null | awk '/'"^${a}"'.*AAAA/ { print $NF }')) fi fi OPENSSL_CONF="$saved_openssl_conf" # see https://github.com/drwetter/testssl.sh/issues/134 @@ -11678,8 +11674,7 @@ get_caa_rr_record() { raw_caa="$(dig $1 type257 +short)" # empty if no CAA record elif which drill &> /dev/null; then - a="$1" - raw_caa="$(drill $a type257 | awk '/'"^${a}"'.*CAA/ { print $5,$6,$7 }')" + raw_caa="$(drill $1 type257 | awk '/'"^${1}"'.*CAA/ { print $5,$6,$7 }')" elif which host &> /dev/null; then raw_caa="$(host -t type257 $1)" if egrep -wvq "has no CAA|has no TYPE257" <<< "$raw_caa"; then @@ -11725,18 +11720,20 @@ get_caa_rr_record() { return 0 } +# watch out: $1 can also be a cname! --> all checked get_mx_record() { local mx="" local saved_openssl_conf="$OPENSSL_CONF" OPENSSL_CONF="" # see https://github.com/drwetter/testssl.sh/issues/134 check_resolver_bins + # we need tha last two columns here! if which host &> /dev/null; then mxs=$(host -t MX "$1" 2>/dev/null | awk '/is handled by/ { print $(NF-1), $NF }') elif which dig &> /dev/null; then - mxs=$(dig +short -t MX "$1" 2>/dev/null) + mxs=$(dig +short -t MX "$1" 2>/dev/null | awk '/^[0-9]/') elif which drill &> /dev/null; then - mxs=$(drill mx "$1" 2>/dev/null | awk '/^\;\;\sANSWER\sSECTION\:$/,/\;\;\sAUTHORITY\sSECTION\:$/ { print $5,$6 }' | sed '/^\s$/d') + mxs=$(drill mx $1 | | awk '/IN[ \t]MX[ \t]+/ { print $(NF-1), $NF }') elif which nslookup &> /dev/null; then mxs=$(nslookup -type=MX "$1" 2>/dev/null | awk '/mail exchanger/ { print $(NF-1), $NF }') else @@ -11824,7 +11821,7 @@ determine_rdns() { elif which host &> /dev/null; then rDNS=$(host -t PTR $nodeip 2>/dev/null | awk '/pointer/ { print $NF }') elif which drill &> /dev/null; then - rDNS=$(drill -x ptr $nodeip 2>/dev/null | awk '/^\;\;\sANSWER\sSECTION\:$/,/\;\;\sAUTHORITY\sSECTION\:$/ { print $5,$6 }' | sed '/^\s$/d') + rDNS=$(drill -x ptr $nodeip 2>/dev/null | awk '/ANSWER SECTION/ { getline; print $NF }') elif which nslookup &> /dev/null; then rDNS=$(nslookup -type=PTR $nodeip 2>/dev/null | grep -v 'canonical name =' | grep 'name = ' | awk '{ print $NF }' | sed 's/\.$//') fi @@ -11841,18 +11838,23 @@ check_proxy() { if ! "$HAS_PROXY"; then fatal "Your $OPENSSL is too old to support the \"-proxy\" option" -5 fi + if [[ "$PROXY" == "auto" ]]; then + # get $ENV + PROXY=${https_proxy#*\/\/} + [[ -z "$PROXY" ]] && PROXY=${http_proxy#*\/\/} + [[ -z "$PROXY" ]] && fatal "you specified \"--proxy=auto\" but \"\$http(s)_proxy\" is empty" 2 + fi PROXYNODE=${PROXY%:*} PROXYPORT=${PROXY#*:} - is_number "$PROXYPORT" || fatal "Proxy port cannot be determined from \"$PROXY\"" "2" + is_number "$PROXYPORT" || fatal "Proxy port cannot be determined from \"$PROXY\"" 2 #if is_ipv4addr "$PROXYNODE" || is_ipv6addr "$PROXYNODE" ; then # IPv6 via openssl -proxy: that doesn't work. Sockets does -#FIXME: to finish this with LibreSSL which supports an IPv6 proxy +#FIXME: finish this with LibreSSL which supports an IPv6 proxy if is_ipv4addr "$PROXYNODE"; then PROXYIP="$PROXYNODE" else - check_resolver_bins - PROXYIP=$(get_a_record $PROXYNODE 2>/dev/null | grep -v alias | sed 's/^.*address //') + PROXYIP=$(get_a_record "$PROXYNODE" 2>/dev/null | grep -v alias | sed 's/^.*address //') [[ -z "$PROXYIP" ]] && fatal "Proxy IP cannot be determined from \"$PROXYNODE\"" "2" fi PROXY="-proxy $PROXYIP:$PROXYPORT" @@ -12274,6 +12276,8 @@ parse_opt_equal_sign() { parse_cmd_line() { + # Show usage if no options were specified + [[ -z "$1" ]] && help 0 # Set defaults if only an URI was specified, maybe ToDo: use "="-option, then: ${i#*=} i.e. substring removal [[ "$#" -eq 1 ]] && set_scanning_defaults @@ -12604,7 +12608,7 @@ parse_cmd_line() { (--) shift break ;; - (-*) pr_magentaln "0: unrecognized option \"$1\"" 1>&2; + (-*) pr_warningln "0: unrecognized option \"$1\"" 1>&2; help 1 ;; (*) break @@ -12613,7 +12617,7 @@ parse_cmd_line() { shift done - # Show usage if no options were specified + # Show usage if no further options were specified if [[ -z "$1" ]] && [[ -z "$FNAME" ]] && ! $do_display_only; then echo && fatal "URI missing" "1" else