aboutsummaryrefslogtreecommitdiffstats
path: root/libmproxy
diff options
context:
space:
mode:
authorAldo Cortesi <aldo@nullcube.com>2013-01-01 11:13:56 +1300
committerAldo Cortesi <aldo@nullcube.com>2013-01-01 11:13:56 +1300
commite2dc7ba09d54fb4fa4af796d5c37cd36174f8897 (patch)
tree09d6d4237e5864aeef6709b44a7a5a7633aaaf03 /libmproxy
parent5347cb9c269acdbc2fc36f92e3545fcbb9de45a1 (diff)
downloadmitmproxy-e2dc7ba09d54fb4fa4af796d5c37cd36174f8897.tar.gz
mitmproxy-e2dc7ba09d54fb4fa4af796d5c37cd36174f8897.tar.bz2
mitmproxy-e2dc7ba09d54fb4fa4af796d5c37cd36174f8897.zip
First draft of OSX transparent proxy mode.
Diffstat (limited to 'libmproxy')
-rw-r--r--libmproxy/platform/osx.py111
-rw-r--r--libmproxy/platform/pf.py16
2 files changed, 30 insertions, 97 deletions
diff --git a/libmproxy/platform/osx.py b/libmproxy/platform/osx.py
index a66c03ed..d1c420e2 100644
--- a/libmproxy/platform/osx.py
+++ b/libmproxy/platform/osx.py
@@ -1,103 +1,20 @@
-import socket, ctypes
-
-# Python socket module does not have this constant
-DIOCNATLOOK = 23
-PFDEV = "/dev/pf"
-
-
-class PF_STATE_XPORT(ctypes.Union):
- """
- union pf_state_xport {
- u_int16_t port;
- u_int16_t call_id;
- u_int32_t spi;
- };
- """
- _fields_ = [
- ("port", ctypes.c_uint),
- ("call_id", ctypes.c_uint),
- ("spi", ctypes.c_ulong),
- ]
-
-
-class PF_ADDR(ctypes.Union):
- """
- struct pf_addr {
- union {
- struct in_addr v4;
- struct in6_addr v6;
- u_int8_t addr8[16];
- u_int16_t addr16[8];
- u_int32_t addr32[4];
- } pfa;
- }
- """
- _fields_ = [
- ("addr8", ctypes.c_byte * 2),
- ("addr16", ctypes.c_byte * 4),
- ("addr32", ctypes.c_byte * 8),
- ]
-
-
-class PFIOC_NATLOOK(ctypes.Structure):
- """
- struct pfioc_natlook {
- struct pf_addr saddr;
- struct pf_addr daddr;
- struct pf_addr rsaddr;
- struct pf_addr rdaddr;
- #ifndef NO_APPLE_EXTENSIONS
- union pf_state_xport sxport;
- union pf_state_xport dxport;
- union pf_state_xport rsxport;
- union pf_state_xport rdxport;
- sa_family_t af;
- u_int8_t proto;
- u_int8_t proto_variant;
- u_int8_t direction;
- #else
- u_int16_t sport;
- u_int16_t dport;
- u_int16_t rsport;
- u_int16_t rdport;
- sa_family_t af;
- u_int8_t proto;
- u_int8_t direction;
- #endif
- };
- """
- _fields_ = [
- ("saddr", PF_ADDR),
- ("daddr", PF_ADDR),
- ("rsaddr", PF_ADDR),
- ("rdaddr", PF_ADDR),
-
- ("sxport", PF_STATE_XPORT),
- ("dxport", PF_STATE_XPORT),
- ("rsxport", PF_STATE_XPORT),
- ("rdxport", PF_STATE_XPORT),
- ("af", ctypes.c_uint),
- ("proto", ctypes.c_ushort),
- ("proto_variant", ctypes.c_ushort),
- ("direction", ctypes.c_ushort),
- ]
+import subprocess
+import pf
+"""
+ Doing this the "right" way by using DIOCNATLOOK on the pf device turns out
+ to be a pain. Apple has made a number of modifications to the data
+ structures returned, and compiling userspace tools to test and work with
+ this turns out to be a pain in the ass. Parsing pfctl output is short,
+ simple, and works.
+"""
class Resolver:
+ STATECMD = ("sudo", "-n", "/sbin/pfctl", "-s", "state")
def __init__(self):
- self.pfdev = open(PFDEV, "r")
+ pass
def original_addr(self, csock):
- """
- The following sttruct defintions are plucked from the current XNU source, found here:
-
- http://www.opensource.apple.com/source/xnu/xnu-1699.26.8/bsd/net/pfvar.h
-
-
- union pf_state_xport {
- u_int16_t port;
- u_int16_t call_id;
- u_int32_t spi;
- };
- """
- pass
+ peer = csock.getpeername()
+ stxt = subprocess.check_output(self.STATECMD, stderr=subprocess.STDOUT)
+ return pf.lookup(peer[0], peer[1], stxt)
diff --git a/libmproxy/platform/pf.py b/libmproxy/platform/pf.py
new file mode 100644
index 00000000..062d3311
--- /dev/null
+++ b/libmproxy/platform/pf.py
@@ -0,0 +1,16 @@
+
+def lookup(address, port, s):
+ """
+ Parse the pfctl state output s, to look up the destination host
+ matching the client (address, port).
+
+ Returns an (address, port) tuple, or None.
+ """
+ spec = "%s:%s"%(address, port)
+ for i in s.split("\n"):
+ if "ESTABLISHED:ESTABLISHED" in i and spec in i:
+ s = i.split()
+ if len(s) > 4:
+ s = s[4].split(":")
+ if len(s) == 2:
+ return s[0], int(s[1])