Commit e6f2395d authored by Brian May's avatar Brian May

Fixup PEP8 issues.

parent d4f10b23
...@@ -105,6 +105,7 @@ def parse_ipport6(s): ...@@ -105,6 +105,7 @@ def parse_ipport6(s):
(ip, port) = (ip or '::', int(port or 0)) (ip, port) = (ip or '::', int(port or 0))
return (ip, port) return (ip, port)
def parse_list(list): def parse_list(list):
return re.split(r'[\s,]+', list.strip()) if list else [] return re.split(r'[\s,]+', list.strip()) if list else []
......
...@@ -12,7 +12,7 @@ import ssyslog ...@@ -12,7 +12,7 @@ import ssyslog
import sys import sys
from sshuttle.ssnet import SockWrapper, Handler, Proxy, Mux, MuxWrapper from sshuttle.ssnet import SockWrapper, Handler, Proxy, Mux, MuxWrapper
from sshuttle.helpers import log, debug1, debug2, debug3, Fatal, islocal, \ from sshuttle.helpers import log, debug1, debug2, debug3, Fatal, islocal, \
resolvconf_nameservers resolvconf_nameservers
recvmsg = None recvmsg = None
try: try:
...@@ -187,11 +187,13 @@ def daemon_cleanup(): ...@@ -187,11 +187,13 @@ def daemon_cleanup():
pf_command_file = None pf_command_file = None
def pf_dst(sock): def pf_dst(sock):
peer = sock.getpeername() peer = sock.getpeername()
proxy = sock.getsockname() proxy = sock.getsockname()
argv = (sock.family, socket.IPPROTO_TCP, peer[0], peer[1], proxy[0], proxy[1]) argv = (sock.family, socket.IPPROTO_TCP,
peer[0], peer[1], proxy[0], proxy[1])
pf_command_file.write("QUERY_PF_NAT %r,%r,%s,%r,%s,%r\n" % argv) pf_command_file.write("QUERY_PF_NAT %r,%r,%s,%r,%s,%r\n" % argv)
pf_command_file.flush() pf_command_file.flush()
line = pf_command_file.readline() line = pf_command_file.readline()
...@@ -202,6 +204,7 @@ def pf_dst(sock): ...@@ -202,6 +204,7 @@ def pf_dst(sock):
return sock.getsockname() return sock.getsockname()
def original_dst(sock): def original_dst(sock):
try: try:
SO_ORIGINAL_DST = 80 SO_ORIGINAL_DST = 80
......
...@@ -360,13 +360,17 @@ import gc ...@@ -360,13 +360,17 @@ import gc
import signal import signal
# Exception classes used by this module. # Exception classes used by this module.
class CalledProcessError(Exception): class CalledProcessError(Exception):
"""This exception is raised when a process run by check_call() returns """This exception is raised when a process run by check_call() returns
a non-zero exit status. The exit status will be stored in the a non-zero exit status. The exit status will be stored in the
returncode attribute.""" returncode attribute."""
def __init__(self, returncode, cmd): def __init__(self, returncode, cmd):
self.returncode = returncode self.returncode = returncode
self.cmd = cmd self.cmd = cmd
def __str__(self): def __str__(self):
return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode) return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode)
...@@ -374,27 +378,29 @@ class CalledProcessError(Exception): ...@@ -374,27 +378,29 @@ class CalledProcessError(Exception):
if mswindows: if mswindows:
import threading import threading
import msvcrt import msvcrt
if 0: # <-- change this to use pywin32 instead of the _subprocess driver if 0: # <-- change this to use pywin32 instead of the _subprocess driver
import pywintypes import pywintypes
from win32api import GetStdHandle, STD_INPUT_HANDLE, \ from win32api import GetStdHandle, STD_INPUT_HANDLE, \
STD_OUTPUT_HANDLE, STD_ERROR_HANDLE STD_OUTPUT_HANDLE, STD_ERROR_HANDLE
from win32api import GetCurrentProcess, DuplicateHandle, \ from win32api import GetCurrentProcess, DuplicateHandle, \
GetModuleFileName, GetVersion GetModuleFileName, GetVersion
from win32con import DUPLICATE_SAME_ACCESS, SW_HIDE from win32con import DUPLICATE_SAME_ACCESS, SW_HIDE
from win32pipe import CreatePipe from win32pipe import CreatePipe
from win32process import CreateProcess, STARTUPINFO, \ from win32process import CreateProcess, STARTUPINFO, \
GetExitCodeProcess, STARTF_USESTDHANDLES, \ GetExitCodeProcess, STARTF_USESTDHANDLES, \
STARTF_USESHOWWINDOW, CREATE_NEW_CONSOLE STARTF_USESHOWWINDOW, CREATE_NEW_CONSOLE
from win32process import TerminateProcess from win32process import TerminateProcess
from win32event import WaitForSingleObject, INFINITE, WAIT_OBJECT_0 from win32event import WaitForSingleObject, INFINITE, WAIT_OBJECT_0
else: else:
from _subprocess import * from _subprocess import *
class STARTUPINFO: class STARTUPINFO:
dwFlags = 0 dwFlags = 0
hStdInput = None hStdInput = None
hStdOutput = None hStdOutput = None
hStdError = None hStdError = None
wShowWindow = 0 wShowWindow = 0
class pywintypes: class pywintypes:
error = IOError error = IOError
else: else:
...@@ -403,7 +409,8 @@ else: ...@@ -403,7 +409,8 @@ else:
import fcntl import fcntl
import pickle import pickle
__all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", "CalledProcessError"] __all__ = ["Popen", "PIPE", "STDOUT", "call",
"check_call", "CalledProcessError"]
try: try:
MAXFD = os.sysconf("SC_OPEN_MAX") MAXFD = os.sysconf("SC_OPEN_MAX")
...@@ -411,14 +418,15 @@ except: ...@@ -411,14 +418,15 @@ except:
MAXFD = 256 MAXFD = 256
# True/False does not exist on 2.2.0 # True/False does not exist on 2.2.0
#try: # try:
# False # False
#except NameError: # except NameError:
# False = 0 # False = 0
# True = 1 # True = 1
_active = [] _active = []
def _cleanup(): def _cleanup():
for inst in _active[:]: for inst in _active[:]:
if inst._internal_poll(_deadstate=sys.maxint) >= 0: if inst._internal_poll(_deadstate=sys.maxint) >= 0:
...@@ -510,7 +518,7 @@ def list2cmdline(seq): ...@@ -510,7 +518,7 @@ def list2cmdline(seq):
bs_buf.append(c) bs_buf.append(c)
elif c == '"': elif c == '"':
# Double backslashes. # Double backslashes.
result.append('\\' * len(bs_buf)*2) result.append('\\' * len(bs_buf) * 2)
bs_buf = [] bs_buf = []
result.append('\\"') result.append('\\"')
else: else:
...@@ -543,6 +551,7 @@ def _closerange(start, max): ...@@ -543,6 +551,7 @@ def _closerange(start, max):
class Popen(object): class Popen(object):
def __init__(self, args, bufsize=0, executable=None, def __init__(self, args, bufsize=0, executable=None,
stdin=None, stdout=None, stderr=None, stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=False, shell=False, preexec_fn=None, close_fds=False, shell=False,
...@@ -634,13 +643,11 @@ class Popen(object): ...@@ -634,13 +643,11 @@ class Popen(object):
else: else:
self.stderr = os.fdopen(errread, 'rb', bufsize) self.stderr = os.fdopen(errread, 'rb', bufsize)
def _translate_newlines(self, data): def _translate_newlines(self, data):
data = data.replace("\r\n", "\n") data = data.replace("\r\n", "\n")
data = data.replace("\r", "\n") data = data.replace("\r", "\n")
return data return data
def __del__(self, sys=sys): def __del__(self, sys=sys):
if not self._child_created: if not self._child_created:
# We didn't get to successfully create a child process. # We didn't get to successfully create a child process.
...@@ -651,7 +658,6 @@ class Popen(object): ...@@ -651,7 +658,6 @@ class Popen(object):
# Child is still running, keep us alive until we can wait on it. # Child is still running, keep us alive until we can wait on it.
_active.append(self) _active.append(self)
def communicate(self, input=None): def communicate(self, input=None):
"""Interact with process: Send data to stdin. Read data from """Interact with process: Send data to stdin. Read data from
stdout and stderr, until end-of-file is reached. Wait for stdout and stderr, until end-of-file is reached. Wait for
...@@ -681,11 +687,9 @@ class Popen(object): ...@@ -681,11 +687,9 @@ class Popen(object):
return self._communicate(input) return self._communicate(input)
def poll(self): def poll(self):
return self._internal_poll() return self._internal_poll()
if mswindows: if mswindows:
# #
# Windows methods # Windows methods
...@@ -755,14 +759,12 @@ class Popen(object): ...@@ -755,14 +759,12 @@ class Popen(object):
c2pread, c2pwrite, c2pread, c2pwrite,
errread, errwrite) errread, errwrite)
def _make_inheritable(self, handle): def _make_inheritable(self, handle):
"""Return a duplicate of handle, which is inheritable""" """Return a duplicate of handle, which is inheritable"""
return DuplicateHandle(GetCurrentProcess(), handle, return DuplicateHandle(GetCurrentProcess(), handle,
GetCurrentProcess(), 0, 1, GetCurrentProcess(), 0, 1,
DUPLICATE_SAME_ACCESS) DUPLICATE_SAME_ACCESS)
def _find_w9xpopen(self): def _find_w9xpopen(self):
"""Find and return absolut path to w9xpopen.exe""" """Find and return absolut path to w9xpopen.exe"""
w9xpopen = os.path.join(os.path.dirname(GetModuleFileName(0)), w9xpopen = os.path.join(os.path.dirname(GetModuleFileName(0)),
...@@ -778,7 +780,6 @@ class Popen(object): ...@@ -778,7 +780,6 @@ class Popen(object):
"shell or platform.") "shell or platform.")
return w9xpopen return w9xpopen
def _execute_child(self, args, executable, preexec_fn, close_fds, def _execute_child(self, args, executable, preexec_fn, close_fds,
cwd, env, universal_newlines, cwd, env, universal_newlines,
startupinfo, creationflags, shell, startupinfo, creationflags, shell,
...@@ -823,13 +824,13 @@ class Popen(object): ...@@ -823,13 +824,13 @@ class Popen(object):
# Start the process # Start the process
try: try:
hp, ht, pid, tid = CreateProcess(executable, args, hp, ht, pid, tid = CreateProcess(executable, args,
# no special security # no special security
None, None, None, None,
int(not close_fds), int(not close_fds),
creationflags, creationflags,
env, env,
cwd, cwd,
startupinfo) startupinfo)
except pywintypes.error, e: except pywintypes.error, e:
# Translate pywintypes.error to WindowsError, which is # Translate pywintypes.error to WindowsError, which is
# a subclass of OSError. FIXME: We should really # a subclass of OSError. FIXME: We should really
...@@ -856,7 +857,6 @@ class Popen(object): ...@@ -856,7 +857,6 @@ class Popen(object):
if errwrite is not None: if errwrite is not None:
errwrite.Close() errwrite.Close()
def _internal_poll(self, _deadstate=None): def _internal_poll(self, _deadstate=None):
"""Check if child process has terminated. Returns returncode """Check if child process has terminated. Returns returncode
attribute.""" attribute."""
...@@ -865,7 +865,6 @@ class Popen(object): ...@@ -865,7 +865,6 @@ class Popen(object):
self.returncode = GetExitCodeProcess(self._handle) self.returncode = GetExitCodeProcess(self._handle)
return self.returncode return self.returncode
def wait(self): def wait(self):
"""Wait for child process to terminate. Returns returncode """Wait for child process to terminate. Returns returncode
attribute.""" attribute."""
...@@ -874,14 +873,12 @@ class Popen(object): ...@@ -874,14 +873,12 @@ class Popen(object):
self.returncode = GetExitCodeProcess(self._handle) self.returncode = GetExitCodeProcess(self._handle)
return self.returncode return self.returncode
def _readerthread(self, fh, buffer): def _readerthread(self, fh, buffer):
buffer.append(fh.read()) buffer.append(fh.read())
def _communicate(self, input): def _communicate(self, input):
stdout = None # Return stdout = None # Return
stderr = None # Return stderr = None # Return
if self.stdout: if self.stdout:
stdout = [] stdout = []
...@@ -988,7 +985,6 @@ class Popen(object): ...@@ -988,7 +985,6 @@ class Popen(object):
c2pread, c2pwrite, c2pread, c2pwrite,
errread, errwrite) errread, errwrite)
def _set_cloexec_flag(self, fd): def _set_cloexec_flag(self, fd):
try: try:
cloexec_flag = fcntl.FD_CLOEXEC cloexec_flag = fcntl.FD_CLOEXEC
...@@ -998,12 +994,10 @@ class Popen(object): ...@@ -998,12 +994,10 @@ class Popen(object):
old = fcntl.fcntl(fd, fcntl.F_GETFD) old = fcntl.fcntl(fd, fcntl.F_GETFD)
fcntl.fcntl(fd, fcntl.F_SETFD, old | cloexec_flag) fcntl.fcntl(fd, fcntl.F_SETFD, old | cloexec_flag)
def _close_fds(self, but): def _close_fds(self, but):
_closerange(3, but) _closerange(3, but)
_closerange(but + 1, MAXFD) _closerange(but + 1, MAXFD)
def _execute_child(self, args, executable, preexec_fn, close_fds, def _execute_child(self, args, executable, preexec_fn, close_fds,
cwd, env, universal_newlines, cwd, env, universal_newlines,
startupinfo, creationflags, shell, startupinfo, creationflags, shell,
...@@ -1109,14 +1103,13 @@ class Popen(object): ...@@ -1109,14 +1103,13 @@ class Popen(object):
os.close(errwrite) os.close(errwrite)
# Wait for exec to fail or succeed; possibly raising exception # Wait for exec to fail or succeed; possibly raising exception
data = os.read(errpipe_read, 1048576) # Exceptions limited to 1 MB data = os.read(errpipe_read, 1048576) # Exceptions limited to 1 MB
os.close(errpipe_read) os.close(errpipe_read)
if data != "": if data != "":
os.waitpid(self.pid, 0) os.waitpid(self.pid, 0)
child_exception = pickle.loads(data) child_exception = pickle.loads(data)
raise child_exception raise child_exception
def _handle_exitstatus(self, sts): def _handle_exitstatus(self, sts):
if os.WIFSIGNALED(sts): if os.WIFSIGNALED(sts):
self.returncode = -os.WTERMSIG(sts) self.returncode = -os.WTERMSIG(sts)
...@@ -1126,7 +1119,6 @@ class Popen(object): ...@@ -1126,7 +1119,6 @@ class Popen(object):
# Should never happen # Should never happen
raise RuntimeError("Unknown child exit status!") raise RuntimeError("Unknown child exit status!")
def _internal_poll(self, _deadstate=None): def _internal_poll(self, _deadstate=None):
"""Check if child process has terminated. Returns returncode """Check if child process has terminated. Returns returncode
attribute.""" attribute."""
...@@ -1140,7 +1132,6 @@ class Popen(object): ...@@ -1140,7 +1132,6 @@ class Popen(object):
self.returncode = _deadstate self.returncode = _deadstate
return self.returncode return self.returncode
def wait(self): def wait(self):
"""Wait for child process to terminate. Returns returncode """Wait for child process to terminate. Returns returncode
attribute.""" attribute."""
...@@ -1149,12 +1140,11 @@ class Popen(object): ...@@ -1149,12 +1140,11 @@ class Popen(object):
self._handle_exitstatus(sts) self._handle_exitstatus(sts)
return self.returncode return self.returncode
def _communicate(self, input): def _communicate(self, input):
read_set = [] read_set = []
write_set = [] write_set = []
stdout = None # Return stdout = None # Return
stderr = None # Return stderr = None # Return
if self.stdin: if self.stdin:
# Flush stdio buffer. This might block, if the user has # Flush stdio buffer. This might block, if the user has
...@@ -1174,7 +1164,8 @@ class Popen(object): ...@@ -1174,7 +1164,8 @@ class Popen(object):
input_offset = 0 input_offset = 0
while read_set or write_set: while read_set or write_set:
try: try:
rlist, wlist, xlist = select.select(read_set, write_set, []) rlist, wlist, xlist = select.select(
read_set, write_set, [])
except select.error, e: except select.error, e:
if e.args[0] == errno.EINTR: if e.args[0] == errno.EINTR:
continue continue
...@@ -1184,7 +1175,7 @@ class Popen(object): ...@@ -1184,7 +1175,7 @@ class Popen(object):
# When select has indicated that the file is writable, # When select has indicated that the file is writable,
# we can write up to PIPE_BUF bytes without risk # we can write up to PIPE_BUF bytes without risk
# blocking. POSIX defines PIPE_BUF >= 512 # blocking. POSIX defines PIPE_BUF >= 512
chunk = input[input_offset : input_offset + 512] chunk = input[input_offset: input_offset + 512]
bytes_written = os.write(self.stdin.fileno(), chunk) bytes_written = os.write(self.stdin.fileno(), chunk)
input_offset += bytes_written input_offset += bytes_written
if input_offset >= len(input): if input_offset >= len(input):
......
...@@ -12,7 +12,7 @@ from sshuttle.helpers import log, debug1, debug3, islocal, Fatal, family_to_stri ...@@ -12,7 +12,7 @@ from sshuttle.helpers import log, debug1, debug3, islocal, Fatal, family_to_stri
resolvconf_nameservers resolvconf_nameservers
from fcntl import ioctl from fcntl import ioctl
from ctypes import c_char, c_uint8, c_uint16, c_uint32, Union, Structure, \ from ctypes import c_char, c_uint8, c_uint16, c_uint32, Union, Structure, \
sizeof, addressof, memmove sizeof, addressof, memmove
# python doesn't have a definition for this # python doesn't have a definition for this
...@@ -465,20 +465,21 @@ def do_ipfw(port, dnsport, family, subnets, udp): ...@@ -465,20 +465,21 @@ def do_ipfw(port, dnsport, family, subnets, udp):
return do_wait return do_wait
def pfctl(args, stdin = None): def pfctl(args, stdin=None):
argv = ['pfctl'] + list(args.split(" ")) argv = ['pfctl'] + list(args.split(" "))
debug1('>> %s\n' % ' '.join(argv)) debug1('>> %s\n' % ' '.join(argv))
p = ssubprocess.Popen(argv, stdin = ssubprocess.PIPE, p = ssubprocess.Popen(argv, stdin=ssubprocess.PIPE,
stdout = ssubprocess.PIPE, stdout=ssubprocess.PIPE,
stderr = ssubprocess.PIPE) stderr=ssubprocess.PIPE)
o = p.communicate(stdin) o = p.communicate(stdin)
if p.returncode: if p.returncode:
raise Fatal('%r returned %d' % (argv, p.returncode)) raise Fatal('%r returned %d' % (argv, p.returncode))
return o return o
_pf_context = {'started_by_sshuttle': False, 'Xtoken':''} _pf_context = {'started_by_sshuttle': False, 'Xtoken': ''}
def do_pf(port, dnsport, nslist, family, subnets, udp): def do_pf(port, dnsport, nslist, family, subnets, udp):
global _pf_started_by_sshuttle global _pf_started_by_sshuttle
...@@ -487,27 +488,33 @@ def do_pf(port, dnsport, nslist, family, subnets, udp): ...@@ -487,27 +488,33 @@ def do_pf(port, dnsport, nslist, family, subnets, udp):
filtering_rules = [] filtering_rules = []
if subnets: if subnets:
includes=[] includes = []
# If a given subnet is both included and excluded, list the exclusion # If a given subnet is both included and excluded, list the exclusion
# first; the table will ignore the second, opposite definition # first; the table will ignore the second, opposite definition
for f, swidth, sexclude, snet \ for f, swidth, sexclude, snet \
in sorted(subnets, key=lambda s: (s[1], s[2]), reverse=True): in sorted(subnets, key=lambda s: (s[1], s[2]), reverse=True):
includes.append("%s%s/%s" % ("!" if sexclude else "", snet, swidth)) includes.append("%s%s/%s" %
("!" if sexclude else "", snet, swidth))
tables.append('table <forward_subnets> {%s}' % ','.join(includes)) tables.append('table <forward_subnets> {%s}' % ','.join(includes))
translating_rules.append('rdr pass on lo0 proto tcp to <forward_subnets> -> 127.0.0.1 port %r' % port) translating_rules.append(
filtering_rules.append('pass out route-to lo0 inet proto tcp to <forward_subnets> keep state') 'rdr pass on lo0 proto tcp to <forward_subnets> -> 127.0.0.1 port %r' % port)
filtering_rules.append(
'pass out route-to lo0 inet proto tcp to <forward_subnets> keep state')
if dnsport: if dnsport:
tables.append('table <dns_servers> {%s}' % ','.join([ns[1] for ns in nslist])) tables.append('table <dns_servers> {%s}' % ','.join(
translating_rules.append('rdr pass on lo0 proto udp to <dns_servers> port 53 -> 127.0.0.1 port %r' % dnsport) [ns[1] for ns in nslist]))
filtering_rules.append('pass out route-to lo0 inet proto udp to <dns_servers> port 53 keep state') translating_rules.append(
'rdr pass on lo0 proto udp to <dns_servers> port 53 -> 127.0.0.1 port %r' % dnsport)
filtering_rules.append(
'pass out route-to lo0 inet proto udp to <dns_servers> port 53 keep state')
rules = '\n'.join(tables + translating_rules + filtering_rules) + '\n' rules = '\n'.join(tables + translating_rules + filtering_rules) + '\n'
pf_status = pfctl('-s all')[0] pf_status = pfctl('-s all')[0]
if not '\nrdr-anchor "sshuttle" all\n' in pf_status: if not '\nrdr-anchor "sshuttle" all\n' in pf_status:
pf_add_anchor_rule(PF_RDR, "sshuttle") pf_add_anchor_rule(PF_RDR, "sshuttle")
if not '\nanchor "sshuttle" all\n' in pf_status: if not '\nanchor "sshuttle" all\n' in pf_status:
pf_add_anchor_rule(PF_PASS, "sshuttle") pf_add_anchor_rule(PF_PASS, "sshuttle")
...@@ -515,7 +522,7 @@ def do_pf(port, dnsport, nslist, family, subnets, udp): ...@@ -515,7 +522,7 @@ def do_pf(port, dnsport, nslist, family, subnets, udp):
if sys.platform == "darwin": if sys.platform == "darwin":
o = pfctl('-E') o = pfctl('-E')
_pf_context['Xtoken'] = re.search(r'Token : (.+)', o[1]).group(1) _pf_context['Xtoken'] = re.search(r'Token : (.+)', o[1]).group(1)
elif 'INFO:\nStatus: Disabled' in pf_status: elif 'INFO:\nStatus: Disabled' in pf_status:
pfctl('-e') pfctl('-e')
_pf_context['started_by_sshuttle'] = True _pf_context['started_by_sshuttle'] = True
else: else:
...@@ -578,13 +585,15 @@ def restore_etc_hosts(port): ...@@ -578,13 +585,15 @@ def restore_etc_hosts(port):
rewrite_etc_hosts(port) rewrite_etc_hosts(port)
# This are some classes and functions used to support pf in yosemite. # This are some classes and functions used to support pf in yosemite.
class pf_state_xport(Union): class pf_state_xport(Union):
_fields_ = [("port", c_uint16), _fields_ = [("port", c_uint16),
("call_id", c_uint16), ("call_id", c_uint16),
("spi", c_uint32)] ("spi", c_uint32)]
class pf_addr(Structure): class pf_addr(Structure):
class _pfa(Union): class _pfa(Union):
_fields_ = [("v4", c_uint32), # struct in_addr _fields_ = [("v4", c_uint32), # struct in_addr
("v6", c_uint32 * 4), # struct in6_addr ("v6", c_uint32 * 4), # struct in6_addr
...@@ -595,6 +604,7 @@ class pf_addr(Structure): ...@@ -595,6 +604,7 @@ class pf_addr(Structure):
_fields_ = [("pfa", _pfa)] _fields_ = [("pfa", _pfa)]
_anonymous_ = ("pfa",) _anonymous_ = ("pfa",)
class pfioc_natlook(Structure): class pfioc_natlook(Structure):
_fields_ = [("saddr", pf_addr), _fields_ = [("saddr", pf_addr),
("daddr", pf_addr), ("daddr", pf_addr),
...@@ -604,20 +614,23 @@ class pfioc_natlook(Structure): ...@@ -604,20 +614,23 @@ class pfioc_natlook(Structure):
("dxport", pf_state_xport), ("dxport", pf_state_xport),
("rsxport", pf_state_xport), ("rsxport", pf_state_xport),
("rdxport", pf_state_xport), ("rdxport", pf_state_xport),
("af", c_uint8), # sa_family_t ("af", c_uint8), # sa_family_t
("proto", c_uint8), ("proto", c_uint8),
("proto_variant", c_uint8), ("proto_variant", c_uint8),
("direction", c_uint8)] ("direction", c_uint8)]
pfioc_rule = c_char * 3104 # sizeof(struct pfioc_rule) pfioc_rule = c_char * 3104 # sizeof(struct pfioc_rule)
pfioc_pooladdr = c_char * 1136 # sizeof(struct pfioc_pooladdr) pfioc_pooladdr = c_char * 1136 # sizeof(struct pfioc_pooladdr)
MAXPATHLEN = 1024 MAXPATHLEN = 1024
DIOCNATLOOK = ((0x40000000L | 0x80000000L) | ((sizeof(pfioc_natlook) & 0x1fff) << 16) | ((ord('D')) << 8) | (23)) DIOCNATLOOK = ((0x40000000L | 0x80000000L) | (
DIOCCHANGERULE = ((0x40000000L | 0x80000000L) | ((sizeof(pfioc_rule) & 0x1fff) << 16) | ((ord('D')) << 8) | (26)) (sizeof(pfioc_natlook) & 0x1fff) << 16) | ((ord('D')) << 8) | (23))
DIOCBEGINADDRS = ((0x40000000L | 0x80000000L) | ((sizeof(pfioc_pooladdr) & 0x1fff) << 16) | ((ord('D')) << 8) | (51)) DIOCCHANGERULE = ((0x40000000L | 0x80000000L) | (
(sizeof(pfioc_rule) & 0x1fff) << 16) | ((ord('D')) << 8) | (26))
DIOCBEGINADDRS = ((0x40000000L | 0x80000000L) | (
(sizeof(pfioc_pooladdr) & 0x1fff) << 16) | ((ord('D')) << 8) | (51))
PF_CHANGE_ADD_TAIL = 2 PF_CHANGE_ADD_TAIL = 2
PF_CHANGE_GET_TICKET = 6 PF_CHANGE_GET_TICKET = 6
...@@ -629,6 +642,7 @@ PF_OUT = 2 ...@@ -629,6 +642,7 @@ PF_OUT = 2
_pf_fd = None _pf_fd = None
def pf_get_dev(): def pf_get_dev():
global _pf_fd global _pf_fd
if _pf_fd == None: if _pf_fd == None:
...@@ -636,9 +650,11 @@ def pf_get_dev(): ...@@ -636,9 +650,11 @@ def pf_get_dev():
return _pf_fd return _pf_fd
def pf_query_nat(family, proto, src_ip, src_port, dst_ip, dst_port): def pf_query_nat(family, proto, src_ip, src_port, dst_ip, dst_port):
[proto, family, src_port, dst_port] = [int(v) for v in [proto, family, src_port, dst_port]] [proto, family, src_port, dst_port] = [
int(v) for v in [proto, family, src_port, dst_port]]
length = 4 if family == socket.AF_INET else 16 length = 4 if family == socket.AF_INET else 16
pnl = pfioc_natlook() pnl = pfioc_natlook()
...@@ -650,12 +666,15 @@ def pf_query_nat(family, proto, src_ip, src_port, dst_ip, dst_port): ...@@ -650,12 +666,15 @@ def pf_query_nat(family, proto, src_ip, src_port, dst_ip, dst_port):
memmove(addressof(pnl.daddr), socket.inet_pton(pnl.af, dst_ip), length) memmove(addressof(pnl.daddr), socket.inet_pton(pnl.af, dst_ip), length)
pnl.dxport.port = socket.htons(dst_port) pnl.dxport.port = socket.htons(dst_port)
ioctl(pf_get_dev(), DIOCNATLOOK, (c_char * sizeof(pnl)).from_address(addressof(pnl))) ioctl(pf_get_dev(), DIOCNATLOOK, (c_char *
sizeof(pnl)).from_address(addressof(pnl)))
ip = socket.inet_ntop(pnl.af, (c_char * length).from_address(addressof(pnl.rdaddr))) ip = socket.inet_ntop(
pnl.af, (c_char * length).from_address(addressof(pnl.rdaddr)))
port = socket.ntohs(pnl.rdxport.port) port = socket.ntohs(pnl.rdxport.port)
return (ip, port) return (ip, port)
def pf_add_anchor_rule(type, name): def pf_add_anchor_rule(type, name):
ACTION_OFFSET = 0 ACTION_OFFSET = 0
POOL_TICKET_OFFSET = 8 POOL_TICKET_OFFSET = 8
...@@ -667,14 +686,18 @@ def pf_add_anchor_rule(type, name): ...@@ -667,14 +686,18 @@ def pf_add_anchor_rule(type, name):
ioctl(pf_get_dev(), DIOCBEGINADDRS, ppa) ioctl(pf_get_dev(), DIOCBEGINADDRS, ppa)
memmove(addressof(pr) + POOL_TICKET_OFFSET, ppa[4:8], 4) #pool_ticket memmove(addressof(pr) + POOL_TICKET_OFFSET, ppa[4:8], 4) # pool_ticket
memmove(addressof(pr) + ANCHOR_CALL_OFFSET, name, min(MAXPATHLEN, len(name))) #anchor_call = name memmove(addressof(pr) + ANCHOR_CALL_OFFSET, name,
memmove(addressof(pr) + RULE_ACTION_OFFSET, struct.pack('I', type), 4) #rule.action = type min(MAXPATHLEN, len(name))) # anchor_call = name
memmove(addressof(pr) + RULE_ACTION_OFFSET,
struct.pack('I', type), 4) # rule.action = type
memmove(addressof(pr) + ACTION_OFFSET, struct.pack('I', PF_CHANGE_GET_TICKET), 4) #action = PF_CHANGE_GET_TICKET memmove(addressof(pr) + ACTION_OFFSET, struct.pack('I',
PF_CHANGE_GET_TICKET), 4) # action = PF_CHANGE_GET_TICKET
ioctl(pf_get_dev(), DIOCCHANGERULE, pr) ioctl(pf_get_dev(), DIOCCHANGERULE, pr)
memmove(addressof(pr) + ACTION_OFFSET, struct.pack('I', PF_CHANGE_ADD_TAIL), 4) #action = PF_CHANGE_ADD_TAIL memmove(addressof(pr) + ACTION_OFFSET, struct.pack('I',
PF_CHANGE_ADD_TAIL), 4) # action = PF_CHANGE_ADD_TAIL
ioctl(pf_get_dev(), DIOCCHANGERULE, pr) ioctl(pf_get_dev(), DIOCCHANGERULE, pr)
...@@ -707,7 +730,8 @@ def main(port_v6, port_v4, dnsport_v6, dnsport_v4, nslist, method, udp, syslog): ...@@ -707,7 +730,8 @@ def main(port_v6, port_v4, dnsport_v6, dnsport_v4, nslist, method, udp, syslog):
elif program_exists('pfctl'): elif program_exists('pfctl'):
method = "pf" method = "pf"
else: else:
raise Fatal("can't find either ipfw, iptables or pfctl; check your PATH") raise Fatal(
"can't find either ipfw, iptables or pfctl; check your PATH")
if method == "nat": if method == "nat":
do_it = do_iptables_nat do_it = do_iptables_nat
......
...@@ -42,6 +42,7 @@ def readfile(name): ...@@ -42,6 +42,7 @@ def readfile(name):
return contents return contents
def empackage(z, name, data=None): def empackage(z, name, data=None):
if not data: if not data:
data = readfile(name) data = readfile(name)
......
...@@ -2,19 +2,19 @@ import sys ...@@ -2,19 +2,19 @@ import sys
import os import os
import pty import pty
from AppKit import ( from AppKit import (
objc, objc,
NSApp, NSApp,
NSApplicationMain, NSApplicationMain,
NSAttributedString, NSAttributedString,
NSFileHandle, NSFileHandle,
NSFileHandleDataAvailableNotification, NSFileHandleDataAvailableNotification,
NSImage, NSImage,
NSMenu, NSMenu,
NSMenuItem, NSMenuItem,
NSNotificationCenter, NSNotificationCenter,
NSObject, NSObject,
NSStatusBar, NSStatusBar,
NSVariableStatusItemLength, NSVariableStatusItemLength,
) )
import my import my
import models import models
......
import os import os
from AppKit import ( from AppKit import (
NSBundle, NSBundle,
NSData, NSData,
NSDictionary, NSDictionary,
NSImage, NSImage,
NSUserDefaults, NSUserDefaults,
) )
import PyObjCTools.AppHelper import PyObjCTools.AppHelper
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment