Commit f1c79c7e authored by Brian May's avatar Brian May

PEP8 fixes.

parent 5529a04c
import sys, zlib
import sys
import zlib
z = zlib.decompressobj()
mainmod = sys.modules[__name__]
......
This diff is collapsed.
This diff is collapsed.
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)
......@@ -43,9 +49,9 @@ def resolvconf_nameservers():
words = line.lower().split()
if len(words) >= 2 and words[0] == 'nameserver':
if ':' in words[1]:
l.append((socket.AF_INET6,words[1]))
l.append((socket.AF_INET6, words[1]))
else:
l.append((socket.AF_INET,words[1]))
l.append((socket.AF_INET, words[1]))
return l
......@@ -58,10 +64,10 @@ def resolvconf_random_nameserver():
random.shuffle(l)
return l[0]
else:
return (socket.AF_INET,'127.0.0.1')
return (socket.AF_INET, '127.0.0.1')
def islocal(ip,family):
def islocal(ip, family):
sock = socket.socket(family)
try:
try:
......@@ -83,4 +89,3 @@ def family_to_string(family):
return "AF_INET"
else:
return str(family)
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
POLL_TIME = 60 * 15
NETSTAT_POLL_TIME = 30
CACHEFILE=os.path.expanduser('~/.sshuttle.hosts')
CACHEFILE = os.path.expanduser('~/.sshuttle.hosts')
_nmb_ok = True
......@@ -28,7 +34,7 @@ def write_host_cache():
tmpname = '%s.%d.tmp' % (CACHEFILE, os.getpid())
try:
f = open(tmpname, 'wb')
for name,ip in sorted(hostnames.items()):
for name, ip in sorted(hostnames.items()):
f.write('%s,%s\n' % (name, ip))
f.close()
os.rename(tmpname, CACHEFILE)
......@@ -50,7 +56,7 @@ def read_host_cache():
for line in f:
words = line.strip().split(',')
if len(words) == 2:
(name,ip) = words
(name, ip) = words
name = re.sub(r'[^-\w]', '-', name).strip()
ip = re.sub(r'[^0-9.]', '', ip).strip()
if name and ip:
......@@ -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
......@@ -187,7 +193,7 @@ def _check_nmb(hostname, is_workgroup, is_master):
global _nmb_ok
if not _nmb_ok:
return
argv = ['nmblookup'] + ['-M']*is_master + ['--', hostname]
argv = ['nmblookup'] + ['-M'] * is_master + ['--', hostname]
debug2(' > n%d%d: %s\n' % (is_workgroup, is_master, hostname))
try:
p = ssubprocess.Popen(argv, stdout=ssubprocess.PIPE, stderr=null)
......@@ -228,13 +234,13 @@ def check_workgroup(hostname):
def _enqueue(op, *args):
t = (op,args)
if queue.get(t) == None:
t = (op, args)
if queue.get(t) is None:
queue[t] = 0
def _stdin_still_ok(timeout):
r,w,x = select.select([sys.stdin.fileno()], [], [], timeout)
r, w, x = select.select([sys.stdin.fileno()], [], [], timeout)
if r:
b = os.read(sys.stdin.fileno(), 4096)
if not b:
......@@ -261,8 +267,8 @@ def hw_main(seed_hosts):
while 1:
now = time.time()
for t,last_polled in queue.items():
(op,args) = t
for t, last_polled in queue.items():
(op, args) = t
if not _stdin_still_ok(0):
break
maxtime = POLL_TIME
......
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
......@@ -9,17 +15,17 @@ def parse_subnet4(s):
m = re.match(r'(\d+)(?:\.(\d+)\.(\d+)\.(\d+))?(?:/(\d+))?$', s)
if not m:
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:
(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 is None:
width = 32
else:
width = int(width)
if a > 255 or b > 255 or c > 255 or d > 255:
raise Fatal('%d.%d.%d.%d has numbers > 255' % (a,b,c,d))
raise Fatal('%d.%d.%d.%d has numbers > 255' % (a, b, c, d))
if width > 32:
raise Fatal('*/%d is greater than the maximum of 32' % width)
return(socket.AF_INET, '%d.%d.%d.%d' % (a,b,c,d), width)
return(socket.AF_INET, '%d.%d.%d.%d' % (a, b, c, d), width)
# 1:2::3/64 or just 1:2::3
......@@ -27,8 +33,8 @@ def parse_subnet6(s):
m = re.match(r'(?:([a-fA-F\d:]+))?(?:/(\d+))?$', s)
if not m:
raise Fatal('%r is not a valid IP subnet format' % s)
(net,width) = m.groups()
if width == None:
(net, width) = m.groups()
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()
......@@ -77,16 +83,16 @@ def parse_ipport4(s):
m = re.match(r'(?:(\d+)\.(\d+)\.(\d+)\.(\d+))?(?::)?(?:(\d+))?$', s)
if not m:
raise Fatal('%r is not a valid IP:port format' % s)
(a,b,c,d,port) = m.groups()
(a,b,c,d,port) = (int(a or 0), int(b or 0), int(c or 0), int(d or 0),
(a, b, c, d, port) = m.groups()
(a, b, c, d, port) = (int(a or 0), int(b or 0), int(c or 0), int(d or 0),
int(port or 0))
if a > 255 or b > 255 or c > 255 or d > 255:
raise Fatal('%d.%d.%d.%d has numbers > 255' % (a,b,c,d))
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)
return ('%d.%d.%d.%d' % (a, b, c, d), port)
# [1:2::3]:456 or [1:2::3] or 456
......@@ -95,8 +101,8 @@ def parse_ipport6(s):
m = re.match(r'(?:\[([^]]*)])?(?::)?(?:(\d+))?$', s)
if not m:
raise Fatal('%s is not a valid IP:port format' % s)
(ip,port) = m.groups()
(ip,port) = (ip or '::', int(port or 0))
(ip, port) = m.groups()
(ip, port) = (ip or '::', int(port or 0))
return (ip, port)
......@@ -156,8 +162,8 @@ try:
o.fatal('at least one subnet, subnet file, or -N expected')
includes = extra
excludes = ['127.0.0.0/8']
for k,v in flags:
if k in ('-x','--exclude'):
for k, v in flags:
if k in ('-x', '--exclude'):
excludes.append(v)
remotename = opt.remote
if remotename == '' or remotename == '-':
......@@ -174,10 +180,10 @@ try:
includes = parse_subnet_file(opt.subnets)
if not opt.method:
method = "auto"
elif opt.method in [ "auto", "nat", "tproxy", "ipfw" ]:
elif opt.method in ["auto", "nat", "tproxy", "ipfw"]:
method = opt.method
else:
o.fatal("method %s not supported"%opt.method)
o.fatal("method %s not supported" % opt.method)
if not opt.listen:
if opt.method == "tproxy":
ipport_v6 = parse_ipport6('[::1]:0')
......
"""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 = {}
......@@ -46,7 +53,8 @@ def _atoi(v):
def _remove_negative_kv(k, v):
if k.startswith('no-') or k.startswith('no_'):
return k[3:], not v
return k,v
return k, v
def _remove_negative_k(k):
return _remove_negative_kv(k, None)[0]
......@@ -55,15 +63,17 @@ 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
(ysize,xsize,ypix,xpix) = struct.unpack('HHHH', s)
(ysize, xsize, ypix, xpix) = struct.unpack('HHHH', s)
return xsize or 70
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')
......@@ -122,7 +134,7 @@ class Options:
flagl = flags.split(',')
flagl_nice = []
for _f in flagl:
f,dvi = _remove_negative_kv(_f, _intify(defval))
f, dvi = _remove_negative_kv(_f, _intify(defval))
self._aliases[f] = _remove_negative_k(flagl[0])
self._hasparms[f] = has_parm
self._defaults[f] = dvi
......@@ -141,7 +153,7 @@ class Options:
prefix = ' %-20s ' % flags_nice
argtext = '\n'.join(textwrap.wrap(extra, width=_tty_width(),
initial_indent=prefix,
subsequent_indent=' '*28))
subsequent_indent=' ' * 28))
out.append(argtext + '\n')
last_was_option = True
else:
......@@ -170,17 +182,18 @@ 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)
opt = OptDict()
for k,v in self._defaults.iteritems():
for k, v in self._defaults.iteritems():
k = self._aliases[k]
opt[k] = v
for (k,v) in flags:
for (k, v) in flags:
k = k.lstrip('-')
if k in ('h', '?', 'help'):
self.usage()
......@@ -195,6 +208,6 @@ class Options:
else:
v = _intify(v)
opt[k] = v
for (f1,f2) in self._aliases.iteritems():
for (f1, f2) in self._aliases.iteritems():
opt[f1] = opt._opts.get(f2)
return (opt,flags,extra)
return (opt, flags, extra)
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)
......@@ -38,12 +51,12 @@ def _maskbits(netmask):
return 32
for i in range(32):
if netmask[0] & _shl(1, i):
return 32-i
return 32 - i
return 0
def _shl(n, bits):
return n * int(2**bits)
return n * int(2 ** bits)
def _list_routes():
......@@ -58,8 +71,9 @@ def _list_routes():
maskw = _ipmatch(cols[2]) # linux only
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))
ip = ipw[0] & _shl(_shl(1, width) - 1, 32 - 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))
......@@ -68,9 +82,9 @@ def _list_routes():
def list_routes():
for (family, ip,width) in _list_routes():
for (family, ip, width) in _list_routes():
if not ip.startswith('0.') and not ip.startswith('127.'):
yield (family, ip,width)
yield (family, ip, width)
def _exc_dump():
......@@ -79,7 +93,7 @@ def _exc_dump():
def start_hostwatch(seed_hosts):
s1,s2 = socket.socketpair()
s1, s2 = socket.socketpair()
pid = os.fork()
if not pid:
# child
......@@ -91,27 +105,29 @@ 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:
os._exit(rv)
s1.close()
return pid,s2
return pid, s2
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)
Handler.__init__(self, [sock])
self.timeout = time.time()+30
self.timeout = time.time() + 30
self.mux = mux
self.chan = chan
self.tries = 0
......@@ -164,10 +180,11 @@ class DnsProxy(Handler):
class UdpProxy(Handler):
def __init__(self, mux, chan, family):
sock = socket.socket(family, socket.SOCK_DGRAM)
Handler.__init__(self, [sock])
self.timeout = time.time()+30
self.timeout = time.time() + 30
self.mux = mux
self.chan = chan
self.sock = sock
......@@ -177,26 +194,28 @@ class UdpProxy(Handler):
def send(self, dstip, data):
debug2('UDP: sending to %r port %d\n' % dstip)
try:
self.sock.sendto(data,dstip)
self.sock.sendto(data, dstip)
except socket.error, e:
log('UDP send to %r port %d: %s\n' % (dstip[0], dstip[1], e))
return
def callback(self):
try:
data,peer = self.sock.recvfrom(4096)
data, peer = self.sock.recvfrom(4096)
except socket.error, e:
log('UDP recv from %r port %d: %s\n' % (peer[0], peer[1], e))
return
debug2('UDP response: %d bytes\n' % len(data))
hdr = "%s,%r,"%(peer[0], peer[1])
self.mux.send(self.chan, ssnet.CMD_UDP_DATA, hdr+data)
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())
......@@ -239,13 +258,13 @@ def main():
def got_host_req(data):
if not hw.pid:
(hw.pid,hw.sock) = start_hostwatch(data.strip().split())
handlers.append(Handler(socks = [hw.sock],
callback = hostwatch_ready))
(hw.pid, hw.sock) = start_hostwatch(data.strip().split())
handlers.append(Handler(socks=[hw.sock],
callback=hostwatch_ready))
mux.got_host_req = got_host_req
def new_channel(channel, data):
(family,dstip,dstport) = data.split(',', 2)
(family, dstip, dstport) = data.split(',', 2)
family = int(family)
dstport = int(dstport)
outwrap = ssnet.connect_dst(family, dstip, dstport)
......@@ -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,14 +281,15 @@ 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))
debug2('Incoming UDP request channel=%d, cmd=%d\n' % (channel, cmd))
if cmd == ssnet.CMD_UDP_DATA:
(dstip,dstport,data) = data.split(",",2)
(dstip, dstport, data) = data.split(",", 2)
dstport = int(dstport)
debug2('is incoming UDP data. %r %d.\n' % (dstip,dstport))
debug2('is incoming UDP data. %r %d.\n' % (dstip, dstport))
h = udphandlers[channel]
h.send((dstip,dstport),data)
h.send((dstip, dstport), data)
elif cmd == ssnet.CMD_UDP_CLOSE:
debug2('is incoming UDP close\n')
h = udphandlers[channel]
......@@ -280,20 +301,20 @@ def main():
family = int(data)
mux.channels[channel] = lambda cmd, data: udp_req(channel, cmd, data)
if channel in udphandlers:
raise Fatal('UDP connection channel %d already open'%channel)
raise Fatal('UDP connection channel %d already open' % channel)
else:
h = UdpProxy(mux, channel, family)
handlers.append(h)
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:
......@@ -302,12 +323,12 @@ def main():
if dnshandlers:
now = time.time()
for channel,h in dnshandlers.items():
for channel, h in dnshandlers.items():
if h.timeout < now or not h.ok:
debug3('expiring dnsreqs channel=%d\n' % channel)
del dnshandlers[channel]
h.ok = False
for channel,h in udphandlers.items():
for channel, h in udphandlers.items():
if not h.ok:
debug3('expiring UDP channel=%d\n' % channel)
del udphandlers[channel]
......
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):
......@@ -15,7 +19,7 @@ def readfile(name):
def empackage(z, filename, data=None):
(path,basename) = os.path.split(filename)
(path, basename) = os.path.split(filename)
if not data:
data = readfile(filename)
content = z.compress(data)
......@@ -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)
......@@ -48,7 +53,7 @@ def connect(ssh_cmd, rhostport, python, stderr, options):
z = zlib.compressobj(1)
content = readfile('assembler.py')
optdata = ''.join("%s=%r\n" % (k,v) for (k,v) in options.items())
optdata = ''.join("%s=%r\n" % (k, v) for (k, v) in options.items())
content2 = (empackage(z, 'cmdline_options.py', optdata) +
empackage(z, 'helpers.py') +
empackage(z, 'compat/ssubprocess.py') +
......@@ -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.
......@@ -83,11 +87,12 @@ def connect(ssh_cmd, rhostport, python, stderr, options):
argv = (sshl +
portl +
[rhost, '--', pycmd])
(s1,s2) = socket.socketpair()
(s1, s2) = socket.socketpair()
def setup():
# runs in the child process
s2.close()
s1a,s1b = os.dup(s1.fileno()), os.dup(s1.fileno())
s1a, s1b = os.dup(s1.fileno()), os.dup(s1.fileno())
s1.close()
debug2('executing: %r\n' % argv)
p = ssubprocess.Popen(argv, stdin=s1a, stdout=s1b, preexec_fn=setup,
......
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
......@@ -177,7 +184,7 @@ class SockWrapper:
if not self.shut_read:
debug2('%r: done reading\n' % self)
self.shut_read = True
#self.rsock.shutdown(SHUT_RD) # doesn't do anything anyway
# self.rsock.shutdown(SHUT_RD) # doesn't do anything anyway
def nowrite(self):
if not self.shut_write:
......@@ -243,7 +250,8 @@ class SockWrapper:
class Handler:
def __init__(self, socks = None, callback = None):
def __init__(self, socks=None, callback=None):
self.ok = True
self.socks = socks or []
if callback:
......@@ -255,7 +263,7 @@ class Handler:
def callback(self):
log('--no callback defined-- %r\n' % self)
(r,w,x) = select.select(self.socks, [], [], 0)
(r, w, x) = select.select(self.socks, [], [], 0)
for s in r:
v = s.recv(4096)
if not v:
......@@ -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
......@@ -349,7 +361,7 @@ class Mux(Handler):
self.send(0, CMD_PING, 'rttest')
self.too_full = True
#ob = []
#for b in self.outbuf:
# for b in self.outbuf:
# (s1,s2,c) = struct.unpack('!ccH', b[:4])
# ob.append(c)
#log('outbuf: %d %r\n' % (self.amount_queued(), ob))
......@@ -360,13 +372,13 @@ class Mux(Handler):
p = struct.pack('!ccHHH', 'S', 'S', channel, cmd, len(data)) + data
self.outbuf.append(p)
debug2(' > channel=%d cmd=%s len=%d (fullness=%d)\n'
% (channel, cmd_to_name.get(cmd,hex(cmd)),
% (channel, cmd_to_name.get(cmd, hex(cmd)),
len(data), self.fullness))
self.fullness += len(data)
def got_packet(self, channel, cmd, data):
debug2('< channel=%d cmd=%s len=%d\n'
% (channel, cmd_to_name.get(cmd,hex(cmd)), len(data)))
% (channel, cmd_to_name.get(cmd, hex(cmd)), len(data)))
if cmd == CMD_PING:
self.send(0, CMD_PONG, data)
elif cmd == CMD_PONG:
......@@ -406,7 +418,7 @@ class Mux(Handler):
callback = self.channels.get(channel)
if not callback:
log('warning: closed channel %d got cmd=%s len=%d\n'
% (channel, cmd_to_name.get(cmd,hex(cmd)), len(data)))
% (channel, cmd_to_name.get(cmd, hex(cmd)), len(data)))
else:
callback(cmd, data)
......@@ -434,11 +446,11 @@ class Mux(Handler):
def handle(self):
self.fill()
#log('inbuf is: (%d,%d) %r\n'
# log('inbuf is: (%d,%d) %r\n'
# % (self.want, len(self.inbuf), self.inbuf))
while 1:
if len(self.inbuf) >= (self.want or HDR_LEN):
(s1,s2,channel,cmd,datalen) = \
(s1, s2, channel, cmd, datalen) = \
struct.unpack('!ccHHH', self.inbuf[:HDR_LEN])
assert(s1 == 'S')
assert(s2 == 'S')
......@@ -457,7 +469,7 @@ class Mux(Handler):
_add(w, self.wsock)
def callback(self):
(r,w,x) = select.select([self.rsock], [self.wsock], [], 0)
(r, w, x) = select.select([self.rsock], [self.wsock], [], 0)
if self.rsock in r:
self.handle()
if self.outbuf and self.wsock in w:
......@@ -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
......@@ -478,7 +491,7 @@ class MuxWrapper(SockWrapper):
SockWrapper.__del__(self)
def __repr__(self):
return 'SW%r:Mux#%d' % (self.peername,self.channel)
return 'SW%r:Mux#%d' % (self.peername, self.channel)
def noread(self):
if not self.shut_read:
......@@ -532,8 +545,8 @@ def connect_dst(family, ip, port):
outsock = socket.socket(family)
outsock.setsockopt(socket.SOL_IP, socket.IP_TTL, 42)
return SockWrapper(outsock, outsock,
connect_to = (ip,port),
peername = '%s:%d' % (ip,port))
connect_to=(ip, port),
peername = '%s:%d' % (ip, port))
def runonce(handlers, mux):
......@@ -545,14 +558,14 @@ def runonce(handlers, mux):
handlers.remove(h)
for s in handlers:
s.pre_select(r,w,x)
s.pre_select(r, w, x)
debug2('Waiting: %d r=%r w=%r x=%r (fullness=%d/%d)\n'
% (len(handlers), _fds(r), _fds(w), _fds(x),
mux.fullness, mux.too_full))
(r,w,x) = select.select(r,w,x)
(r, w, x) = select.select(r, w, x)
debug2(' Ready: %d r=%r w=%r x=%r\n'
% (len(handlers), _fds(r), _fds(w), _fds(x)))
ready = r+w+x
ready = r + w + x
did = {}
for h in handlers:
for s in h.socks:
......
import sys, os
import sys
import os
from compat import ssubprocess
_p = None
def start_syslog():
global _p
_p = ssubprocess.Popen(['logger',
......
#!/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))
......@@ -23,7 +26,7 @@ while 1:
if count >= 16384:
count = 1
print 'cli CREATING %d' % count
b = struct.pack('I', count) + 'x'*count
b = struct.pack('I', count) + 'x' * count
remain[c] = count
print 'cli >> %r' % len(b)
c.send(b)
......@@ -32,13 +35,13 @@ while 1:
r = [listener]
time.sleep(0.1)
else:
r = [listener]+servers+clients
r = [listener] + servers + clients
print 'select(%d)' % len(r)
r,w,x = select.select(r, [], [], 5)
r, w, x = select.select(r, [], [], 5)
assert(r)
for i in r:
if i == listener:
s,addr = listener.accept()
s, addr = listener.accept()
servers.append(s)
elif i in servers:
b = i.recv(4096)
......@@ -47,7 +50,7 @@ while 1:
assert(len(b) >= 4)
want = struct.unpack('I', b[:4])[0]
b = b[4:]
#i.send('y'*want)
# i.send('y'*want)
else:
want = remain[i]
if want < len(b):
......@@ -64,7 +67,7 @@ while 1:
del remain[i]
else:
print 'srv >> %r' % len(b)
i.send('y'*len(b))
i.send('y' * len(b))
if not want:
i.shutdown(socket.SHUT_WR)
elif i in clients:
......
import sys, os, re, subprocess
import re
import subprocess
def askpass(prompt):
prompt = prompt.replace('"', "'")
......@@ -6,7 +8,7 @@ def askpass(prompt):
if 'yes/no' in prompt:
return "yes"
script="""
script = """
tell application "Finder"
activate
display dialog "%s" \
......
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
......@@ -49,7 +58,7 @@ class Runner:
self.logfunc('\nConnecting to %s.\n' % self.serverobj.host())
print 'will run: %r' % argv
self.serverobj.setConnected_(False)
pid,fd = pty.fork()
pid, fd = pty.fork()
if pid == 0:
# child
try:
......@@ -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,8 +83,8 @@ class Runner:
self.wait()
def _try_wait(self, options):
if self.rv == None and self.pid > 0:
pid,code = os.waitpid(self.pid, options)
if self.rv is None and self.pid > 0:
pid, code = os.waitpid(self.pid, options)
if pid == self.pid:
if os.WIFEXITED(code):
self.rv = os.WEXITSTATUS(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()
......@@ -118,10 +128,11 @@ class Runner:
self.file.writeData_(my.Data(resp + '\n'))
self.file.waitForDataInBackgroundAndNotify()
self.poll()
#print 'gotdata done!'
# print 'gotdata done!'
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)
......@@ -164,12 +177,12 @@ class SshuttleController(NSObject):
manual_nets = []
noLatencyControl = (server.latencyControl() != models.LAT_INTERACTIVE)
conn = Runner(sshuttle_args(host,
auto_nets = nets_mode == models.NET_AUTO,
auto_hosts = server.autoHosts(),
dns = server.useDns(),
nets = manual_nets,
debug = self.debugField.state(),
no_latency_control = noLatencyControl),
auto_nets=nets_mode == models.NET_AUTO,
auto_hosts=server.autoHosts(),
dns=server.useDns(),
nets=manual_nets,
debug=self.debugField.state(),
no_latency_control=noLatencyControl),
logfunc=logfunc, promptfunc=promptfunc,
serverobj=server)
self.conns[host] = conn
......@@ -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,
......
......@@ -35,24 +35,29 @@ 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!'
# print 'validateSubnet!'
return True, _validate_ip(value), error
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!'
# print 'validateWidth!'
return True, _validate_width(value), error
NET_ALL = 0
......@@ -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()
......@@ -107,40 +119,47 @@ class SshuttleServer(NSObject):
suffix = " (all traffic)"
elif an == NET_MANUAL:
n = self.nets()
suffix = ' (%d subnet%s)' % (len(n), len(n)!=1 and 's' or '')
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)
# print 'validatehost! %r %r %r' % (self, value, error)
while value.startswith('-'):
value = value[1:]
return True, value, error
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'
# print 'checking netsHidden'
return self.autoNets() != NET_MANUAL
def setNetsHidden_(self, v):
config_changed()
#print 'setting netsHidden to %r' % v
# 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()
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)
......
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