aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mitmproxy/console/flowdetailview.py1
-rw-r--r--mitmproxy/flow_format_compat.py1
-rw-r--r--mitmproxy/models/connections.py1
-rw-r--r--netlib/socks.py58
-rw-r--r--netlib/tcp.py3
-rw-r--r--test/mitmproxy/tutils.py1
-rw-r--r--test/netlib/test_socks.py39
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()