PEP8 fixes.

This commit is contained in:
Brian May 2014-09-16 10:24:16 +10:00
parent 5529a04cc9
commit f1c79c7e92
16 changed files with 569 additions and 377 deletions

View File

@ -1,4 +1,5 @@
import sys, zlib
import sys
import zlib
z = zlib.decompressobj()
mainmod = sys.modules[__name__]

View File

@ -1,8 +1,17 @@
import struct, select, errno, re, signal, time
import struct
import errno
import re
import signal
import time
import compat.ssubprocess as ssubprocess
import helpers, ssnet, ssh, ssyslog
import helpers
import os
import ssnet
import ssh
import ssyslog
import sys
from ssnet import SockWrapper, Handler, Proxy, Mux, MuxWrapper
from helpers import *
from helpers import log, debug1, debug2, debug3, Fatal, islocal
recvmsg = None
try:
@ -23,6 +32,7 @@ except AttributeError:
_extra_fd = os.open('/dev/null', os.O_RDONLY)
def got_signal(signum, frame):
log('exiting on signal %d\n' % signum)
sys.exit(1)
@ -40,7 +50,8 @@ IPV6_RECVORIGDSTADDR = IPV6_ORIGDSTADDR
if recvmsg == "python":
def recv_udp(listener, bufsize):
debug3('Accept UDP python using recvmsg.\n')
data, ancdata, msg_flags, srcip = listener.recvmsg(4096,socket.CMSG_SPACE(24))
data, ancdata, msg_flags, srcip = listener.recvmsg(
4096, socket.CMSG_SPACE(24))
dstip = None
family = None
for cmsg_level, cmsg_type, cmsg_data in ancdata:
@ -70,7 +81,8 @@ if recvmsg == "python":
elif recvmsg == "socket_ext":
def recv_udp(listener, bufsize):
debug3('Accept UDP using socket_ext recvmsg.\n')
srcip, data, adata, flags = listener.recvmsg((bufsize,),socket.CMSG_SPACE(24))
srcip, data, adata, flags = listener.recvmsg(
(bufsize,), socket.CMSG_SPACE(24))
dstip = None
family = None
for a in adata:
@ -82,7 +94,8 @@ elif recvmsg == "socket_ext":
length = 4
else:
raise Fatal("Unsupported socket type '%s'" % family)
ip = socket.inet_ntop(family, a.cmsg_data[start:start+length])
ip = socket.inet_ntop(
family, a.cmsg_data[start:start + length])
dstip = (ip, port)
break
elif a.cmsg_level == SOL_IPV6 and a.cmsg_type == IPV6_ORIGDSTADDR:
@ -93,7 +106,8 @@ elif recvmsg == "socket_ext":
length = 16
else:
raise Fatal("Unsupported socket type '%s'" % family)
ip = socket.inet_ntop(family, a.cmsg_data[start:start+length])
ip = socket.inet_ntop(
family, a.cmsg_data[start:start + length])
dstip = (ip, port)
break
return (srcip, dstip, data[0])
@ -201,9 +215,15 @@ class MultiListener:
def add_handler(self, handlers, callback, method, mux):
if self.v6:
handlers.append(Handler([self.v6], lambda: callback(self.v6, method, mux, handlers)))
handlers.append(
Handler(
[self.v6],
lambda: callback(self.v6, method, mux, handlers)))
if self.v4:
handlers.append(Handler([self.v4], lambda: callback(self.v4, method, mux, handlers)))
handlers.append(
Handler(
[self.v4],
lambda: callback(self.v4, method, mux, handlers)))
def listen(self, backlog):
if self.v6:
@ -239,7 +259,9 @@ class MultiListener:
class FirewallClient:
def __init__(self, port_v6, port_v4, subnets_include, subnets_exclude, dnsport_v6, dnsport_v4, method, udp):
def __init__(self, port_v6, port_v4, subnets_include, subnets_exclude,
dnsport_v6, dnsport_v4, method, udp):
self.auto_nets = []
self.subnets_include = subnets_include
self.subnets_exclude = subnets_exclude
@ -261,6 +283,7 @@ class FirewallClient:
# Instead, attach a *bidirectional* socket to its stdout, and use
# that for talking in both directions.
(s1, s2) = socket.socketpair()
def setup():
# run in the child process
s2.close()
@ -321,6 +344,8 @@ class FirewallClient:
dnsreqs = {}
udp_by_src = {}
def expire_connections(now, mux):
for chan, timeout in dnsreqs.items():
if timeout < now:
@ -355,7 +380,7 @@ def onaccept_tcp(listener, method, mux, handlers):
else:
raise
if method == "tproxy":
dstip = sock.getsockname();
dstip = sock.getsockname()
else:
dstip = original_dst(sock)
debug1('Accept TCP: %s:%r -> %s:%r.\n' % (srcip[0], srcip[1],
@ -369,7 +394,8 @@ def onaccept_tcp(listener, method, mux, handlers):
log('warning: too many open channels. Discarded connection.\n')
sock.close()
return
mux.send(chan, ssnet.CMD_TCP_CONNECT, '%d,%s,%s' % (sock.family, dstip[0], dstip[1]))
mux.send(chan, ssnet.CMD_TCP_CONNECT, '%d,%s,%s' %
(sock.family, dstip[0], dstip[1]))
outwrap = MuxWrapper(mux, chan)
handlers.append(Proxy(SockWrapper(sock, sock), outwrap))
expire_connections(time.time(), mux)
@ -395,14 +421,17 @@ def onaccept_udp(listener, method, mux, handlers):
now = time.time()
srcip, dstip, data = recv_udp(listener, 4096)
if not dstip:
debug1("-- ignored UDP from %r: couldn't determine destination IP address\n" % (srcip,))
debug1(
"-- ignored UDP from %r: "
"couldn't determine destination IP address\n" % (srcip,))
return
debug1('Accept UDP: %r -> %r.\n' % (srcip, dstip,))
if srcip in udp_by_src:
chan, timeout = udp_by_src[srcip]
else:
chan = mux.next_channel()
mux.channels[chan] = lambda cmd,data: udp_done(chan, data, method, listener.family, dstip=srcip)
mux.channels[chan] = lambda cmd, data: udp_done(
chan, data, method, listener.family, dstip=srcip)
mux.send(chan, ssnet.CMD_UDP_OPEN, listener.family)
udp_by_src[srcip] = chan, now + 30
@ -433,17 +462,21 @@ def ondns(listener, method, mux, handlers):
now = time.time()
srcip, dstip, data = recv_udp(listener, 4096)
if method == "tproxy" and not dstip:
debug1("-- ignored UDP from %r: couldn't determine destination IP address\n" % (srcip,))
debug1(
"-- ignored UDP from %r: "
"couldn't determine destination IP address\n" % (srcip,))
return
debug1('DNS request from %r to %r: %d bytes\n' % (srcip, dstip, len(data)))
chan = mux.next_channel()
dnsreqs[chan] = now + 30
mux.send(chan, ssnet.CMD_DNS_REQ, data)
mux.channels[chan] = lambda cmd,data: dns_done(chan, data, method, listener, srcip=dstip, dstip=srcip, mux=mux)
mux.channels[chan] = lambda cmd, data: dns_done(
chan, data, method, listener, srcip=dstip, dstip=srcip, mux=mux)
expire_connections(now, mux)
def _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename, python, latency_control,
def _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename,
python, latency_control,
dns_listener, method, seed_hosts, auto_nets,
syslog, daemon):
handlers = []
@ -454,7 +487,8 @@ def _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename, python, latency_c
debug1('connecting to server...\n')
try:
(serverproc, serversock) = ssh.connect(ssh_cmd, remotename, python,
(serverproc, serversock) = ssh.connect(
ssh_cmd, remotename, python,
stderr=ssyslog._p and ssyslog._p.stdin,
options=dict(latency_control=latency_control, method=method))
except socket.error, e:
@ -531,7 +565,7 @@ def _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename, python, latency_c
if dns_listener:
dns_listener.add_handler(handlers, ondns, method, mux)
if seed_hosts != None:
if seed_hosts is not None:
debug1('seed_hosts: %r\n' % seed_hosts)
mux.send(0, ssnet.CMD_HOST_REQ, '\n'.join(seed_hosts))
@ -684,20 +718,23 @@ def main(listenip_v6, listenip_v4,
dnsport_v4 = 0
dns_listener = None
fw = FirewallClient(redirectport_v6, redirectport_v4, subnets_include, subnets_exclude, dnsport_v6, dnsport_v4, method, udp)
fw = FirewallClient(redirectport_v6, redirectport_v4, subnets_include,
subnets_exclude, dnsport_v6, dnsport_v4, method, udp)
if fw.method == "tproxy":
tcp_listener.setsockopt(socket.SOL_IP, IP_TRANSPARENT, 1)
if udp_listener:
udp_listener.setsockopt(socket.SOL_IP, IP_TRANSPARENT, 1)
if udp_listener.v4 is not None:
udp_listener.v4.setsockopt(socket.SOL_IP, IP_RECVORIGDSTADDR, 1)
udp_listener.v4.setsockopt(
socket.SOL_IP, IP_RECVORIGDSTADDR, 1)
if udp_listener.v6 is not None:
udp_listener.v6.setsockopt(SOL_IPV6, IPV6_RECVORIGDSTADDR, 1)
if dns_listener:
dns_listener.setsockopt(socket.SOL_IP, IP_TRANSPARENT, 1)
if dns_listener.v4 is not None:
dns_listener.v4.setsockopt(socket.SOL_IP, IP_RECVORIGDSTADDR, 1)
dns_listener.v4.setsockopt(
socket.SOL_IP, IP_RECVORIGDSTADDR, 1)
if dns_listener.v6 is not None:
dns_listener.v6.setsockopt(SOL_IPV6, IPV6_RECVORIGDSTADDR, 1)

View File

@ -1,7 +1,13 @@
import re, errno, socket, select, struct
import errno
import socket
import select
import struct
import compat.ssubprocess as ssubprocess
import helpers, ssyslog
from helpers import *
import ssyslog
import sys
import os
from helpers import log, debug1, debug3, islocal, Fatal, family_to_string, \
resolvconf_nameservers
# python doesn't have a definition for this
IPPROTO_DIVERT = 254
@ -45,6 +51,8 @@ def _ipt(family, table, *args):
_no_ttl_module = False
def _ipt_ttl(family, *args):
global _no_ttl_module
if not _no_ttl_module:
@ -72,13 +80,17 @@ def _ipt_ttl(family, *args):
def do_iptables_nat(port, dnsport, family, subnets, udp):
# only ipv4 supported with NAT
if family != socket.AF_INET:
raise Exception('Address family "%s" unsupported by nat method'%family_to_string(family))
raise Exception(
'Address family "%s" unsupported by nat method'
% family_to_string(family))
if udp:
raise Exception("UDP not supported by nat method")
table = "nat"
def ipt(*args):
return _ipt(family, table, *args)
def ipt_ttl(*args):
return _ipt_ttl(family, table, *args)
@ -103,7 +115,8 @@ def do_iptables_nat(port, dnsport, family, subnets, udp):
# to least-specific, and at any given level of specificity, we want
# excludes to come first. That's why the columns are in such a non-
# intuitive order.
for f,swidth,sexclude,snet in sorted(subnets, key=lambda s: s[1], reverse=True):
for f, swidth, sexclude, snet \
in sorted(subnets, key=lambda s: s[1], reverse=True):
if sexclude:
ipt('-A', chain, '-j', 'RETURN',
'--dest', '%s/%s' % (snet, swidth),
@ -126,11 +139,15 @@ def do_iptables_nat(port, dnsport, family, subnets, udp):
def do_iptables_tproxy(port, dnsport, family, subnets, udp):
if family not in [socket.AF_INET, socket.AF_INET6]:
raise Exception('Address family "%s" unsupported by tproxy method'%family_to_string(family))
raise Exception(
'Address family "%s" unsupported by tproxy method'
% family_to_string(family))
table = "mangle"
def ipt(*args):
return _ipt(family, table, *args)
def ipt_ttl(*args):
return _ipt_ttl(family, table, *args)
@ -182,7 +199,8 @@ def do_iptables_tproxy(port, dnsport, family, subnets, udp):
'--on-port', str(dnsport))
if subnets:
for f,swidth,sexclude,snet in sorted(subnets, key=lambda s: s[1], reverse=True):
for f, swidth, sexclude, snet \
in sorted(subnets, key=lambda s: s[1], reverse=True):
if sexclude:
ipt('-A', mark_chain, '-j', 'RETURN',
'--dest', '%s/%s' % (snet, swidth),
@ -191,10 +209,12 @@ def do_iptables_tproxy(port, dnsport, family, subnets, udp):
'--dest', '%s/%s' % (snet, swidth),
'-m', 'tcp', '-p', 'tcp')
else:
ipt('-A', mark_chain, '-j', 'MARK', '--set-mark', '1',
ipt('-A', mark_chain, '-j', 'MARK',
'--set-mark', '1',
'--dest', '%s/%s' % (snet, swidth),
'-m', 'tcp', '-p', 'tcp')
ipt('-A', tproxy_chain, '-j', 'TPROXY', '--tproxy-mark', '0x1/0x1',
ipt('-A', tproxy_chain, '-j', 'TPROXY',
'--tproxy-mark', '0x1/0x1',
'--dest', '%s/%s' % (snet, swidth),
'-m', 'tcp', '-p', 'tcp',
'--on-port', str(port))
@ -207,10 +227,12 @@ def do_iptables_tproxy(port, dnsport, family, subnets, udp):
'--dest', '%s/%s' % (snet, swidth),
'-m', 'udp', '-p', 'udp')
elif udp:
ipt('-A', mark_chain, '-j', 'MARK', '--set-mark', '1',
ipt('-A', mark_chain, '-j', 'MARK',
'--set-mark', '1',
'--dest', '%s/%s' % (snet, swidth),
'-m', 'udp', '-p', 'udp')
ipt('-A', tproxy_chain, '-j', 'TPROXY', '--tproxy-mark', '0x1/0x1',
ipt('-A', tproxy_chain, '-j', 'TPROXY',
'--tproxy-mark', '0x1/0x1',
'--dest', '%s/%s' % (snet, swidth),
'-m', 'udp', '-p', 'udp',
'--on-port', str(port))
@ -235,6 +257,8 @@ def ipfw_rule_exists(n):
_oldctls = {}
def _fill_oldctls(prefix):
argv = ['sysctl', prefix]
p = ssubprocess.Popen(argv, stdout=ssubprocess.PIPE)
@ -256,6 +280,8 @@ def _sysctl_set(name, val):
_changedctls = []
def sysctl_set(name, val, permanent=False):
PREFIX = 'net.inet.ip'
assert(name.startswith(PREFIX + '.'))
@ -293,6 +319,8 @@ def _udp_repack(p, src, dst):
_real_dns_server = [None]
def _handle_diversion(divertsock, dnsport):
p, tag = divertsock.recvfrom(4096)
src, dst = _udp_unpack(p)
@ -324,7 +352,9 @@ def ipfw(*args):
def do_ipfw(port, dnsport, family, subnets, udp):
# IPv6 not supported
if family not in [socket.AF_INET, ]:
raise Exception('Address family "%s" unsupported by ipfw method'%family_to_string(family))
raise Exception(
'Address family "%s" unsupported by ipfw method'
% family_to_string(family))
if udp:
raise Exception("UDP not supported by ipfw method")
@ -360,7 +390,8 @@ def do_ipfw(port, dnsport, family, subnets, udp):
if subnets:
# create new subnet entries
for f,swidth,sexclude,snet in sorted(subnets, key=lambda s: s[1], reverse=True):
for f, swidth, sexclude, snet \
in sorted(subnets, key=lambda s: s[1], reverse=True):
if sexclude:
ipfw('add', sport, 'skipto', xsport,
'log', 'tcp',
@ -440,6 +471,8 @@ def program_exists(name):
hostmap = {}
def rewrite_etc_hosts(port):
HOSTSFILE = '/etc/hosts'
BAKFILE = '%s.sbak' % HOSTSFILE
@ -564,13 +597,15 @@ def main(port_v6, port_v4, dnsport_v6, dnsport_v4, method, udp, syslog):
subnets_v6 = filter(lambda i: i[0] == socket.AF_INET6, subnets)
if port_v6:
do_wait = do_it(port_v6, dnsport_v6, socket.AF_INET6, subnets_v6, udp)
do_wait = do_it(
port_v6, dnsport_v6, socket.AF_INET6, subnets_v6, udp)
elif len(subnets_v6) > 0:
debug1("IPv6 subnets defined but IPv6 disabled\n")
subnets_v4 = filter(lambda i: i[0] == socket.AF_INET, subnets)
if port_v4:
do_wait = do_it(port_v4, dnsport_v4, socket.AF_INET, subnets_v4, udp)
do_wait = do_it(
port_v4, dnsport_v4, socket.AF_INET, subnets_v4, udp)
elif len(subnets_v4) > 0:
debug1('IPv4 subnets defined but IPv4 disabled\n')
@ -587,7 +622,8 @@ def main(port_v6, port_v4, dnsport_v6, dnsport_v4, method, udp, syslog):
# to stay running so that we don't need a *second* password
# authentication at shutdown time - that cleanup is important!
while 1:
if do_wait: do_wait()
if do_wait:
do_wait()
line = sys.stdin.readline(128)
if line.startswith('HOST '):
(name, ip) = line[5:].strip().split(',', 1)

View File

@ -1,8 +1,11 @@
import sys, os, socket, errno
import sys
import socket
import errno
logprefix = ''
verbose = 0
def log(s):
try:
sys.stdout.flush()
@ -13,14 +16,17 @@ def log(s):
# our tty closes. That sucks, but it's no reason to abort the program.
pass
def debug1(s):
if verbose >= 1:
log(s)
def debug2(s):
if verbose >= 2:
log(s)
def debug3(s):
if verbose >= 3:
log(s)
@ -83,4 +89,3 @@ def family_to_string(family):
return "AF_INET"
else:
return str(family)

View File

@ -1,8 +1,14 @@
import time, socket, re, select, errno
import time
import socket
import re
import select
import errno
import os
import sys
if not globals().get('skip_imports'):
import compat.ssubprocess as ssubprocess
import helpers
from helpers import *
from helpers import log, debug1, debug2, debug3
POLL_TIME = 60 * 15
NETSTAT_POLL_TIME = 30
@ -94,7 +100,7 @@ def _check_revdns(ip):
debug3('< %s\n' % r[0])
check_host(r[0])
found_host(r[0], ip)
except socket.herror, e:
except socket.herror:
pass
@ -105,7 +111,7 @@ def _check_dns(hostname):
debug3('< %s\n' % ip)
check_host(ip)
found_host(hostname, ip)
except socket.gaierror, e:
except socket.gaierror:
pass
@ -229,7 +235,7 @@ def check_workgroup(hostname):
def _enqueue(op, *args):
t = (op, args)
if queue.get(t) == None:
if queue.get(t) is None:
queue[t] = 0

View File

@ -1,7 +1,13 @@
import sys, os, re, socket
import helpers, options, client, server, firewall, hostwatch
import compat.ssubprocess as ssubprocess
from helpers import *
import sys
import re
import socket
import helpers
import options
import client
import server
import firewall
import hostwatch
from helpers import log, Fatal
# 1.2.3.4/5 or just 1.2.3.4
@ -11,7 +17,7 @@ def parse_subnet4(s):
raise Fatal('%r is not a valid IP subnet format' % s)
(a, b, c, d, width) = m.groups()
(a, b, c, d) = (int(a or 0), int(b or 0), int(c or 0), int(d or 0))
if width == None:
if width is None:
width = 32
else:
width = int(width)
@ -28,7 +34,7 @@ def parse_subnet6(s):
if not m:
raise Fatal('%r is not a valid IP subnet format' % s)
(net, width) = m.groups()
if width == None:
if width is None:
width = 128
else:
width = int(width)
@ -41,7 +47,7 @@ def parse_subnet6(s):
def parse_subnet_file(s):
try:
handle = open(s, 'r')
except OSError, e:
except OSError:
raise Fatal('Unable to open subnet file: %s' % s)
raw_config_lines = handle.readlines()
@ -84,7 +90,7 @@ def parse_ipport4(s):
raise Fatal('%d.%d.%d.%d has numbers > 255' % (a, b, c, d))
if port > 65535:
raise Fatal('*:%d is greater than the maximum of 65535' % port)
if a == None:
if a is None:
a = b = c = d = 0
return ('%d.%d.%d.%d' % (a, b, c, d), port)

View File

@ -1,9 +1,16 @@
"""Command-line options parser.
With the help of an options spec string, easily parse command-line options.
"""
import sys, os, textwrap, getopt, re, struct
import sys
import os
import textwrap
import getopt
import re
import struct
class OptDict:
def __init__(self):
self._opts = {}
@ -48,6 +55,7 @@ def _remove_negative_kv(k, v):
return k[3:], not v
return k, v
def _remove_negative_k(k):
return _remove_negative_kv(k, None)[0]
@ -55,7 +63,8 @@ def _remove_negative_k(k):
def _tty_width():
s = struct.pack("HHHH", 0, 0, 0, 0)
try:
import fcntl, termios
import fcntl
import termios
s = fcntl.ioctl(sys.stderr.fileno(), termios.TIOCGWINSZ, s)
except (IOError, ImportError):
return _atoi(os.environ.get('WIDTH')) or 70
@ -64,6 +73,7 @@ def _tty_width():
class Options:
"""Option parser.
When constructed, two strings are mandatory. The first one is the command
name showed before error messages. The second one is a string called an
@ -76,6 +86,7 @@ class Options:
By default, the parser function is getopt.gnu_getopt, and the abort
behaviour is to exit the program.
"""
def __init__(self, optspec, optfunc=getopt.gnu_getopt,
onabort=_default_onabort):
self.optspec = optspec
@ -95,7 +106,8 @@ class Options:
first_syn = True
while lines:
l = lines.pop()
if l == '--': break
if l == '--':
break
out.append('%s: %s\n' % (first_syn and 'usage' or ' or', l))
first_syn = False
out.append('\n')
@ -170,7 +182,8 @@ class Options:
and "extra" is a list of positional arguments.
"""
try:
(flags,extra) = self.optfunc(args, self._shortopts, self._longopts)
(flags, extra) = self.optfunc(
args, self._shortopts, self._longopts)
except getopt.GetoptError, e:
self.fatal(e)

View File

@ -1,9 +1,22 @@
import re, struct, socket, select, traceback, time
import re
import struct
import socket
import traceback
import time
import sys
import os
if not globals().get('skip_imports'):
import ssnet, helpers, hostwatch
import ssnet
import helpers
import hostwatch
import compat.ssubprocess as ssubprocess
from ssnet import SockWrapper, Handler, Proxy, Mux, MuxWrapper
from helpers import *
from ssnet import Handler, Proxy, Mux, MuxWrapper
from helpers import log, debug1, debug2, debug3, Fatal, \
resolvconf_random_nameserver
if not globals().get('latency_control'):
latency_control = None
def _ipmatch(ipstr):
@ -14,13 +27,13 @@ def _ipmatch(ipstr):
g = m.groups()
ips = g[0]
width = int(g[4] or 32)
if g[1] == None:
if g[1] is None:
ips += '.0.0.0'
width = min(width, 8)
elif g[2] == None:
elif g[2] is None:
ips += '.0.0'
width = min(width, 16)
elif g[3] == None:
elif g[3] is None:
ips += '.0'
width = min(width, 24)
return (struct.unpack('!I', socket.inet_aton(ips))[0], width)
@ -59,7 +72,8 @@ def _list_routes():
mask = _maskbits(maskw) # returns 32 if maskw is null
width = min(ipw[1], mask)
ip = ipw[0] & _shl(_shl(1, width) - 1, 32 - width)
routes.append((socket.AF_INET, socket.inet_ntoa(struct.pack('!I', ip)), width))
routes.append(
(socket.AF_INET, socket.inet_ntoa(struct.pack('!I', ip)), width))
rv = p.wait()
if rv != 0:
log('WARNING: %r returned %d\n' % (argv, rv))
@ -91,7 +105,7 @@ def start_hostwatch(seed_hosts):
os.dup2(s1.fileno(), 0)
s1.close()
rv = hostwatch.hw_main(seed_hosts) or 0
except Exception, e:
except Exception:
log('%s\n' % _exc_dump())
rv = 98
finally:
@ -101,12 +115,14 @@ def start_hostwatch(seed_hosts):
class Hostwatch:
def __init__(self):
self.pid = 0
self.sock = None
class DnsProxy(Handler):
def __init__(self, mux, chan, request):
# FIXME! IPv4 specific
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
@ -164,6 +180,7 @@ class DnsProxy(Handler):
class UdpProxy(Handler):
def __init__(self, mux, chan, family):
sock = socket.socket(family, socket.SOCK_DGRAM)
Handler.__init__(self, [sock])
@ -192,11 +209,13 @@ class UdpProxy(Handler):
hdr = "%s,%r," % (peer[0], peer[1])
self.mux.send(self.chan, ssnet.CMD_UDP_DATA, hdr + data)
def main():
if helpers.verbose >= 1:
helpers.logprefix = ' s: '
else:
helpers.logprefix = 'server: '
assert latency_control is not None
debug1('latency control setting = %r\n' % latency_control)
routes = list(list_routes())
@ -253,6 +272,7 @@ def main():
mux.new_channel = new_channel
dnshandlers = {}
def dns_req(channel, data):
debug2('Incoming DNS request channel=%d.\n' % channel)
h = DnsProxy(mux, channel, data)
@ -261,6 +281,7 @@ def main():
mux.got_dns_req = dns_req
udphandlers = {}
def udp_req(channel, cmd, data):
debug2('Incoming UDP request channel=%d, cmd=%d\n' % (channel, cmd))
if cmd == ssnet.CMD_UDP_DATA:
@ -287,13 +308,13 @@ def main():
udphandlers[channel] = h
mux.got_udp_open = udp_open
while mux.ok:
if hw.pid:
assert(hw.pid > 0)
(rpid, rv) = os.waitpid(hw.pid, os.WNOHANG)
if rpid:
raise Fatal('hostwatch exited unexpectedly: code 0x%04x\n' % rv)
raise Fatal(
'hostwatch exited unexpectedly: code 0x%04x\n' % rv)
ssnet.runonce(handlers, mux)
if latency_control:

View File

@ -1,7 +1,11 @@
import sys, os, re, socket, zlib
import sys
import os
import re
import socket
import zlib
import compat.ssubprocess as ssubprocess
import helpers
from helpers import *
from helpers import debug2
def readfile(name):
@ -24,7 +28,6 @@ def empackage(z, filename, data=None):
def connect(ssh_cmd, rhostport, python, stderr, options):
main_exe = sys.argv[0]
portl = []
if (rhostport or '').count(':') > 1:
@ -35,7 +38,9 @@ def connect(ssh_cmd, rhostport, python, stderr, options):
result[1] = result[1].strip(':')
if result[1] is not '':
portl = ['-p', str(int(result[1]))]
else: # can't disambiguate IPv6 colons and a port number. pass the hostname through.
# can't disambiguate IPv6 colons and a port number. pass the hostname
# through.
else:
rhost = rhostport
else: # IPv4
l = (rhostport or '').split(':', 1)
@ -65,7 +70,6 @@ def connect(ssh_cmd, rhostport, python, stderr, options):
""" % (helpers.verbose or 0, len(content))
pyscript = re.sub(r'\s+', ' ', pyscript.strip())
if not rhost:
# ignore the --python argument when running locally; we already know
# which python version works.
@ -84,6 +88,7 @@ def connect(ssh_cmd, rhostport, python, stderr, options):
portl +
[rhost, '--', pycmd])
(s1, s2) = socket.socketpair()
def setup():
# runs in the child process
s2.close()

View File

@ -1,6 +1,10 @@
import struct, socket, errno, select
import struct
import socket
import errno
import select
import os
if not globals().get('skip_imports'):
from helpers import *
from helpers import log, debug1, debug2, debug3, Fatal
MAX_CHANNEL = 65535
@ -92,7 +96,10 @@ def _try_peername(sock):
_swcount = 0
class SockWrapper:
def __init__(self, rsock, wsock, connect_to=None, peername=None):
global _swcount
_swcount += 1
@ -243,6 +250,7 @@ class SockWrapper:
class Handler:
def __init__(self, socks=None, callback=None):
self.ok = True
self.socks = socks or []
@ -265,6 +273,7 @@ class Handler:
class Proxy(Handler):
def __init__(self, wrap1, wrap2):
Handler.__init__(self, [wrap1.rsock, wrap1.wsock,
wrap2.rsock, wrap2.wsock])
@ -272,8 +281,10 @@ class Proxy(Handler):
self.wrap2 = wrap2
def pre_select(self, r, w, x):
if self.wrap1.shut_write: self.wrap2.noread()
if self.wrap2.shut_write: self.wrap1.noread()
if self.wrap1.shut_write:
self.wrap2.noread()
if self.wrap2.shut_write:
self.wrap1.noread()
if self.wrap1.connect_to:
_add(w, self.wrap1.rsock)
@ -312,6 +323,7 @@ class Proxy(Handler):
class Mux(Handler):
def __init__(self, rsock, wsock):
Handler.__init__(self, [rsock, wsock])
self.rsock = rsock
@ -465,6 +477,7 @@ class Mux(Handler):
class MuxWrapper(SockWrapper):
def __init__(self, mux, channel):
SockWrapper.__init__(self, mux.rsock, mux.wsock)
self.mux = mux

View File

@ -1,8 +1,11 @@
import sys, os
import sys
import os
from compat import ssubprocess
_p = None
def start_syslog():
global _p
_p = ssubprocess.Popen(['logger',

View File

@ -1,5 +1,8 @@
#!/usr/bin/env python
import sys, os, socket, select, struct, time
import socket
import select
import struct
import time
listener = socket.socket()
listener.bind(('127.0.0.1', 0))

View File

@ -1,4 +1,6 @@
import sys, os, re, subprocess
import re
import subprocess
def askpass(prompt):
prompt = prompt.replace('"', "'")

View File

@ -1,6 +1,11 @@
import sys, os, pty
import sys
import os
import pty
from AppKit import *
import my, models, askpass
import my
import models
import askpass
def sshuttle_args(host, auto_nets, auto_hosts, dns, nets, debug,
no_latency_control):
@ -21,21 +26,25 @@ def sshuttle_args(host, auto_nets, auto_hosts, dns, nets, debug,
class _Callback(NSObject):
def initWithFunc_(self, func):
self = super(_Callback, self).init()
self.func = func
return self
def func_(self, obj):
return self.func(obj)
class Callback:
def __init__(self, func):
self.obj = _Callback.alloc().initWithFunc_(func)
self.sel = self.obj.func_
class Runner:
def __init__(self, argv, logfunc, promptfunc, serverobj):
print 'in __init__'
self.id = argv
@ -65,7 +74,8 @@ class Runner:
.initWithFileDescriptor_closeOnDealloc_(fd, True)
self.cb = Callback(self.gotdata)
NSNotificationCenter.defaultCenter()\
.addObserver_selector_name_object_(self.cb.obj, self.cb.sel,
.addObserver_selector_name_object_(
self.cb.obj, self.cb.sel,
NSFileHandleDataAvailableNotification, self.file)
self.file.waitForDataInBackgroundAndNotify()
@ -73,7 +83,7 @@ class Runner:
self.wait()
def _try_wait(self, options):
if self.rv == None and self.pid > 0:
if self.rv is None and self.pid > 0:
pid, code = os.waitpid(self.pid, options)
if pid == self.pid:
if os.WIFEXITED(code):
@ -95,7 +105,7 @@ class Runner:
def kill(self):
assert(self.pid > 0)
print 'killing: pid=%r rv=%r' % (self.pid, self.rv)
if self.rv == None:
if self.rv is None:
self.logfunc('Disconnecting from %s.\n' % self.serverobj.host())
os.kill(self.pid, 15)
self.wait()
@ -122,6 +132,7 @@ class Runner:
class SshuttleApp(NSObject):
def initialize(self):
d = my.PList('UserDefaults')
my.Defaults().registerDefaults_(d)
@ -145,12 +156,14 @@ class SshuttleController(NSObject):
host = server.host()
print 'connecting %r' % host
self.fill_menu()
def logfunc(msg):
print 'log! (%d bytes)' % len(msg)
self.logField.textStorage()\
.appendAttributedString_(NSAttributedString.alloc()\
.appendAttributedString_(NSAttributedString.alloc()
.initWithString_(msg))
self.logField.didChangeText()
def promptfunc(prompt):
print 'prompt! %r' % prompt
return askpass.askpass(prompt)
@ -213,6 +226,7 @@ class SshuttleController(NSObject):
it.setRepresentedObject_(obj)
it.setTarget_(self)
it.setAction_(func)
def addnote(name):
additem(name, None, None)
@ -271,7 +285,8 @@ class SshuttleController(NSObject):
sl = []
for s in l:
host = s.get('host', None)
if not host: continue
if not host:
continue
nets = s.get('nets', [])
nl = []
@ -302,11 +317,13 @@ class SshuttleController(NSObject):
l = []
for s in self.servers:
host = s.host()
if not host: continue
if not host:
continue
nets = []
for n in s.nets():
subnet = n.subnet()
if not subnet: continue
if not subnet:
continue
nets.append((subnet, n.width()))
d = dict(host=s.host(),
nets=nets,

View File

@ -35,11 +35,14 @@ def _validate_width(v):
class SshuttleNet(NSObject):
def subnet(self):
return getattr(self, '_k_subnet', None)
def setSubnet_(self, v):
self._k_subnet = v
config_changed()
@objc_validator
def validateSubnet_error_(self, value, error):
# print 'validateSubnet!'
@ -47,9 +50,11 @@ class SshuttleNet(NSObject):
def width(self):
return getattr(self, '_k_width', 24)
def setWidth_(self, v):
self._k_width = v
config_changed()
@objc_validator
def validateWidth_error_(self, value, error):
# print 'validateWidth!'
@ -62,7 +67,9 @@ NET_MANUAL = 2
LAT_BANDWIDTH = 0
LAT_INTERACTIVE = 1
class SshuttleServer(NSObject):
def init(self):
self = super(SshuttleServer, self).init()
config_changed()
@ -70,22 +77,27 @@ class SshuttleServer(NSObject):
def wantConnect(self):
return getattr(self, '_k_wantconnect', False)
def setWantConnect_(self, v):
self._k_wantconnect = v
self.setError_(None)
config_changed()
if setconnect_callback: setconnect_callback(self)
if setconnect_callback:
setconnect_callback(self)
def connected(self):
return getattr(self, '_k_connected', False)
def setConnected_(self, v):
print 'setConnected of %r to %r' % (self, v)
self._k_connected = v
if v: self.setError_(None) # connected ok, so no error
if v:
self.setError_(None) # connected ok, so no error
config_changed()
def error(self):
return getattr(self, '_k_error', None)
def setError_(self, v):
self._k_error = v
config_changed()
@ -109,16 +121,19 @@ class SshuttleServer(NSObject):
n = self.nets()
suffix = ' (%d subnet%s)' % (len(n), len(n) != 1 and 's' or '')
return self.host() + suffix
def setTitle_(self, v):
# title is always auto-generated
config_changed()
def host(self):
return getattr(self, '_k_host', None)
def setHost_(self, v):
self._k_host = v
self.setTitle_(None)
config_changed()
@objc_validator
def validateHost_error_(self, value, error):
# print 'validatehost! %r %r %r' % (self, value, error)
@ -128,19 +143,23 @@ class SshuttleServer(NSObject):
def nets(self):
return getattr(self, '_k_nets', [])
def setNets_(self, v):
self._k_nets = v
self.setTitle_(None)
config_changed()
def netsHidden(self):
# print 'checking netsHidden'
return self.autoNets() != NET_MANUAL
def setNetsHidden_(self, v):
config_changed()
# print 'setting netsHidden to %r' % v
def autoNets(self):
return getattr(self, '_k_autoNets', NET_AUTO)
def setAutoNets_(self, v):
self._k_autoNets = v
self.setNetsHidden_(-1)
@ -150,18 +169,21 @@ class SshuttleServer(NSObject):
def autoHosts(self):
return getattr(self, '_k_autoHosts', True)
def setAutoHosts_(self, v):
self._k_autoHosts = v
config_changed()
def useDns(self):
return getattr(self, '_k_useDns', False)
def setUseDns_(self, v):
self._k_useDns = v
config_changed()
def latencyControl(self):
return getattr(self, '_k_latencyControl', LAT_INTERACTIVE)
def setLatencyControl_(self, v):
self._k_latencyControl = v
config_changed()

View File

@ -1,4 +1,4 @@
import sys, os
import os
from AppKit import *
import PyObjCTools.AppHelper
@ -44,11 +44,13 @@ def Defaults():
#
def DelayedCallback(func, *args, **kwargs):
flag = [0]
def _go():
if flag[0]:
print 'running %r (flag=%r)' % (func, flag)
flag[0] = 0
func(*args, **kwargs)
def call():
flag[0] += 1
PyObjCTools.AppHelper.callAfter(_go)