Add a -v (and -vv) flag and decrease default message verbosity.

This commit is contained in:
Avery Pennarun 2010-05-02 02:14:20 -04:00
parent a244b325cb
commit 2dd328ada4
7 changed files with 42 additions and 26 deletions

View File

@ -1,5 +1,5 @@
import struct, socket, select, subprocess, errno import struct, socket, select, subprocess, errno
import ssnet, ssh, helpers import helpers, ssnet, ssh
from ssnet import SockWrapper, Handler, Proxy, Mux, MuxWrapper from ssnet import SockWrapper, Handler, Proxy, Mux, MuxWrapper
from helpers import * from helpers import *
@ -15,7 +15,9 @@ def original_dst(sock):
def iptables_setup(port, subnets): def iptables_setup(port, subnets):
subnets_str = ['%s/%d' % (ip,width) for ip,width in subnets] subnets_str = ['%s/%d' % (ip,width) for ip,width in subnets]
argv = ['sudo', sys.argv[0], '--iptables', str(port)] + subnets_str argv = (['sudo', sys.argv[0]] +
['-v'] * (helpers.verbose or 0) +
['--iptables', str(port)] + subnets_str)
rv = subprocess.call(argv) rv = subprocess.call(argv)
if rv != 0: if rv != 0:
raise Exception('%r returned %d' % (argv, rv)) raise Exception('%r returned %d' % (argv, rv))
@ -46,10 +48,10 @@ def _main(listener, listenport, use_server, remotename, subnets):
def onaccept(): def onaccept():
sock,srcip = listener.accept() sock,srcip = listener.accept()
dstip = original_dst(sock) dstip = original_dst(sock)
log('Accept: %r:%r -> %r:%r.\n' % (srcip[0],srcip[1], debug1('Accept: %r:%r -> %r:%r.\n' % (srcip[0],srcip[1],
dstip[0],dstip[1])) dstip[0],dstip[1]))
if dstip == sock.getsockname(): if dstip == sock.getsockname():
log("-- ignored: that's my address!\n") debug1("-- ignored: that's my address!\n")
sock.close() sock.close()
return return
if use_server: if use_server:
@ -73,7 +75,7 @@ def _main(listener, listenport, use_server, remotename, subnets):
handlers = filter(lambda s: s.ok, handlers) handlers = filter(lambda s: s.ok, handlers)
for s in handlers: for s in handlers:
s.pre_select(r,w,x) s.pre_select(r,w,x)
log('Waiting: %d[%d,%d,%d]...\n' debug2('Waiting: %d[%d,%d,%d]...\n'
% (len(handlers), len(r), len(w), len(x))) % (len(handlers), len(r), len(w), len(x)))
(r,w,x) = select.select(r,w,x) (r,w,x) = select.select(r,w,x)
#log('r=%r w=%r x=%r\n' % (r,w,x)) #log('r=%r w=%r x=%r\n' % (r,w,x))
@ -84,7 +86,7 @@ def _main(listener, listenport, use_server, remotename, subnets):
def main(listenip, use_server, remotename, subnets): def main(listenip, use_server, remotename, subnets):
log('Starting sshuttle proxy.\n') debug1('Starting sshuttle proxy.\n')
listener = socket.socket() listener = socket.socket()
listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if listenip[1]: if listenip[1]:
@ -93,22 +95,22 @@ def main(listenip, use_server, remotename, subnets):
ports = xrange(12300,65536) ports = xrange(12300,65536)
last_e = None last_e = None
bound = False bound = False
log('Binding:') debug2('Binding:')
for port in ports: for port in ports:
log(' %d' % port) debug2(' %d' % port)
try: try:
listener.bind((listenip[0], port)) listener.bind((listenip[0], port))
bound = True bound = True
break break
except socket.error, e: except socket.error, e:
last_e = e last_e = e
log('\n') debug2('\n')
if not bound: if not bound:
assert(last_e) assert(last_e)
raise last_e raise last_e
listener.listen(10) listener.listen(10)
listenip = listener.getsockname() listenip = listener.getsockname()
log('Listening on %r.\n' % (listenip,)) debug1('Listening on %r.\n' % (listenip,))
try: try:
return _main(listener, listenip[1], use_server, remotename, subnets) return _main(listener, listenip[1], use_server, remotename, subnets)

View File

@ -1,8 +1,17 @@
import sys, os import sys, os
logprefix = '' logprefix = ''
verbose = 0
def log(s): def log(s):
sys.stdout.flush() sys.stdout.flush()
sys.stderr.write(logprefix + s) sys.stderr.write(logprefix + s)
sys.stderr.flush() sys.stderr.flush()
def debug1(s):
if verbose >= 1:
log(s)
def debug2(s):
if verbose >= 2:
log(s)

View File

@ -1,4 +1,5 @@
import subprocess, re import subprocess, re
import helpers
from helpers import * from helpers import *
@ -15,7 +16,7 @@ def chain_exists(name):
def ipt(*args): def ipt(*args):
argv = ['iptables', '-t', 'nat'] + list(args) argv = ['iptables', '-t', 'nat'] + list(args)
log('>> %s\n' % ' '.join(argv)) debug1('>> %s\n' % ' '.join(argv))
rv = subprocess.call(argv) rv = subprocess.call(argv)
if rv: if rv:
raise Exception('%r returned %d' % (argv, rv)) raise Exception('%r returned %d' % (argv, rv))

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
import sys, os, re import sys, os, re
import options, client, iptables, server import helpers, options, client, server, iptables
# list of: # list of:
@ -50,6 +50,7 @@ sshuttle --server
-- --
l,listen= transproxy to this ip address and port number [default=0] l,listen= transproxy to this ip address and port number [default=0]
r,remote= ssh hostname (and optional username) of remote sshuttle server r,remote= ssh hostname (and optional username) of remote sshuttle server
v,verbose increase debug message verbosity
noserver don't use a separate server process (mostly for debugging) noserver don't use a separate server process (mostly for debugging)
server [internal use only] server [internal use only]
iptables [internal use only] iptables [internal use only]
@ -57,6 +58,8 @@ iptables [internal use only]
o = options.Options('sshuttle', optspec) o = options.Options('sshuttle', optspec)
(opt, flags, extra) = o.parse(sys.argv[1:]) (opt, flags, extra) = o.parse(sys.argv[1:])
helpers.verbose = opt.verbose
if opt.server: if opt.server:
sys.exit(server.main()) sys.exit(server.main())
elif opt.iptables: elif opt.iptables:

View File

@ -32,7 +32,7 @@ def main():
handlers = filter(lambda s: s.ok, handlers) handlers = filter(lambda s: s.ok, handlers)
for s in handlers: for s in handlers:
s.pre_select(r,w,x) s.pre_select(r,w,x)
log('Waiting: %d[%d,%d,%d]...\n' debug2('Waiting: %d[%d,%d,%d]...\n'
% (len(handlers), len(r), len(w), len(x))) % (len(handlers), len(r), len(w), len(x)))
(r,w,x) = select.select(r,w,x) (r,w,x) = select.select(r,w,x)
#log('r=%r w=%r x=%r\n' % (r,w,x)) #log('r=%r w=%r x=%r\n' % (r,w,x))

3
ssh.py
View File

@ -1,4 +1,5 @@
import sys, os, re, subprocess, socket import sys, os, re, subprocess, socket
import helpers
def connect(rhost): def connect(rhost):
main_exe = sys.argv[0] main_exe = sys.argv[0]
@ -7,7 +8,7 @@ def connect(rhost):
if rhost == '-': if rhost == '-':
rhost = None rhost = None
if not rhost: if not rhost:
argv = ['sshuttle', '--server'] argv = ['sshuttle', '--server'] + ['-v']*(helpers.verbose or 0)
else: else:
# WARNING: shell quoting security holes are possible here, so we # WARNING: shell quoting security holes are possible here, so we
# have to be super careful. We have to use 'sh -c' because # have to be super careful. We have to use 'sh -c' because

View File

@ -55,9 +55,9 @@ class SockWrapper:
self.peername = peername or _try_peername(self.rsock) self.peername = peername or _try_peername(self.rsock)
def __del__(self): def __del__(self):
log('%r: deleting\n' % self) debug1('%r: deleting\n' % self)
if self.exc: if self.exc:
log('%r: error was: %r\n' % (self, self.exc)) debug1('%r: error was: %r\n' % (self, self.exc))
def __repr__(self): def __repr__(self):
return 'SW:%s' % (self.peername,) return 'SW:%s' % (self.peername,)
@ -68,13 +68,13 @@ class SockWrapper:
def noread(self): def noread(self):
if not self.shut_read: if not self.shut_read:
log('%r: done reading\n' % self) debug2('%r: done reading\n' % self)
self.shut_read = True self.shut_read = True
#self.rsock.shutdown(socket.SHUT_RD) # doesn't do anything anyway #self.rsock.shutdown(socket.SHUT_RD) # doesn't do anything anyway
def nowrite(self): def nowrite(self):
if not self.shut_write: if not self.shut_write:
log('%r: done writing\n' % self) debug2('%r: done writing\n' % self)
self.shut_write = True self.shut_write = True
try: try:
self.wsock.shutdown(socket.SHUT_WR) self.wsock.shutdown(socket.SHUT_WR)
@ -200,18 +200,18 @@ class Mux(Handler):
assert(len(data) <= 65535) assert(len(data) <= 65535)
p = struct.pack('!ccHHH', 'S', 'S', channel, cmd, len(data)) + data p = struct.pack('!ccHHH', 'S', 'S', channel, cmd, len(data)) + data
self.outbuf.append(p) self.outbuf.append(p)
log(' > channel=%d cmd=%s len=%d\n' debug2(' > channel=%d cmd=%s len=%d\n'
% (channel, cmd_to_name[cmd], len(data))) % (channel, cmd_to_name[cmd], len(data)))
#log('Mux: send queue is %d/%d\n' #log('Mux: send queue is %d/%d\n'
# % (len(self.outbuf), sum(len(b) for b in self.outbuf))) # % (len(self.outbuf), sum(len(b) for b in self.outbuf)))
def got_packet(self, channel, cmd, data): def got_packet(self, channel, cmd, data):
log('< channel=%d cmd=%s len=%d\n' debug2('< channel=%d cmd=%s len=%d\n'
% (channel, cmd_to_name[cmd], len(data))) % (channel, cmd_to_name[cmd], len(data)))
if cmd == CMD_PING: if cmd == CMD_PING:
self.send(0, CMD_PONG, data) self.send(0, CMD_PONG, data)
elif cmd == CMD_PONG: elif cmd == CMD_PONG:
log('received PING response\n') debug2('received PING response\n')
elif cmd == CMD_EXIT: elif cmd == CMD_EXIT:
self.ok = False self.ok = False
elif cmd == CMD_CONNECT: elif cmd == CMD_CONNECT:
@ -278,7 +278,7 @@ class MuxWrapper(SockWrapper):
self.mux = mux self.mux = mux
self.channel = channel self.channel = channel
self.mux.channels[channel] = self.got_packet self.mux.channels[channel] = self.got_packet
log('new channel: %d\n' % channel) debug2('new channel: %d\n' % channel)
def __del__(self): def __del__(self):
self.nowrite() self.nowrite()
@ -322,7 +322,7 @@ class MuxWrapper(SockWrapper):
def connect_dst(ip, port): def connect_dst(ip, port):
log('Connecting to %s:%d\n' % (ip, port)) debug2('Connecting to %s:%d\n' % (ip, port))
outsock = socket.socket() outsock = socket.socket()
outsock.setsockopt(socket.SOL_IP, socket.IP_TTL, 42) outsock.setsockopt(socket.SOL_IP, socket.IP_TTL, 42)
e = None e = None