Last active
December 25, 2015 04:29
-
-
Save ZhanruiLiang/6917556 to your computer and use it in GitHub Desktop.
More advanced than the older version.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/python2 | |
import pexpect | |
import os, sys | |
from time import sleep | |
CONFIG_PATH = os.path.expanduser('~/.fkgfw_config') | |
CHECK_DURATION = 5 | |
FIFO = '/tmp/fkgfw_fifo' | |
class Proxy: | |
""" | |
Commands: | |
> quit | |
> reconnect | |
Example config: | |
{ | |
'addr':'myvps.com', | |
'user':'bobby', | |
'port':'22', | |
'passwd':'secret', | |
'local_port': 7070, | |
'ssh_config_path': os.path.expanduser('~/.fkgfw_ssh_config'), | |
} | |
Default config path: ~/.fkgfw_config | |
Custom config: | |
Run: > fkgfw {/path/to/config_file} | |
""" | |
NEED = ['user', 'passwd', 'local_port', 'addr', 'port', 'ssh_config_path'] | |
def __init__(self, info): | |
for attr in self.NEED: | |
if attr not in info: | |
raise Exception('Attribute %s not in provided info' % attr) | |
self.info = info | |
self._quit = False | |
self.ssh = None | |
def connect(self): | |
info = self.info | |
cmd = 'ssh -N -D %(local_port)s %(user)s@%(addr)s -p %(port)s -F %(ssh_config_path)s' % info | |
print cmd | |
while 1: | |
print 'Connecting...' | |
if self.ssh: | |
self.ssh.terminate() | |
ssh = self.ssh = pexpect.spawn(cmd) | |
e = ssh.expect(['password:', '(yes/no)', pexpect.EOF]) | |
if e == 0: | |
ssh.sendline(info['passwd']) | |
print 'Sent password' | |
return self | |
elif e == 1: | |
ssh.sendline('yes') | |
elif e == 2: | |
print 'Received EOF' | |
sleep(0.5) | |
return self | |
def keep(self): | |
os.mkfifo(FIFO) | |
try: | |
while not self._quit: | |
print 'Ready for command' | |
command = open(FIFO).readline().strip() | |
print 'recv:', command | |
if command == 'quit': | |
self._quit = True | |
elif command == 'reconnect': | |
self.connect() | |
else: | |
print 'Unknown:', command | |
finally: | |
os.remove(FIFO) | |
if __name__ == '__main__': | |
configPath = sys.argv[1] if len(sys.argv) > 1 else CONFIG_PATH | |
info = eval(open(configPath).read()) | |
Proxy(info).connect().keep() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment