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
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"
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
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)
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
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)
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
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
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
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)
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)
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()
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.") """
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"
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())
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