Merge pull request #536 from typingArtist/fix_starttls

Implement proper STARTTLS handshake for ftp, smtp, pop, imap and nntp
This commit is contained in:
Dirk Wetter 2016-12-01 16:29:12 +01:00 committed by GitHub
commit 7aee9b9f0b
1 changed files with 113 additions and 19 deletions

View File

@ -853,6 +853,7 @@ fileout() { # ID, SEVERITY, FINDING
debugme() {
[[ "$DEBUG" -ge 2 ]] && "$@"
return 0
}
hex2dec() {
@ -6073,8 +6074,8 @@ starttls_line() {
}
starttls_just_send(){
debugme echo -e "\n=== sending \"$1\" ..."
echo -e "$1" >&5
debugme echo -e "C: $1"
echo -ne "$1\r\n" >&5
}
starttls_just_read(){
@ -6090,6 +6091,108 @@ starttls_just_read(){
return 0
}
starttls_full_read(){
starttls_read_data=()
local one_line=""
local ret=0
local cont_pattern="$1"
local end_pattern="$2"
local ret_found=0
if [[ $# -ge 3 ]]; then
debugme echo "=== we have to search for $3 pattern ==="
ret_found=3
fi
debugme echo "=== full read banner ==="
local oldIFS="$IFS"
IFS=''
while read -r -t $STARTTLS_SLEEP one_line; do
debugme echo "S: ${one_line}"
if [[ $# -ge 3 ]]; then
if [[ ${one_line} =~ $3 ]]; then
ret_found=0
debugme echo "^^^^^^^ that's what we were looking for ==="
fi
fi
starttls_read_data+=("${one_line}")
if [[ ${one_line} =~ ${end_pattern} ]]; then
debugme echo "=== full read finished ==="
IFS="${oldIFS}"
return ${ret_found}
fi
if [[ ! ${one_line} =~ ${cont_pattern} ]]; then
debugme echo "=== full read syntax error, expected regex pattern ${cont_pattern} (cont) or ${end_pattern} (end) ==="
IFS="${oldIFS}"
return 2
fi
done <&5
ret=$?
debugme echo "=== full read error/timeout ==="
IFS="${oldIFS}"
return $ret
}
starttls_ftp_dialog(){
debugme echo "=== starting ftp STARTTLS dialog ==="
local reAUTHTLS='^ AUTH TLS'
starttls_full_read '^220-' '^220 ' && debugme echo "received server greeting" &&
starttls_just_send 'FEAT' && debugme echo "sent FEAT" &&
starttls_full_read '^(211-| )' '^211 ' "${reAUTHTLS}" && debugme echo "received server features and checked STARTTLS availability" &&
starttls_just_send 'AUTH TLS' && debugme echo "initiated STARTTLS" &&
starttls_full_read '^234-' '^234 ' && debugme echo "received ack for STARTTLS"
local ret=$?
debugme echo "=== finished ftp STARTTLS dialog with ${ret} ==="
return $ret
}
starttls_smtp_dialog(){
debugme echo "=== starting smtp STARTTLS dialog ==="
local re250STARTTLS='^250[ -]STARTTLS'
starttls_full_read '^220-' '^220 ' && debugme echo "received server greeting" &&
starttls_just_send 'EHLO testssl.sh' && debugme echo "sent EHLO" &&
starttls_full_read '^250-' '^250 ' "${re250STARTTLS}" && debugme echo "received server capabilities and checked STARTTLS availability" &&
starttls_just_send 'STARTTLS' && debugme echo "initiated STARTTLS" &&
starttls_full_read '^220-' '^220 ' && debugme echo "received ack for STARTTLS"
local ret=$?
debugme echo "=== finished smtp STARTTLS dialog with ${ret} ==="
return $ret
}
starttls_pop3_dialog() {
debugme echo "=== starting pop3 STARTTLS dialog ==="
starttls_full_read '$^' '^+OK' && debugme echo "received server greeting" &&
starttls_just_send 'STLS' && debugme echo "initiated STARTTLS" &&
starttls_full_read '$^' '^+OK' && debugme echo "received ack for STARTTLS"
local ret=$?
debugme echo "=== finished pop3 STARTTLS dialog with ${ret} ==="
return $ret
}
starttls_imap_dialog() {
debugme echo "=== starting imap STARTTLS dialog ==="
local reSTARTTLS='^\* CAPABILITY(( .*)? IMAP4rev1( .*)? STARTTLS( .*)?|( .*)? STARTTLS( .*)? IMAP4rev1( .*)?)$'
starttls_full_read '^\* ' '^\* OK ' && debugme echo "received server greeting" &&
starttls_just_send 'a001 CAPABILITY' && debugme echo "sent CAPABILITY" &&
starttls_full_read '^\* ' '^a001 OK ' "${reSTARTTLS}" && debugme echo "received server capabilities and checked STARTTLS availability" &&
starttls_just_send 'a002 STARTTLS' && debugme echo "initiated STARTTLS" &&
starttls_full_read '^\* ' '^a002 OK ' && debugme echo "received ack for STARTTLS"
local ret=$?
debugme echo "=== finished imap STARTTLS dialog with ${ret} ==="
return $ret
}
starttls_nntp_dialog() {
debugme echo "=== starting nntp STARTTLS dialog ==="
starttls_full_read '$^' '^20[01] ' && debugme echo "received server greeting" &&
starttls_just_send 'CAPABILITIES' && debugme echo "sent CAPABILITIES" &&
starttls_full_read '$^' '^101 ' &&
starttls_full_read '' '^\.$' "^STARTTLS$" && debugme echo "received server capabilities and checked STARTTLS availability" &&
starttls_just_send 'STARTTLS' && debugme echo "initiated STARTTLS" &&
starttls_full_read '$^' '^382 ' && debugme echo "received ack for STARTTLS"
local ret=$?
debugme echo "=== finished nntp STARTTLS dialog with ${ret} ==="
return $ret
}
# arg for a fd doesn't work here
fd_socket() {
@ -6127,29 +6230,20 @@ fd_socket() {
if [[ -n "$STARTTLS" ]]; then
case "$STARTTLS_PROTOCOL" in # port
ftp|ftps) # https://tools.ietf.org/html/rfc4217
$FAST_STARTTLS || starttls_just_read
$FAST_STARTTLS || starttls_line "FEAT" "211" && starttls_just_send "FEAT"
starttls_line "AUTH TLS" "successful|234"
ftp|ftps) # https://tools.ietf.org/html/rfc4217, https://tools.ietf.org/html/rfc959
starttls_ftp_dialog
;;
smtp|smtps) # SMTP, see https://tools.ietf.org/html/rfc4217
$FAST_STARTTLS || starttls_just_read
$FAST_STARTTLS || starttls_line "EHLO testssl.sh" "220|250" && starttls_just_send "EHLO testssl.sh"
starttls_line "STARTTLS" "220"
smtp|smtps) # SMTP, see https://tools.ietf.org/html/rfc5321, https://tools.ietf.org/html/rfc3207
starttls_smtp_dialog
;;
pop3|pop3s) # POP, see https://tools.ietf.org/html/rfc2595
$FAST_STARTTLS || starttls_just_read
starttls_line "STLS" "OK"
starttls_pop3_dialog
;;
nntp|nntps) # NNTP, see https://tools.ietf.org/html/rfc4642
$FAST_STARTTLS || starttls_just_read
$FAST_STARTTLS || starttls_line "CAPABILITIES" "101|200" && starttls_just_send "CAPABILITIES"
starttls_line "STARTTLS" "382"
starttls_nntp_dialog
;;
imap|imaps) # IMAP, https://tools.ietf.org/html/rfc2595
$FAST_STARTTLS || starttls_just_read
$FAST_STARTTLS || starttls_line "a001 CAPABILITY" "OK" && starttls_just_send "a001 CAPABILITY"
starttls_line "a002 STARTTLS" "OK"
imap|imaps) # IMAP, https://tools.ietf.org/html/rfc2595, https://tools.ietf.org/html/rfc3501
starttls_imap_dialog
;;
ldap|ldaps) # LDAP, https://tools.ietf.org/html/rfc2830, https://tools.ietf.org/html/rfc4511
fatal "FIXME: LDAP+STARTTLS over sockets not yet supported (try \"--ssl-native\")" -4