2012-12-31 22:13:56 +00:00
|
|
|
import subprocess
|
2013-06-16 04:23:36 +00:00
|
|
|
import pf
|
2012-09-16 23:05:20 +00:00
|
|
|
|
2012-12-31 22:13:56 +00:00
|
|
|
"""
|
|
|
|
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
|
2013-06-16 04:23:36 +00:00
|
|
|
this turns out to be a pain in the ass. Parsing pfctl output is short,
|
2012-12-31 22:13:56 +00:00
|
|
|
simple, and works.
|
2014-07-01 21:37:52 +00:00
|
|
|
|
|
|
|
Note: Also Tested with FreeBSD 10 pkgng Python 2.7.x.
|
|
|
|
Should work almost exactly as on Mac OS X and except with some changes to
|
|
|
|
the output processing of pfctl (see pf.py).
|
2012-12-31 22:13:56 +00:00
|
|
|
"""
|
2012-06-30 03:42:10 +00:00
|
|
|
|
2014-08-10 14:10:49 +00:00
|
|
|
|
|
|
|
class Resolver(object):
|
2013-06-16 04:23:36 +00:00
|
|
|
STATECMD = ("sudo", "-n", "/sbin/pfctl", "-s", "state")
|
2012-09-16 23:05:20 +00:00
|
|
|
|
2012-06-30 03:42:10 +00:00
|
|
|
def original_addr(self, csock):
|
2012-12-31 22:13:56 +00:00
|
|
|
peer = csock.getpeername()
|
2015-10-29 19:56:43 +00:00
|
|
|
try:
|
|
|
|
stxt = subprocess.check_output(self.STATECMD, stderr=subprocess.STDOUT)
|
|
|
|
except subprocess.CalledProcessError, e:
|
|
|
|
if "sudo: a password is required" in e.output:
|
|
|
|
insufficient_priv = True
|
|
|
|
else:
|
|
|
|
raise RuntimeError("Error getting pfctl state: " + repr(e))
|
2015-11-04 20:04:18 +00:00
|
|
|
else:
|
|
|
|
insufficient_priv = "sudo: a password is required" in stxt
|
2015-10-29 19:56:43 +00:00
|
|
|
|
2015-11-04 20:04:18 +00:00
|
|
|
if insufficient_priv:
|
2015-05-30 00:03:28 +00:00
|
|
|
raise RuntimeError(
|
|
|
|
"Insufficient privileges to access pfctl. "
|
|
|
|
"See http://mitmproxy.org/doc/transparent/osx.html for details.")
|
2013-06-16 04:23:36 +00:00
|
|
|
return pf.lookup(peer[0], peer[1], stxt)
|