diff --git a/testssl.sh b/testssl.sh index bd74d77..69bcea0 100755 --- a/testssl.sh +++ b/testssl.sh @@ -158,7 +158,7 @@ HAS_OPENBSDDATE=false if date -d @735275209 >/dev/null 2>&1; then if date -r @735275209 >/dev/null 2>&1; then # it can't do any conversion from a plain date output - HAS_OPENBSDDATE=true + HAS_OPENBSDDATE=true else HAS_GNUDATE=true fi @@ -277,6 +277,7 @@ HTMLHEADER=true # same for HTML SECTION_FOOTER_NEEDED=false # kludge for tracking whether we need to close the JSON section object GIVE_HINTS=false # give an additional info to findings SERVER_SIZE_LIMIT_BUG=false # Some servers have either a ClientHello total size limit or a 128 cipher limit (e.g. old ASAs) +MULTIPLE_CHECKS=false # need to know whether an MX record or a hostname resolves to multiple IPs to check CHILD_MASS_TESTING=${CHILD_MASS_TESTING:-false} HAD_SLEPT=0 NR_SOCKET_FAIL=0 # Counter for socket failures @@ -1937,7 +1938,7 @@ service_detection() { # connectivity_problem() { if [[ $1 -lt $2 ]]; then - prln_warning "Oops: $3" + prln_warning " Oops: $3" return 0 fi if [[ $1 -ge $2 ]]; then @@ -3241,7 +3242,7 @@ neat_list(){ [[ "$DISPLAY_CIPHERNAMES" != openssl-only ]] && tls_cipher="$(show_rfc_style "$hexcode")" - if [[ "$5" != "true" ]]; then + if [[ "$5" != true ]]; then if [[ "$DISPLAY_CIPHERNAMES" =~ rfc ]]; then line="$(printf -- " %-7s %-49s %-10s %-12s%-8s" "$hexcode" "$tls_cipher" "$kx" "$enc" "$strength")" [[ "$DISPLAY_CIPHERNAMES" != rfc-only ]] && line+="$(printf -- " %-33s${SHOW_EACH_C:+ %-0s}" "$ossl_cipher")" @@ -3601,15 +3602,6 @@ run_cipher_match(){ done "$using_sockets" && HAS_DH_BITS="$has_dh_bits" tmpfile_handle ${FUNCNAME[0]}.txt - stopwatch run_cipher_match - fileout_section_footer true - outln - calc_scantime - datebanner " Done" - - "$MEASURE_TIME" && printf "%${COLUMNS}s\n" "$SCAN_TIME" - [[ -e "$MEASURE_TIME_FILE" ]] && echo "Total : $SCAN_TIME " >> "$MEASURE_TIME_FILE" - exit done outln @@ -9438,6 +9430,9 @@ fd_socket() { imap|imaps) # IMAP, https://tools.ietf.org/html/rfc2595, https://tools.ietf.org/html/rfc3501 starttls_imap_dialog ;; + irc|ircs) # IRC, https://ircv3.net/specs/extensions/tls-3.1.html, https://ircv3.net/specs/core/capability-negotiation.html + fatal "FIXME: IRC+STARTTLS not yet supported" $ERR_NOSUPPORT + ;; ldap|ldaps) # LDAP, https://tools.ietf.org/html/rfc2830, https://tools.ietf.org/html/rfc4511 fatal "FIXME: LDAP+STARTTLS over sockets not yet supported (try \"--ssl-native\")" $ERR_NOSUPPORT ;; @@ -9459,7 +9454,7 @@ fd_socket() { esac fi [[ $? -eq 0 ]] && return 0 - prln_warning "STARTTLS handshake failed" + prln_warning " STARTTLS handshake failed" return 1 } @@ -16246,9 +16241,11 @@ child_error() { exit $ERR_CHILD } + +# Program terminates prematurely, with error code # arg1: string to print / to write to file -# arg2: error code, is a global, see ERR_* above -# arg3: an optional string +# arg2: global error code, see ERR_* above +# arg3: an optional hint (string) # fatal() { outln @@ -16262,6 +16259,18 @@ fatal() { exit $2 } +# This OTOH doesn't exit but puts a fatal error to the screen but continues with the next +# IP/hostname. It should only be used if a single IP/Hostname in a scan is not reachable. +# arg1: string to print / to write to file +# +ip_fatal() { + outln + prln_magenta "Fatal error: $1, proceeding with next IP (if any)" >&2 + [[ -n "$LOGFILE" ]] && prln_magenta "Fatal error: $1, proceeding with next IP (if any)" >>$LOGFILE + outln + fileout "scanProblem" "FATAL" "$1, proceeding with next IP (if any)" + return 0 +} initialize_engine(){ # for now only GOST engine @@ -16895,21 +16904,26 @@ determine_optimal_proto() { } -# arg1: ftp smtp, lmtp, pop3, imap, xmpp, telnet, ldap, postgres, mysql (maybe with trailing s) +# arg1: ftp smtp, lmtp, pop3, imap, xmpp, telnet, ldap, postgres, mysql, irc, nntp (maybe with trailing s) determine_service() { local ua - local protocol + local protocol error_msg - if ! fd_socket 5; then # check if we can connect to $NODEIP:$PORT + # check if we can connect to $NODEIP:$PORT + if ! fd_socket 5; then if [[ -n "$PROXY" ]]; then fatal "You're sure $PROXYNODE:$PROXYPORT allows tunneling here? Can't connect to \"$NODEIP:$PORT\"" $ERR_CONNECT else - fatal "Can't connect to \"$NODEIP:$PORT\"\nMake sure a firewall is not between you and your scanning target!" $ERR_CONNECT + if "$MULTIPLE_CHECKS"; then + ip_fatal "Couldn't connect to $NODEIP:$PORT" + return 1 + else + fatal "Can't connect to \"$NODEIP:$PORT\"\nMake sure a firewall is not between you and your scanning target!" $ERR_CONNECT + fi fi fi close_socket - datebanner " Start" outln if [[ -z "$1" ]]; then # no STARTTLS. @@ -16926,6 +16940,7 @@ determine_service() { else protocol=${1%s} # strip trailing 's' in ftp(s), smtp(s), pop3(s), etc fi + case "$protocol" in ftp|smtp|lmtp|pop3|imap|xmpp|telnet|ldap|postgres|mysql|nntp) STARTTLS="-starttls $protocol" @@ -16973,12 +16988,20 @@ determine_service() { fatal "Your $OPENSSL does not support the \"-starttls nntp\" option" $ERR_OSSLBIN fi fi + $OPENSSL s_client $(s_client_options "-connect $NODEIP:$PORT $PROXY $BUGS $STARTTLS") 2>$ERRFILE >$TMPFILE