<s> """<STR_LIT>""" <EOL> import struct <EOL> import string <EOL> import socket <EOL> import time <EOL> from twisted . internet import reactor , protocol , defer <EOL> from twisted . python import log <EOL> class SOCKSv4Outgoing ( protocol . Protocol ) : <EOL> def __init__ ( self , socks ) : <EOL> self . socks = socks <EOL> def connectionMade ( self ) : <EOL> peer = self . transport . getPeer ( ) <EOL> self . socks . makeReply ( <NUM_LIT> , <NUM_LIT:0> , port = peer . port , ip = peer . host ) <EOL> self . socks . otherConn = self <EOL> def connectionLost ( self , reason ) : <EOL> self . socks . transport . loseConnection ( ) <EOL> def dataReceived ( self , data ) : <EOL> self . socks . write ( data ) <EOL> def write ( self , data ) : <EOL> self . socks . log ( self , data ) <EOL> self . transport . write ( data ) <EOL> class SOCKSv4Incoming ( protocol . Protocol ) : <EOL> def __init__ ( self , socks ) : <EOL> self . socks = socks <EOL> self . socks . otherConn = self <EOL> def connectionLost ( self , reason ) : <EOL> self . socks . transport . loseConnection ( ) <EOL> def dataReceived ( self , data ) : <EOL> self . socks . write ( data ) <EOL> def write ( self , data ) : <EOL> self . socks . log ( self , data ) <EOL> self . transport . write ( data ) <EOL> class SOCKSv4 ( protocol . Protocol ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , logging = None , reactor = reactor ) : <EOL> self . logging = logging <EOL> self . reactor = reactor <EOL> def connectionMade ( self ) : <EOL> self . buf = "<STR_LIT>" <EOL> self . otherConn = None <EOL> def dataReceived ( self , data ) : <EOL> """<STR_LIT>""" <EOL> if self . otherConn : <EOL> self . otherConn . write ( data ) <EOL> return <EOL> self . buf = self . buf + data <EOL> completeBuffer = self . buf <EOL> if "<STR_LIT>" in self . buf [ <NUM_LIT:8> : ] : <EOL> head , self . buf = self . buf [ : <NUM_LIT:8> ] , self . buf [ <NUM_LIT:8> : ] <EOL> version , code , port = struct . unpack ( "<STR_LIT>" , head [ : <NUM_LIT:4> ] ) <EOL> user , self . buf = self . buf . split ( "<STR_LIT>" , <NUM_LIT:1> ) <EOL> if head [ <NUM_LIT:4> : <NUM_LIT:7> ] == "<STR_LIT>" and head [ <NUM_LIT:7> ] != "<STR_LIT>" : <EOL> if "<STR_LIT>" not in self . buf : <EOL> self . buf = completeBuffer <EOL> return <EOL> server , self . buf = self . buf . split ( "<STR_LIT>" , <NUM_LIT:1> ) <EOL> d = self . reactor . resolve ( server ) <EOL> d . addCallback ( self . _dataReceived2 , user , <EOL> version , code , port ) <EOL> d . addErrback ( lambda result , self = self : self . makeReply ( <NUM_LIT> ) ) <EOL> return <EOL> else : <EOL> server = socket . inet_ntoa ( head [ <NUM_LIT:4> : <NUM_LIT:8> ] ) <EOL> self . _dataReceived2 ( server , user , version , code , port ) <EOL> def _dataReceived2 ( self , server , user , version , code , port ) : <EOL> """<STR_LIT>""" <EOL> assert version == <NUM_LIT:4> , "<STR_LIT>" % version <EOL> if not self . authorize ( code , server , port , user ) : <EOL> self . makeReply ( <NUM_LIT> ) <EOL> return <EOL> if code == <NUM_LIT:1> : <EOL> d = self . connectClass ( server , port , SOCKSv4Outgoing , self ) <EOL> d . addErrback ( lambda result , self = self : self . makeReply ( <NUM_LIT> ) ) <EOL> elif code == <NUM_LIT:2> : <EOL> d = self . listenClass ( <NUM_LIT:0> , SOCKSv4IncomingFactory , self , server ) <EOL> d . addCallback ( lambda ( h , p ) , <EOL> self = self : self . makeReply ( <NUM_LIT> , <NUM_LIT:0> , p , h ) ) <EOL> else : <EOL> raise RuntimeError , "<STR_LIT>" % code <EOL> assert self . buf == "<STR_LIT>" , "<STR_LIT>" % repr ( <EOL> self . buf ) <EOL> def connectionLost ( self , reason ) : <EOL> if self . otherConn : <EOL> self . otherConn . transport . loseConnection ( ) <EOL> def authorize ( self , code , server , port , user ) : <EOL> log . msg ( "<STR_LIT>" % ( code , server , port , user ) ) <EOL> return <NUM_LIT:1> <EOL> def connectClass ( self , host , port , klass , * args ) : <EOL> return protocol . ClientCreator ( reactor , klass , * args ) . connectTCP ( host , port ) <EOL> def listenClass ( self , port , klass , * args ) : <EOL> serv = reactor . listenTCP ( port , klass ( * args ) ) <EOL> return defer . succeed ( serv . getHost ( ) [ <NUM_LIT:1> : ] ) <EOL> def makeReply ( self , reply , version = <NUM_LIT:0> , port = <NUM_LIT:0> , ip = "<STR_LIT>" ) : <EOL> self . transport . write ( struct . pack ( "<STR_LIT>" , version , reply , port ) + socket . inet_aton ( ip ) ) <EOL> if reply != <NUM_LIT> : self . transport . loseConnection ( ) <EOL> def write ( self , data ) : <EOL> self . log ( self , data ) <EOL> self . transport . write ( data ) <EOL> def log ( self , proto , data ) : <EOL> if not self . logging : return <EOL> peer = self . transport . getPeer ( ) <EOL> their_peer = self . otherConn . transport . getPeer ( ) <EOL> f = open ( self . logging , "<STR_LIT:a>" ) <EOL> f . write ( "<STR_LIT>" % ( time . ctime ( ) , <EOL> peer . host , peer . port , <EOL> ( ( proto == self and '<STR_LIT:<>' ) or '<STR_LIT:>>' ) , <EOL> their_peer . host , their_peer . port ) ) <EOL> while data : <EOL> p , data = data [ : <NUM_LIT:16> ] , data [ <NUM_LIT:16> : ] <EOL> f . write ( string . join ( map ( lambda x : '<STR_LIT>' % ord ( x ) , p ) , '<STR_LIT:U+0020>' ) + '<STR_LIT:U+0020>' ) <EOL> f . write ( ( <NUM_LIT:16> - len ( p ) ) * <NUM_LIT:3> * '<STR_LIT:U+0020>' ) <EOL> for c in p : <EOL> if len ( repr ( c ) ) > <NUM_LIT:3> : f . write ( '<STR_LIT:.>' ) <EOL> else : f . write ( c ) <EOL> f . write ( '<STR_LIT:\n>' ) <EOL> f . write ( '<STR_LIT:\n>' ) <EOL> f . close ( ) <EOL> class SOCKSv4Factory ( protocol . Factory ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , log ) : <EOL> self . logging = log <EOL> def buildProtocol ( self , addr ) : <EOL> return SOCKSv4 ( self . logging , reactor ) <EOL> class SOCKSv4IncomingFactory ( protocol . Factory ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , socks , ip ) : <EOL> self . socks = socks <EOL> self . ip = ip <EOL> def buildProtocol ( self , addr ) : <EOL> if addr [ <NUM_LIT:0> ] == self . ip : <EOL> self . ip = "<STR_LIT>" <EOL> self . socks . makeReply ( <NUM_LIT> , <NUM_LIT:0> ) <EOL> return SOCKSv4Incoming ( self . socks ) <EOL> elif self . ip == "<STR_LIT>" : <EOL> return None <EOL> else : <EOL> self . socks . makeReply ( <NUM_LIT> , <NUM_LIT:0> ) <EOL> self . ip = "<STR_LIT>" <EOL> return None </s>
