Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F1822497
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Size
10 KB
Subscribers
None
View Options
diff --git a/sockpy.ini b/sockpy.ini
new file mode 100644
--- /dev/null
+++ b/sockpy.ini
@@ -0,0 +1,14 @@
+[General]
+username = myRemoteUsername
+password = myRemotePassword
+host = https://my.remote.host
+
+[server-imap]
+localport = 1143
+remoteport = 143
+remotehost = localhost
+
+[server-smtp]
+localport = 1125
+remoteport = 25
+remotehost = localhost
diff --git a/sockpy.py b/sockpy.py
--- a/sockpy.py
+++ b/sockpy.py
@@ -1,245 +1,268 @@
#!/usr/bin/env python2
import requests
import simplejson as json
import threading
from optparse import OptionParser
+import ConfigParser
import socket
import select
import uuid
import time
import base64
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("-f", "--file", dest="file", help="config file to load add values from", 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")
parser.add_option("-v", "--verbose", action="store_true", dest="verbose", help="enable verbose output", default=False)
(opts, args) = parser.parse_args()
class SocketServerWrapper(threading.Thread):
def __init__(self, host, user, password, connStr, verbose):
self.url = host
self.user = user
self.password = password
self.connStr = connStr
connArr = connStr.split(":")
self.localPort = int(connArr[0])
self.error = False
self.verbose = verbose
self.running = True
self.sock = None
self.socketThreads = []
threading.Thread.__init__(self)
self.setDaemon(True)
def close(self):
for thread in self.socketThreads:
thread.close()
def run(self):
print "Spawning socket and waiting for connections on port: " + str(self.localPort)
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 5)
self.sock.bind(('', self.localPort))
self.sock.listen(1)
while self.running:
clientSocket, addr = self.sock.accept()
self.socketThreads.append(SocketWrapper(self.url, self.user, self.password, self.connStr, clientSocket, self.verbose))
self.socketThreads[-1].start()
print "ThreadedSocketServer exit."
class SocketWrapper(threading.Thread):
def __init__(self, host, user, password, connStr, clientSocket, verbose):
self.url = host
self.user = user
self.verbose = verbose
self.password = password
connArr = connStr.split(":")
self.remotePort = connArr[-1]
self.error = False
self.connected = False
self.running = True
self.uid = str(uuid.uuid4())
self.clientSocket = clientSocket
if len(connArr) == 3:
self.remoteHost = connArr[1]
else:
self.remoteHost = "127.0.0.1"
threading.Thread.__init__(self)
self.setDaemon(True)
def run(self):
if self.connect():
if self.login():
self.connectRemote()
while self.connected:
self.sendRemote(self.recvLocal())
self.sendLocal(self.recvRemote())
self.disconnectRemote()
self.disconnectLocal()
print "Thread exit"
def close(self):
print "Closing Thread..."
if self.connected:
self.disconnectRemote()
self.disconnectLocal()
self.connected = False
self.running = False
def disconnectRemote(self):
if self.verbose:
print "Disconnecting Remote..."
payload = {}
payload["command"] = "quit"
payload["uid"] = self.uid
payload["payload"] = json.dumps({})
self.connected = False
try:
r = requests.post(self.url, data=payload, verify=False)
except:
return False
return True
def disconnectLocal(self):
if self.verbose:
print "Disconnecting Local..."
try:
self.clientSocket.shutdown(socket.SHUT_RDWR)
self.clientSocket.close()
except:
pass
def connect(self):
if self.verbose:
print "Connecting..."
payload = {}
payload["command"] = "status"
payload["payload"] = json.dumps({})
payload["uid"] = self.uid
try:
r = requests.post(self.url, data=payload, verify=False)
except:
return False
reply = json.loads(r.content)
return True
def login(self):
if self.verbose:
print "Logging in..."
payload = {}
payload["command"] = "login"
payload["uid"] = self.uid
payload["payload"] = json.dumps({"username" : self.user, "password" : self.password})
try:
r = requests.post(self.url, data=payload, verify=False)
except:
return False
reply = json.loads(r.content)
if reply["status"]:
return True
else:
return False
def connectRemote(self):
if self.verbose:
print "Connecting Remote..."
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, verify=False)
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], [], [self.clientSocket], 0)
if self.clientSocket in readable:
data = self.clientSocket.recv(MAXLEN)
if len(data) == 0:
self.connected = False
print "Local disconnect, closing socket..."
elif self.clientSocket in errored:
self.connected = False
else:
data = ""
return data
def sendLocal(self, data):
read, writable, errored = select.select([], [self.clientSocket], [self.clientSocket], 0)
if self.clientSocket in writable and data != "":
sent = self.clientSocket.sendall(data)
if sent is not None:
self.connected = False
print "Error sending to local socket, disconnecting..."
elif self.clientSocket in errored:
self.connected = False
def recvRemote(self):
payload = {}
payload["command"] = "recv"
payload["payload"] = json.dumps({})
payload["uid"] = self.uid
try:
r = requests.post(self.url, data=payload, verify=False)
except:
self.connected = False
return ""
reply = json.loads(r.content)
if reply["status"] == False:
self.connected = False
if reply["connected"] == False:
self.connected = False
print "Remote disconnect, closing socket..."
data = base64.b64decode(reply["data"])
if self.verbose:
print "Got from Remote: " + data
return data
def sendRemote(self, data):
if data != "":
if self.verbose:
print "Sending to Remote: " + data
payload = {}
payload["command"] = "send"
payload["payload"] = json.dumps({"data" : base64.b64encode(data)})
payload["uid"] = self.uid
try:
r = requests.post(self.url, data=payload, verify=False)
except:
self.connected = False
return
reply = json.loads(r.content)
if reply["status"] == False:
self.connected = False
if reply["connected"] == False:
print "Remote disconnect, closing socket..."
self.connected = False
+def parseConfigFile(filename):
+ config = ConfigParser.SafeConfigParser()
+ config.read(filename)
+ username = config.get("General", "username")
+ password = config.get("General", "password")
+ hostname = config.get("General", "host")
+ hostList = []
+ for section in config.sections():
+ if section != "General":
+ host = config.get(section, "remotehost")
+ localport = config.get(section, "localport")
+ remoteport = config.get(section, "remoteport")
+ hostList.append(localport + ":" + host + ":" + remoteport)
+ return hostList, hostname, username, password
+
if __name__ == "__main__":
- if opts.connect == "":
+ if opts.connect == "" and opts.file == "":
sys.exit()
- hostList = opts.connect.split(",")
+ if opts.file != "":
+ hostList, host, user, password = parseConfigFile(opts.file)
+ else:
+ host = opts.host
+ user = opts.user
+ password = opts.password
+ hostList = opts.connect.split(",")
sockConns = []
for connStr in hostList:
- sockConns.append(SocketServerWrapper(opts.host, opts.user, opts.password, connStr, opts.verbose))
+ sockConns.append(SocketServerWrapper(host, user, password, connStr, opts.verbose))
sockConns[-1].start()
try:
while True:
time.sleep(1)
finally:
for conn in sockConns:
conn.close()
print "done"
- sys.exit(1)
+ sys.exit(0)
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Dec 24, 7:43 PM (1 d, 12 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
534147
Default Alt Text
(10 KB)
Attached To
rSOCKPY Socket-over-HTTP Bridge
Event Timeline
Log In to Comment