Skip to content

Instantly share code, notes, and snippets.

@russdill
Last active August 29, 2015 14:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save russdill/1a0da3fd5a553e3a9e5a to your computer and use it in GitHub Desktop.
Save russdill/1a0da3fd5a553e3a9e5a to your computer and use it in GitHub Desktop.
#!/usr/bin/python
import socket
import select
import fcntl
import struct
import errno
import os
import asyncore
import sys
proxy_port = 1080
try:
proxy = sys.argv[1].split(':')
proxy_server = proxy[0]
if len(proxy) > 1:
proxy_port = int(proxy[1])
host = sys.argv[2].split(':')
if len(host) > 2:
listen_port = int(host[0])
connect_address = host[1]
connect_port = int(host[2])
if len(host) > 1:
connect_address = host[0]
connect_port = int(host[1])
listen_port = connect_port
else:
connect_address = 'localhost'
connect_port = int(host[0])
listen_port = connect_port
except:
print 'socks_forward.py <proxy>[:<port>] [<listen_port:][<address>:]<port>'
sys.exit(1)
class socks_client(asyncore.dispatcher_with_send):
def __init__(self, sock):
asyncore.dispatcher_with_send.__init__(self, sock)
self.pc = None
self.waiting = False
def set_pass(self, pc):
self.pc = pc;
if self.waiting:
self.pc.send(self.recv(8192))
def handle_close(self):
if self.pc is not None:
self.pc.finish()
sys.exit(0)
def finish(self):
self.socket.setblocking(1)
self.socket.send(self.out_buffer)
def handle_read(self):
if self.pc is None:
self.waiting = True
else:
self.pc.send(self.recv(8192))
class pass_client(asyncore.dispatcher_with_send):
def __init__(self, host, port, sc):
asyncore.dispatcher_with_send.__init__(self)
self.sc = sc
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.connect((host, port))
self.host = host
self.port = port
def handle_connect(self):
print 'Connected to', self.host + ':' + str(self.port)
def handle_close(self):
self.sc.finish()
sys.exit(0)
def finish(self):
self.socket.setblocking(1)
self.socket.send(self.out_buffer)
def handle_read(self):
self.sc.send(self.recv(8192))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((proxy_server, proxy_port))
s.send(struct.pack('!BBHIB', 4, 2, listen_port, 0, 0))
ver, resp, port, ip = struct.unpack('!BBHI', s.recv(8))
ip = struct.pack('!I', ip);
if resp == 91:
raise Exception("Denied")
elif resp != 90:
raise Exception("Unknown response")
print 'Granted, ip', socket.inet_ntoa(ip), 'port', port
ver, resp, port, ip = struct.unpack('!BBHI', s.recv(8))
if resp != 90:
raise Exception("Connect failed")
ip = struct.pack('!I', ip);
print 'Connection from', socket.inet_ntoa(ip) + ':' + str(port)
sc = socks_client(s)
pc = pass_client(connect_address, connect_port, sc)
sc.set_pass(pc)
asyncore.loop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment