Merge branch 'drwetter/2.9dev' into 2.9dev

This commit is contained in:
AlGreed 2016-12-14 11:26:03 +01:00
commit 98d7d25aa1
1 changed files with 258 additions and 62 deletions

View File

@ -226,6 +226,7 @@ HAS_SPDY=false
HAS_FALLBACK_SCSV=false HAS_FALLBACK_SCSV=false
HAS_PROXY=false HAS_PROXY=false
HAS_XMPP=false HAS_XMPP=false
HAS_POSTGRES=false
ADD_RFC_STR="rfc" # display RFC ciphernames ADD_RFC_STR="rfc" # display RFC ciphernames
PORT=443 # unless otherwise auto-determined, see below PORT=443 # unless otherwise auto-determined, see below
NODE="" NODE=""
@ -6227,6 +6228,16 @@ starttls_nntp_dialog() {
return $ret return $ret
} }
starttls_postgres_dialog() {
debugme echo "=== starting postgres STARTTLS dialog ==="
local reINITTLS="\x00\x00\x00\x08\x04\xD2\x16\x2F"
starttls_just_send "${reINITTLS}" && debugme echo "initiated STARTTLS" &&
starttls_full_read '' '' 'S' && debugme echo "received ack for STARTTLS"
local ret=$?
debugme echo "=== finished postgres STARTTLS dialog with ${ret} ==="
return $ret
}
# arg for a fd doesn't work here # arg for a fd doesn't work here
fd_socket() { fd_socket() {
local jabber="" local jabber=""
@ -6301,6 +6312,9 @@ EOF
starttls_line "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>" "proceed" starttls_line "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>" "proceed"
# BTW: https://xmpp.net ! # BTW: https://xmpp.net !
;; ;;
postgres|postgress) # Postgres SQL, see http://www.postgresql.org/docs/devel/static/protocol-message-formats.html
starttls_postgres_dialog
;;
*) # we need to throw an error here -- otherwise testssl.sh treats the STARTTLS protocol as plain SSL/TLS which leads to FP *) # we need to throw an error here -- otherwise testssl.sh treats the STARTTLS protocol as plain SSL/TLS which leads to FP
fatal "FIXME: STARTTLS protocol $STARTTLS_PROTOCOL is not yet supported" -4 fatal "FIXME: STARTTLS protocol $STARTTLS_PROTOCOL is not yet supported" -4
esac esac
@ -6476,9 +6490,12 @@ parse_sslv2_serverhello() {
# [cipher spec length] ==> ciphers GOOD: HERE ARE ALL CIPHERS ALREADY! # [cipher spec length] ==> ciphers GOOD: HERE ARE ALL CIPHERS ALREADY!
local ret=3 local ret=3
local parse_complete="false"
if [[ "$2" == "true" ]]; then if [[ "$2" == "true" ]]; then
echo "======================================" > $TMPFILE parse_complete=true
fi fi
"$parse_complete" && echo "======================================" > $TMPFILE
v2_hello_ascii=$(hexdump -v -e '16/1 "%02X"' $1) v2_hello_ascii=$(hexdump -v -e '16/1 "%02X"' $1)
[[ "$DEBUG" -ge 5 ]] && echo "$v2_hello_ascii" [[ "$DEBUG" -ge 5 ]] && echo "$v2_hello_ascii"
@ -6514,10 +6531,13 @@ parse_sslv2_serverhello() {
fi fi
fi fi
"$parse_complete" || return $ret
rm -f $HOSTCERT $TEMPDIR/intermediatecerts.pem
if [[ $ret -eq 3 ]]; then
certificate_len=2*$(hex2dec "$v2_hello_cert_length") certificate_len=2*$(hex2dec "$v2_hello_cert_length")
[[ -e $HOSTCERT ]] && rm $HOSTCERT
[[ -e $TEMPDIR/intermediatecerts.pem ]] && rm $TEMPDIR/intermediatecerts.pem if [[ "$v2_cert_type" == "01" ]] && [[ "$v2_hello_cert_length" != "00" ]]; then
if [[ "$2" == "true" ]] && [[ "$v2_cert_type" == "01" ]] && [[ "$v2_hello_cert_length" != "00" ]]; then
tmp_der_certfile=$(mktemp $TEMPDIR/der_cert.XXXXXX) || return $ret tmp_der_certfile=$(mktemp $TEMPDIR/der_cert.XXXXXX) || return $ret
asciihex_to_binary_file "${v2_hello_ascii:26:certificate_len}" "$tmp_der_certfile" asciihex_to_binary_file "${v2_hello_ascii:26:certificate_len}" "$tmp_der_certfile"
$OPENSSL x509 -inform DER -in $tmp_der_certfile -outform PEM -out $HOSTCERT $OPENSSL x509 -inform DER -in $tmp_der_certfile -outform PEM -out $HOSTCERT
@ -6527,7 +6547,6 @@ parse_sslv2_serverhello() {
fi fi
# Output list of supported ciphers # Output list of supported ciphers
if [[ "$2" == "true" ]]; then
let offset=26+$certificate_len let offset=26+$certificate_len
nr_ciphers_detected=$((V2_HELLO_CIPHERSPEC_LENGTH / 3)) nr_ciphers_detected=$((V2_HELLO_CIPHERSPEC_LENGTH / 3))
for (( i=0 ; i<nr_ciphers_detected; i++ )); do for (( i=0 ; i<nr_ciphers_detected; i++ )); do
@ -8991,16 +9010,23 @@ run_lucky13() {
# http://blog.cryptographyengineering.com/2013/03/attack-of-week-rc4-is-kind-of-broken-in.html # http://blog.cryptographyengineering.com/2013/03/attack-of-week-rc4-is-kind-of-broken-in.html
run_rc4() { run_rc4() {
local -i rc4_offered=0 local -i rc4_offered=0
local -i sclient_success local -i nr_ciphers=0 nr_ossl_ciphers=0 nr_nonossl_ciphers=0 ret
local hexcode dash rc4_cipher sslvers kx auth enc mac export local n auth mac export hexc sslv2_ciphers_hex="" sslv2_ciphers_ossl="" s
local rc4_ciphers_list="ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:DHE-DSS-RC4-SHA:AECDH-RC4-SHA:ADH-RC4-MD5:ECDH-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:RC4-SHA:RC4-MD5:RC4-MD5:RSA-PSK-RC4-SHA:PSK-RC4-SHA:KRB5-RC4-SHA:KRB5-RC4-MD5:RC4-64-MD5:EXP1024-DHE-DSS-RC4-SHA:EXP1024-RC4-SHA:EXP-ADH-RC4-MD5:EXP-RC4-MD5:EXP-RC4-MD5:EXP-KRB5-RC4-SHA:EXP-KRB5-RC4-MD5" local -a normalized_hexcode hexcode ciph sslvers kx enc export2 sigalg ossl_supported
local rc4_ssl2_ciphers_list="RC4-MD5:RC4-64-MD5:EXP-RC4-MD5" local -i i
local rc4_detected="" local -a ciphers_found ciphers_found2 hexcode2 ciph2 sslvers2 rfc_ciph2
local available="" local -i -a index
local dhlen available="" ciphers_to_test supported_sslv2_ciphers addcmd=""
local has_dh_bits="$HAS_DH_BITS" rc4_detected=""
local using_sockets=true
local cve="CVE-2013-2566, CVE-2015-2808" local cve="CVE-2013-2566, CVE-2015-2808"
local cwe="CWE-310" local cwe="CWE-310"
local hint="" local hint=""
"$SSL_NATIVE" && using_sockets=false
"$FAST" && using_sockets=false
[[ $TLS_NR_CIPHERS == 0 ]] && using_sockets=false
if [[ $VULN_COUNT -le $VULN_THRESHLD ]]; then if [[ $VULN_COUNT -le $VULN_THRESHLD ]]; then
outln outln
pr_headlineln " Checking for vulnerable RC4 Ciphers " pr_headlineln " Checking for vulnerable RC4 Ciphers "
@ -9010,62 +9036,215 @@ run_rc4() {
fi fi
pr_bold " RC4"; out " ($cve) " pr_bold " RC4"; out " ($cve) "
$OPENSSL s_client -cipher $rc4_ciphers_list $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI >$TMPFILE 2>$ERRFILE </dev/null # get a list of all the cipher suites to test
sclient_connect_successful $? $TMPFILE if "$using_sockets" || [[ $OSSL_VER_MAJOR -lt 1 ]]; then
sclient_success=$? for (( i=0; i < TLS_NR_CIPHERS; i++ )); do
if $HAS_SSL2 && [[ $sclient_success -ne 0 ]]; then if [[ "${TLS_CIPHER_RFC_NAME[i]}" =~ "RC4" ]] && ( "$using_sockets" || "${TLS_CIPHER_OSSL_SUPPORTED[i]}" ); then
$OPENSSL s_client -cipher $rc4_ssl2_ciphers_list $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY -ssl2 >$TMPFILE 2>$ERRFILE </dev/null hexc="$(tolower "${TLS_CIPHER_HEXCODE[i]}")"
sclient_connect_successful $? $TMPFILE ciph[nr_ciphers]="${TLS_CIPHER_OSSL_NAME[i]}"
sclient_success=$? rfc_ciph[nr_ciphers]="${TLS_CIPHER_RFC_NAME[i]}"
sslvers[nr_ciphers]="${TLS_CIPHER_SSLVERS[i]}"
kx[nr_ciphers]="${TLS_CIPHER_KX[i]}"
enc[nr_ciphers]="${TLS_CIPHER_ENC[i]}"
export2[nr_ciphers]="${TLS_CIPHER_EXPORT[i]}"
ciphers_found[nr_ciphers]=false
sigalg[nr_ciphers]=""
ossl_supported[nr_ciphers]="${TLS_CIPHER_OSSL_SUPPORTED[i]}"
if "$using_sockets" && "$WIDE" && ! "$HAS_DH_BITS" &&
( [[ ${kx[nr_ciphers]} == "Kx=ECDH" ]] || [[ ${kx[nr_ciphers]} == "Kx=DH" ]] || [[ ${kx[nr_ciphers]} == "Kx=EDH" ]] ); then
ossl_supported[nr_ciphers]=false
fi fi
if [[ $sclient_success -eq 0 ]]; then if [[ ${#hexc} -eq 9 ]]; then
"$WIDE" || pr_svrty_high "VULNERABLE (NOT ok): " hexcode[nr_ciphers]="${hexc:2:2},${hexc:7:2}"
if [[ "${hexc:2:2}" == "00" ]]; then
normalized_hexcode[nr_ciphers]="x${hexc:7:2}"
else
normalized_hexcode[nr_ciphers]="x${hexc:2:2}${hexc:7:2}"
fi
else
hexcode[nr_ciphers]="${hexc:2:2},${hexc:7:2},${hexc:12:2}"
normalized_hexcode[nr_ciphers]="x${hexc:2:2}${hexc:7:2}${hexc:12:2}"
sslv2_ciphers_hex+=", ${hexcode[nr_ciphers]}"
sslv2_ciphers_ossl+=":${ciph[nr_ciphers]}"
fi
nr_ciphers+=1
fi
done
else
while read hexc n ciph[nr_ciphers] sslvers[nr_ciphers] kx[nr_ciphers] auth enc[nr_ciphers] mac export2[nr_ciphers]; do
if [[ "${ciph[nr_ciphers]}" =~ "RC4" ]]; then
ciphers_found[nr_ciphers]=false
if [[ ${#hexc} -eq 9 ]]; then
if [[ "${hexc:2:2}" == "00" ]]; then
normalized_hexcode[nr_ciphers]="$(tolower "x${hexc:7:2}")"
else
normalized_hexcode[nr_ciphers]="$(tolower "x${hexc:2:2}${hexc:7:2}")"
fi
else
normalized_hexcode[nr_ciphers]="$(tolower "x${hexc:2:2}${hexc:7:2}${hexc:12:2}")"
sslv2_ciphers_ossl+=":${ciph[nr_ciphers]}"
fi
sigalg[nr_ciphers]=""
ossl_supported[nr_ciphers]=true
nr_ciphers+=1
fi
done < <($OPENSSL ciphers -V 'ALL:COMPLEMENTOFALL:@STRENGTH' 2>>$ERRFILE)
fi
if "$using_sockets" && [[ -n "$sslv2_ciphers_hex" ]]; then
sslv2_sockets "${sslv2_ciphers_hex:2}" "true"
if [[ $? -eq 3 ]] && [[ "$V2_HELLO_CIPHERSPEC_LENGTH" -ne 0 ]]; then
supported_sslv2_ciphers="$(grep "Supported cipher: " "$TEMPDIR/$NODEIP.parse_sslv2_serverhello.txt")"
"$WIDE" && "$SHOW_SIGALGO" && s="$($OPENSSL x509 -noout -text -in "$HOSTCERT" | awk -F':' '/Signature Algorithm/ { print $2 }' | head -1)"
for (( i=0 ; i<nr_ciphers; i++ )); do
if [[ "${sslvers[i]}" == "SSLv2" ]] && [[ "$supported_sslv2_ciphers" =~ "${normalized_hexcode[i]}" ]]; then
ciphers_found[i]=true
"$WIDE" && "$SHOW_SIGALGO" && sigalg[i]="$s"
rc4_offered=1 rc4_offered=1
fi
done
fi
elif "$HAS_SSL2" && [[ -n "$sslv2_ciphers_ossl" ]]; then
$OPENSSL s_client -cipher "${sslv2_ciphers_ossl:1}" $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY -ssl2 >$TMPFILE 2>$ERRFILE </dev/null
sclient_connect_successful "$?" "$TMPFILE"
if [[ "$?" -eq 0 ]]; then
supported_sslv2_ciphers="$(grep -A 4 "Ciphers common between both SSL endpoints:" $TMPFILE)"
"$WIDE" && "$SHOW_SIGALGO" && s="$($OPENSSL x509 -noout -text -in $TMPFILE | awk -F':' '/Signature Algorithm/ { print $2 }' | head -1)"
for (( i=0 ; i<nr_ciphers; i++ )); do
if [[ "${sslvers[i]}" == "SSLv2" ]] && [[ "$supported_sslv2_ciphers" =~ "${ciph[i]}" ]]; then
ciphers_found[i]=true
"$WIDE" && "$SHOW_SIGALGO" && sigalg[i]="$s"
rc4_offered=1
fi
done
fi
fi
for (( i=0; i < nr_ciphers; i++ )); do
if "${ossl_supported[i]}" && [[ "${sslvers[i]}" != "SSLv2" ]]; then
ciphers_found2[nr_ossl_ciphers]=false
sslvers2[nr_ossl_ciphers]="${sslvers[i]}"
ciph2[nr_ossl_ciphers]="${ciph[i]}"
index[nr_ossl_ciphers]=$i
nr_ossl_ciphers+=1
fi
done
"$HAS_NO_SSL2" && addcmd="-no_ssl2"
for (( success=0; success==0 ; 1 )); do
ciphers_to_test=""
for (( i=0; i < nr_ossl_ciphers; i++ )); do
! "${ciphers_found2[i]}" && ciphers_to_test+=":${ciph2[i]}"
done
success=1
if [[ -n "$ciphers_to_test" ]]; then
$OPENSSL s_client $addcmd -cipher "${ciphers_to_test:1}" $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI >$TMPFILE 2>$ERRFILE </dev/null
sclient_connect_successful "$?" "$TMPFILE"
if [[ "$?" -eq 0 ]]; then
cipher=$(awk '/Cipher *:/ { print $3 }' $TMPFILE)
if [[ -n "$cipher" ]]; then
success=0
rc4_offered=1
for (( i=0; i < nr_ossl_ciphers; i++ )); do
[[ "$cipher" == "${ciph2[i]}" ]] && ciphers_found2[i]=true && break
done
i=${index[i]}
ciphers_found[i]=true
if "$WIDE" && ( [[ ${kx[i]} == "Kx=ECDH" ]] || [[ ${kx[i]} == "Kx=DH" ]] || [[ ${kx[i]} == "Kx=EDH" ]] ); then
dhlen=$(read_dhbits_from_file "$TMPFILE" quiet)
kx[i]="${kx[i]} $dhlen"
fi
"$WIDE" && "$SHOW_SIGALGO" && grep -q "\-\-\-\-\-BEGIN CERTIFICATE\-\-\-\-\-" $TMPFILE && \
sigalg[i]="$($OPENSSL x509 -noout -text -in $TMPFILE | awk -F':' '/Signature Algorithm/ { print $2 }' | head -1)"
fi
fi
fi
done
if "$using_sockets"; then
for (( i=0; i < nr_ciphers; i++ )); do
if ! "${ciphers_found[i]}" && [[ "${sslvers[i]}" != "SSLv2" ]]; then
ciphers_found2[nr_nonossl_ciphers]=false
sslvers2[nr_nonossl_ciphers]="${sslvers[i]}"
hexcode2[nr_nonossl_ciphers]="${hexcode[i]}"
rfc_ciph2[nr_nonossl_ciphers]="${rfc_ciph[i]}"
index[nr_nonossl_ciphers]=$i
nr_nonossl_ciphers+=1
fi
done
fi
for (( success=0; success==0 ; 1 )); do
ciphers_to_test=""
for (( i=0; i < nr_nonossl_ciphers; i++ )); do
! "${ciphers_found2[i]}" && ciphers_to_test+=", ${hexcode2[i]}"
done
success=1
if [[ -n "$ciphers_to_test" ]]; then
if "$WIDE" && "$SHOW_SIGALGO"; then
tls_sockets "03" "${ciphers_to_test:2}, 00,ff" "all"
else
tls_sockets "03" "${ciphers_to_test:2}, 00,ff" "ephemeralkey"
fi
ret=$?
if [[ $ret -eq 0 ]] || [[ $ret -eq 2 ]]; then
success=0
rc4_offered=1
cipher=$(awk '/Cipher *:/ { print $3 }' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt")
for (( i=0; i < nr_nonossl_ciphers; i++ )); do
[[ "$cipher" == "${rfc_ciph2[i]}" ]] && ciphers_found2[i]=true && break
done
i=${index[i]}
ciphers_found[i]=true
if "$WIDE" && ( [[ ${kx[i]} == "Kx=ECDH" ]] || [[ ${kx[i]} == "Kx=DH" ]] || [[ ${kx[i]} == "Kx=EDH" ]] ); then
dhlen=$(read_dhbits_from_file "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" quiet)
kx[i]="${kx[i]} $dhlen"
fi
"$WIDE" && "$SHOW_SIGALGO" && [[ -r "$HOSTCERT" ]] && \
sigalg[i]="$($OPENSSL x509 -noout -text -in "$HOSTCERT" | awk -F':' '/Signature Algorithm/ { print $2 }' | head -1)"
fi
fi
done
if [[ $rc4_offered -eq 1 ]]; then
"$WIDE" || pr_svrty_high "VULNERABLE (NOT ok): "
if "$WIDE"; then if "$WIDE"; then
outln "\n" outln "\n"
neat_header neat_header
fi fi
while read hexcode dash rc4_cipher sslvers kx auth enc mac; do for (( i=0 ; i<nr_ciphers; i++ )); do
if [[ "$sslvers" == "SSLv2" ]]; then if ! "${ciphers_found[i]}" && ! "$SHOW_EACH_C"; then
$OPENSSL s_client -cipher $rc4_cipher $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY -ssl2 </dev/null >$TMPFILE 2>$ERRFILE
else
$OPENSSL s_client -cipher $rc4_cipher $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI </dev/null >$TMPFILE 2>$ERRFILE
fi
sclient_connect_successful $? $TMPFILE
sclient_success=$? # here we may have a fp with openssl < 1.0, TBC
if [[ $sclient_success -ne 0 ]] && ! "$SHOW_EACH_C"; then
continue # no successful connect AND not verbose displaying each cipher continue # no successful connect AND not verbose displaying each cipher
fi fi
if "$WIDE"; then if "$WIDE"; then
#FIXME: JSON+CSV in wide mode is missing #FIXME: JSON+CSV in wide mode is missing
normalize_ciphercode "$hexcode" neat_list "${normalized_hexcode[i]}" "${ciph[i]}" "${kx[i]}" "${enc[i]}"
neat_list "$HEXC" "$rc4_cipher" "$kx" "$enc"
if "$SHOW_EACH_C"; then if "$SHOW_EACH_C"; then
if [[ $sclient_success -eq 0 ]]; then if "${ciphers_found[i]}"; then
pr_svrty_high "available" pr_svrty_high "available"
else else
out "not a/v" out "not a/v"
fi fi
else
rc4_offered=1
out
fi fi
outln outln "${sigalg[i]}"
else elif "${ciphers_found[i]}"; then
[[ $sclient_success -eq 0 ]] && pr_svrty_high "$rc4_cipher " pr_svrty_high "${ciph[i]} "
fi fi
[[ $sclient_success -eq 0 ]] && rc4_detected+="$rc4_cipher " "${ciphers_found[i]}" && rc4_detected+="${ciph[i]} "
done < <($OPENSSL ciphers -V $rc4_ciphers_list:@STRENGTH) done
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"
elif [[ $nr_ciphers -eq 0 ]]; then
local_problem_ln "No RC4 Ciphers configured in $OPENSSL"
fileout "rc4" "WARN" "RC4 ciphers not supported by local OpenSSL ($OPENSSL)"
else else
pr_done_goodln "no RC4 ciphers detected (OK)" pr_done_goodln "no RC4 ciphers detected (OK)"
fileout "rc4" "OK" "RC4: not vulnerable" "$cve" "$cwe" fileout "rc4" "OK" "RC4: not vulnerable" "$cve" "$cwe"
rc4_offered=0
fi fi
outln outln
"$using_sockets" && HAS_DH_BITS="$has_dh_bits"
tmpfile_handle $FUNCNAME.txt tmpfile_handle $FUNCNAME.txt
return $rc4_offered return $rc4_offered
} }
@ -9155,6 +9334,7 @@ test_openssl_suffix() {
find_openssl_binary() { find_openssl_binary() {
local s_client_has=$TEMPDIR/s_client_has.txt local s_client_has=$TEMPDIR/s_client_has.txt
local s_client_starttls_has=$TEMPDIR/s_client_starttls_has.txt
# 0. check environment variable whether it's executable # 0. check environment variable whether it's executable
if [[ -n "$OPENSSL" ]] && [[ ! -x "$OPENSSL" ]]; then if [[ -n "$OPENSSL" ]] && [[ ! -x "$OPENSSL" ]]; then
@ -9211,6 +9391,8 @@ find_openssl_binary() {
$OPENSSL s_client -help 2>$s_client_has $OPENSSL s_client -help 2>$s_client_has
$OPENSSL s_client -starttls foo 2>$s_client_starttls_has
grep -qw '\-alpn' $s_client_has && \ grep -qw '\-alpn' $s_client_has && \
HAS_ALPN=true HAS_ALPN=true
@ -9226,6 +9408,9 @@ find_openssl_binary() {
grep -q '\-xmpp' $s_client_has && \ grep -q '\-xmpp' $s_client_has && \
HAS_XMPP=true HAS_XMPP=true
grep -q 'postgres' $s_client_starttls_has && \
HAS_POSTGRES=true
if [[ "$OPENSSL_TIMEOUT" != "" ]]; then if [[ "$OPENSSL_TIMEOUT" != "" ]]; then
if which timeout >&2 2>/dev/null ; then if which timeout >&2 2>/dev/null ; then
# there are different "timeout". Check whether --preserve-status is supported # there are different "timeout". Check whether --preserve-status is supported
@ -9307,7 +9492,7 @@ help() {
"$PROG_NAME <options> URI", where <options> is: "$PROG_NAME <options> URI", where <options> is:
-t, --starttls <protocol> does a default run against a STARTTLS enabled <protocol, -t, --starttls <protocol> does a default run against a STARTTLS enabled <protocol,
protocol is <ftp|smtp|pop3|imap|xmpp|telnet|ldap> (latter two require supplied openssl) protocol is <ftp|smtp|pop3|imap|xmpp|telnet|ldap|postgres> (latter three require supplied openssl)
--xmpphost <to_domain> for STARTTLS enabled XMPP it supplies the XML stream to-'' domain -- sometimes needed --xmpphost <to_domain> for STARTTLS enabled XMPP it supplies the XML stream to-'' domain -- sometimes needed
--mx <domain/host> tests MX records from high to low priority (STARTTLS, port 25) --mx <domain/host> tests MX records from high to low priority (STARTTLS, port 25)
--file <fname> mass testing option: Reads command lines from <fname>, one line per instance. --file <fname> mass testing option: Reads command lines from <fname>, one line per instance.
@ -9405,7 +9590,7 @@ maketempf() {
} }
prepare_debug() { prepare_debug() {
local hexc ossl_ciph ossl_supported_tls="" ossl_supported_sslv2="" local hexc mac ossl_ciph ossl_supported_tls="" ossl_supported_sslv2=""
if [[ $DEBUG -ne 0 ]]; then if [[ $DEBUG -ne 0 ]]; then
cat >$TEMPDIR/environment.txt << EOF cat >$TEMPDIR/environment.txt << EOF
@ -9440,6 +9625,7 @@ HAS_ALPN: $HAS_ALPN
HAS_FALLBACK_SCSV: $HAS_FALLBACK_SCSV HAS_FALLBACK_SCSV: $HAS_FALLBACK_SCSV
HAS_PROXY: $HAS_PROXY HAS_PROXY: $HAS_PROXY
HAS_XMPP: $HAS_XMPP HAS_XMPP: $HAS_XMPP
HAS_POSTGRES: $HAS_POSTGRES
PATH: $PATH PATH: $PATH
PROG_NAME: $PROG_NAME PROG_NAME: $PROG_NAME
@ -9484,7 +9670,7 @@ EOF
if [[ -e $CIPHERS_BY_STRENGTH_FILE ]]; then if [[ -e $CIPHERS_BY_STRENGTH_FILE ]]; then
"$HAS_SSL2" && ossl_supported_sslv2="$($OPENSSL ciphers -ssl2 -V 'ALL:COMPLEMENTOFALL:@STRENGTH' 2>$ERRFILE)" "$HAS_SSL2" && ossl_supported_sslv2="$($OPENSSL ciphers -ssl2 -V 'ALL:COMPLEMENTOFALL:@STRENGTH' 2>$ERRFILE)"
ossl_supported_tls="$($OPENSSL ciphers -tls1 -V 'ALL:COMPLEMENTOFALL:@STRENGTH' 2>$ERRFILE)" ossl_supported_tls="$($OPENSSL ciphers -tls1 -V 'ALL:COMPLEMENTOFALL:@STRENGTH' 2>$ERRFILE)"
while read hexc n TLS_CIPHER_OSSL_NAME[TLS_NR_CIPHERS] TLS_CIPHER_RFC_NAME[TLS_NR_CIPHERS] TLS_CIPHER_SSLVERS[TLS_NR_CIPHERS] TLS_CIPHER_KX[TLS_NR_CIPHERS] TLS_CIPHER_AUTH[TLS_NR_CIPHERS] TLS_CIPHER_ENC[TLS_NR_CIPHERS] TLS_CIPHER_EXPORT[TLS_NR_CIPHERS]; do while read hexc n TLS_CIPHER_OSSL_NAME[TLS_NR_CIPHERS] TLS_CIPHER_RFC_NAME[TLS_NR_CIPHERS] TLS_CIPHER_SSLVERS[TLS_NR_CIPHERS] TLS_CIPHER_KX[TLS_NR_CIPHERS] TLS_CIPHER_AUTH[TLS_NR_CIPHERS] TLS_CIPHER_ENC[TLS_NR_CIPHERS] mac TLS_CIPHER_EXPORT[TLS_NR_CIPHERS]; do
TLS_CIPHER_HEXCODE[TLS_NR_CIPHERS]="$hexc" TLS_CIPHER_HEXCODE[TLS_NR_CIPHERS]="$hexc"
TLS_CIPHER_OSSL_SUPPORTED[TLS_NR_CIPHERS]=false TLS_CIPHER_OSSL_SUPPORTED[TLS_NR_CIPHERS]=false
if [[ ${#hexc} -eq 9 ]]; then if [[ ${#hexc} -eq 9 ]]; then
@ -9762,7 +9948,7 @@ get_local_aaaa() {
local etchosts="/etc/hosts /c/Windows/System32/drivers/etc/hosts" local etchosts="/etc/hosts /c/Windows/System32/drivers/etc/hosts"
# for security testing sometimes we have local entries. Getent is BS under Linux for localhost: No network, no resolution # for security testing sometimes we have local entries. Getent is BS under Linux for localhost: No network, no resolution
ip6=$(grep -wh "$NODE" $etchosts 2>/dev/null | grep ':' | grep -v '^#' | egrep "[[:space:]]$NODE" | awk '{ print $1 }') ip6=$(grep -wh "$1" $etchosts 2>/dev/null | grep ':' | egrep -v '^#|\.local' | egrep "[[:space:]]$1" | awk '{ print $1 }')
if is_ipv6addr "$ip6"; then if is_ipv6addr "$ip6"; then
echo "$ip6" echo "$ip6"
else else
@ -9775,7 +9961,7 @@ get_local_a() {
local etchosts="/etc/hosts /c/Windows/System32/drivers/etc/hosts" local etchosts="/etc/hosts /c/Windows/System32/drivers/etc/hosts"
# for security testing sometimes we have local entries. Getent is BS under Linux for localhost: No network, no resolution # for security testing sometimes we have local entries. Getent is BS under Linux for localhost: No network, no resolution
ip4=$(grep -wh "$1[^\.]" $etchosts 2>/dev/null | egrep -v ':|^#' | egrep "[[:space:]]$1" | awk '{ print $1 }') ip4=$(grep -wh "$1" $etchosts 2>/dev/null | egrep -v ':|^#|\.local' | egrep "[[:space:]]$1" | awk '{ print $1 }')
if is_ipv4addr "$ip4"; then if is_ipv4addr "$ip4"; then
echo "$ip4" echo "$ip4"
else else
@ -10070,7 +10256,7 @@ determine_optimal_proto() {
} }
# arg1: ftp smtp, pop3, imap, xmpp, telnet, ldap (maybe with trailing s) # arg1: ftp smtp, pop3, imap, xmpp, telnet, ldap, postgres (maybe with trailing s)
determine_service() { determine_service() {
local ua local ua
local protocol local protocol
@ -10097,9 +10283,13 @@ determine_service() {
service_detection $OPTIMAL_PROTO service_detection $OPTIMAL_PROTO
else else
# STARTTLS # STARTTLS
if [[ "$1" == postgres ]]; then
protocol="postgres"
else
protocol=${1%s} # strip trailing 's' in ftp(s), smtp(s), pop3(s), etc protocol=${1%s} # strip trailing 's' in ftp(s), smtp(s), pop3(s), etc
fi
case "$protocol" in case "$protocol" in
ftp|smtp|pop3|imap|xmpp|telnet|ldap) ftp|smtp|pop3|imap|xmpp|telnet|ldap|postgres)
STARTTLS="-starttls $protocol" STARTTLS="-starttls $protocol"
SNI="" SNI=""
if [[ "$protocol" == xmpp ]]; then if [[ "$protocol" == xmpp ]]; then
@ -10113,6 +10303,12 @@ determine_service() {
# see http://xmpp.org/rfcs/rfc3920.html # see http://xmpp.org/rfcs/rfc3920.html
fi fi
fi fi
if [[ "$protocol" == postgres ]]; then
# Check if openssl version supports postgres.
if ! "$HAS_POSTGRES"; then
fatal "Your $OPENSSL does not support the \"-starttls postgres\" option" -5
fi
fi
$OPENSSL s_client -connect $NODEIP:$PORT $PROXY $BUGS $STARTTLS 2>$ERRFILE >$TMPFILE </dev/null $OPENSSL s_client -connect $NODEIP:$PORT $PROXY $BUGS $STARTTLS 2>$ERRFILE >$TMPFILE </dev/null
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
debugme cat $TMPFILE debugme cat $TMPFILE
@ -10126,7 +10322,7 @@ determine_service() {
outln outln
;; ;;
*) outln *) outln
fatal "momentarily only ftp, smtp, pop3, imap, xmpp, telnet and ldap allowed" -4 fatal "momentarily only ftp, smtp, pop3, imap, xmpp, telnet, ldap and postgres allowed" -4
;; ;;
esac esac
fi fi
@ -10438,8 +10634,8 @@ parse_cmd_line() {
STARTTLS_PROTOCOL=$(parse_opt_equal_sign "$1" "$2") STARTTLS_PROTOCOL=$(parse_opt_equal_sign "$1" "$2")
[[ $? -eq 0 ]] && shift [[ $? -eq 0 ]] && shift
case $STARTTLS_PROTOCOL in case $STARTTLS_PROTOCOL in
ftp|smtp|pop3|imap|xmpp|telnet|ldap|nntp) ;; ftp|smtp|pop3|imap|xmpp|telnet|ldap|nntp|postgres) ;;
ftps|smtps|pop3s|imaps|xmpps|telnets|ldaps|nntps) ;; ftps|smtps|pop3s|imaps|xmpps|telnets|ldaps|nntps|postgress) ;;
*) pr_magentaln "\nunrecognized STARTTLS protocol \"$1\", see help" 1>&2 *) pr_magentaln "\nunrecognized STARTTLS protocol \"$1\", see help" 1>&2
help 1 ;; help 1 ;;
esac esac