Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Fix problems with early errors #1398

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 33 additions & 23 deletions testssl.sh
Original file line number Diff line number Diff line change
@@ -275,6 +275,10 @@ FIRST_FINDING=true # is this the first finding we are outpu
JSONHEADER=true # include JSON headers and footers in HTML file, if one is being created
CSVHEADER=true # same for CSV
HTMLHEADER=true # same for HTML
JSONFILENAME_SET=false # Indicates whether json_header() has been called to set up JSONFILE.
CSVFILENAME_SET=false # Indicates whether csv_header() has been called to set up CSVFILE.
HTMLFILENAME_SET=false # Indicates whether html_header() has been called to set up HTMLFILE.
LOGFILENAME_SET=false # Indicates whether prepare_logging() has been called to set up LOGFILE.
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)
@@ -493,7 +497,7 @@ html_reserved(){

html_out() {
"$do_html" || return 0
[[ -n "$HTMLFILE" ]] && [[ ! -d "$HTMLFILE" ]] && printf -- "%b" "${1//%/%%}" >> "$HTMLFILE"
"$HTMLFILENAME_SET" && [[ -n "$HTMLFILE" ]] && [[ ! -d "$HTMLFILE" ]] && printf -- "%b" "${1//%/%%}" >> "$HTMLFILE"
# here and other printf's: a little bit of sanitizing with bash internal search&replace -- otherwise printf will hiccup at '%'. '--' and %b do the rest.
}

@@ -734,7 +738,7 @@ strip_quote() {
#################### JSON FILE FORMATTING ####################

fileout_json_footer() {
if "$do_json"; then
if "$do_json" && "$JSONFILENAME_SET"; then
if [[ "$SCAN_TIME" -eq 0 ]]; then
fileout_json_finding "scanTime" "WARN" "Scan interrupted" "" "" ""
elif [[ $SEVERITY_LEVEL -lt $LOW ]] ; then
@@ -743,7 +747,7 @@ fileout_json_footer() {
fi
printf "]\n" >> "$JSONFILE"
fi
if "$do_pretty_json"; then
if "$do_pretty_json" && "$JSONFILENAME_SET"; then
if [[ "$SCAN_TIME" -eq 0 ]]; then
echo -e " ],\n \"scanTime\" : \"Scan interrupted\"\n}" >> "$JSONFILE"
else
@@ -773,14 +777,14 @@ fileout_json_section() {
fileout_section_header() {
local str=""
"$2" && str="$(fileout_section_footer false)"
"$do_pretty_json" && FIRST_FINDING=true && (printf "%s%s\n" "$str" "$(fileout_json_section "$1")") >> "$JSONFILE"
"$do_pretty_json" && "$JSONFILENAME_SET" && FIRST_FINDING=true && (printf "%s%s\n" "$str" "$(fileout_json_section "$1")") >> "$JSONFILE"
SECTION_FOOTER_NEEDED=true
}

# arg1: whether to end object too
fileout_section_footer() {
"$do_pretty_json" && printf "\n ]" >> "$JSONFILE"
"$do_pretty_json" && "$1" && echo -e "\n }" >> "$JSONFILE"
"$do_pretty_json" && "$JSONFILENAME_SET" && printf "\n ]" >> "$JSONFILE"
"$do_pretty_json" && "$JSONFILENAME_SET" && "$1" && echo -e "\n }" >> "$JSONFILE"
SECTION_FOOTER_NEEDED=false
}

@@ -807,7 +811,7 @@ fileout_json_finding() {
local cwe="$5"
local hint="$6"

if "$do_json"; then
if "$do_json" && "$JSONFILENAME_SET"; then
"$FIRST_FINDING" || echo -n "," >> "$JSONFILE"
echo -e " {" >> "$JSONFILE"
fileout_json_print_parameter "id" " " "$1" true
@@ -820,7 +824,7 @@ fileout_json_finding() {
fileout_json_print_parameter "finding" " " "$finding" false
echo -e "\n }" >> "$JSONFILE"
fi
if "$do_pretty_json"; then
if "$do_pretty_json" && "$JSONFILENAME_SET"; then
if [[ "$1" == service ]]; then
if [[ $SERVER_COUNTER -gt 1 ]]; then
echo " ," >> "$JSONFILE"
@@ -871,14 +875,14 @@ fileout_pretty_json_banner() {
fileout_banner() {
if "$JSONHEADER"; then
# "$do_json" && # here we maybe should add a banner, too
"$do_pretty_json" && (printf "%s\n" "$(fileout_pretty_json_banner)") >> "$JSONFILE"
"$do_pretty_json" && "$JSONFILENAME_SET" && (printf "%s\n" "$(fileout_pretty_json_banner)") >> "$JSONFILE"
fi
}

fileout_separator() {
if "$JSONHEADER"; then
"$do_pretty_json" && echo " ," >> "$JSONFILE"
"$do_json" && echo -n "," >> "$JSONFILE"
"$do_pretty_json" && "$JSONFILENAME_SET" && echo " ," >> "$JSONFILE"
"$do_json" && "$JSONFILENAME_SET" && echo -n "," >> "$JSONFILE"
fi
}

@@ -902,13 +906,13 @@ fileout_insert_warning() {
[[ "$CMDLINE=" =~ -iL ]] && return 0
# Note we still have the message on screen + in HTML which is not as optimal as it could be

if "$do_pretty_json"; then
if "$do_pretty_json" && "$JSONFILENAME_SET"; then
echo -e " \"clientProblem${CLIENT_PROB_NO}\" : [" >>"$JSONFILE"
CLIENT_PROB_NO=$((CLIENT_PROB_NO + 1))
FIRST_FINDING=true # make sure we don't have a comma here
fi
fileout "$1" "$2" "$3"
if "$do_pretty_json"; then
if "$do_pretty_json" && "$JSONFILENAME_SET"; then
echo -e "\n ]," >>"$JSONFILE"
fi
}
@@ -938,8 +942,8 @@ fileout() {

if ( "$do_pretty_json" && [[ "$1" == service ]] ) || show_finding "$severity"; then
local finding=$(strip_lf "$(newline_to_spaces "$(strip_quote "$3")")") # additional quotes will mess up screen output
[[ -e "$JSONFILE" ]] && [[ ! -d "$JSONFILE" ]] && fileout_json_finding "$1" "$severity" "$finding" "$cve" "$cwe" "$hint"
"$do_csv" && [[ -n "$CSVFILE" ]] && [[ ! -d "$CSVFILE" ]] && \
"$JSONFILENAME_SET" && [[ -e "$JSONFILE" ]] && [[ ! -d "$JSONFILE" ]] && fileout_json_finding "$1" "$severity" "$finding" "$cve" "$cwe" "$hint"
"$do_csv" && "$CSVFILENAME_SET" && [[ -n "$CSVFILE" ]] && [[ ! -d "$CSVFILE" ]] && \
fileout_csv_finding "$1" "$NODE/$NODEIP" "$PORT" "$severity" "$finding" "$cve" "$cwe" "$hint"
"$FIRST_FINDING" && FIRST_FINDING=false
fi
@@ -957,7 +961,7 @@ json_header() {
# * this is an individual test within a mass test and all output is being placed in a single file.
! "$do_json" && ! "$do_pretty_json" && JSONHEADER=false && return 0
"$do_mass_testing" && ! "$filename_provided" && JSONHEADER=false && return 0
"$CHILD_MASS_TESTING" && "$filename_provided" && JSONHEADER=false && return 0
"$CHILD_MASS_TESTING" && "$filename_provided" && JSONHEADER=false && JSONFILENAME_SET=true && return 0

if "$do_display_only"; then
fname_prefix="local-ciphers"
@@ -986,6 +990,7 @@ json_header() {
"$do_json" && echo "[" > "$JSONFILE"
"$do_pretty_json" && echo "{" > "$JSONFILE"
fi
JSONFILENAME_SET=true
return 0
}

@@ -998,7 +1003,7 @@ csv_header() {
# CSV similar to JSON
! "$do_csv" && CSVHEADER=false && return 0
"$do_mass_testing" && ! "$filename_provided" && CSVHEADER=false && return 0
"$CHILD_MASS_TESTING" && "$filename_provided" && CSVHEADER=false && return 0
"$CHILD_MASS_TESTING" && "$filename_provided" && CSVHEADER=false && CSVFILENAME_SET=true && return 0

if "$do_display_only"; then
fname_prefix="local-ciphers"
@@ -1022,8 +1027,10 @@ csv_header() {
fi
if "$APPEND"; then
CSVHEADER=false
CSVFILENAME_SET=true
else
[[ -s "$CSVFILE" ]] && fatal "non-empty \"$CSVFILE\" exists. Either use \"--append\" or (re)move it" $ERR_FCREATE
CSVFILENAME_SET=true
touch "$CSVFILE"
if "$GIVE_HINTS"; then
fileout_csv_finding "id" "fqdn/ip" "port" "severity" "finding" "cve" "cwe" "hint"
@@ -1048,7 +1055,7 @@ html_header() {
# * this is an individual test within a mass test and all HTML output is being placed in a single file.
! "$do_html" && HTMLHEADER=false && return 0
"$do_mass_testing" && ! "$filename_provided" && HTMLHEADER=false && return 0
"$CHILD_MASS_TESTING" && "$filename_provided" && HTMLHEADER=false && return 0
"$CHILD_MASS_TESTING" && "$filename_provided" && HTMLHEADER=false && HTMLFILENAME_SET=true && return 0

if "$do_display_only"; then
fname_prefix="local-ciphers"
@@ -1072,8 +1079,10 @@ html_header() {
fi
if "$APPEND"; then
HTMLHEADER=false
HTMLFILENAME_SET=true
else
[[ -s "$HTMLFILE" ]] && fatal "non-empty \"$HTMLFILE\" exists. Either use \"--append\" or (re)move it" $ERR_FCREATE
HTMLFILENAME_SET=true
html_out "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
html_out "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"
html_out "<!-- This file was created with testssl.sh. https://testssl.sh -->\n"
@@ -1118,7 +1127,7 @@ prepare_logging() {
# Similar to html_header():
! "$do_logging" && return 0
"$do_mass_testing" && ! "$filename_provided" && return 0
"$CHILD_MASS_TESTING" && "$filename_provided" && return 0
"$CHILD_MASS_TESTING" && "$filename_provided" && LOGFILENAME_SET=true && return 0

[[ -z "$fname_prefix" ]] && fname_prefix="${FNAME_PREFIX}${NODE}_p${PORT}"

@@ -1134,6 +1143,7 @@ prepare_logging() {
if ! "$APPEND"; then
[[ -s "$LOGFILE" ]] && fatal "non-empty \"$LOGFILE\" exists. Either use \"--append\" or (re)move it" $ERR_FCREATE
fi
LOGFILENAME_SET=true
tmln_out "## Scan started as: \"$PROG_NAME $CMDLINE\"" >>"$LOGFILE"
tmln_out "## at $HNAME:$OPENSSL_LOCATION" >>"$LOGFILE"
tmln_out "## version testssl: $VERSION ${GIT_REL_SHORT:-$CVS_REL_SHORT} from $REL_DATE" >>"$LOGFILE"
@@ -17295,10 +17305,10 @@ child_error() {
fatal() {
outln
prln_magenta "Fatal error: $1" >&2
[[ -n "$LOGFILE" ]] && prln_magenta "Fatal error: $1" >>$LOGFILE
"$LOGFILENAME_SET" && [[ -n "$LOGFILE" ]] && prln_magenta "Fatal error: $1" >>$LOGFILE
if [[ -n "$3" ]]; then
outln "$3" >&2
[[ -n "$LOGFILE" ]] && outln "$3" >>$LOGFILE
"$LOGFILENAME_SET" && [[ -n "$LOGFILE" ]] && outln "$3" >>$LOGFILE
fi
fileout "scanProblem" "FATAL" "$1"
exit $2
@@ -17311,7 +17321,7 @@ fatal() {
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
"$LOGFILENAME_SET" && [[ -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
@@ -17323,7 +17333,7 @@ ip_fatal() {
generic_nonfatal() {
prln_magenta "$1" >&2
[[ -n $2 ]] && outln "$2"
[[ -n "$LOGFILE" ]] && prln_magenta "$1" >>$LOGFILE && [[ -n $2 ]] && outln "$2" >>$LOGFILE
"$LOGFILENAME_SET" && [[ -n "$LOGFILE" ]] && prln_magenta "$1" >>$LOGFILE && [[ -n $2 ]] && outln "$2" >>$LOGFILE
outln
fileout "scanProblem" "WARN" "$1"
return 0