コード例 #1
0
    def __call__(self):
        client = self.client_conn.connection
        server = self.server_conn.connection
        conns = [client, server]

        try:
            while not self.channel.should_exit.is_set():
                r = tcp.ssl_read_select(conns, 1)
                for conn in r:
                    source_conn = self.client_conn if conn == client else self.server_conn
                    other_conn = self.server_conn if conn == client else self.client_conn
                    is_server = (conn == self.server_conn.connection)

                    frame = websockets.Frame.from_file(source_conn.rfile)

                    if not self._handle_frame(frame, source_conn, other_conn,
                                              is_server):
                        return
        except (socket.error, netlib.exceptions.TcpException, SSL.Error) as e:
            self.log(
                "WebSockets connection closed unexpectedly by {}: {}".format(
                    "server" if is_server else "client", repr(e)), "info")
        except Exception as e:  # pragma: no cover
            raise exceptions.ProtocolException(
                "Error in WebSockets connection: {}".format(repr(e)))
コード例 #2
0
    def connect(self):
        """
        Establishes a server connection.
        Must not be called if there is an existing connection.

        Raises:
            ~mitmproxy.exceptions.ProtocolException: if the connection could not be established.
        """
        if not self.server_conn.address:
            raise exceptions.ProtocolException("Cannot connect to server, no server address given.")
        self.log("serverconnect", "debug", [repr(self.server_conn.address)])
        self.channel.ask("serverconnect", self.server_conn)
        try:
            self.server_conn.connect()
        except netlib.exceptions.TcpException as e:
            raise exceptions.ProtocolException(
                "Server connection to {} failed: {}".format(
                    repr(self.server_conn.address), str(e)
                )
            )
コード例 #3
0
ファイル: base.py プロジェクト: tdickers/mitmproxy
 def __check_self_connect(self):
     """
     We try to protect the proxy from _accidentally_ connecting to itself,
     e.g. because of a failed transparent lookup or an invalid configuration.
     """
     address = self.server_conn.address
     if address:
         self_connect = (address.port == self.config.port and address.host
                         in ("localhost", "127.0.0.1", "::1"))
         if self_connect:
             raise exceptions.ProtocolException(
                 "Invalid server address: {}\r\n"
                 "The proxy shall not connect to itself.".format(
                     repr(address)))
コード例 #4
0
    def _next_layer(self, top_layer):
        try:
            d = top_layer.client_conn.rfile.peek(3)
        except netlib.exceptions.TcpException as e:
            six.reraise(exceptions.ProtocolException,
                        exceptions.ProtocolException(str(e)),
                        sys.exc_info()[2])
        client_tls = protocol.is_tls_record_magic(d)

        # 1. check for --ignore
        if self.config.check_ignore:
            ignore = self.config.check_ignore(top_layer.server_conn.address)
            if not ignore and client_tls:
                try:
                    client_hello = protocol.TlsClientHello.from_client_conn(
                        self.client_conn)
                except exceptions.TlsProtocolException as e:
                    self.log("Cannot parse Client Hello: %s" % repr(e),
                             "error")
                else:
                    ignore = self.config.check_ignore((client_hello.sni, 443))
            if ignore:
                return protocol.RawTCPLayer(top_layer, ignore=True)

        # 2. Always insert a TLS layer, even if there's neither client nor server tls.
        # An inline script may upgrade from http to https,
        # in which case we need some form of TLS layer.
        if isinstance(top_layer, modes.ReverseProxy):
            return protocol.TlsLayer(top_layer, client_tls,
                                     top_layer.server_tls,
                                     top_layer.server_conn.address.host)
        if isinstance(top_layer, protocol.ServerConnectionMixin) or isinstance(
                top_layer, protocol.UpstreamConnectLayer):
            return protocol.TlsLayer(top_layer, client_tls, client_tls)

        # 3. In Http Proxy mode and Upstream Proxy mode, the next layer is fixed.
        if isinstance(top_layer, protocol.TlsLayer):
            if isinstance(top_layer.ctx, modes.HttpProxy):
                return protocol.Http1Layer(top_layer, "regular")
            if isinstance(top_layer.ctx, modes.HttpUpstreamProxy):
                return protocol.Http1Layer(top_layer, "upstream")

        # 4. Check for other TLS cases (e.g. after CONNECT).
        if client_tls:
            return protocol.TlsLayer(top_layer, True, True)

        # 4. Check for --tcp
        if self.config.check_tcp(top_layer.server_conn.address):
            return protocol.RawTCPLayer(top_layer)

        # 5. Check for TLS ALPN (HTTP1/HTTP2)
        if isinstance(top_layer, protocol.TlsLayer):
            alpn = top_layer.client_conn.get_alpn_proto_negotiated()
            if alpn == b'h2':
                return protocol.Http2Layer(top_layer, 'transparent')
            if alpn == b'http/1.1':
                return protocol.Http1Layer(top_layer, 'transparent')

        # 6. Check for raw tcp mode
        is_ascii = (
            len(d) == 3 and
            # expect A-Za-z
            all(65 <= x <= 90 or 97 <= x <= 122 for x in six.iterbytes(d)))
        if self.config.options.rawtcp and not is_ascii:
            return protocol.RawTCPLayer(top_layer)

        # 7. Assume HTTP1 by default
        return protocol.Http1Layer(top_layer, 'transparent')