out_row_aligned_max_width()

This PR improves `out_row_aligned_max_width()` in a few ways:

* It makes better use of bash's string manipulation capabilities in order to simplify the function.

* It improves the function's performance. One of the most costly parts of `out_row_aligned_max_width()` was the while loop to print each entry in the text. Since there is only one place in the code where the the entries are not all printed the same ways (the list of supported curves printed by `run_pfs()`), the PR changes `out_row_aligned_max_width()` to just return a plain text string, which the calling function prints in the appropriate way. For the curves printed by `run_pfs()`, a new function, `out_row_aligned_max_width_by_entry()` takes care of getting the output from `out_row_aligned_max_width()` and then printing each entry appropriately.

* The PR also introduces a trick so that when the TLS extensions are printed, the text for an extension won't get split across two rows. It does this by replacing the space charters within the text for an extension with "}", formatting the result with `out_row_aligned_max_width()`, and then converting the "}" back to space characters.
This commit is contained in:
David Cooper 2017-03-28 13:54:54 -04:00 committed by GitHub
parent 53de1dc7c4
commit 227a31b788

View File

@ -1222,63 +1222,73 @@ out_row_aligned() {
} }
# prints text over multiple lines, trying to make no line longer than $max_width. # prints text over multiple lines, trying to make no line longer than $max_width.
# Each line is indented with $spaces and each word in $text is printed using $print_function. # Each line is indented with $spaces.
out_row_aligned_max_width() { out_row_aligned_max_width() {
local text="$1" local text="$1"
local spaces="$2" local spaces="$2"
local -i max_width="$3" local -i max_width="$3"
local print_function="$4"
local -i i len local -i i len
local cr=$'\n' local cr=$'\n'
local line entry first=true last=false local line first=true
max_width=$max_width-1 # at the moment we align to terminal width. This makes sure we don't wrap too late
max_width=$max_width-${#spaces} max_width=$max_width-${#spaces}
len=${#text} len=${#text}
while true; do while true; do
i=$max_width if [[ $len -lt $max_width ]]; then
if [[ $i -ge $len ]]; then # If the remaining text to print is shorter than $max_width,
# then just print it.
i=$len i=$len
else else
while true; do # Find the final space character in the text that is less than
[[ "${text:i:1}" == " " ]] && break # $max_width characters into the remaining text, and make the
[[ $i -eq 0 ]] && break # text up to that space character the next line to print.
i=$i-1 line="${text:0:max_width}"
done line="${line% *}"
if [[ $i -eq 0 ]]; then i=${#line}
i=$max_width+1 if [[ $i -eq $max_width ]]; then
while true; do # If there are no space characters in the first $max_width
[[ "${text:i:1}" == " " ]] && break # characters of the remaining text, then make the text up
[[ $i -eq $len ]] && break # to the first space the next line to print. If there are
i+=1 # no space characters in the remaining text, make the
done # remaining text the next line to print.
line="${text#* }"
i=$len-${#line}
[[ $i -eq 0 ]] && i=$len
fi fi
fi fi
if [[ $i -eq $len ]]; then if ! "$first"; then
line="$text" tm_out "${cr}${spaces}"
if ! "$first"; then
out "${cr}${spaces}"
fi
last=true
else
line="${text:0:i}"
if ! "$first"; then
out "${cr}${spaces}"
fi
len=$len-$i-1
i=$i+1
text="${text:i:len}"
first=false
[[ $len -eq 0 ]] && last=true
fi fi
while read entry; do tm_out "${text:0:i}"
$print_function "$entry" ; out " " [[ $i -eq $len ]] && break
done <<< "$(tr ' ' '\n' <<< "$line")" len=$len-$i-1
"$last" && break i=$i+1
text="${text:i:len}"
first=false
[[ $len -eq 0 ]] && break
done done
return 0 return 0
} }
out_row_aligned_max_width_by_entry() {
local text="$1"
local spaces="$2"
local -i max_width="$3"
local print_function="$4"
local resp entry prev_entry=" "
resp="$(out_row_aligned_max_width "$text" "$spaces" "$max_width")"
while read -d " " entry; do
if [[ -n "$entry" ]]; then
$print_function "$entry"
elif [[ -n "$prev_entry" ]]; then
outln; out " "
fi
out " "
prev_entry="$entry"
done <<< "$resp"
}
tmpfile_handle() { tmpfile_handle() {
mv $TMPFILE "$TEMPDIR/$NODEIP.$1" 2>/dev/null mv $TMPFILE "$TEMPDIR/$NODEIP.$1" 2>/dev/null
@ -4877,7 +4887,7 @@ cipher_pref_check() {
if [[ -n "$order" ]]; then if [[ -n "$order" ]]; then
outln outln
out "$(printf " %-10s " "$proto: ")" out "$(printf " %-10s " "$proto: ")"
out_row_aligned_max_width "$order" " " $TERM_WIDTH out out "$(out_row_aligned_max_width "$order" " " $TERM_WIDTH)"
fileout "order_$p" "INFO" "Default cipher order for protocol $p: $order" fileout "order_$p" "INFO" "Default cipher order for protocol $p: $order"
fi fi
done done
@ -5773,7 +5783,7 @@ certificate_info() {
while read san; do while read san; do
[[ -n "$san" ]] && all_san+="$san " [[ -n "$san" ]] && all_san+="$san "
done <<< "$sans" done <<< "$sans"
out_row_aligned_max_width "$all_san" "$indent " $TERM_WIDTH pr_italic pr_italic "$(out_row_aligned_max_width "$all_san" "$indent " $TERM_WIDTH)"
fileout "${json_prefix}san" "INFO" "subjectAltName (SAN) : $all_san" fileout "${json_prefix}san" "INFO" "subjectAltName (SAN) : $all_san"
else else
out "-- " out "-- "
@ -6078,7 +6088,7 @@ run_server_defaults() {
local -a previous_hostcert previous_intermediates keysize cipher local -a previous_hostcert previous_intermediates keysize cipher
local -a ocsp_response ocsp_response_status sni_used local -a ocsp_response ocsp_response_status sni_used
local -a ciphers_to_test success local -a ciphers_to_test success
local cn_nosni cn_sni sans_nosni sans_sni san local cn_nosni cn_sni sans_nosni sans_sni san tls_extensions
local alpn_proto alpn="" alpn_list_len_hex alpn_extn_len_hex success local alpn_proto alpn="" alpn_list_len_hex alpn_extn_len_hex success
local -i alpn_list_len alpn_extn_len local -i alpn_list_len alpn_extn_len
@ -6216,7 +6226,16 @@ run_server_defaults() {
fileout "tls_extensions" "INFO" "TLS server extensions (std): (none)" fileout "tls_extensions" "INFO" "TLS server extensions (std): (none)"
else else
#FIXME: we rather want to have the chance to print each ext in italcs or another format. Atm is a string of quoted strings -- that needs to be fixed at the root #FIXME: we rather want to have the chance to print each ext in italcs or another format. Atm is a string of quoted strings -- that needs to be fixed at the root
out_row_aligned_max_width "$TLS_EXTENSIONS" " " $TERM_WIDTH out; outln # out_row_aligned_max_width() places line breaks at space characters.
# So, in order to prevent the text for an extension from being broken
# across lines, temporarily replace space characters within the text
# of an extension with "}", and then convert the "}" back to space in
# the output of out_row_aligned_max_width().
tls_extensions="${TLS_EXTENSIONS// /{}"
tls_extensions="${tls_extensions//\"{\"/\" \"}"
tls_extensions="$(out_row_aligned_max_width "$tls_extensions" " " $TERM_WIDTH)"
tls_extensions="${tls_extensions//{/ }"
outln "$tls_extensions"
fileout "tls_extensions" "INFO" "TLS server extensions (std): $TLS_EXTENSIONS" fileout "tls_extensions" "INFO" "TLS server extensions (std): $TLS_EXTENSIONS"
fi fi
@ -6443,7 +6462,7 @@ run_pfs() {
outln "${sigalg[i]}" outln "${sigalg[i]}"
fi fi
done done
! "$WIDE" && out_row_aligned_max_width "$pfs_ciphers" " " $TERM_WIDTH out ! "$WIDE" && out "$(out_row_aligned_max_width "$pfs_ciphers" " " $TERM_WIDTH)"
debugme echo $pfs_offered debugme echo $pfs_offered
"$WIDE" || outln "$WIDE" || outln
fileout "pfs_ciphers" "INFO" "(Perfect) Forward Secrecy Ciphers: $pfs_ciphers" fileout "pfs_ciphers" "INFO" "(Perfect) Forward Secrecy Ciphers: $pfs_ciphers"
@ -6524,7 +6543,7 @@ run_pfs() {
if [[ -n "$curves_offered" ]]; then if [[ -n "$curves_offered" ]]; then
"$WIDE" && outln "$WIDE" && outln
pr_bold " Elliptic curves offered: " pr_bold " Elliptic curves offered: "
out_row_aligned_max_width "$curves_offered" " " $TERM_WIDTH pr_ecdh_curve_quality out_row_aligned_max_width_by_entry "$curves_offered" " " $TERM_WIDTH pr_ecdh_curve_quality
outln outln
fileout "ecdhe_curves" "INFO" "Elliptic curves offered $curves_offered" fileout "ecdhe_curves" "INFO" "Elliptic curves offered $curves_offered"
fi fi
@ -10079,8 +10098,8 @@ run_beast(){
! "$first" && out "$spaces" ! "$first" && out "$spaces"
out "$(toupper $proto): " out "$(toupper $proto): "
[[ -n "$higher_proto_supported" ]] && \ [[ -n "$higher_proto_supported" ]] && \
out_row_aligned_max_width "$detected_cbc_ciphers" " " $TERM_WIDTH pr_svrty_low || \ pr_svrty_low "$(out_row_aligned_max_width "$detected_cbc_ciphers" " " $TERM_WIDTH)" || \
out_row_aligned_max_width "$detected_cbc_ciphers" " " $TERM_WIDTH pr_svrty_medium pr_svrty_medium "$(out_row_aligned_max_width "$detected_cbc_ciphers" " " $TERM_WIDTH)"
outln outln
detected_cbc_ciphers="" # empty for next round detected_cbc_ciphers="" # empty for next round
first=false first=false
@ -10417,7 +10436,7 @@ run_rc4() {
fi fi
fi fi
done done
! "$WIDE" && out_row_aligned_max_width "$rc4_detected" " " $TERM_WIDTH pr_svrty_high ! "$WIDE" && pr_svrty_high "$(out_row_aligned_max_width "$rc4_detected" " " $TERM_WIDTH)"
outln outln
"$WIDE" && pr_svrty_high "VULNERABLE (NOT ok)" "$WIDE" && pr_svrty_high "VULNERABLE (NOT ok)"
fileout "rc4" "HIGH" "RC4: VULNERABLE, Detected ciphers: $rc4_detected" "$cve" "$cwe" "$hint" fileout "rc4" "HIGH" "RC4: VULNERABLE, Detected ciphers: $rc4_detected" "$cve" "$cwe" "$hint"
@ -11665,8 +11684,7 @@ display_rdns_etc() {
further_ip_addrs+="$ip " further_ip_addrs+="$ip "
fi fi
done done
out_row_aligned_max_width "$further_ip_addrs" " $CORRECT_SPACES" $TERM_WIDTH out outln "$(out_row_aligned_max_width "$further_ip_addrs" " $CORRECT_SPACES" $TERM_WIDTH)"
outln
fi fi
if "$LOCAL_A"; then if "$LOCAL_A"; then
outln " A record via $CORRECT_SPACES /etc/hosts " outln " A record via $CORRECT_SPACES /etc/hosts "
@ -11675,7 +11693,7 @@ display_rdns_etc() {
fi fi
if [[ -n "$rDNS" ]]; then if [[ -n "$rDNS" ]]; then
out "$(printf " %-23s %s" "rDNS ($nodeip):")" out "$(printf " %-23s %s" "rDNS ($nodeip):")"
out_row_aligned_max_width "$rDNS" " $CORRECT_SPACES" $TERM_WIDTH out out "$(out_row_aligned_max_width "$rDNS" " $CORRECT_SPACES" $TERM_WIDTH)"
fi fi
} }