diff options
Diffstat (limited to 'sshuttle')
-rw-r--r-- | sshuttle/client.py | 4 | ||||
-rw-r--r-- | sshuttle/firewall.py | 31 |
2 files changed, 27 insertions, 8 deletions
diff --git a/sshuttle/client.py b/sshuttle/client.py index f9bf04b..abc3836 100644 --- a/sshuttle/client.py +++ b/sshuttle/client.py @@ -298,8 +298,8 @@ class FirewallClient: else: user = b'%d' % self.user - self.pfile.write(b'GO %d %s %s\n' % - (udp, user, bytes(self.tmark, 'ascii'))) + self.pfile.write(b'GO %d %s %s %d\n' % + (udp, user, bytes(self.tmark, 'ascii'), os.getpid())) self.pfile.flush() line = self.pfile.readline() diff --git a/sshuttle/firewall.py b/sshuttle/firewall.py index d3806cd..fb9471d 100644 --- a/sshuttle/firewall.py +++ b/sshuttle/firewall.py @@ -13,7 +13,7 @@ from sshuttle.helpers import debug1, debug2, Fatal from sshuttle.methods import get_auto_method, get_method HOSTSFILE = '/etc/hosts' - +sshuttle_pid = None def rewrite_etc_hosts(hostmap, port): BAKFILE = '%s.sbak' % HOSTSFILE @@ -55,6 +55,23 @@ def restore_etc_hosts(hostmap, port): debug2('undoing /etc/hosts changes.') rewrite_etc_hosts({}, port) +def firewall_exit(signum, frame): + # The typical sshuttle exit is that the main sshuttle process + # exits, closes file descriptors it uses, and the firewall process + # notices that it can't read from stdin anymore and exits + # (cleaning up firewall rules). + # + # However, in some cases, Ctrl+C might get sent to the firewall + # process. This might caused if someone manually tries to kill the + # firewall process, or if sshuttle was started using sudo's use_pty option + # and they try to exit by pressing Ctrl+C. Here, we forward the + # Ctrl+C/SIGINT to the main sshuttle process which should trigger + # the typical exit process as described above. + global sshuttle_pid + if sshuttle_pid: + debug1("Relaying SIGINT to sshuttle process %d\n" % sshuttle_pid) + os.kill(sshuttle_pid, signal.SIGINT) + # Isolate function that needs to be replaced for tests def setup_daemon(): @@ -65,8 +82,8 @@ def setup_daemon(): # disappears; we still have to clean up. signal.signal(signal.SIGHUP, signal.SIG_IGN) signal.signal(signal.SIGPIPE, signal.SIG_IGN) - signal.signal(signal.SIGTERM, signal.SIG_IGN) - signal.signal(signal.SIGINT, signal.SIG_IGN) + signal.signal(signal.SIGTERM, firewall_exit) + signal.signal(signal.SIGINT, firewall_exit) # ctrl-c shouldn't be passed along to me. When the main sshuttle dies, # I'll die automatically. @@ -230,12 +247,14 @@ def main(method_name, syslog): raise Fatal('expected GO but got %r' % line) _, _, args = line.partition(" ") - udp, user, tmark = args.strip().split(" ", 2) + global sshuttle_pid + udp, user, tmark, sshuttle_pid = args.strip().split(" ", 3) udp = bool(int(udp)) + sshuttle_pid = int(sshuttle_pid) if user == '-': user = None - debug2('Got udp: %r, user: %r, tmark: %s' % - (udp, user, tmark)) + debug2('Got udp: %r, user: %r, tmark: %s, sshuttle_pid: %d' % + (udp, user, tmark, sshuttle_pid)) subnets_v6 = [i for i in subnets if i[0] == socket.AF_INET6] nslist_v6 = [i for i in nslist if i[0] == socket.AF_INET6] |