Page MenuHomePhabricator

No OneTemporary

diff --git a/sockpy.py b/sockpy.py
new file mode 100755
--- /dev/null
+++ b/sockpy.py
@@ -0,0 +1,128 @@
+#!/usr/bin/env python2
+
+import requests
+import simplejson as json
+import threading
+from optparse import OptionParser
+import socket
+import select
+import uuid
+import time
+import sys
+
+MAXLEN = 16384
+
+parser = OptionParser()
+parser.add_option("-c", "--connect", dest="connect", help="connect local port to remote host and port, use localPort:remoteHost:remotePort; separate multiple hosts by \",\"", default="")
+parser.add_option("-s", "--server", dest="host", help="the host running the sockpy server application", default="http://127.0.0.1:8051")
+parser.add_option("-u", "--user", dest="user", help="the username for logging into the remote sockpy server", default="admin")
+parser.add_option("-p", "--password", dest="password", help="the password for logging into the remote sockpy server", default="admin")
+
+(opts, args) = parser.parse_args()
+
+class SocketWrapper(threading.Thread):
+ def __init__(self, host, user, password, connStr):
+ self.url = host
+ self.user = user
+ self.password = password
+ connArr = connStr.split(":")
+ self.localPort = int(connArr[0])
+ self.remotePort = connArr[-1]
+ self.error = False
+ self.connected = False
+ self.sock = None
+ self.uid = str(uuid.uuid4())
+ self.clientSocket = None
+ if len(connArr) == 3:
+ self.remoteHost = connArr[1]
+ else:
+ self.remoteHost = "127.0.0.1"
+ threading.Thread.__init__(self)
+
+ def run(self):
+ self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ self.sock.bind(('', self.localPort))
+ self.sock.listen(5)
+ self.clientSocket, addr = self.sock.accept()
+ if self.connect():
+ if self.login():
+ self.connectRemote()
+ while self.connected:
+ self.sendRemote(self.recvLocal())
+ self.sendLocal(self.recvRemote())
+
+ def connect(self):
+ payload = {}
+ payload["command"] = "status"
+ payload["payload"] = json.dumps({})
+ payload["uid"] = self.uid
+ r = requests.post(self.url, data=payload)
+ reply = json.loads(r.content)
+ return True # FIXME: requests will fail if connect is unsuccessful
+
+ def login(self):
+ payload = {}
+ payload["command"] = "login"
+ payload["uid"] = self.uid
+ payload["payload"] = json.dumps({"username" : self.user, "password" : self.password})
+ r = requests.post(self.url, data=payload)
+ reply = json.loads(r.content)
+ if reply["status"]:
+ return True
+ else:
+ return False
+
+ def connectRemote(self):
+ payload = {}
+ payload["command"] = "connect"
+ payload["payload"] = json.dumps({"host" : self.remoteHost, "port" : self.remotePort})
+ payload["uid"] = self.uid
+ r = requests.post(self.url, data=payload)
+ reply = json.loads(r.content)
+ if reply["connected"]:
+ self.connected = True
+ return True
+ else:
+ self.connected = False
+ return False
+
+ def recvLocal(self):
+ readable, writable, errored = select.select([self.clientSocket], [], [], 0)
+ if self.clientSocket in readable:
+ data = self.clientSocket.recv(MAXLEN)
+ else:
+ data = ""
+ return data
+
+ def sendLocal(self, data):
+ read, writable, errored = select.select([], [self.clientSocket], [], 0)
+ if self.clientSocket in writable and data != "":
+ self.clientSocket.sendall(data)
+
+ def recvRemote(self):
+ payload = {}
+ payload["command"] = "recv"
+ payload["payload"] = json.dumps({})
+ payload["uid"] = self.uid
+ r = requests.post(self.url, data=payload)
+ reply = json.loads(r.content)
+ return reply["data"]
+
+ def sendRemote(self, data):
+ if data != "":
+ payload = {}
+ payload["command"] = "send"
+ payload["payload"] = json.dumps({"data" : data})
+ payload["uid"] = self.uid
+ r = requests.post(self.url, data=payload)
+
+if __name__ == "__main__":
+ if opts.connect == "":
+ sys.exit()
+ hostList = opts.connect.split(",")
+ sockConns = []
+ for connStr in hostList:
+ sockConns.append(SocketWrapper(opts.host, opts.user, opts.password, connStr))
+ sockConns[-1].start()
+ while True:
+ time.sleep(1)
diff --git a/sockpy.wsgi b/sockpy.wsgi
new file mode 100755
--- /dev/null
+++ b/sockpy.wsgi
@@ -0,0 +1,135 @@
+#!/usr/bin/env python2
+
+from cgi import parse_qs, escape
+import simplejson as json
+import socket
+import select
+import time
+
+MAXLEN = 16348
+gbl_keys = {}
+
+def ExpireOldUIDs():
+ currTime = time.time()
+ for uid in gbl_keys.keys():
+ if gbl_keys[uid].has_key("timeStamp"):
+ if currTime - gbl_keys[uid]["timeStamp"] > 3600:
+ del gbl_keys[uid]
+
+def GetValueForUID(uid, key):
+ if gbl_keys.has_key(uid):
+ if gbl_keys[uid].has_key(key):
+ gbl_keys[uid]["timeStamp"] = time.time()
+ return gbl_keys[uid][key]
+ return False
+
+def SetValueForUID(uid, key, val):
+ if not gbl_keys.has_key(uid):
+ gbl_keys[uid] = {}
+ gbl_keys[uid][key] = val
+ gbl_keys[uid]["timeStamp"] = time.time()
+
+
+def application(environ, start_response):
+
+ # the environment variable CONTENT_LENGTH may be empty or missing
+ try:
+ request_body_size = int(environ.get('CONTENT_LENGTH', 0))
+ except (ValueError):
+ request_body_size = 0
+
+ # When the method is POST the query string will be sent
+ # in the HTTP request body which is passed by the WSGI server
+ # in the file like wsgi.input environment variable.
+ request_body = environ['wsgi.input'].read(request_body_size)
+ d = parse_qs(request_body)
+
+ command = escape(d.get('command', [''])[0])
+ uid = escape(d.get('uid', [''])[0])
+ payload = json.loads(d.get('payload', [''])[0])
+
+ response_array = {}
+
+ if command == 'status':
+ print "status"
+ response_array['status'] = GetValueForUID(uid, 'status')
+ elif command == 'login':
+ print "login"
+ if payload['username'] == "admin" and payload['password'] == "admin":
+ print "success"
+ response_array['status'] = True
+ SetValueForUID(uid, 'status', True)
+ else:
+ print "fail"
+ response_array['status'] = False
+ elif command == 'send':
+ print "send"
+ if GetValueForUID(uid, 'connected') and GetValueForUID(uid, 'status'):
+ data = payload['data']
+ sock = GetValueForUID(uid, 'socket')
+ readable, writable, errored = select.select([], [sock], [sock], 0)
+ if sock in writable:
+ sock.sendall(data)
+ response_array['status'] = True
+ elif sock in errored:
+ response_array['status'] = False
+ else:
+ response_array['status'] = False
+ elif command == 'connect':
+ print "connect"
+ if GetValueForUID(uid, 'status') and not GetValueForUID(uid, 'connected'):
+ host = payload['host']
+ port = payload['port']
+ print "host: " + host
+ print "port: " + port
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ s.connect((host, int(port)))
+ #s.setblocking(0)
+ SetValueForUID(uid, 'socket', s)
+ SetValueForUID(uid, 'connected', True)
+ response_array['status'] = True
+ response_array['connected'] = True
+ else:
+ response_array['status'] = False
+ response_array['connected'] = False
+ elif command == 'quit':
+ print "quit"
+ if GetValueForUID(uid, 'connected') and GetValueForUID(uid, 'status'):
+ s.close()
+ SetValueForUID(uid, 'connected', False)
+ response_array['status'] = True
+ elif command == 'recv':
+ print "recv"
+ if GetValueForUID(uid, 'connected') and GetValueForUID(uid, 'status'):
+ sock = GetValueForUID(uid, 'socket')
+ readable, writable, errored = select.select([sock], [], [sock], 0)
+ if sock in readable:
+ data = sock.recv(MAXLEN)
+ response_array['status'] = True
+ elif sock in errored:
+ response_array['status'] = False
+ data = ""
+ else:
+ data = ""
+ response_array['status'] = True
+ response_array['data'] = data
+ else:
+ response_array['status'] = False
+
+ response_body = json.dumps(response_array)
+ print response_body
+
+ status = '200 OK'
+
+ response_headers = [('Content-Type', 'text/html'),
+ ('Content-Length', str(len(response_body)))]
+ start_response(status, response_headers)
+
+ ExpireOldUIDs()
+
+ return [response_body]
+
+if __name__ == "__main__":
+ from wsgiref.simple_server import make_server
+ httpd = make_server('localhost', 8051, application)
+ httpd.serve_forever()

File Metadata

Mime Type
text/x-diff
Expires
Fri, Nov 22, 8:59 PM (4 d, 7 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
530068
Default Alt Text
(9 KB)

Event Timeline