From 13ba1ce9667abbbf5d502b037cf50c1cf4639048 Mon Sep 17 00:00:00 2001 From: Dirk Date: Mon, 27 Mar 2017 00:30:42 +0200 Subject: [PATCH 1/9] partly (1/2) fixing #653 --- testssl.sh | 323 +++++++++++++++++++++++++++++------------------------ 1 file changed, 178 insertions(+), 145 deletions(-) diff --git a/testssl.sh b/testssl.sh index f38c079..1204023 100755 --- a/testssl.sh +++ b/testssl.sh @@ -80,7 +80,6 @@ readonly PS4='|${LINENO}> \011${FUNCNAME[0]:+${FUNCNAME[0]}(): }' DEBUGTIME=${DEBUGTIME:-false} - if grep -q xtrace <<< "$SHELLOPTS"; then if "$DEBUGTIME" ; then # separate debugging, doesn't mess up the screen, $DEBUGTIME determines whether we also do performance analysis @@ -173,12 +172,15 @@ LOGFILE=${LOGFILE:-""} # logfile if used JSONFILE=${JSONFILE:-""} # jsonfile if used CSVFILE=${CSVFILE:-""} # csvfile if used HTMLFILE=${HTMLFILE:-""} # HTML if used -HTMLHEADER=true # include HTML headers and footers in HTML file, if one is being created +FIRST_FINDING=true # Is this the first finding we are outputting to file? +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 APPEND=${APPEND:-false} # append to csv/json file instead of overwriting it GIVE_HINTS=false # give an addtional info to findings HAS_IPv6=${HAS_IPv6:-false} # if you have OpenSSL with IPv6 support AND IPv6 networking set it to yes UNBRACKTD_IPV6=${UNBRACKTD_IPV6:-false} # some versions of OpenSSL (like Gentoo) don't support [bracketed] IPv6 addresses -SERVER_SIZE_LIMIT_BUG=false # Some servers have either a ClientHello total size limit or cipher limit of ~128 ciphers (e.g. old ASAs) +SERVER_SIZE_LIMIT_BUG=false # Some servers have either a ClientHello total size limit or a 128 cipher limit (e.g. old ASAs) # tuning vars, can not be set by a cmd line switch EXPERIMENTAL=${EXPERIMENTAL:-false} @@ -277,7 +279,6 @@ HTTP_TIME="" GET_REQ11="" readonly UA_STD="TLS tester from $SWURL" readonly UA_SNEAKY="Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0" -FIRST_FINDING=true # Is this the first finding we are outputting to file? START_TIME=0 # time in epoch when the action started END_TIME=0 # .. ended SCAN_TIME=0 # diff of both: total scan time @@ -806,30 +807,12 @@ strip_quote() { } #################### JSON FILE FORMATING #################### -fileout_pretty_json_header() { - target="$NODE" - $do_mx_all_ips && target="$URI" - - echo -e " \"Invocation\" : \"$PROG_NAME $CMDLINE\", - \"at\" : \"$HNAME:$OPENSSL_LOCATION\", - \"version\" : \"$VERSION ${GIT_REL_SHORT:-$CVS_REL_SHORT} from $REL_DATE\", - \"openssl\" : \"$OSSL_VER from $OSSL_BUILD_DATE\", - \"target host\" : \"$target\", - \"port\" : \"$PORT\", - \"startTime\" : \"$START_TIME\", - \"scanResult\" : [" -} fileout_pretty_json_footer() { echo -e " ], \"scanTime\" : \"$SCAN_TIME\"\n}" } -fileout_json_header() { - "$do_json" && printf "[\n" > "$JSONFILE" - "$do_pretty_json" && (printf "{\n%s\n" "$(fileout_pretty_json_header)") > "$JSONFILE" -} - fileout_json_footer() { "$do_json" && printf "]\n" >> "$JSONFILE" "$do_pretty_json" && (printf "$(fileout_pretty_json_footer)") >> "$JSONFILE" @@ -850,15 +833,15 @@ fileout_json_section() { esac } -fileout_section_header(){ +fileout_section_header() { local str="" - $2 && str="$(fileout_section_footer false)" + "$2" && str="$(fileout_section_footer false)" "$do_pretty_json" && FIRST_FINDING=true && (printf "%s%s\n" "$str" "$(fileout_json_section "$1")") >> "$JSONFILE" } -fileout_section_footer() { # IS_THE_LAST_ONE +fileout_section_footer() { "$do_pretty_json" && printf "\n ]" >> "$JSONFILE" - "$do_pretty_json" && $1 && echo -e "\n }" >> "$JSONFILE" + "$do_pretty_json" && "$1" && echo -e "\n }" >> "$JSONFILE" } fileout_json_print_parameter() { @@ -866,34 +849,30 @@ fileout_json_print_parameter() { local filler="$2" local value="$3" local not_last="$4" + local spaces="" - local shift="" - - if "$do_json"; then - shift=" " - else - shift=" " - fi - + "$do_json" && \ + spaces=" " || \ + spaces=" " if [[ ! -z "$value" ]]; then - printf "%s%s%s%s" "$shift" "\"$parameter\"" "$filler" ": \"$value\"" >> "$JSONFILE" + printf "%s%s%s%s" "$spaces" "\"$parameter\"" "$filler" ": \"$value\"" >> "$JSONFILE" "$not_last" && printf ",\n" >> "$JSONFILE" fi } fileout_json_finding() { - if "$do_json"; then - "$FIRST_FINDING" || echo -n "," >> "$JSONFILE" - echo -e " {" >> "$JSONFILE" - fileout_json_print_parameter "id" " " "$1" true - fileout_json_print_parameter "ip" " " "$NODE/$NODEIP" true - fileout_json_print_parameter "port" " " "$PORT" true - fileout_json_print_parameter "severity" " " "$2" true - fileout_json_print_parameter "cve" " " "$cve" true - fileout_json_print_parameter "cwe" " " "$cwe" true - "$GIVE_HINTS" && fileout_json_print_parameter "hint" " " "$hint" true - fileout_json_print_parameter "finding" " " "$finding" false - echo -e "\n }" >> "$JSONFILE" + if "$do_json"; then + "$FIRST_FINDING" || echo -n "," >> "$JSONFILE" + echo -e " {" >> "$JSONFILE" + fileout_json_print_parameter "id" " " "$1" true + fileout_json_print_parameter "ip" " " "$NODE/$NODEIP" true + fileout_json_print_parameter "port" " " "$PORT" true + fileout_json_print_parameter "severity" " " "$2" true + fileout_json_print_parameter "cve" " " "$cve" true + fileout_json_print_parameter "cwe" " " "$cwe" true + "$GIVE_HINTS" && fileout_json_print_parameter "hint" " " "$hint" true + fileout_json_print_parameter "finding" " " "$finding" false + echo -e "\n }" >> "$JSONFILE" fi if "$do_pretty_json"; then if [[ "$1" == "service" ]]; then @@ -904,70 +883,141 @@ fileout_json_finding() { \"service\" : \"$finding\", \"ip\" : \"$NODEIP\"," >> "$JSONFILE" $do_mx_all_ips && echo -e " \"hostname\" : \"$NODE\"," >> "$JSONFILE" - else - ("$FIRST_FINDING" && echo -n " {" >> "$JSONFILE") || echo -n ",{" >> "$JSONFILE" - echo -e -n "\n" >> "$JSONFILE" - fileout_json_print_parameter "id" " " "$1" true - fileout_json_print_parameter "severity" " " "$2" true - fileout_json_print_parameter "cve" " " "$cve" true - fileout_json_print_parameter "cwe" " " "$cwe" true - "$GIVE_HINTS" && fileout_json_print_parameter "hint" " " "$hint" true - fileout_json_print_parameter "finding" " " "$finding" false - echo -e -n "\n }" >> "$JSONFILE" - fi + else + ("$FIRST_FINDING" && echo -n " {" >> "$JSONFILE") || echo -n ",{" >> "$JSONFILE" + echo -e -n "\n" >> "$JSONFILE" + fileout_json_print_parameter "id" " " "$1" true + fileout_json_print_parameter "severity" " " "$2" true + fileout_json_print_parameter "cve" " " "$cve" true + fileout_json_print_parameter "cwe" " " "$cwe" true + "$GIVE_HINTS" && fileout_json_print_parameter "hint" " " "$hint" true + fileout_json_print_parameter "finding" " " "$finding" false + echo -e -n "\n }" >> "$JSONFILE" + fi fi } -is_json_format() { - ( [[ -f "$JSONFILE" ]] && ("$do_json" || "$do_pretty_json") ) -} - ##################### FILE FORMATING ######################### -fileout_header() { - if "$APPEND"; then - if [[ -f "$JSONFILE" ]]; then - FIRST_FINDING=false # We need to insert a comma, because there is file content already - else - fileout_json_header +fileout_pretty_json_banner() { + echo -e " \"Invocation\" : \"$PROG_NAME $CMDLINE\", + \"at\" : \"$HNAME:$OPENSSL_LOCATION\", + \"version\" : \"$VERSION ${GIT_REL_SHORT:-$CVS_REL_SHORT} from $REL_DATE\", + \"openssl\" : \"$OSSL_VER from $OSSL_BUILD_DATE\", + \"target host\" : \"$target\", + \"port\" : \"$PORT\", + \"startTime\" : \"$START_TIME\", + \"scanResult\" : [" +} + +fileout_banner() { + local target="$NODE" + $do_mx_all_ips && target="$URI" + + #if ! "$APPEND"; then + # if "$CSVHEADER"; then + # : + # fi + if "$JSONHEADER"; then + # "$do_json" && # here we maybe should add a banner, too + "$do_pretty_json" && (printf "%s\n" "$(fileout_pretty_json_banner)") >> "$JSONFILE" fi - if "$do_csv"; then - if [[ -f "$CSVFILE" ]]; then - # add lf, just for overview - echo >> "$CSVFILE" - else - # create file, with headline - echo "\"id\",\"fqdn/ip\",\"port\",\"severity\",\"finding\",\"cve\",\"cwe\",\"hint\"" > "$CSVFILE" - fi - fi - else - fileout_json_header - "$do_csv" && echo "\"id\",\"fqdn/ip\",\"port\",\"severity\",\"finding\",\"cve\",\"cwe\",\"hint\"" > "$CSVFILE" - fi + #fi } fileout_footer() { - is_json_format && fileout_json_footer + [[ -f "$JSONFILE" ]] && fileout_json_footer + # CSV: no footer } -fileout() { # ID, SEVERITY, FINDING, CVE, CWE, HINT +# ID, SEVERITY, FINDING, CVE, CWE, HINT +fileout() { local severity="$2" local cwe="$5" local hint="$6" if ( "$do_pretty_json" && [[ "$1" == "service" ]] ) || show_finding "$severity"; then local finding=$(strip_lf "$(newline_to_spaces "$(strip_quote "$3")")") - - is_json_format && (fileout_json_finding "$1" "$severity" "$finding" "$cve" "$cwe" "$hint") - - # does the following do any sanitization? - if "$do_csv"; then + [[ -f "$JSONFILE" ]] && (fileout_json_finding "$1" "$severity" "$finding" "$cve" "$cwe" "$hint") + "$do_csv" && \ echo -e \""$1\"",\"$NODE/$NODEIP\",\"$PORT"\",\""$severity"\",\""$finding"\",\""$cve"\",\""$cwe"\",\""$hint"\"" >> "$CSVFILE" - fi - "$FIRST_FINDING" && FIRST_FINDING=false fi + "$FIRST_FINDING" && FIRST_FINDING=false } + +json_header() { + local fname_prefix + + # Similar to HTML: Don't create headers and footers in the following scenarios: + # * no JSON/CSV output is being created. + # * mass testing is being performed and each test will have its own file. + # * this is an individual test within a mass test and all output is being placed in a single file. + + if ( ! "$do_json" && ! "$do_pretty_json" ) || \ + ( "$do_mass_testing" && ( [[ -z "$JSONFILE" ]] || [[ -d "$JSONFILE" ]] ) ) || \ + ( "$APPEND" && [[ -n "$JSONFILE" ]] && [[ ! -d "$JSONFILE" ]] ); then + JSONHEADER=false + return 0 + fi + if "$do_display_only"; then + fname_prefix="local-ciphers" + elif "$do_mass_testing"; then + : + elif "$do_mx_all_ips"; then + fname_prefix="mx-$URI" + else + ( [[ -z "$JSONFILE" ]] || [[ -d "$JSONFILE" ]] ) && parse_hn_port "${URI}" + # NODE, URL_PATH, PORT, IPADDR and IP46ADDR is set now --> wrong place + fname_prefix="${NODE}"_p"${PORT}" + fi + if [[ -n "$JSONFILE" ]] && [[ ! -d "$JSONFILE" ]]; then + rm -f "$JSONFILE" + elif [[ -z "$JSONFILE" ]]; then + JSONFILE=$fname_prefix-$(date +"%Y%m%d-%H%M".json) + else + JSONFILE=$JSONFILE/$fname_prefix-$(date +"%Y%m%d-%H%M".json) + fi + "$do_json" && printf "[\n" > "$JSONFILE" + "$do_pretty_json" && printf "{\n" > "$JSONFILE" + #FIRST_FINDING=false + return 0 +} + + +csv_header() { + local fname_prefix + + # CSV similar: + if ! "$do_csv" || \ + ( "$do_mass_testing" && ( [[ -z "$CSVFILE" ]] || [[ -d "$CSVFILE" ]] ) ) || \ + ( "$APPEND" && [[ -n "$CSVFILE" ]] && [[ ! -d "$CSVFILE" ]] ); then + CSVHEADER=false + return 0 + fi + if "$do_display_only"; then + fname_prefix="local-ciphers" + elif "$do_mass_testing"; then + : + elif "$do_mx_all_ips"; then + fname_prefix="mx-$URI" + else + ( [[ -z "$CSVFILE" ]] || [[ -d "$CSVFILE" ]] ) && parse_hn_port "${URI}" + # NODE, URL_PATH, PORT, IPADDR and IP46ADDR is set now --> wrong place + fname_prefix="${NODE}"_p"${PORT}" + fi + if [[ -n "$CSVFILE" ]] && [[ ! -d "$CSVFILE" ]]; then + rm -f "$CSVFILE" + elif [[ -z "$CSVFILE" ]]; then + CSVFILE=$fname_prefix-$(date +"%Y%m%d-%H%M".csv) + else + CSVFILE=$CSVFILE/$fname_prefix-$(date +"%Y%m%d-%H%M".csv) + fi + "$do_csv" && echo "\"id\",\"fqdn/ip\",\"port\",\"severity\",\"finding\",\"cve\",\"cwe\",\"hint\"" > "$CSVFILE" + return 0 +} + + ################# JSON FILE FORMATING END. HTML START #################### html_header() { @@ -980,7 +1030,7 @@ html_header() { if ! "$do_html" || \ ( "$do_mass_testing" && ( [[ -z "$HTMLFILE" ]] || [[ -d "$HTMLFILE" ]] ) ) || \ ( "$APPEND" && [[ -n "$HTMLFILE" ]] && [[ ! -d "$HTMLFILE" ]] ); then - HTMLHEADER=false + HTMLHEADER=false return 0 fi @@ -1016,7 +1066,7 @@ html_header() { } html_banner() { - if "$APPEND" && "$HTMLHEADER"; then + if ! "$APPEND" && "$HTMLHEADER"; then html_out "## Scan started as: \"$PROG_NAME $CMDLINE\"\n" html_out "## at $HNAME:$OPENSSL_LOCATION\n" html_out "## version testssl: $VERSION ${GIT_REL_SHORT:-$CVS_REL_SHORT} from $REL_DATE\n" @@ -10926,8 +10976,8 @@ cleanup () { [[ -d "$TEMPDIR" ]] && rm -rf "$TEMPDIR"; fi outln - "$APPEND" || fileout_footer html_footer + fileout_footer # debugging off, see above grep -q xtrace <<< "$SHELLOPTS" && exec 2>&42 42>&- } @@ -11071,28 +11121,7 @@ prepare_logging() { tmln_out "## version testssl: $VERSION ${GIT_REL_SHORT:-$CVS_REL_SHORT} from $REL_DATE" >>${LOGFILE} tmln_out "## version openssl: \"$OSSL_VER\" from \"$OSSL_BUILD_DATE\")\n" >>${LOGFILE} exec > >(tee -a ${LOGFILE}) - # not decided yet. Maybe good to have a separate file or none at all - #exec 2> >(tee -a ${LOGFILE} >&2) fi - - if "$do_json" || "$do_pretty_json"; then - if [[ -z "$JSONFILE" ]]; then - JSONFILE=$fname_prefix-$(date +"%Y%m%d-%H%M".json) - elif [[ -d "$JSONFILE" ]]; then - # actually we were instructed to place all files in a DIR instead of the current working dir - JSONFILE=$JSONFILE/$fname_prefix-$(date +"%Y%m%d-%H%M".json) - fi - fi - if "$do_csv"; then - if [[ -z "$CSVFILE" ]]; then - CSVFILE=$fname_prefix-$(date +"%Y%m%d-%H%M".csv) - elif [[ -d "$CSVFILE" ]]; then - # actually we were instructed to place all files in a DIR instead of the current working dir - CSVFILE=$CSVFILE/$fname_prefix-$(date +"%Y%m%d-%H%M".csv) - fi - fi - fileout_header # write out any CSV/JSON header line - return 0 } @@ -12371,9 +12400,14 @@ lets_roll() { ################# main ################# +ret=0 +ip="" + lets_roll init initialize_globals parse_cmd_line "$@" +json_header +csv_header html_header get_install_dir set_color_functions @@ -12386,10 +12420,6 @@ check_proxy check4openssl_oldfarts check_bsd_mount -# TODO: it is ugly to have those two vars here --> main() -ret=0 -ip="" - if $do_display_only; then prettyprint_local "$PATTERN2SHOW" exit $? @@ -12402,41 +12432,44 @@ if $do_mass_testing; then fi html_banner +fileout_banner + #TODO: there shouldn't be the need for a special case for --mx, only the ip adresses we would need upfront and the do-parser if $do_mx_all_ips; then - query_globals # if we have just 1x "do_*" --> we do a standard run -- otherwise just the one specified + query_globals # if we have just 1x "do_*" --> we do a standard run -- otherwise just the one specified [[ $? -eq 1 ]] && set_scanning_defaults - run_mx_all_ips "${URI}" $PORT # we should reduce run_mx_all_ips to the stuff neccessary as ~15 lines later we have sililar code + run_mx_all_ips "${URI}" $PORT # we should reduce run_mx_all_ips to the stuff neccessary as ~15 lines later we have sililar code + exit $? +fi + +[[ -z "$NODE" ]] && parse_hn_port "${URI}" # NODE, URL_PATH, PORT, IPADDR and IP46ADDR is set now +prepare_logging +if ! determine_ip_addresses; then + fatal "No IP address could be determined" 2 +fi +if [[ -n "$CMDLINE_IP" ]]; then + # we just test the one supplied + lets_roll "${STARTTLS_PROTOCOL}" ret=$? -else - [[ -z "$NODE" ]] && parse_hn_port "${URI}" # NODE, URL_PATH, PORT, IPADDR and IP46ADDR is set now - prepare_logging - if ! determine_ip_addresses; then - fatal "No IP address could be determined" 2 - fi - if [[ -n "$CMDLINE_IP" ]]; then - # we just test the one supplied - lets_roll "${STARTTLS_PROTOCOL}" - ret=$? - else # no --ip was supplied - if [[ $(count_words "$(echo -n "$IPADDRs")") -gt 1 ]]; then # we have more than one ipv4 address to check - pr_bold "Testing all IPv4 addresses (port $PORT): "; outln "$IPADDRs" - for ip in $IPADDRs; do - draw_line "-" $((TERM_WIDTH * 2 / 3)) - outln - NODEIP="$ip" - lets_roll "${STARTTLS_PROTOCOL}" - ret=$(($? + ret)) - done +else # no --ip was supplied + if [[ $(count_words "$(echo -n "$IPADDRs")") -gt 1 ]]; then # we have more than one ipv4 address to check + pr_bold "Testing all IPv4 addresses (port $PORT): "; outln "$IPADDRs" + for ip in $IPADDRs; do draw_line "-" $((TERM_WIDTH * 2 / 3)) outln - pr_bold "Done testing now all IP addresses (on port $PORT): "; outln "$IPADDRs" - else # we need just one ip4v to check - NODEIP="$IPADDRs" + NODEIP="$ip" lets_roll "${STARTTLS_PROTOCOL}" - ret=$? - fi + ret=$(($? + ret)) + done + draw_line "-" $((TERM_WIDTH * 2 / 3)) + outln + pr_bold "Done testing now all IP addresses (on port $PORT): "; outln "$IPADDRs" + else # we need just one ip4v to check + NODEIP="$IPADDRs" + lets_roll "${STARTTLS_PROTOCOL}" + ret=$? fi fi exit $? + From a8b2dfec40ed5997af5245066393dba5f481f5b8 Mon Sep 17 00:00:00 2001 From: Dirk Date: Mon, 27 Mar 2017 00:34:42 +0200 Subject: [PATCH 2/9] allow '=' after --htmlfile --- testssl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index 1204023..72c73b2 100755 --- a/testssl.sh +++ b/testssl.sh @@ -12190,7 +12190,7 @@ parse_cmd_line() { do_html=true ;; # DEFINITION of HTMLFILE is not arg specified: automagically in parse_hn_port() # following does the same but we can specify a file location additionally - --htmlfile) + --htmlfile|--htmlfile=*) HTMLFILE=$(parse_opt_equal_sign "$1" "$2") [[ $? -eq 0 ]] && shift do_html=true From 9f1877b192908dc8681ce8db0dcb4c9bca2630cf Mon Sep 17 00:00:00 2001 From: Dirk Date: Mon, 27 Mar 2017 00:54:38 +0200 Subject: [PATCH 3/9] save work (still double footer, see #653) --- testssl.sh | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/testssl.sh b/testssl.sh index 72c73b2..cf0ad79 100755 --- a/testssl.sh +++ b/testssl.sh @@ -926,8 +926,11 @@ fileout_banner() { } fileout_footer() { - [[ -f "$JSONFILE" ]] && fileout_json_footer + if "$JSONHEADER"; then + fileout_json_footer + fi # CSV: no footer + return 0 } # ID, SEVERITY, FINDING, CVE, CWE, HINT @@ -958,7 +961,7 @@ json_header() { ( "$do_mass_testing" && ( [[ -z "$JSONFILE" ]] || [[ -d "$JSONFILE" ]] ) ) || \ ( "$APPEND" && [[ -n "$JSONFILE" ]] && [[ ! -d "$JSONFILE" ]] ); then JSONHEADER=false - return 0 + return 0 fi if "$do_display_only"; then fname_prefix="local-ciphers" @@ -993,7 +996,7 @@ csv_header() { ( "$do_mass_testing" && ( [[ -z "$CSVFILE" ]] || [[ -d "$CSVFILE" ]] ) ) || \ ( "$APPEND" && [[ -n "$CSVFILE" ]] && [[ ! -d "$CSVFILE" ]] ); then CSVHEADER=false - return 0 + return 0 fi if "$do_display_only"; then fname_prefix="local-ciphers" @@ -1031,7 +1034,7 @@ html_header() { ( "$do_mass_testing" && ( [[ -z "$HTMLFILE" ]] || [[ -d "$HTMLFILE" ]] ) ) || \ ( "$APPEND" && [[ -n "$HTMLFILE" ]] && [[ ! -d "$HTMLFILE" ]] ); then HTMLHEADER=false - return 0 + return 0 fi if "$do_display_only"; then @@ -1041,7 +1044,8 @@ html_header() { elif "$do_mx_all_ips"; then fname_prefix="mx-$URI" else - ( [[ -z "$HTMLFILE" ]] || [[ -d "$HTMLFILE" ]] ) && parse_hn_port "${URI}" # NODE, URL_PATH, PORT, IPADDR and IP46ADDR is set now + ( [[ -z "$HTMLFILE" ]] || [[ -d "$HTMLFILE" ]] ) && parse_hn_port "${URI}" + # NODE, URL_PATH, PORT, IPADDR and IP46ADDR is set now --> wrong place fname_prefix="${NODE}"_p"${PORT}" fi From 7543aa30fb5cbefe14f043b9e35567fa872455fc Mon Sep 17 00:00:00 2001 From: Dirk Date: Mon, 27 Mar 2017 08:59:29 +0200 Subject: [PATCH 4/9] make travis mute again / introduce DEBUG_ALLINONE to use script for debug output all in one file --- testssl.sh | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/testssl.sh b/testssl.sh index cf0ad79..b67e356 100755 --- a/testssl.sh +++ b/testssl.sh @@ -79,15 +79,20 @@ # debugging help: readonly PS4='|${LINENO}> \011${FUNCNAME[0]:+${FUNCNAME[0]}(): }' -DEBUGTIME=${DEBUGTIME:-false} +# see stackoverflow.com/questions/5014823/how-to-profile-a-bash-shell-script-slow-startup#20855353 +# how to paste both in order to do performance analysis +DEBUGTIME=${DEBUGTIME:-false} +DEBUG_ALLINONE=${DEBUG_ALLINONE:-false} # true: do debugging in one sceen if grep -q xtrace <<< "$SHELLOPTS"; then if "$DEBUGTIME" ; then # separate debugging, doesn't mess up the screen, $DEBUGTIME determines whether we also do performance analysis exec 42>&2 2> >(tee /tmp/testssl-$$.log | sed -u 's/^.*$/now/' | date -f - +%s.%N >/tmp/testssl-$$.time) - # for pasting both togher see https://stackoverflow.com/questions/5014823/how-to-profile-a-bash-shell-script-slow-startup#20855353 - else - exec 42>| /tmp/testssl-$$.log BASH_XTRACEFD=42 + else + if ! "$DEBUG_ALLINONE"; then + exec 42>| /tmp/testssl-$$.log + BASH_XTRACEFD=42 + fi fi fi @@ -944,8 +949,8 @@ fileout() { [[ -f "$JSONFILE" ]] && (fileout_json_finding "$1" "$severity" "$finding" "$cve" "$cwe" "$hint") "$do_csv" && \ echo -e \""$1\"",\"$NODE/$NODEIP\",\"$PORT"\",\""$severity"\",\""$finding"\",\""$cve"\",\""$cwe"\",\""$hint"\"" >> "$CSVFILE" - fi "$FIRST_FINDING" && FIRST_FINDING=false + fi } @@ -10983,7 +10988,7 @@ cleanup () { html_footer fileout_footer # debugging off, see above - grep -q xtrace <<< "$SHELLOPTS" && exec 2>&42 42>&- + grep -q xtrace <<< "$SHELLOPTS" && ! "$DEBUG_ALLINONE" && exec 2>&42 42>&- } fatal() { From c0af8b113fb0b2913c3981684045dc03fa1c099b Mon Sep 17 00:00:00 2001 From: Dirk Date: Mon, 27 Mar 2017 11:29:21 +0200 Subject: [PATCH 5/9] FIX #680 --- testssl.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/testssl.sh b/testssl.sh index b67e356..8557e8c 100755 --- a/testssl.sh +++ b/testssl.sh @@ -11123,8 +11123,12 @@ prepare_logging() { else : # just for clarity: a log file was specified, no need to do anything else fi - [[ -e $LOGFILE ]] && fatal "\"$LOGFILE\" exists. Either use \"--append\" or (re)move it" 1 - >$LOGFILE + + if ! "$APPEND"; then + [[ -e $LOGFILE ]] && fatal "\"$LOGFILE\" exists. Either use \"--append\" or (re)move it" 1 + else + >$LOGFILE + fi 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} From bcc597dbab6ceef94951b7cf9a5d2d823b667c2b Mon Sep 17 00:00:00 2001 From: Dirk Date: Mon, 27 Mar 2017 11:37:18 +0200 Subject: [PATCH 6/9] clarify help #680 --- testssl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index 8557e8c..959c474 100755 --- a/testssl.sh +++ b/testssl.sh @@ -10784,7 +10784,7 @@ file output options (can also be preset via environment variables): --htmlfile additional output as HTML to the specifed file --hints additional hints to findings --severity severities with lower level will be filtered for CSV+JSON, possible values - --append if , or exists rather append then overwrite + --append if , , or exists rather append then overwrite. Omits any header Options requiring a value can also be called with '=' e.g. testssl.sh -t=smtp --wide --openssl=/usr/bin/openssl . From d629cbcc282fbd57b1601e5a000508bbe4039e1a Mon Sep 17 00:00:00 2001 From: David Cooper Date: Mon, 27 Mar 2017 10:52:24 -0400 Subject: [PATCH 7/9] Missing HTML banner With the commit made on March 26, "partly (1/2) fixing #653," an HTML banner isn't added to the HTML files anymore. A banner should be added to the top of the HTML file if mass testing is being performed and a separate HTML file is being created for each test. The `$APPEND` flag being `true` is an indicator that mass testing is being performed and that this is one of the individual tests being run. Given that `$APPEND` is `true`, `$HTMLHEADER` being `true` indicates that testssl.sh is creating the file name for the HTML output. So, it is when both flags are `true` that the HTML banner should be created. --- testssl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index 959c474..8142b3a 100755 --- a/testssl.sh +++ b/testssl.sh @@ -1075,7 +1075,7 @@ html_header() { } html_banner() { - if ! "$APPEND" && "$HTMLHEADER"; then + if "$APPEND" && "$HTMLHEADER"; then html_out "## Scan started as: \"$PROG_NAME $CMDLINE\"\n" html_out "## at $HNAME:$OPENSSL_LOCATION\n" html_out "## version testssl: $VERSION ${GIT_REL_SHORT:-$CVS_REL_SHORT} from $REL_DATE\n" From 38cf16854de1a4ff7f2ea10ac3c2cd1f79c5ea54 Mon Sep 17 00:00:00 2001 From: Dirk Date: Mon, 27 Mar 2017 17:35:45 +0200 Subject: [PATCH 8/9] FIX #682 --- testssl.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/testssl.sh b/testssl.sh index 959c474..9144cdd 100755 --- a/testssl.sh +++ b/testssl.sh @@ -3683,7 +3683,8 @@ run_client_simulation() { what_dh=$(awk -F',' '{ print $1 }' <<< $temp) bits=$(awk -F',' '{ print $3 }' <<< $temp) grep -q bits <<< $bits || bits=$(awk -F',' '{ print $2 }' <<< $temp) - bits="${bits/ bits/}" + bits="${bits/bits/}" + bits="${bits// /}" if [[ "$what_dh" == "DH" ]]; then [[ ${minDhBits[i]} -ne -1 ]] && [[ $bits -lt ${minDhBits[i]} ]] && sclient_success=1 [[ ${maxDhBits[i]} -ne -1 ]] && [[ $bits -gt ${maxDhBits[i]} ]] && sclient_success=1 @@ -4293,7 +4294,8 @@ read_dhbits_from_file() { else bits=$(awk -F',' '{ print $2 }' <<< $temp) fi - bits="${bits/ bits/}" + bits="${bits/bits/}" + bits="${bits// /}" if [[ "$what_dh" == "X25519" ]] || [[ "$what_dh" == "X448" ]]; then curve="$what_dh" From e2d5dc7778ef82d895f1c4f37d64b650f2880af6 Mon Sep 17 00:00:00 2001 From: Dirk Date: Mon, 27 Mar 2017 21:31:54 +0200 Subject: [PATCH 9/9] part 2/2: fix for #653 --- testssl.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index 44db78a..ad064ac 100755 --- a/testssl.sh +++ b/testssl.sh @@ -11788,7 +11788,6 @@ run_mass_testing() { outln "$cmdline" $cmdline done < "${FNAME}" - fileout_footer return $? }