diff options
-rw-r--r-- | mitmproxy/console/flowdetailview.py | 1 | ||||
-rw-r--r-- | mitmproxy/flow_format_compat.py | 1 | ||||
-rw-r--r-- | mitmproxy/models/connections.py | 1 | ||||
-rw-r--r-- | netlib/socks.py | 58 | ||||
-rw-r--r-- | netlib/tcp.py | 3 | ||||
-rw-r--r-- | test/mitmproxy/tutils.py | 1 | ||||
-rw-r--r-- | test/netlib/test_socks.py | 39 |
7 files changed, 103 insertions, 1 deletions
diff --git a/mitmproxy/console/flowdetailview.py b/mitmproxy/console/flowdetailview.py index 757c76fd..8e3a47ae 100644 --- a/mitmproxy/console/flowdetailview.py +++ b/mitmproxy/console/flowdetailview.py @@ -23,6 +23,7 @@ def flowdetails(state, flow): text.append(urwid.Text([("head", "Server Connection:")])) parts = [ ["Address", repr(sc.address)], + ["Peer Address", repr(sc.peer_address)], ] text.extend( diff --git a/mitmproxy/flow_format_compat.py b/mitmproxy/flow_format_compat.py index a7a95af3..4c3aa727 100644 --- a/mitmproxy/flow_format_compat.py +++ b/mitmproxy/flow_format_compat.py @@ -35,6 +35,7 @@ def convert_015_016(data): def convert_016_017(data): + data["server_conn"]["peer_address"] = None data["version"] = (0, 17) return data diff --git a/mitmproxy/models/connections.py b/mitmproxy/models/connections.py index 857580b8..2ffc667d 100644 --- a/mitmproxy/models/connections.py +++ b/mitmproxy/models/connections.py @@ -120,6 +120,7 @@ class ServerConnection(tcp.TCPClient, stateobject.StateObject): timestamp_tcp_setup=float, timestamp_ssl_setup=float, address=tcp.Address, + peer_address=tcp.Address, source_address=tcp.Address, cert=certutils.SSLCert, ssl_established=bool, diff --git a/netlib/socks.py b/netlib/socks.py index 51ad1c63..57ccd1be 100644 --- a/netlib/socks.py +++ b/netlib/socks.py @@ -10,7 +10,6 @@ class SocksError(Exception): super(SocksError, self).__init__(message) self.code = code - VERSION = utils.BiDi( SOCKS4=0x04, SOCKS5=0x05 @@ -47,6 +46,10 @@ METHOD = utils.BiDi( NO_ACCEPTABLE_METHODS=0xFF ) +USERNAME_PASSWORD_VERSION = utils.BiDi( + DEFAULT=0x01 +) + class ClientGreeting(object): __slots__ = ("ver", "methods") @@ -113,6 +116,59 @@ class ServerGreeting(object): f.write(struct.pack("!BB", self.ver, self.method)) +class UsernamePasswordAuth(object): + __slots__ = ("ver", "username", "password") + + def __init__(self, ver, username, password): + self.ver = ver + self.username = username + self.password = password + + def assert_authver1(self): + if self.ver != USERNAME_PASSWORD_VERSION.DEFAULT: + raise SocksError( + 0, + "Invalid auth version. Expected 0x01, got 0x%x" % self.ver + ) + + @classmethod + def from_file(cls, f): + ver, ulen = struct.unpack("!BB", f.safe_read(2)) + username = f.safe_read(ulen) + plen, = struct.unpack("!B", f.safe_read(1)) + password = f.safe_read(plen) + return cls(ver, username.decode(), password.decode()) + + def to_file(self, f): + f.write(struct.pack("!BB", self.ver, len(self.username))) + f.write(self.username.encode()) + f.write(struct.pack("!B", len(self.password))) + f.write(self.password.encode()) + + +class UsernamePasswordAuthResponse(object): + __slots__ = ("ver", "status") + + def __init__(self, ver, status): + self.ver = ver + self.status = status + + def assert_authver1(self): + if self.ver != USERNAME_PASSWORD_VERSION.DEFAULT: + raise SocksError( + 0, + "Invalid auth version. Expected 0x01, got 0x%x" % self.ver + ) + + @classmethod + def from_file(cls, f): + ver, status = struct.unpack("!BB", f.safe_read(2)) + return cls(ver, status) + + def to_file(self, f): + f.write(struct.pack("!BB", self.ver, self.status)) + + class Message(object): __slots__ = ("ver", "msg", "atyp", "addr") diff --git a/netlib/tcp.py b/netlib/tcp.py index 6423888a..574f3845 100644 --- a/netlib/tcp.py +++ b/netlib/tcp.py @@ -458,9 +458,11 @@ class _Connection(object): def __init__(self, connection): if connection: self.connection = connection + self.peer_address = Address(connection.getpeername()) self._makefile() else: self.connection = None + self.peer_address = None self.rfile = None self.wfile = None @@ -701,6 +703,7 @@ class TCPClient(_Connection): 'Error connecting to "%s": %s' % (self.address.host, err)) self.connection = connection + self.peer_address = Address(connection.getpeername()) self._makefile() def settimeout(self, n): diff --git a/test/mitmproxy/tutils.py b/test/mitmproxy/tutils.py index edcdf3e2..0d65df71 100644 --- a/test/mitmproxy/tutils.py +++ b/test/mitmproxy/tutils.py @@ -93,6 +93,7 @@ def tserver_conn(): c = ServerConnection.from_state(dict( address=dict(address=("address", 22), use_ipv6=True), source_address=dict(address=("address", 22), use_ipv6=True), + peer_address=None, cert=None, timestamp_start=1, timestamp_tcp_setup=2, diff --git a/test/netlib/test_socks.py b/test/netlib/test_socks.py index d95dee41..486b975b 100644 --- a/test/netlib/test_socks.py +++ b/test/netlib/test_socks.py @@ -85,6 +85,45 @@ def test_server_greeting_assert_socks5(): assert False +def test_username_password_auth(): + raw = tutils.treader(b"\x01\x03usr\x03psd\xBE\xEF") + out = BytesIO() + auth = socks.UsernamePasswordAuth.from_file(raw) + auth.assert_authver1() + assert raw.read(2) == b"\xBE\xEF" + auth.to_file(out) + + assert out.getvalue() == raw.getvalue()[:-2] + assert auth.ver == socks.USERNAME_PASSWORD_VERSION.DEFAULT + assert auth.username == "usr" + assert auth.password == "psd" + + +def test_username_password_auth_assert_ver1(): + raw = tutils.treader(b"\x02\x03usr\x03psd\xBE\xEF") + auth = socks.UsernamePasswordAuth.from_file(raw) + tutils.raises(socks.SocksError, auth.assert_authver1) + + +def test_username_password_auth_response(): + raw = tutils.treader(b"\x01\x00\xBE\xEF") + out = BytesIO() + auth = socks.UsernamePasswordAuthResponse.from_file(raw) + auth.assert_authver1() + assert raw.read(2) == b"\xBE\xEF" + auth.to_file(out) + + assert out.getvalue() == raw.getvalue()[:-2] + assert auth.ver == socks.USERNAME_PASSWORD_VERSION.DEFAULT + assert auth.status == 0 + + +def test_username_password_auth_response_auth_assert_ver1(): + raw = tutils.treader(b"\x02\x00\xBE\xEF") + auth = socks.UsernamePasswordAuthResponse.from_file(raw) + tutils.raises(socks.SocksError, auth.assert_authver1) + + def test_message(): raw = tutils.treader(b"\x05\x01\x00\x03\x0bexample.com\xDE\xAD\xBE\xEF") out = BytesIO() |