- fix bug where a host name like AAA.BBB.CCC.DDD.in-addr.arpa.DOMAIN.TLS was taken as an ipv4 address

- freebsd 9 supports now also colors with setaf, Darwin?
- correct indentation of help
- improved parsing in command line so that where a distinct option is required it is also tested in the 1st place
- removed -q in help (deprecated as we might want to use it for other things in the future)
- fix: if $PWD/openssl was a dir it bailed out
- cleanup of fatal errors ==> provide ONE function
This commit is contained in:
Dirk 2015-08-24 22:17:35 +02:00
parent 83bf9067aa
commit aa91990fb3

View File

@ -299,6 +299,8 @@ pr_reverse() { [[ "$COLOR" -ne 0 ]] && out "\033[7m$1" || out "$1"; pr_off;
### colorswitcher (see e.g. https://linuxtidbits.wordpress.com/2008/08/11/output-color-on-bash-scripts/
### http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x405.html
set_color_functions() {
local linux_tput=true
# empty vars if we have no color:
red=""
green=""
@ -312,7 +314,9 @@ set_color_functions() {
bold=""
underline=""
tput sgr0 || linux_tput=false
if [[ "$COLOR" -eq 2 ]]; then
if $linux_tput; then
red=$(tput setaf 1)
green=$(tput setaf 2)
brown=$(tput setaf 3)
@ -321,12 +325,29 @@ set_color_functions() {
cyan=$(tput setaf 6)
grey=$(tput setaf 7)
yellow=$(tput setaf 3; tput bold)
else # this is a try for old BSD, see terminfo(5)
red=$(tput AF 1)
green=$(tput AF 2)
brown=$(tput AF 3)
blue=$(tput AF 4)
magenta=$(tput AF 5)
cyan=$(tput AF 6)
grey=$(tput AF 7)
yellow=$(tput AF 3; tput md)
fi
fi
if [[ "$COLOR" -ge 1 ]]; then
if $linux_tput; then
bold=$(tput bold)
underline=$(tput sgr 0 1)
off=$(tput sgr0)
else # this is a try for old BSD, see terminfo(5)
bold=$(tput md)
underline=$(tput us)
reverse=$(tput mr)
off=$(tput me)
fi
fi
}
@ -570,7 +591,7 @@ run_http_date() {
detect_ipv4() {
local octet="(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])"
local ipv4address="$octet\\.$octet\\.$octet\\.$octet"
local your_ip_msg=" (check if it's yours or e.g. a cluster IP)"
local your_ip_msg="(check if it's your IP address or e.g. a cluster IP)"
local result
local first=true
local spaces=" "
@ -594,7 +615,7 @@ detect_ipv4() {
first=false
fi
pr_litered "$result"
outln "$your_ip_msg"
outln "\n$spaces$your_ip_msg"
fi
done
fi
@ -1652,6 +1673,25 @@ get_host_cert() {
return $?
}
get_all_certs() {
local savedir
local nrsaved
local ret
$OPENSSL s_client -showcerts $STARTTLS -connect $NODEIP:$PORT $PROXY $SNI 2>/dev/null </dev/null >$TEMPDIR/allcerts.txt
ret=$?
savedir=$(pwd); cd $TEMPDIR
# http://backreference.org/2010/05/09/ocsp-verification-with-openssl/
awk -v n=-1 '/-----BEGIN CERTIFICATE-----/{ inc=1; n++ }
inc { print > ("level" n ".crt") }
/---END CERTIFICATE-----/{ inc=0 }' $TEMPDIR/allcerts.txt
nrsaved=$(count_words "$(echo level?.crt 2>/dev/null)")
cd "$savedir"
echo $nrsaved
return $ret
}
tls_time() {
local now difftime
@ -1682,7 +1722,7 @@ run_server_defaults() {
local gost_status_problem=false
local extensions
local sessticket_str lifetime unit keysize sig_algo key_algo
local expire secs2warn ocsp_uri crl savedir startdate enddate issuer_c issuer_o issuer sans san cn cn_nosni
local expire secs2warn ocsp_uri crl startdate enddate issuer_c issuer_o issuer sans san cn cn_nosni
local policy_oid
local spaces=" "
@ -1785,7 +1825,7 @@ run_server_defaults() {
cn_nosni="no CN field in subject"
fi
fi
debugme out "\'$NODE\' | \'$cn\' | \'$cn_nosni\'"
debugme out "\"$NODE\" | \"$cn\" | \"$cn_nosni\""
if [[ $NODE == $cn_nosni ]]; then
if [[ $SERVICE != "HTTP" ]]; then
outln " (matches certificate directly)"
@ -1885,15 +1925,8 @@ run_server_defaults() {
outln " ($startdate --> $enddate)"
$OPENSSL s_client -showcerts $STARTTLS -connect $NODEIP:$PORT $PROXY $SNI 2>/dev/null </dev/null >$TEMPDIR/allcerts.txt
savedir=$(pwd); cd $TEMPDIR
# http://backreference.org/2010/05/09/ocsp-verification-with-openssl/
awk -v n=-1 '/-----BEGIN CERTIFICATE-----/{ inc=1; n++ }
inc { print > ("level" n ".crt") }
/---END CERTIFICATE-----/{ inc=0 }' $TEMPDIR/allcerts.txt
nrsaved=$(count_words "$(echo level?.crt 2>/dev/null)")
cd "$savedir"
pr_bold " # of certificates provided"; outln " $nrsaved"
pr_bold " # of certificates provided"; outln " $(get_all_certs)"
pr_bold " Certificate Revocation List "
crl="$($OPENSSL x509 -in $HOSTCERT -noout -text | grep -A 4 "CRL Distribution" | grep URI | sed 's/^.*URI://')"
@ -2152,7 +2185,7 @@ fd_socket() {
done
elif ! exec 5<>/dev/tcp/$NODEIP/$PORT; then # 2>/dev/null would remove an error message, but disables debugging
outln
pr_magentaln "Unable to open a socket to $NODEIP:$PORT. "
pr_magenta "Unable to open a socket to $NODEIP:$PORT. "
# It can last ~2 minutes but for for those rare occasions we don't do a timeout handler here, KISS
return 6
fi
@ -2184,7 +2217,7 @@ fd_socket() {
starttls_line "a002 STARTTLS" "OK"
;;
ldap) # LDAP, https://tools.ietf.org/html/rfc2830, https://tools.ietf.org/html/rfc4511
pr_magentaln "FIXME: LDAP/STARTTLS not yet supported"
pr_magentaln "FIXME: LDAP+STARTTLS over sockets not yet supported (try \"--ssl-native\")"
exit -4
;;
acap) # ACAP = Application Configuration Access Protocol, see https://tools.ietf.org/html/rfc2595
@ -3444,9 +3477,8 @@ run_tls_truncation() {
}
old_fart() {
pr_magentaln "Your $OPENSSL $OSSL_VER version is an old fart... . It doesn\'t make much sense to proceed."
outln "Get precompiled bins or compile https://github.com/PeterMosmans/openssl ."
exit -2
fatal "Your $OPENSSL $OSSL_VER version is an old fart... . It doesn\'t make much sense to proceed." -2
}
# try very hard to determine th install path to get ahold of the mapping file
@ -3484,14 +3516,13 @@ test_openssl_suffix() {
local uname_arch=$(uname -m)
[[ $uname_arch =~ "64" ]] && myarch_suffix=64 || myarch_suffix=32
if [[ -n "$1/openssl" ]] && [[ -x "$1/openssl" ]]; then
if [[ -f "$1/openssl" ]] && [[ -x "$1/openssl" ]]; then
OPENSSL="$1/openssl"
return 0
elif [[ -n "$1/openssl.$naming_ext" ]] && [[ -x "$1/openssl.$naming_ext" ]]; then
elif [[ -f "$1/openssl.$naming_ext" ]] && [[ -x "$1/openssl.$naming_ext" ]]; then
OPENSSL="$1/openssl.$naming_ext"
return 0
elif [[ -n "$1/openssl.$uname_arch" ]] && [[ -x "$1/openssl.$uname_arch" ]]; then
elif [[ -f "$1/openssl.$uname_arch" ]] && [[ -x "$1/openssl.$uname_arch" ]]; then
OPENSSL="$1/openssl.$uname_arch"
return 0
fi
@ -3506,7 +3537,7 @@ find_openssl_binary() {
[[ $uname_arch =~ "64" ]] && myarch_suffix=64 || myarch_suffix=32
# 0. check environment variable whether it's executable
if [[ -n "$OPENSSL" ]] && [[ ! -x "$OPENSSL" ]]; then
pr_red "\ncannot find specified (\$OPENSSL=$OPENSSL) binary."
pr_litemagentaln "\ncannot find specified (\$OPENSSL=$OPENSSL) binary."
outln " Looking some place else ..."
elif [[ -x "$OPENSSL" ]]; then
: # 1. all ok supplied $OPENSSL is excutable
@ -3516,9 +3547,9 @@ find_openssl_binary() {
: # 3. otherwise here, this is supposed to be the standard --platform independed path in the future!!!
elif [[ -x "$RUN_DIR/openssl-bins/openssl-1.0.2-chacha.pm/openssl"$myarch_suffix"-1.0.2pm-krb5" ]]; then
OPENSSL="$RUN_DIR/openssl-bins/openssl-1.0.2-chacha.pm/openssl"$myarch_suffix"-1.0.2pm-krb5"
# 4. legacy dirs follow, first kerberos binaries from pm (if executable)
# 4. legacy dirs follow, first kerberos binaries from pm (if executable) ^^^^ deprecated!
elif [[ -x "$RUN_DIR/openssl-bins/openssl-1.0.2-chacha.pm/openssl"$myarch_suffix"-1.0.2pm-static" ]]; then
# 5. otherwise default is trying the statically linked ones
# 5. otherwise default is trying the statically linked ones ^^^^ deprecated!
OPENSSL="$RUN_DIR/openssl-bins/openssl-1.0.2-chacha.pm/openssl"$myarch_suffix"-1.0.2pm-static"
elif test_openssl_suffix $(dirname $(which openssl)); then
: # 5. we tried hard and failed, so now we use the system binaries
@ -3526,9 +3557,7 @@ find_openssl_binary() {
$OPENSSL version -a 2>/dev/null >/dev/null
if [ $? -ne 0 ] || [ ! -x "$OPENSSL" ]; then
outln
pr_magentaln "FATAL: cannot exec or find any openssl binary "
exit -1
fatal "cannot exec or find any openssl binary" -1
fi
# http://www.openssl.org/news/openssl-notes.html
@ -3645,7 +3674,7 @@ tuning options:
--openssl <PATH> use this openssl binary (default: look in \$PATH, \$RUN_DIR of $PROG_NAME
--proxy <host>:<port> connect via the specified HTTP proxy
--sneaky be less verbose wrt referer headers
-q. --quiet don't out put the banner. By doing this you acknowledge usage terms normally appearing in the banner
--quiet don't output the banner. By doing this you acknowledge usage terms normally appearing in the banner
--wide wide output for tests like RC4, BEAST. PFS also with hexcode, kx, strength, RFC name
--show-each for wide outputs: display all ciphers tested -- not only succeeded ones
--warnings <batch|off|false> "batch" doesn't wait for keypress, "off" or "false" skips connection warning
@ -3893,6 +3922,8 @@ is_ipv4addr() {
local ipv4address="$octet\\.$octet\\.$octet\\.$octet"
[[ -z "$1" ]] && return 1
# more than numbers, important for hosts like AAA.BBB.CCC.DDD.in-addr.arpa.DOMAIN.TLS
[[ -n $(tr -d '[0-9\.]' <<< "$1") ]] && return 1
echo -n "$1" | grep -Eq $ipv4address && \
return 0 || \
@ -3901,7 +3932,6 @@ is_ipv4addr() {
# a bit easier
is_ipv6addr() {
[[ -z "$1" ]] && return 1
# less than 2x ":"
[[ $(count_lines "$(echo -n "$1" | tr ':' '\n')") -le 1 ]] && \
@ -4025,7 +4055,7 @@ determine_ip_addresses() {
SNI="" # override Server Name Indication as we test the IP only
else
ip4=$(get_local_a $NODE) # is there a local host entry?
if [ -z $ip4 ]; then # empty: no (LOCAL_A is predefined as false)
if [[ -z $ip4 ]]; then # empty: no (LOCAL_A is predefined as false)
ip4=$(get_a_record $NODE)
else
LOCAL_A=true # we have the ip4 from local host entry and need to set this
@ -4041,9 +4071,7 @@ determine_ip_addresses() {
fi
IPADDRs=$(newline_to_spaces "$ip4")
if [[ -z "$IPADDRs" ]] && [[ -z "$CMDLINE_IP" ]] ; then
pr_magenta "Can't proceed: No IPv4 address for \"$NODE\" available"
outln "\n"
exit -1
fatal "No IPv4 address for \"$NODE\" available" -1
fi
[[ -z "$ip6" ]] && IP46ADDRs="$IPADDRs" || IP46ADDRs="$ip4 $ip6"
IP46ADDRs=$(newline_to_spaces "$IP46ADDRs")
@ -4086,6 +4114,11 @@ get_mx_record() {
echo "$mxs"
}
fatal() {
pr_magentaln "Fatal error: $1"
exit $2
}
# We need to get the IP address of the proxy so we can use it in fd_socket
check_proxy(){
@ -4094,8 +4127,7 @@ check_proxy(){
if [[ -n "$PROXY" ]]; then
if ! $OPENSSL s_client help 2>&1 | grep -qw proxy; then
pr_magentaln "Local problem: Your $OPENSSL is too old to support the \"--proxy\" option"
exit -1
fatal "Your $OPENSSL is too old to support the \"--proxy\" option" -1
fi
PROXYNODE=${PROXY%:*}
PROXYPORT=${PROXY#*:}
@ -4105,10 +4137,7 @@ check_proxy(){
LOCAL_AAAA=$save_LOCAL_AAAA
# no RFC 1918:
#if ! is_ipv4addr $PROXYIP ; then
if [[ -z "$PROXYIP" ]]; then
pr_magentaln "Fatal error: Proxy IP cannot be determined from \"$PROXYNODE\""
exit -3
fi
[[ -z "$PROXYIP" ]] && fatal "Proxy IP cannot be determined from \"$PROXYNODE\"" "-3"
PROXY="-proxy $PROXYIP:$PROXYPORT"
fi
}
@ -4121,9 +4150,7 @@ determine_service() {
local protocol
if ! fd_socket; then # check if we can connect to $NODEIP:$PORT
pr_magentaln "Fatal error: can't connect to $NODEIP:$PORT"
outln "\nMake sure a firewall is not between you and your scanning target"
exit -2
fatal "can't connect to \"$NODEIP:$PORT\"\nMake sure a firewall is not between you and your scanning target!" -2
fi
close_socket
@ -4163,9 +4190,7 @@ determine_service() {
if [[ -n "$XMPP_HOST" ]] ; then
if ! $OPENSSL s_client --help 2>&1 | grep -q xmpphost; then
outln
pr_magentaln " Local problem: Your $OPENSSL does not support the \"-xmpphost\" option"
exit -3
fatal "Your $OPENSSL does not support the \"-xmpphost\" option" -3
fi
STARTTLS="$STARTTLS -xmpphost $XMPP_HOST" # it's a hack -- instead of changing calls all over the place
# see http://xmpp.org/rfcs/rfc3920.html
@ -4409,6 +4434,12 @@ parse_cmd_line() {
do_starttls=true
STARTTLS_PROTOCOL=$(parse_opt_equal_sign "$1" "$2")
[[ $? -eq 0 ]] && shift
case $STARTTLS_PROTOCOL in
ftp|smtp|pop3|imap|xmpp|telnet|ldap) ;;
ftps|smtps|pop3s|imaps|xmpps|telnets|ldaps) ;;
*) pr_magentaln "\nunrecognized STARTTLS protocol \"$1\", see help" 1>&2
help 1 ;;
esac
;;
--xmpphost|--xmpphost=*)
XMPP_HOST=$(parse_opt_equal_sign "$1" "$2")
@ -4538,7 +4569,8 @@ parse_cmd_line() {
[[ $? -eq 0 ]] && shift
case "$WARNING" in
batch|off|false) ;;
default) pr_magentaln "warnings can be either \"batch\", \"off\" or \"false\"" ;;
*) pr_magentaln "\nwarnings can be either \"batch\", \"off\" or \"false\""
help 1;;
esac
;;
--show[-_]each)
@ -4547,15 +4579,21 @@ parse_cmd_line() {
--debug|--debug=*)
DEBUG=$(parse_opt_equal_sign "$1" "$2")
[[ $? -eq 0 ]] && shift
case $DEBUG in
[0-6]) ;;
*) pr_magentaln "\nunrecognized debug value \"$1\", must be between 0..6" 1>&2
help 1 ;;
esac
;;
--color|--color=*)
COLOR=$(parse_opt_equal_sign "$1" "$2")
[[ $? -eq 0 ]] && shift
if [ $COLOR -ne 0 ] && [ $COLOR -ne 1 ] && [ $COLOR -ne 2 ] ; then
COLOR=2
pr_magentaln "$0: unrecognized color: $2" 1>&2
help 1
fi
case $COLOR in
[0-2]) ;;
*) COLOR=2
pr_magentaln "\nunrecognized color: \"$1\", must be between 0..2" 1>&2
help 1 ;;
esac
;;
--openssl|--openssl=*)
OPENSSL=$(parse_opt_equal_sign "$1" "$2")
@ -4571,7 +4609,7 @@ parse_cmd_line() {
(--) shift
break
;;
(-*) pr_magentaln "$0: unrecognized option $1" 1>&2;
(-*) pr_magentaln "\n$0: unrecognized option \"$1\"" 1>&2;
help 1
;;
(*) break
@ -4581,10 +4619,10 @@ parse_cmd_line() {
done
# Show usage if no options were specified
[ -z $1 ] && help 0
[[ -z "$1" ]] && help 0
# left off here is the URI
URI=$1
URI="$1"
[ "$DEBUG" -ge 4 ] && debug_globals
# if we have no "do_*" set here --> query_globals: we do a standard run -- otherwise just the one specified
@ -4595,7 +4633,7 @@ parse_cmd_line() {
lets_roll() {
local ret
[ -z "$NODEIP" ] && pr_magentaln "$NODE doesn't resolve to an IP address" && exit -1
[ -z "$NODEIP" ] && fatal "$NODE doesn't resolve to an IP address" -1
determine_rdns
determine_service "$1" # any starttls service goes here
@ -4671,8 +4709,7 @@ ip=""
if $do_read_from_file; then
if [[ ! -r "$FNAME" ]] && $IKNOW_FNAME; then
pr_magentaln "Fatal error: Can't read \"$FNAME\""
exit -1
fatal "Can't read file \"$FNAME\"" "-1"
fi
pr_reverse "====== Running in file batch mode with file=\"$FNAME\" ======"; outln "\n"
cat "$FNAME" | while read cmdline; do
@ -4694,8 +4731,8 @@ if $do_mx_all_ips; then
ret=$?
else
parse_hn_port "${URI}" # NODE, URL_PATH, PORT, IPADDR and IP46ADDR is set now
if ! determine_ip_addresses && [[ -z $CMDLINE_IP ]]; then
pr_magentaln "fatal error: No IP address could be determined"
if ! determine_ip_addresses && [[ -z "$CMDLINE_IP" ]]; then
fatal "No IP address could be determined"
fi
if [[ -n "$CMDLINE_IP" ]]; then
[[ "$CMDLINE_IP" == "one" ]] && \
@ -4727,4 +4764,4 @@ fi
exit $ret
# $Id: testssl.sh,v 1.353 2015/08/23 19:16:33 dirkw Exp $
# $Id: testssl.sh,v 1.357 2015/08/24 12:09:44 dirkw Exp $