Commit cca69eb4 authored by Avery Pennarun's avatar Avery Pennarun

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.
parent 91f65132
...@@ -5,6 +5,21 @@ from ssnet import SockWrapper, Handler, Proxy, Mux, MuxWrapper ...@@ -5,6 +5,21 @@ from ssnet import SockWrapper, Handler, Proxy, Mux, MuxWrapper
from helpers import * 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): def original_dst(sock):
try: try:
SO_ORIGINAL_DST = 80 SO_ORIGINAL_DST = 80
...@@ -108,7 +123,7 @@ def _main(listener, fw, ssh_cmd, remotename, python, seed_hosts, auto_nets): ...@@ -108,7 +123,7 @@ def _main(listener, fw, ssh_cmd, remotename, python, seed_hosts, auto_nets):
try: try:
(serverproc, serversock) = ssh.connect(ssh_cmd, remotename, python) (serverproc, serversock) = ssh.connect(ssh_cmd, remotename, python)
except socket.error, e: except socket.error, e:
if e.errno == errno.EPIPE: if e.args[0] == errno.EPIPE:
raise Fatal("failed to establish ssh session") raise Fatal("failed to establish ssh session")
else: else:
raise raise
...@@ -157,7 +172,7 @@ def _main(listener, fw, ssh_cmd, remotename, python, seed_hosts, auto_nets): ...@@ -157,7 +172,7 @@ def _main(listener, fw, ssh_cmd, remotename, python, seed_hosts, auto_nets):
dstip = original_dst(sock) dstip = original_dst(sock)
debug1('Accept: %s:%r -> %s:%r.\n' % (srcip[0],srcip[1], debug1('Accept: %s:%r -> %s:%r.\n' % (srcip[0],srcip[1],
dstip[0],dstip[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") debug1("-- ignored: that's my address!\n")
sock.close() sock.close()
return return
......
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