diff --git a/dotfiles/.local/bin/commands b/dotfiles/.local/bin/commands index baf2ac0..d46e713 100755 --- a/dotfiles/.local/bin/commands +++ b/dotfiles/.local/bin/commands @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import functools import re +import tempfile import signal import datetime import sys @@ -1250,6 +1251,130 @@ def suspend_timer(argv): print("suspend computer at %s" % t1.isoformat()) subprocess.check_call(["systemctl", "suspend"]); +def socat_ssh(argv): + parser = optparse.OptionParser() + parser.add_option( + '--local_port', + dest='local_port', + default=None, + type=int, + ) + parser.add_option( + '--ssh_key', + dest='ssh_key', + default=None, + type=str, + ) + parser.add_option( + '--socat_verbose', + dest='socat_verbose', + action='store_true', + default=False, + ) + parser.add_option( + '--ssh_host', + dest='ssh_host', + default=None, + type=str, + ) + parser.add_option( + '--target_port', + dest='target_port', + default=None, + type=int, + ) + parser.add_option( + '--gateway_command', + dest='gateway_command', + default=None, + type=str, + help=( + 'a shell command that forwards ssh socket data ' + 'somewhere else, like ' + 'busybox nc 127.0.0.1 $(cat remote-ssh.port)' + ), + ) + options, args = parser.parse_args(argv) + + ssh_command = ['ssh', '-T'] + + if not options.ssh_key is None: + subprocess.check_call(['ssh-add', options.ssh_key]) + ssh_command.extend([ + '-i', options.ssh_key, + ]) + + if not options.ssh_host is None: + ssh_command.extend([options.ssh_host]) + + restart = False + + def on_interrupt(*args, **kwargs): + nonlocal restart + restart = True + + + socat_command = ['socat'] + + if options.socat_verbose: + socat_command.extend(['-v']) + + socat_command.extend([ + 'tcp-listen:%d,fork,bind=127.0.0.1' % ( + options.local_port, + ), + ]) + + signal.signal( + signal.SIGINT, + on_interrupt, + ) + signal.signal( + signal.SIGTERM, + on_interrupt, + ) + + gateway = None + p = None + + while True: + if gateway is None: + gateway = tempfile.NamedTemporaryFile(suffix='.sh', mode='w') + gateway.write( + r''' + exec %s + ''' % ' '.join( + ssh_command + options.gateway_command + ) + ) + gateway.flush() + + if p is None: + p = subprocess.Popen( + socat_command + [ + 'EXEC:sh %s' % gateway.name, + ] + ) + + time.sleep(1) + + if restart: + try: + p.terminate() + p.wait(10) + except: + p.kill() + + restart = False + + if not p.poll() is None: + p = None + + if not gateway is None: + os.path.unlink(gateway.name) + if not p is None: + p.terminate() + def share_wifi(argv): parser = optparse.OptionParser() @@ -1522,6 +1647,8 @@ def commands_cli(): ) elif sys.argv[1] == 'share-wifi': share_wifi(sys.argv[2:]) + elif sys.argv[1] == 'socat-ssh': + socat_ssh(sys.argv[2:]) elif sys.argv[1] == 'suspend-timer': suspend_timer(sys.argv[2:]) elif sys.argv[1] == 'desktop-services':