Skip to content

Instantly share code, notes, and snippets.

@jsoref
Forked from sivachandran/SimpleTcpRedirector.py
Last active November 1, 2017 19:13
Show Gist options
  • Save jsoref/a61aa7b9cb971328eb9700df4a32d5c4 to your computer and use it in GitHub Desktop.
Save jsoref/a61aa7b9cb971328eb9700df4a32d5c4 to your computer and use it in GitHub Desktop.
Redirector for localhost driven SMTP based on a simple TCP redirector in python
#!/usr/bin/env python
# SMTP client ip tunneler
#
# ./SMTPRedirector 0.0.0.0 LISTENPORT SMTPHOST SMTPPORT
#
# Based on https://gist.githubusercontent.com/sivachandran/1969859/raw/f834e72c27488c279166a53ce1623b7f2f79e70c/SimpleTcpRedirector.py
import socket
import threading
import select
import sys
import os
terminateAll = False
class ClientThread(threading.Thread):
def __init__(self, clientSocket, targetHost, targetPort, sourceHost):
threading.Thread.__init__(self)
self.__clientSocket = clientSocket
self.__targetHost = targetHost
self.__targetPort = targetPort
self.__sourceHost = sourceHost
def run(self):
#print "ClientThread started"
self.__clientSocket.setblocking(0)
targetHostSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
targetHostSocket.bind((self.__sourceHost, 0))
targetHostSocket.connect((self.__targetHost, self.__targetPort))
targetHostSocket.setblocking(0)
clientData = ""
targetHostData = ""
terminate = False
while not terminate and not terminateAll:
inputs = [self.__clientSocket, targetHostSocket]
outputs = []
if len(clientData) > 0:
outputs.append(self.__clientSocket)
if len(targetHostData) > 0:
outputs.append(targetHostSocket)
try:
inputsReady, outputsReady, errorsReady = select.select(inputs, outputs, [], 1.0)
except Exception, e:
print e
break
for inp in inputsReady:
if inp == self.__clientSocket:
try:
data = self.__clientSocket.recv(4096)
except Exception, e:
print e
if data != None:
if len(data) > 0:
targetHostData += data
else:
terminate = True
elif inp == targetHostSocket:
try:
data = targetHostSocket.recv(4096)
except Exception, e:
print e
if data != None:
if len(data) > 0:
clientData += data
else:
terminate = True
for out in outputsReady:
if out == self.__clientSocket and len(clientData) > 0:
bytesWritten = self.__clientSocket.send(clientData)
if bytesWritten > 0:
clientData = clientData[bytesWritten:]
elif out == targetHostSocket and len(targetHostData) > 0:
bytesWritten = targetHostSocket.send(targetHostData)
if bytesWritten > 0:
targetHostData = targetHostData[bytesWritten:]
self.__clientSocket.close()
targetHostSocket.close()
#print "ClientThread terminating"
def usage(appname):
print 'Usage:\n\t'+appname+' <host> <port> <remote host> <remote port>'
print 'Example:\n\t'+appname+' 0.0.0.0 5025 localhost 25'
sys.exit(0)
if __name__ == '__main__':
appname = sys.argv[0]
if len(sys.argv) < 5:
usage(appname)
if sys.argv[1] == '-p':
pidfilename = sys.argv[2]
sys.argv[1:] = sys.argv[3:]
pidfile = open(pidfilename, 'w+')
pidfile.write(str(os.getpid())+"\n")
pidfile.close()
pidfile = None
if len(sys.argv) != 5:
appname = sys.argv[0]
print 'Usage:\n\t'+appname+' <host> <port> <remote host> <remote port>'
print 'Example:\n\t'+appname+' 0.0.0.0 5025 localhost 25'
sys.exit(0)
localHost = sys.argv[1]
localPort = int(sys.argv[2])
targetHost = sys.argv[3]
targetPort = int(sys.argv[4])
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serverSocket.bind((localHost, localPort))
serverSocket.listen(5)
#print "Waiting for client..."
while True:
try:
clientSocket, address = serverSocket.accept()
sourceSocket = clientSocket.getsockname()
sourceHost = sourceSocket[0]
print sourceHost
if sourceHost[0:4] != '127.':
clientSocket.close()
continue
except KeyboardInterrupt:
#print "\nTerminating..."
terminateAll = True
break
ClientThread(clientSocket, targetHost, targetPort, sourceHost).start()
serverSocket.close()
try:
os.remove(pidfilename)
except OSError:
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment