mirror of
https://github.com/sshuttle/sshuttle.git
synced 2025-07-05 17:20:35 +02:00
Compare commits
9 Commits
sshuttle-0
...
sshuttle-0
Author | SHA1 | Date | |
---|---|---|---|
a8b71f6387 | |||
4bfcd7091d | |||
bd489b3319 | |||
8ab5ef283d | |||
e67208a294 | |||
7859be13c2 | |||
f313d50690 | |||
15e26d2e0e | |||
e2ec475de3 |
@ -72,7 +72,7 @@ This is how you use it:
|
|||||||
|
|
||||||
- If you would also like your DNS queries to be proxied
|
- If you would also like your DNS queries to be proxied
|
||||||
through the DNS server of the server you are connect to:
|
through the DNS server of the server you are connect to:
|
||||||
<tt>./sshuttle --dns -rvv username@sshserver 0/0</tt>
|
<tt>./sshuttle --dns -vvr username@sshserver 0/0</tt>
|
||||||
|
|
||||||
The above is probably what you want to use to prevent
|
The above is probably what you want to use to prevent
|
||||||
local network attacks such as Firesheep and friends.
|
local network attacks such as Firesheep and friends.
|
||||||
|
116
client.py
116
client.py
@ -175,6 +175,65 @@ class FirewallClient:
|
|||||||
raise Fatal('cleanup: %r returned %d' % (self.argv, rv))
|
raise Fatal('cleanup: %r returned %d' % (self.argv, rv))
|
||||||
|
|
||||||
|
|
||||||
|
def onaccept(listener, mux, handlers):
|
||||||
|
global _extra_fd
|
||||||
|
try:
|
||||||
|
sock,srcip = listener.accept()
|
||||||
|
except socket.error, e:
|
||||||
|
if e.args[0] in [errno.EMFILE, errno.ENFILE]:
|
||||||
|
debug1('Rejected incoming connection: too many open files!\n')
|
||||||
|
# free up an fd so we can eat the connection
|
||||||
|
os.close(_extra_fd)
|
||||||
|
try:
|
||||||
|
sock,srcip = listener.accept()
|
||||||
|
sock.close()
|
||||||
|
finally:
|
||||||
|
_extra_fd = os.open('/dev/null', os.O_RDONLY)
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
dstip = original_dst(sock)
|
||||||
|
debug1('Accept: %s:%r -> %s:%r.\n' % (srcip[0],srcip[1],
|
||||||
|
dstip[0],dstip[1]))
|
||||||
|
if dstip[1] == listener.getsockname()[1] and islocal(dstip[0]):
|
||||||
|
debug1("-- ignored: that's my address!\n")
|
||||||
|
sock.close()
|
||||||
|
return
|
||||||
|
chan = mux.next_channel()
|
||||||
|
if not chan:
|
||||||
|
log('warning: too many open channels. Discarded connection.\n')
|
||||||
|
sock.close()
|
||||||
|
return
|
||||||
|
mux.send(chan, ssnet.CMD_CONNECT, '%s,%s' % dstip)
|
||||||
|
outwrap = MuxWrapper(mux, chan)
|
||||||
|
handlers.append(Proxy(SockWrapper(sock, sock), outwrap))
|
||||||
|
|
||||||
|
|
||||||
|
dnsreqs = {}
|
||||||
|
def dns_done(chan, data):
|
||||||
|
peer,sock,timeout = dnsreqs.get(chan) or (None,None,None)
|
||||||
|
debug3('dns_done: channel=%r peer=%r\n' % (chan, peer))
|
||||||
|
if peer:
|
||||||
|
del dnsreqs[chan]
|
||||||
|
debug3('doing sendto %r\n' % (peer,))
|
||||||
|
sock.sendto(data, peer)
|
||||||
|
|
||||||
|
|
||||||
|
def ondns(listener, mux, handlers):
|
||||||
|
pkt,peer = listener.recvfrom(4096)
|
||||||
|
now = time.time()
|
||||||
|
if pkt:
|
||||||
|
debug1('DNS request from %r: %d bytes\n' % (peer, len(pkt)))
|
||||||
|
chan = mux.next_channel()
|
||||||
|
dnsreqs[chan] = peer,listener,now+30
|
||||||
|
mux.send(chan, ssnet.CMD_DNS_REQ, pkt)
|
||||||
|
mux.channels[chan] = lambda cmd,data: dns_done(chan,data)
|
||||||
|
for chan,(peer,sock,timeout) in dnsreqs.items():
|
||||||
|
if timeout < now:
|
||||||
|
del dnsreqs[chan]
|
||||||
|
debug3('Remaining DNS requests: %d\n' % len(dnsreqs))
|
||||||
|
|
||||||
|
|
||||||
def _main(listener, fw, ssh_cmd, remotename, python, latency_control,
|
def _main(listener, fw, ssh_cmd, remotename, python, latency_control,
|
||||||
dnslistener, seed_hosts, auto_nets,
|
dnslistener, seed_hosts, auto_nets,
|
||||||
syslog, daemon):
|
syslog, daemon):
|
||||||
@ -255,63 +314,10 @@ def _main(listener, fw, ssh_cmd, remotename, python, latency_control,
|
|||||||
fw.sethostip(name, ip)
|
fw.sethostip(name, ip)
|
||||||
mux.got_host_list = onhostlist
|
mux.got_host_list = onhostlist
|
||||||
|
|
||||||
def onaccept():
|
handlers.append(Handler([listener], lambda: onaccept(listener, mux, handlers)))
|
||||||
global _extra_fd
|
|
||||||
try:
|
|
||||||
sock,srcip = listener.accept()
|
|
||||||
except socket.error, e:
|
|
||||||
if e.args[0] in [errno.EMFILE, errno.ENFILE]:
|
|
||||||
debug1('Rejected incoming connection: too many open files!\n')
|
|
||||||
# free up an fd so we can eat the connection
|
|
||||||
os.close(_extra_fd)
|
|
||||||
try:
|
|
||||||
sock,srcip = listener.accept()
|
|
||||||
sock.close()
|
|
||||||
finally:
|
|
||||||
_extra_fd = os.open('/dev/null', os.O_RDONLY)
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
raise
|
|
||||||
dstip = original_dst(sock)
|
|
||||||
debug1('Accept: %s:%r -> %s:%r.\n' % (srcip[0],srcip[1],
|
|
||||||
dstip[0],dstip[1]))
|
|
||||||
if dstip[1] == listener.getsockname()[1] and islocal(dstip[0]):
|
|
||||||
debug1("-- ignored: that's my address!\n")
|
|
||||||
sock.close()
|
|
||||||
return
|
|
||||||
chan = mux.next_channel()
|
|
||||||
if not chan:
|
|
||||||
log('warning: too many open channels. Discarded connection.\n')
|
|
||||||
sock.close()
|
|
||||||
return
|
|
||||||
mux.send(chan, ssnet.CMD_CONNECT, '%s,%s' % dstip)
|
|
||||||
outwrap = MuxWrapper(mux, chan)
|
|
||||||
handlers.append(Proxy(SockWrapper(sock, sock), outwrap))
|
|
||||||
handlers.append(Handler([listener], onaccept))
|
|
||||||
|
|
||||||
dnsreqs = {}
|
|
||||||
def dns_done(chan, data):
|
|
||||||
peer,timeout = dnsreqs.get(chan) or (None,None)
|
|
||||||
debug3('dns_done: channel=%r peer=%r\n' % (chan, peer))
|
|
||||||
if peer:
|
|
||||||
del dnsreqs[chan]
|
|
||||||
debug3('doing sendto %r\n' % (peer,))
|
|
||||||
dnslistener.sendto(data, peer)
|
|
||||||
def ondns():
|
|
||||||
pkt,peer = dnslistener.recvfrom(4096)
|
|
||||||
now = time.time()
|
|
||||||
if pkt:
|
|
||||||
debug1('DNS request from %r: %d bytes\n' % (peer, len(pkt)))
|
|
||||||
chan = mux.next_channel()
|
|
||||||
dnsreqs[chan] = peer,now+30
|
|
||||||
mux.send(chan, ssnet.CMD_DNS_REQ, pkt)
|
|
||||||
mux.channels[chan] = lambda cmd,data: dns_done(chan,data)
|
|
||||||
for chan,(peer,timeout) in dnsreqs.items():
|
|
||||||
if timeout < now:
|
|
||||||
del dnsreqs[chan]
|
|
||||||
debug3('Remaining DNS requests: %d\n' % len(dnsreqs))
|
|
||||||
if dnslistener:
|
if dnslistener:
|
||||||
handlers.append(Handler([dnslistener], ondns))
|
handlers.append(Handler([dnslistener], lambda: ondns(dnslistener, mux, handlers)))
|
||||||
|
|
||||||
if seed_hosts != None:
|
if seed_hosts != None:
|
||||||
debug1('seed_hosts: %r\n' % seed_hosts)
|
debug1('seed_hosts: %r\n' % seed_hosts)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import sys, os, socket
|
import sys, os, socket, errno
|
||||||
|
|
||||||
logprefix = ''
|
logprefix = ''
|
||||||
verbose = 0
|
verbose = 0
|
||||||
|
11
ssnet.py
11
ssnet.py
@ -152,6 +152,17 @@ class SockWrapper:
|
|||||||
debug3('%r: fixed connect result: %s\n' % (self, e))
|
debug3('%r: fixed connect result: %s\n' % (self, e))
|
||||||
if e.args[0] in [errno.EINPROGRESS, errno.EALREADY]:
|
if e.args[0] in [errno.EINPROGRESS, errno.EALREADY]:
|
||||||
pass # not connected yet
|
pass # not connected yet
|
||||||
|
elif e.args[0] == 0:
|
||||||
|
# connected successfully (weird Linux bug?)
|
||||||
|
# Sometimes Linux seems to return EINVAL when it isn't
|
||||||
|
# invalid. This *may* be caused by a race condition
|
||||||
|
# between connect() and getsockopt(SO_ERROR) (ie. it
|
||||||
|
# finishes connecting in between the two, so there is no
|
||||||
|
# longer an error). However, I'm not sure of that.
|
||||||
|
#
|
||||||
|
# I did get at least one report that the problem went away
|
||||||
|
# when we added this, however.
|
||||||
|
self.connect_to = None
|
||||||
elif e.args[0] == errno.EISCONN:
|
elif e.args[0] == errno.EISCONN:
|
||||||
# connected successfully (BSD)
|
# connected successfully (BSD)
|
||||||
self.connect_to = None
|
self.connect_to = None
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
exec >&2
|
exec >&2
|
||||||
redo-ifchange runpython.c
|
redo-ifchange runpython.c
|
||||||
ARCHES=""
|
ARCHES=""
|
||||||
|
printf "Platforms: "
|
||||||
for d in /usr/libexec/gcc/darwin/*; do
|
for d in /usr/libexec/gcc/darwin/*; do
|
||||||
ARCHES="$ARCHES -arch $(basename $d)"
|
PLAT=$(basename "$d")
|
||||||
|
[ "$PLAT" != "ppc64" ] || continue # fails for some reason on my Mac
|
||||||
|
ARCHES="$ARCHES -arch $PLAT"
|
||||||
|
printf "$PLAT "
|
||||||
done
|
done
|
||||||
|
printf "\n"
|
||||||
gcc $ARCHES \
|
gcc $ARCHES \
|
||||||
-Wall -o $3 runpython.c \
|
-Wall -o $3 runpython.c \
|
||||||
-I/usr/include/python2.5 \
|
-I/usr/include/python2.5 \
|
||||||
|
@ -3,6 +3,7 @@ import my
|
|||||||
|
|
||||||
|
|
||||||
configchange_callback = setconnect_callback = None
|
configchange_callback = setconnect_callback = None
|
||||||
|
objc_validator = objc.signature('@@:N^@o^@')
|
||||||
|
|
||||||
|
|
||||||
def config_changed():
|
def config_changed():
|
||||||
@ -39,7 +40,7 @@ class SshuttleNet(NSObject):
|
|||||||
def setSubnet_(self, v):
|
def setSubnet_(self, v):
|
||||||
self._k_subnet = v
|
self._k_subnet = v
|
||||||
config_changed()
|
config_changed()
|
||||||
@objc.accessor
|
@objc_validator
|
||||||
def validateSubnet_error_(self, value, error):
|
def validateSubnet_error_(self, value, error):
|
||||||
#print 'validateSubnet!'
|
#print 'validateSubnet!'
|
||||||
return True, _validate_ip(value), error
|
return True, _validate_ip(value), error
|
||||||
@ -49,7 +50,7 @@ class SshuttleNet(NSObject):
|
|||||||
def setWidth_(self, v):
|
def setWidth_(self, v):
|
||||||
self._k_width = v
|
self._k_width = v
|
||||||
config_changed()
|
config_changed()
|
||||||
@objc.accessor
|
@objc_validator
|
||||||
def validateWidth_error_(self, value, error):
|
def validateWidth_error_(self, value, error):
|
||||||
#print 'validateWidth!'
|
#print 'validateWidth!'
|
||||||
return True, _validate_width(value), error
|
return True, _validate_width(value), error
|
||||||
@ -118,7 +119,7 @@ class SshuttleServer(NSObject):
|
|||||||
self._k_host = v
|
self._k_host = v
|
||||||
self.setTitle_(None)
|
self.setTitle_(None)
|
||||||
config_changed()
|
config_changed()
|
||||||
@objc.accessor
|
@objc_validator
|
||||||
def validateHost_error_(self, value, error):
|
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('-'):
|
while value.startswith('-'):
|
||||||
|
Reference in New Issue
Block a user