示例#1
0
    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
示例#2
0
    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)
示例#3
0
    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
示例#4
0
    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)
示例#5
0
    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
示例#6
0
    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
示例#7
0
    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
示例#8
0
    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
示例#9
0
    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