summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvery Pennarun <apenwarr@gmail.com>2010-12-31 21:05:41 -0800
committerAvery Pennarun <apenwarr@gmail.com>2010-12-31 21:22:32 -0800
commitcca69eb49621d4a39b9011380f269a404f49e24a (patch)
tree9d20bc02118b4c467908fad380fd5f2e78931a13
parent91f65132be0733cdea9e451bc5e949f71b83121a (diff)
Don't allow proxying of connections to the proxy port.
Add some cleverness for breaking infinite loops. Previously we'd only detect it successfully if you connected to exactly the same IP as we were listening on, but that was unreliable if we're listening on 0.0.0.0 and you connected to one of the IP addresses we haven't heard of. Now, if you try to connect to our listen port on *any* IP, we try binding to that IP as a local socket; if it works, that's a local IP, and therefore it's our socket, so reject the connection. If it doesn't work, it's a remote IP, so forward it along. Thanks to 'tass' on github for noticing the problem.
-rw-r--r--client.py19
1 files changed, 17 insertions, 2 deletions
diff --git a/client.py b/client.py
index 2a9d835..a1ceaae 100644
--- a/client.py
+++ b/client.py
@@ -5,6 +5,21 @@ from ssnet import SockWrapper, Handler, Proxy, Mux, MuxWrapper
from helpers import *
+def _islocal(ip):
+ sock = socket.socket()
+ try:
+ try:
+ sock.bind((ip, 0))
+ except socket.error, e:
+ if e.args[0] == errno.EADDRNOTAVAIL:
+ return False # not a local IP
+ else:
+ raise
+ finally:
+ sock.close()
+ return True # it's a local IP, or there would have been an error
+
+
def original_dst(sock):
try:
SO_ORIGINAL_DST = 80
@@ -108,7 +123,7 @@ def _main(listener, fw, ssh_cmd, remotename, python, seed_hosts, auto_nets):
try:
(serverproc, serversock) = ssh.connect(ssh_cmd, remotename, python)
except socket.error, e:
- if e.errno == errno.EPIPE:
+ if e.args[0] == errno.EPIPE:
raise Fatal("failed to establish ssh session")
else:
raise
@@ -157,7 +172,7 @@ def _main(listener, fw, ssh_cmd, remotename, python, seed_hosts, auto_nets):
dstip = original_dst(sock)
debug1('Accept: %s:%r -> %s:%r.\n' % (srcip[0],srcip[1],
dstip[0],dstip[1]))
- if dstip == listener.getsockname():
+ if dstip[1] == listener.getsockname()[1] and _islocal(dstip[0]):
debug1("-- ignored: that's my address!\n")
sock.close()
return