Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

auto-hosts: don't add hosts that aren't being routed by sshuttle.

I've been meaning to add this patch for a long time, but it's especially
important once we add FQDN support to --auto-hosts.  Basically, auto-hosts
will still discover all the hostnames it can, but we'll only add them to
/etc/hosts if their IP address is in one of the routed subnet ranges.  That
prevents polluting the /etc/hosts file with cruft.
  • Loading branch information...
commit 432e98cad5eac07bb150ae6c5fb785d27c26d963 1 parent 29d2e06
@apenwarr authored
Showing with 25 additions and 13 deletions.
  1. +16 −2 firewall.py
  2. +7 −0 helpers.py
  3. +2 −11 server.py
View
18 firewall.py
@@ -430,6 +430,19 @@ def restore_etc_hosts(port):
rewrite_etc_hosts(port)
+def _mask(ip, width):
+ nip = struct.unpack('!I', socket.inet_aton(ip))[0]
+ masked = nip & shl(shl(1, width) - 1, 32-width)
+ return socket.inet_ntoa(struct.pack('!I', masked))
+
+
+def ip_in_subnets(ip, subnets):
+ for swidth,sexclude,snet in sorted(subnets, reverse=True):
+ if _mask(snet, swidth) == _mask(ip, swidth):
+ return not sexclude
+ return False
+
+
# This is some voodoo for setting up the kernel's transparent
# proxying stuff. If subnets is empty, we just delete our sshuttle rules;
# otherwise we delete it, then make them from scratch.
@@ -521,8 +534,9 @@ def main(port, dnsport, syslog):
line = sys.stdin.readline(128)
if line.startswith('HOST '):
(name,ip) = line[5:].strip().split(',', 1)
- hostmap[name] = ip
- rewrite_etc_hosts(port)
+ if ip_in_subnets(ip, subnets):
+ hostmap[name] = ip
+ rewrite_etc_hosts(port)
elif line:
raise Fatal('expected EOF, got %r' % line)
else:
View
7 helpers.py
@@ -78,3 +78,10 @@ def islocal(ip):
return True # it's a local IP, or there would have been an error
+def shl(n, bits):
+ # we use our own implementation of left-shift because
+ # results may be different between older and newer versions
+ # of python for numbers like 1<<32. We use long() because
+ # int(2**32) doesn't work in older python, which has limited
+ # int sizes.
+ return n * long(2**bits)
View
13 server.py
@@ -37,20 +37,11 @@ def _maskbits(netmask):
if not netmask:
return 32
for i in range(32):
- if netmask[0] & _shl(1, i):
+ if netmask[0] & shl(1, i):
return 32-i
return 0
-def _shl(n, bits):
- # we use our own implementation of left-shift because
- # results may be different between older and newer versions
- # of python for numbers like 1<<32. We use long() because
- # int(2**32) doesn't work in older python, which has limited
- # int sizes.
- return n * long(2**bits)
-
-
def _list_routes():
argv = ['netstat', '-rn']
p = ssubprocess.Popen(argv, stdout=ssubprocess.PIPE)
@@ -63,7 +54,7 @@ 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)
+ ip = ipw[0] & shl(shl(1, width) - 1, 32-width)
routes.append((socket.inet_ntoa(struct.pack('!I', ip)), width))
rv = p.wait()
if rv != 0:
Please sign in to comment.
Something went wrong with that request. Please try again.