mirror of
				https://github.com/drwetter/testssl.sh.git
				synced 2025-10-30 21:35:26 +01:00 
			
		
		
		
	Implemented proper STARTTLS handshake for ftp, smtp, pop, imap and nntp
This commit is contained in:
		
							
								
								
									
										131
									
								
								testssl.sh
									
									
									
									
									
								
							
							
						
						
									
										131
									
								
								testssl.sh
									
									
									
									
									
								
							| @@ -6073,8 +6073,8 @@ starttls_line() { | |||||||
| } | } | ||||||
|  |  | ||||||
| starttls_just_send(){ | starttls_just_send(){ | ||||||
|      debugme echo -e "\n=== sending \"$1\" ..." |      debugme echo -e "C: $1" | ||||||
|      echo -e "$1" >&5 |      echo -ne "$1\r\n" >&5 | ||||||
| } | } | ||||||
|  |  | ||||||
| starttls_just_read(){ | starttls_just_read(){ | ||||||
| @@ -6090,6 +6090,108 @@ starttls_just_read(){ | |||||||
|      return 0 |      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 | # arg for a fd doesn't work here | ||||||
| fd_socket() { | fd_socket() { | ||||||
| @@ -6127,29 +6229,20 @@ fd_socket() { | |||||||
|  |  | ||||||
|      if [[ -n "$STARTTLS" ]]; then |      if [[ -n "$STARTTLS" ]]; then | ||||||
|           case "$STARTTLS_PROTOCOL" in # port |           case "$STARTTLS_PROTOCOL" in # port | ||||||
|                ftp|ftps)  # https://tools.ietf.org/html/rfc4217 |                ftp|ftps)  # https://tools.ietf.org/html/rfc4217, https://tools.ietf.org/html/rfc959 | ||||||
|                     $FAST_STARTTLS || starttls_just_read |                     starttls_ftp_dialog | ||||||
|                     $FAST_STARTTLS || starttls_line "FEAT" "211" && starttls_just_send "FEAT" |  | ||||||
|                     starttls_line "AUTH TLS" "successful|234" |  | ||||||
|                     ;; |                     ;; | ||||||
|                smtp|smtps)  # SMTP, see https://tools.ietf.org/html/rfc4217 |                smtp|smtps)  # SMTP, see https://tools.ietf.org/html/rfc5321, https://tools.ietf.org/html/rfc3207 | ||||||
|                     $FAST_STARTTLS || starttls_just_read |                     starttls_smtp_dialog | ||||||
|                     $FAST_STARTTLS || starttls_line "EHLO testssl.sh" "220|250" && starttls_just_send "EHLO testssl.sh" |  | ||||||
|                     starttls_line "STARTTLS" "220" |  | ||||||
|                     ;; |                     ;; | ||||||
|                pop3|pop3s) # POP, see https://tools.ietf.org/html/rfc2595 |                pop3|pop3s) # POP, see https://tools.ietf.org/html/rfc2595 | ||||||
|                     $FAST_STARTTLS || starttls_just_read |                     starttls_pop3_dialog | ||||||
|                     starttls_line "STLS" "OK" |  | ||||||
|                     ;; |                     ;; | ||||||
|                nntp|nntps) # NNTP, see https://tools.ietf.org/html/rfc4642 |                nntp|nntps) # NNTP, see https://tools.ietf.org/html/rfc4642 | ||||||
|                     $FAST_STARTTLS || starttls_just_read |                     starttls_nntp_dialog | ||||||
|                     $FAST_STARTTLS || starttls_line "CAPABILITIES" "101|200" && starttls_just_send "CAPABILITIES" |  | ||||||
|                     starttls_line "STARTTLS" "382" |  | ||||||
|                     ;; |                     ;; | ||||||
|                imap|imaps) # IMAP, https://tools.ietf.org/html/rfc2595 |                imap|imaps) # IMAP, https://tools.ietf.org/html/rfc2595, https://tools.ietf.org/html/rfc3501 | ||||||
|                     $FAST_STARTTLS || starttls_just_read |                     starttls_imap_dialog | ||||||
|                     $FAST_STARTTLS || starttls_line "a001 CAPABILITY" "OK" && starttls_just_send "a001 CAPABILITY" |  | ||||||
|                     starttls_line "a002 STARTTLS" "OK" |  | ||||||
|                     ;; |                     ;; | ||||||
|                ldap|ldaps) # LDAP, https://tools.ietf.org/html/rfc2830, https://tools.ietf.org/html/rfc4511 |                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 |                     fatal "FIXME: LDAP+STARTTLS over sockets not yet supported (try \"--ssl-native\")" -4 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 typingArtist
					typingArtist