User Tools

Site Tools


python:socksv4_proxy

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

python:socksv4_proxy [2011/05/20 13:50] (current)
tkbletsc created
Line 1: Line 1:
 +This is a simple [[http://​en.wikipedia.org/​wiki/​SOCKS|SOCKSv4 proxy]] written in pure python. ​ Suitable for use with browsers.
  
 +<​code=python>​
 +#​!/​usr/​bin/​python
 +import sys
 +import socket
 +import struct
 +import thread
 +from optparse import OptionParser
 +
 +# Very simple multi-threaded SOCKSv4(a) proxy
 +# by Tyler Bletsch (Tyler.Bletsch at gmail dot com)
 +
 +parser = OptionParser("​Usage:​ %prog [options]"​)
 + 
 +parser.add_option("​-p",​ "​--port",​ dest="​listen_port",​ help="​Port on which to listen (default: %default).",​ metavar="​PORT",​ type="​int",​ default=1080)
 +parser.add_option("​-l",​ "​--listen-interface",​ dest="​listen_interface",​ help="​IP address of the interface to listen on (default: all of them).",​ metavar="​IP",​ default='​0.0.0.0'​)
 +parser.add_option("​-c",​ "​--connect-interface",​ dest="​connect_interface",​ help="​IP address of the interface to connect out with (default: default route).",​ metavar="​IP",​ default=None)
 +parser.add_option("​-b",​ "​--buffer-size",​ dest="​buffer_size",​ help="​Size of the forwarding buffer (default: %default).",​ metavar="​N",​ type="​int",​ default=4096)
 + 
 +(options, args) = parser.parse_args()
 + 
 +buffer_size = options.buffer_size
 +listen_port = options.listen_port
 +listen_interface = options.listen_interface
 +connect_interface = options.connect_interface
 +
 +def readstr(s):
 + r=''​
 + while 1:
 + c = s.recv(1)
 + if not c: return None
 + if c == '​\0':​ break
 + r += c
 + return r
 +
 +def tunnel(src,​dest):​
 + while 1:
 + try:
 + r = src.recv(buffer_size)
 + except Exception as e:
 + print "Recv error: %s" % e
 + src.close()
 + dest.close()
 + break
 +
 + if not r:
 + src.close()
 + dest.close()
 + break
 +
 + try:
 + dest.send(r)
 + except Exception as e:
 + print "Send error: %s" % e
 + src.close()
 + dest.close()
 + break
 +
 +
 +svr = socket.socket(socket.AF_INET,​ socket.SOCK_STREAM)
 +svr.bind((listen_interface,​ listen_port))
 +svr.listen(32)
 +
 +SOCKS4_REQUEST_FORMAT = '​!BBH4s'​ # byte (socks_ver),​ byte (command), short (port), 4-char string (IP addr)
 +SOCKS4_RESPONSE_OKAY = struct.pack('​!BBHI',​0,​0x5a,​0,​0)
 +SOCKS4_RESPONSE_FAIL = struct.pack('​!BBHI',​0,​0x5b,​0,​0)
 +
 +print "​Listening on %s:​%d..."​ % (listen_interface,​listen_port)
 +
 +while 1:
 + initiator, initiator_addr = svr.accept()
 + sys.stdout.write('​%16s:​%-5d ' % (initiator_addr))
 +
 + data = initiator.recv(struct.calcsize(SOCKS4_REQUEST_FORMAT))
 +
 + if not data: 
 + print "​Connection dropped."​
 + break
 +
 + (socks_ver,​command,​target_port,​target_addr) = struct.unpack(SOCKS4_REQUEST_FORMAT,​data)
 + (target_addr_int,​) = struct.unpack('​!I',​target_addr)
 + target_addr = socket.inet_ntoa(target_addr)
 + username = readstr(initiator)
 +
 + if socks_ver!=4:​
 + print "​Dropping non-SOCKSv4 request."​
 + initiator.send(SOCKS4_RESPONSE_FAIL)
 + initiator.close()
 + continue
 +
 + if command!=1:
 + print "​Dropping non-connect request."​
 + initiator.send(SOCKS4_RESPONSE_FAIL)
 + initiator.close()
 + continue
 +
 + is_socks4a = target_addr_int>​0 and target_addr_int<​256 # check for 0.0.0.x, i.e. SOCKS4a domain mode
 + if is_socks4a: ​
 + target_addr = readstr(initiator)
 +
 + sys.stdout.write("​SOCKSv4%s => %s:%d  " % ('​a'​ if is_socks4a else ' ', target_addr,​ target_port))
 +
 + target = socket.socket(socket.AF_INET,​ socket.SOCK_STREAM)
 + if connect_interface:​ target.bind((connect_interface,​ 0))
 + try:
 + target.connect((target_addr,​ target_port))
 + except Exception as e:
 + initiator.send(SOCKS4_RESPONSE_FAIL)
 + initiator.close()
 + print "FAIL: %s" % e
 + continue
 + if not target:
 + initiator.send(SOCKS4_RESPONSE_FAIL)
 + initiator.close()
 + print "​FAIL"​
 + continue
 +
 + print "​OK"​
 + initiator.send(SOCKS4_RESPONSE_OKAY)
 + thread.start_new_thread(tunnel,​(initiator,​target))
 + thread.start_new_thread(tunnel,​(target,​initiator))
 +
 +
 +</​code>​
python/socksv4_proxy.txt ยท Last modified: 2011/05/20 13:50 by tkbletsc