def post_handshake_check(self): try: # Send an HTTP GET to the server and store the HTTP Status Code self.write(self.HTTP_GET_REQ.format(self._host)) # Parse the response and print the Location header http_response = parse_http_response(self) if http_response.version == 9: # HTTP 0.9 => Probably not an HTTP response result = self.ERR_NOT_HTTP else: redirect = '' if 300 <= http_response.status < 400: if http_response.getheader('Location', None): # Add redirection URL to the result redirect = ' - ' + http_response.getheader( 'Location', None) result = self.GET_RESULT_FORMAT.format(http_response.status, http_response.reason, redirect) except socket.timeout: result = self.ERR_HTTP_TIMEOUT return result
def do_pre_handshake(self): """Open a socket to the server; setup HTTP tunneling if a proxy was configured.""" if self._tunnel_host: # Proxy configured; setup HTTP tunneling try: self._sock = socket.create_connection((self._tunnel_host, self._tunnel_port), self.NETWORK_TIMEOUT) except socket.timeout as e: raise ProxyError(self.ERR_PROXY_OFFLINE.format(e[0])) except socket.error as e: raise ProxyError(self.ERR_PROXY_OFFLINE.format(e[1])) # Send a CONNECT request with the host we want to tunnel to if self._tunnel_basic_auth_token is None: self._sock.send(self.HTTP_CONNECT_REQ.format(self._host, self._port)) else: self._sock.send(self.HTTP_CONNECT_REQ_PROXY_AUTH_BASIC.format(self._host, self._port, self._tunnel_basic_auth_token)) http_response = parse_http_response(self._sock) # Check if the proxy was able to connect to the host if http_response.status != 200: raise ProxyError(self.ERR_CONNECT_REJECTED) else: # No proxy; connect directly to the server self._sock = socket.create_connection((self._ip, self._port), self.NETWORK_TIMEOUT)
def post_handshake_check(self): try: # TODO: This is code only used by OpenSSLCipherSuitesPlugin anf should be moved there # Send an HTTP GET to the server and store the HTTP Status Code self.write(self.HTTP_GET_REQ.format(self._host)) # Parse the response and print the Location header http_response = parse_http_response(self) if http_response.version == 9 : # HTTP 0.9 => Probably not an HTTP response result = self.ERR_NOT_HTTP else: redirect = '' if 300 <= http_response.status < 400: if http_response.getheader('Location', None): # Add redirection URL to the result redirect = ' - ' + http_response.getheader('Location', None) result = self.GET_RESULT_FORMAT.format(http_response.status, http_response.reason, redirect) except socket.timeout: result = self.ERR_HTTP_TIMEOUT except IOError: result = self.ERR_GENERIC return result
def do_pre_handshake(self): """Open a socket to the server; setup HTTP tunneling if a proxy was configured.""" if self._tunnel_host: # Proxy configured; setup HTTP tunneling try: self._sock = socket.create_connection( (self._tunnel_host, self._tunnel_port), self.NETWORK_TIMEOUT) except socket.timeout as e: raise ProxyError(self.ERR_PROXY_OFFLINE.format(e[0])) except socket.error as e: raise ProxyError(self.ERR_PROXY_OFFLINE.format(e[1])) # Send a CONNECT request with the host we want to tunnel to if self._tunnel_basic_auth_token is None: self._sock.send( self.HTTP_CONNECT_REQ.format(self._host, self._port)) else: self._sock.send( self.HTTP_CONNECT_REQ_PROXY_AUTH_BASIC.format( self._host, self._port, self._tunnel_basic_auth_token)) http_response = parse_http_response(self._sock) # Check if the proxy was able to connect to the host if http_response.status != 200: raise ProxyError(self.ERR_CONNECT_REJECTED) else: # No proxy; connect directly to the server self._sock = socket.create_connection((self._ip, self._port), self.NETWORK_TIMEOUT)
def post_handshake_check(self): try: # TODO: This is code only used by OpenSSLCipherSuitesPlugin anf should be moved there # Send an HTTP GET to the server and store the HTTP Status Code self.write(self.HTTP_GET_REQ.format(self._host)) # Parse the response and print the Location header http_response = parse_http_response(self) if http_response.version == 9: # HTTP 0.9 => Probably not an HTTP response result = self.ERR_NOT_HTTP else: redirect = '' if 300 <= http_response.status < 400: if http_response.getheader('Location', None): # Add redirection URL to the result redirect = ' - ' + http_response.getheader( 'Location', None) result = self.GET_RESULT_FORMAT.format(http_response.status, http_response.reason, redirect) except socket.timeout: result = self.ERR_HTTP_TIMEOUT except IOError: result = self.ERR_GENERIC return result
def _get_security_headers(cls, server_info): hpkp_report_only = False # Perform the SSL handshake ssl_connection = server_info.get_preconfigured_ssl_connection() ssl_connection.connect() certificate_chain = ssl_connection.get_peer_cert_chain() # Send an HTTP GET request to the server ssl_connection.write( cls.HTTP_GET_FORMAT.format(host=server_info.hostname)) http_resp = parse_http_response(ssl_connection) ssl_connection.close() if http_resp.version == 9: # HTTP 0.9 => Probably not an HTTP response raise ValueError('Server did not return an HTTP response') else: hsts_header = http_resp.getheader('strict-transport-security', None) hpkp_header = http_resp.getheader('public-key-pins', None) if hpkp_header is None: hpkp_report_only = True hpkp_header = http_resp.getheader( 'public-key-pins-report-only', None) # We do not follow redirections because the security headers must be set on the first page according to # https://hstspreload.appspot.com/: # "If you are serving an additional redirect from your HTTPS site, that redirect must still have the HSTS # header (rather than the page it redirects to)." return hsts_header, hpkp_header, hpkp_report_only, certificate_chain
def _get_hsts_header(self, server_info): hsts_header = None nb_redirect = 0 http_get_format = 'GET {0} HTTP/1.0\r\nHost: {1}\r\n{2}Connection: close\r\n\r\n'.format http_path = '/' http_append = '' while nb_redirect < self.MAX_REDIRECT: # Always use a new connection as some servers always close the connection after sending back an HTTP # response ssl_connection = server_info.get_preconfigured_ssl_connection() # Perform the SSL handshake ssl_connection.connect() ssl_connection.write( http_get_format(http_path, server_info.hostname, http_append)) http_resp = parse_http_response(ssl_connection) ssl_connection.close() if http_resp.version == 9: # HTTP 0.9 => Probably not an HTTP response raise ValueError('Server did not return an HTTP response') else: hsts_header = http_resp.getheader('strict-transport-security', None) # If there was no HSTS header, check if the server returned a redirection if hsts_header is None and 300 <= http_resp.status < 400: redirect_header = http_resp.getheader('Location', None) cookie_header = http_resp.getheader('Set-Cookie', None) if redirect_header is None: break o = urlparse(redirect_header) # Handle absolute redirection URL but only allow redirections to the same domain and port if o.hostname and o.hostname != server_info.hostname: break else: http_path = o.path if o.scheme == 'http': # We would have to use urllib for http: URLs raise ValueError( "Error: server sent a redirection to HTTP.") # Handle cookies if cookie_header: cookie = Cookie.SimpleCookie(cookie_header) if cookie: http_append = 'Cookie:' + cookie.output( attrs=[], header='', sep=';') + '\r\n' nb_redirect += 1 else: # If the server did not return a redirection just give up break return hsts_header
def _get_hsts_header(self, server_info): hsts_header = None nb_redirect = 0 http_get_format = 'GET {0} HTTP/1.0\r\nHost: {1}\r\n{2}Connection: close\r\n\r\n'.format http_path = '/' http_append = '' while nb_redirect < self.MAX_REDIRECT: # Always use a new connection as some servers always close the connection after sending back an HTTP # response ssl_connection = server_info.get_preconfigured_ssl_connection() # Perform the SSL handshake ssl_connection.connect() ssl_connection.write(http_get_format(http_path, server_info.hostname, http_append)) http_resp = parse_http_response(ssl_connection) ssl_connection.close() if http_resp.version == 9 : # HTTP 0.9 => Probably not an HTTP response raise ValueError('Server did not return an HTTP response') else: hsts_header = http_resp.getheader('strict-transport-security', None) # If there was no HSTS header, check if the server returned a redirection if hsts_header is None and 300 <= http_resp.status < 400: redirect_header = http_resp.getheader('Location', None) cookie_header = http_resp.getheader('Set-Cookie', None) if redirect_header is None: break o = urlparse(redirect_header) # Handle absolute redirection URL but only allow redirections to the same domain and port if o.hostname and o.hostname != server_info.hostname: break else: http_path = o.path if o.scheme == 'http': # We would have to use urllib for http: URLs break # Handle cookies if cookie_header: cookie = Cookie.SimpleCookie(cookie_header) if cookie: http_append = 'Cookie:' + cookie.output(attrs=[], header='', sep=';') + '\r\n' nb_redirect+=1 else: # If the server did not return a redirection just give up break return hsts_header
def post_handshake_check(self): try: # Send an HTTP GET to the server and store the HTTP Status Code self.write(self.HTTP_GET_REQ.format(self._host)) # Parse the response and print the Location header http_response = parse_http_response(self) if http_response.version == 9 : # HTTP 0.9 => Probably not an HTTP response result = self.ERR_NOT_HTTP else: redirect = '' if 300 <= http_response.status < 400: # Add redirection URL to the result redirect = ' - ' + http_response.getheader('Location', None) result = self.GET_RESULT_FORMAT.format(http_response.status, http_response.reason, redirect) except socket.timeout: result = self.ERR_HTTP_TIMEOUT return result