Add support for testing postgres protocol over TLS/SSL

The Postgres protocol uses STARTTLS with a custom start packet. This
functionality is supported by openssl s_client in the current openssl
master branch but not yet in any released version.

This patch detects whether the given openssl binary supports postgres
and runs the usual tests against a postgres server.

Example of no openssl support:

    ~/bin/testssl$ ./testssl.sh --quiet
    --openssl=/opt/openssl/openssl-1.1.0c/bin/openssl --starttls=postgres
    test.postgres.server.com:5432

     Start 2016-12-07 18:03:24    -->> ip.add.re.ss:5432
    (test.postgres.server.com:5432) <<--

    Fatal error: Your /opt/openssl/openssl-1.1.0c/bin/openssl does not
    support the "-starttls postgres" option

Example of openssl support:

    ~/bin/testssl$ ./testssl.sh --quiet
    --openssl=/opt/openssl/openssl-2016-12-07/bin/openssl --startt ls=postgres
    test.postgres.server.com:5432

     Start 2016-12-07 18:06:03    -->> ip.add.re.ss:5432
    (test.postgres.server.com:5432) <<--

     Service set:            STARTTLS via POSTGRES

     Testing protocols (via openssl, SSLv2 via sockets)

     SSLv2               not offered (OK)
     SSLv3               offered (NOT ok)
     TLS 1               offered
     TLS 1.1             offered
     TLS 1.2             offered (OK)
     SPDY/NPN            (SPDY is an HTTP protocol and thus not tested here)
     HTTP2/ALPN          (HTTP/2 is a HTTP protocol and thus not tested
    here)
    ...
This commit is contained in:
Steven Danneman 2016-12-08 10:54:44 -08:00
parent c985f68533
commit 1f165bcdf4

View File

@ -223,6 +223,7 @@ HAS_SPDY=false
HAS_FALLBACK_SCSV=false
HAS_PROXY=false
HAS_XMPP=false
HAS_POSTGRES=false
ADD_RFC_STR="rfc" # display RFC ciphernames
PORT=443 # unless otherwise auto-determined, see below
NODE=""
@ -5571,6 +5572,10 @@ EOF
starttls_line "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>" "proceed"
# BTW: https://xmpp.net !
;;
postgres|postgress) # Postgres SQL, see http://www.postgresql.org/docs/devel/static/protocol-message-formats.html
$FAST_STARTTLS || starttls_just_read
starttls_line "\x00\x00\x00\x08\x04\xD2\x16\x2F" "S"
;;
*) # 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
esac
@ -7426,6 +7431,7 @@ test_openssl_suffix() {
find_openssl_binary() {
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
if [[ -n "$OPENSSL" ]] && [[ ! -x "$OPENSSL" ]]; then
@ -7482,6 +7488,8 @@ find_openssl_binary() {
$OPENSSL s_client -help 2>$s_client_has
$OPENSSL s_client -starttls foo 2>$s_client_starttls_has
grep -qw '\-alpn' $s_client_has && \
HAS_ALPN=true
@ -7497,6 +7505,9 @@ find_openssl_binary() {
grep -q '\-xmpp' $s_client_has && \
HAS_XMPP=true
grep -q 'postgres' $s_client_starttls_has && \
HAS_POSTGRES=true
return 0
}
@ -7592,8 +7603,8 @@ special invocations:
partly mandatory parameters:
URI host|host:port|URL|URL:port (port 443 is assumed unless otherwise specified)
pattern an ignore case word pattern of cipher hexcode or any other string in the name, kx or bits
protocol is one of the STARTTLS protocols ftp,smtp,pop3,imap,xmpp,telnet,ldap
(for the latter two you need e.g. the supplied openssl)
protocol is one of the STARTTLS protocols ftp,smtp,pop3,imap,xmpp,telnet,ldap,postgres
(for telnet and ldap you need e.g. the supplied openssl)
tuning options (can also be preset via environment variables):
--bugs enables the "-bugs" option of s_client, needed e.g. for some buggy F5s
@ -7681,6 +7692,7 @@ HAS_ALPN: $HAS_ALPN
HAS_FALLBACK_SCSV: $HAS_FALLBACK_SCSV
HAS_PROXY: $HAS_PROXY
HAS_XMPP: $HAS_XMPP
HAS_POSTGRES: $HAS_POSTGRES
PATH: $PATH
PROG_NAME: $PROG_NAME
@ -8284,7 +8296,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() {
local ua
local protocol
@ -8311,9 +8323,13 @@ determine_service() {
service_detection $OPTIMAL_PROTO
else
# STARTTLS
protocol=${1%s} # strip trailing 's' in ftp(s), smtp(s), pop3(s), etc
if [[ "$1" == postgres ]]; then
protocol="postgres"
else
protocol=${1%s} # strip trailing 's' in ftp(s), smtp(s), pop3(s), etc
fi
case "$protocol" in
ftp|smtp|pop3|imap|xmpp|telnet|ldap)
ftp|smtp|pop3|imap|xmpp|telnet|ldap|postgres)
STARTTLS="-starttls $protocol"
SNI=""
if [[ "$protocol" == xmpp ]]; then
@ -8327,6 +8343,12 @@ determine_service() {
# see http://xmpp.org/rfcs/rfc3920.html
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
if [[ $? -ne 0 ]]; then
debugme cat $TMPFILE
@ -8340,7 +8362,7 @@ determine_service() {
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
fi
@ -8648,8 +8670,8 @@ parse_cmd_line() {
STARTTLS_PROTOCOL=$(parse_opt_equal_sign "$1" "$2")
[[ $? -eq 0 ]] && shift
case $STARTTLS_PROTOCOL in
ftp|smtp|pop3|imap|xmpp|telnet|ldap|nntp) ;;
ftps|smtps|pop3s|imaps|xmpps|telnets|ldaps|nntps) ;;
ftp|smtp|pop3|imap|xmpp|telnet|ldap|nntp|postgres) ;;
ftps|smtps|pop3s|imaps|xmpps|telnets|ldaps|nntps|postgress) ;;
*) pr_magentaln "\nunrecognized STARTTLS protocol \"$1\", see help" 1>&2
help 1 ;;
esac