Ejemplo n.º 1
0
 def test_simple(self):
     a = tcp.Address("localhost", True)
     assert a.use_ipv6
     b = tcp.Address("foo.com", True)
     assert not a == b
     c = tcp.Address("localhost", True)
     assert a == c
Ejemplo n.º 2
0
 def test_simple(self):
     a = tcp.Address(("localhost", 80), True)
     assert a.use_ipv6
     b = tcp.Address(("foo.com", 80), True)
     assert not a == b
     c = tcp.Address(("localhost", 80), True)
     assert a == c
     assert not a != c
     assert repr(a) == "localhost:80"
Ejemplo n.º 3
0
    def load_state(self, state):
        super(ServerConnection, self).load_state(state)

        self.address = tcp.Address(
            **state["address"]) if state["address"] else None
        self.source_address = tcp.Address(
            **state["source_address"]) if state["source_address"] else None
        self.cert = certutils.SSLCert.from_pem(
            state["cert"]) if state["cert"] else None
Ejemplo n.º 4
0
 def test_simple(self):
     a = tcp.Address("localhost", True)
     assert a.use_ipv6
     b = tcp.Address("foo.com", True)
     assert not a == b
     assert str(b) == str(tuple("foo.com"))
     c = tcp.Address("localhost", True)
     assert a == c
     assert not a != c
     assert repr(a)
Ejemplo n.º 5
0
 def test_echo(self):
     testval = b"echo!\n"
     c = tcp.TCPClient(tcp.Address(("::1", self.port), use_ipv6=True))
     with c.connect():
         c.wfile.write(testval)
         c.wfile.flush()
         assert c.rfile.readline() == testval
Ejemplo n.º 6
0
    def from_file(cls, f):
        ver, msg, rsv, atyp = struct.unpack("!BBBB", f.safe_read(4))
        if rsv != 0x00:
            raise SocksError(REP.GENERAL_SOCKS_SERVER_FAILURE,
                             "Socks Request: Invalid reserved byte: %s" % rsv)
        if atyp == ATYP.IPV4_ADDRESS:
            # We use tnoa here as ntop is not commonly available on Windows.
            host = ipaddress.IPv4Address(f.safe_read(4)).compressed
            use_ipv6 = False
        elif atyp == ATYP.IPV6_ADDRESS:
            host = ipaddress.IPv6Address(f.safe_read(16)).compressed
            use_ipv6 = True
        elif atyp == ATYP.DOMAINNAME:
            length, = struct.unpack("!B", f.safe_read(1))
            host = f.safe_read(length)
            if not utils.is_valid_host(host):
                raise SocksError(REP.GENERAL_SOCKS_SERVER_FAILURE,
                                 "Invalid hostname: %s" % host)
            host = host.decode("idna")
            use_ipv6 = False
        else:
            raise SocksError(REP.ADDRESS_TYPE_NOT_SUPPORTED,
                             "Socks Request: Unknown ATYP: %s" % atyp)

        port, = struct.unpack("!H", f.safe_read(2))
        addr = tcp.Address((host, port), use_ipv6=use_ipv6)
        return cls(ver, msg, atyp, addr)
Ejemplo n.º 7
0
 def _response(self, cookie, host):
     s = flow.StickyCookieState(filt.parse(".*"))
     f = tutils.tflow_full()
     f.server_conn.address = tcp.Address((host, 80))
     f.response.headers["Set-Cookie"] = [cookie]
     s.handle_response(f)
     return s, f
Ejemplo n.º 8
0
    def process_server_address(self, flow):
        # Depending on the proxy mode, server handling is entirely different
        # We provide a mostly unified API to the user, which needs to be
        # unfiddled here
        # ( See also: https://github.com/mitmproxy/mitmproxy/issues/337 )
        address = tcp.Address((flow.request.host, flow.request.port))

        ssl = (flow.request.scheme == "https")

        if self.c.config.mode == "upstream":
            # The connection to the upstream proxy may have a state we may need
            # to take into account.
            connected_to = None
            for s in flow.server_conn.state:
                if s[0] == "http" and s[1]["state"] == "connect":
                    connected_to = tcp.Address((s[1]["host"], s[1]["port"]))

            # We need to reconnect if the current flow either requires a
            # (possibly impossible) change to the connection state, e.g. the
            # host has changed but we already CONNECTed somewhere else.
            needs_server_change = (
                ssl != self.c.server_conn.ssl_established
                or
                # HTTP proxying is "stateless", CONNECT isn't.
                (connected_to and address != connected_to)
            )

            if needs_server_change:
                # force create new connection to the proxy server to reset
                # state
                self.live.change_server(self.c.server_conn.address, force=True)
                if ssl:
                    send_connect_request(
                        self.c.server_conn,
                        address.host,
                        address.port
                    )
                    self.c.establish_ssl(server=True)
        else:
            # If we're not in upstream mode, we just want to update the host
            # and possibly establish TLS. This is a no op if the addresses
            # match.
            self.live.change_server(address, ssl=ssl)

        flow.server_conn = self.c.server_conn
Ejemplo n.º 9
0
class TestServerIPv6(tservers.ServerTestBase):
    handler = EchoHandler
    addr = tcp.Address(("localhost", 0), use_ipv6=True)

    def test_echo(self):
        testval = b"echo!\n"
        c = tcp.TCPClient(tcp.Address(("::1", self.port), use_ipv6=True))
        with c.connect():
            c.wfile.write(testval)
            c.wfile.flush()
            assert c.rfile.readline() == testval
Ejemplo n.º 10
0
def parse_server_spec(spec):
    try:
        p = url.parse(spec)
        if p[0] not in (b"http", b"https"):
            raise ValueError()
    except ValueError:
        raise exceptions.OptionsError("Invalid server specification: %s" %
                                      spec)
    host, port = p[1:3]
    address = tcp.Address((host.decode("ascii"), port))
    scheme = p[0].decode("ascii").lower()
    return ServerSpec(scheme, address)
Ejemplo n.º 11
0
def parse_server_spec(spec):
    try:
        p = url.parse(spec)
        if p[0] not in ("http", "https"):
            raise ValueError()
    except ValueError:
        raise configargparse.ArgumentTypeError(
            "Invalid server specification: %s" % spec)

    address = tcp.Address(p[1:3])
    scheme = p[0].lower()
    return config.ServerSpec(scheme, address)
Ejemplo n.º 12
0
    def __call__(self):
        try:
            # Parse Client Greeting
            client_greet = socks.ClientGreeting.from_file(self.client_conn.rfile, fail_early=True)
            client_greet.assert_socks5()
            if socks.METHOD.NO_AUTHENTICATION_REQUIRED not in client_greet.methods:
                raise socks.SocksError(
                    socks.METHOD.NO_ACCEPTABLE_METHODS,
                    "mitmproxy only supports SOCKS without authentication"
                )

            # Send Server Greeting
            server_greet = socks.ServerGreeting(
                socks.VERSION.SOCKS5,
                socks.METHOD.NO_AUTHENTICATION_REQUIRED
            )
            server_greet.to_file(self.client_conn.wfile)
            self.client_conn.wfile.flush()

            # Parse Connect Request
            connect_request = socks.Message.from_file(self.client_conn.rfile)
            connect_request.assert_socks5()
            if connect_request.msg != socks.CMD.CONNECT:
                raise socks.SocksError(
                    socks.REP.COMMAND_NOT_SUPPORTED,
                    "mitmproxy only supports SOCKS5 CONNECT."
                )

            # We always connect lazily, but we need to pretend to the client that we connected.
            connect_reply = socks.Message(
                socks.VERSION.SOCKS5,
                socks.REP.SUCCEEDED,
                connect_request.atyp,
                # dummy value, we don't have an upstream connection yet.
                connect_request.addr
            )
            connect_reply.to_file(self.client_conn.wfile)
            self.client_conn.wfile.flush()

        except (socks.SocksError, TcpException) as e:
            raise Socks5ProtocolException("SOCKS5 mode failure: %s" % repr(e))

        # https://github.com/mitmproxy/mitmproxy/issues/839
        address_bytes = (connect_request.addr.host.encode("idna"), connect_request.addr.port)
        self.server_conn.address = tcp.Address(address_bytes, connect_request.addr.use_ipv6)

        layer = self.ctx.next_layer(self)
        try:
            layer()
        finally:
            if self.server_conn:
                self.disconnect()
Ejemplo n.º 13
0
    def establish_server_connection(self, flow):
        address = tcp.Address((flow.request.host, flow.request.port))
        tls = (flow.request.scheme == "https")

        if self.mode == "regular" or self.mode == "transparent":
            # If there's an existing connection that doesn't match our expectations, kill it.
            if address != self.server_conn.address or tls != self.server_conn.tls_established:
                self.set_server(address, tls, address.host)
            # Establish connection is neccessary.
            if not self.server_conn:
                self.connect()
        else:
            if not self.server_conn:
                self.connect()
            if tls:
                raise HttpProtocolException("Cannot change scheme in upstream proxy mode.")
            """
Ejemplo n.º 14
0
    def test_get_url(self):
        r = tutils.tflow().request

        assert r.get_url() == "http://address:22/path"

        r.flow.server_conn.ssl_established = True
        assert r.get_url() == "https://address:22/path"

        r.flow.server_conn.address = tcp.Address(("host", 42))
        assert r.get_url() == "https://host:42/path"

        r.host = "address"
        r.port = 22
        assert r.get_url() == "https://address:22/path"

        assert r.get_url(hostheader=True) == "https://address:22/path"
        r.headers["Host"] = ["foo.com"]
        assert r.get_url() == "https://address:22/path"
        assert r.get_url(hostheader=True) == "https://foo.com:22/path"
Ejemplo n.º 15
0
def test_message_unknown_atyp():
    raw = tutils.treader("\x05\x02\x00\x02\x7f\x00\x00\x01\xDE\xAD\xBE\xEF")
    tutils.raises(socks.SocksError, socks.Message.from_file, raw)

    m = socks.Message(5, 1, 0x02, tcp.Address(("example.com", 5050)))
    tutils.raises(socks.SocksError, m.to_file, StringIO())
Ejemplo n.º 16
0
 def load_state(self, state):
     super(ClientConnection, self).load_state(state)
     self.address = tcp.Address(
         **state["address"]) if state["address"] else None
     self.clientcert = certutils.SSLCert.from_pem(
         state["clientcert"]) if state["clientcert"] else None