18d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi"""SocksiPy - Python SOCKS module. 28d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi KandoiVersion 1.00 38d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 48d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi KandoiCopyright 2006 Dan-Haim. All rights reserved. 58d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 68d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi KandoiRedistribution and use in source and binary forms, with or without modification, 78d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoiare permitted provided that the following conditions are met: 88d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi1. Redistributions of source code must retain the above copyright notice, this 98d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi list of conditions and the following disclaimer. 108d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi2. Redistributions in binary form must reproduce the above copyright notice, 118d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi this list of conditions and the following disclaimer in the documentation 128d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi and/or other materials provided with the distribution. 138d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi3. Neither the name of Dan Haim nor the names of his contributors may be used 148d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi to endorse or promote products derived from this software without specific 158d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi prior written permission. 168d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 178d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi KandoiTHIS SOFTWARE IS PROVIDED BY DAN HAIM "AS IS" AND ANY EXPRESS OR IMPLIED 188d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi KandoiWARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 198d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi KandoiMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 208d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi KandoiEVENT SHALL DAN HAIM OR HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 218d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi KandoiINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 228d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi KandoiLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA 238d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi KandoiOR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 248d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi KandoiLIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 258d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi KandoiOF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMANGE. 268d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 278d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 288d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi KandoiThis module provides a standard socket-like interface for Python 298d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoifor tunneling connections through SOCKS proxies. 308d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 318d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi""" 328d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 338d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi""" 348d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 358d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi KandoiMinor modifications made by Christopher Gilbert (http://motomastyle.com/) 368d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoifor use in PyLoris (http://pyloris.sourceforge.net/) 378d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 388d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi KandoiMinor modifications made by Mario Vilas (http://breakingcode.wordpress.com/) 398d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoimainly to merge bug fixes found in Sourceforge 408d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 418d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi KandoiMinor modifications made by Eugene Dementiev (http://www.dementiev.eu/) 428d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 438d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi""" 448d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 458d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoiimport socket 468d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoiimport struct 478d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoiimport sys 488d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 498d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi KandoiPROXY_TYPE_SOCKS4 = 1 508d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi KandoiPROXY_TYPE_SOCKS5 = 2 518d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi KandoiPROXY_TYPE_HTTP = 3 528d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 538d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi_defaultproxy = None 548d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi_orgsocket = socket.socket 558d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 568d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoiclass ProxyError(Exception): pass 578d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoiclass GeneralProxyError(ProxyError): pass 588d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoiclass Socks5AuthError(ProxyError): pass 598d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoiclass Socks5Error(ProxyError): pass 608d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoiclass Socks4Error(ProxyError): pass 618d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoiclass HTTPError(ProxyError): pass 628d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 638d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi_generalerrors = ("success", 648d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "invalid data", 658d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "not connected", 668d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "not available", 678d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "bad proxy type", 688d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "bad input") 698d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 708d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi_socks5errors = ("succeeded", 718d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "general SOCKS server failure", 728d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "connection not allowed by ruleset", 738d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "Network unreachable", 748d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "Host unreachable", 758d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "Connection refused", 768d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "TTL expired", 778d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "Command not supported", 788d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "Address type not supported", 798d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "Unknown error") 808d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 818d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi_socks5autherrors = ("succeeded", 828d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "authentication is required", 838d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "all offered authentication methods were rejected", 848d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "unknown username or invalid password", 858d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "unknown error") 868d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 878d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi_socks4errors = ("request granted", 888d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "request rejected or failed", 898d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "request rejected because SOCKS server cannot connect to identd on the client", 908d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "request rejected because the client program and identd report different user-ids", 918d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi "unknown error") 928d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 938d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoidef setdefaultproxy(proxytype=None, addr=None, port=None, rdns=True, username=None, password=None): 948d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """setdefaultproxy(proxytype, addr[, port[, rdns[, username[, password]]]]) 958d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Sets a default proxy which all further socksocket objects will use, 968d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi unless explicitly changed. 978d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 988d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi global _defaultproxy 998d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi _defaultproxy = (proxytype, addr, port, rdns, username, password) 1008d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1018d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoidef wrapmodule(module): 1028d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """wrapmodule(module) 1038d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Attempts to replace a module's socket library with a SOCKS socket. Must set 1048d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi a default proxy using setdefaultproxy(...) first. 1058d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi This will only work on modules that import socket directly into the namespace; 1068d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi most of the Python Standard Library falls into this category. 1078d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 1088d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if _defaultproxy != None: 1098d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi module.socket.socket = socksocket 1108d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi else: 1118d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi raise GeneralProxyError((4, "no proxy specified")) 1128d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1138d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoiclass socksocket(socket.socket): 1148d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """socksocket([family[, type[, proto]]]) -> socket object 1158d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Open a SOCKS enabled socket. The parameters are the same as 1168d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi those of the standard socket init. In order for SOCKS to work, 1178d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi you must specify family=AF_INET, type=SOCK_STREAM and proto=0. 1188d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 1198d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1208d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def __init__(self, family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, _sock=None): 1218d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi _orgsocket.__init__(self, family, type, proto, _sock) 1228d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if _defaultproxy != None: 1238d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.__proxy = _defaultproxy 1248d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi else: 1258d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.__proxy = (None, None, None, None, None, None) 1268d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.__proxysockname = None 1278d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.__proxypeername = None 1288d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1298d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def __recvall(self, count): 1308d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """__recvall(count) -> data 1318d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Receive EXACTLY the number of bytes requested from the socket. 1328d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Blocks until the required number of bytes have been received. 1338d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 1348d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi data = self.recv(count) 1358d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi while len(data) < count: 1368d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi d = self.recv(count-len(data)) 1378d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if not d: raise GeneralProxyError((0, "connection closed unexpectedly")) 1388d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi data = data + d 1398d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return data 1408d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1418d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def setproxy(self, proxytype=None, addr=None, port=None, rdns=True, username=None, password=None): 1428d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """setproxy(proxytype, addr[, port[, rdns[, username[, password]]]]) 1438d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Sets the proxy to be used. 1448d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi proxytype - The type of the proxy to be used. Three types 1458d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi are supported: PROXY_TYPE_SOCKS4 (including socks4a), 1468d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi PROXY_TYPE_SOCKS5 and PROXY_TYPE_HTTP 1478d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi addr - The address of the server (IP or DNS). 1488d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi port - The port of the server. Defaults to 1080 for SOCKS 1498d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi servers and 8080 for HTTP proxy servers. 1508d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi rdns - Should DNS queries be preformed on the remote side 1518d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi (rather than the local side). The default is True. 1528d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Note: This has no effect with SOCKS4 servers. 1538d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi username - Username to authenticate with to the server. 1548d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi The default is no authentication. 1558d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi password - Password to authenticate with to the server. 1568d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Only relevant when username is also provided. 1578d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 1588d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.__proxy = (proxytype, addr, port, rdns, username, password) 1598d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 1608d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def __negotiatesocks5(self, destaddr, destport): 1618d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """__negotiatesocks5(self,destaddr,destport) 1628d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Negotiates a connection through a SOCKS5 server. 1638d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 1648d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # First we'll send the authentication packages we support. 1658d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if (self.__proxy[4]!=None) and (self.__proxy[5]!=None): 1668d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # The username/password details were supplied to the 1678d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # setproxy method so we support the USERNAME/PASSWORD 1688d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # authentication (in addition to the standard none). 1698d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.sendall(struct.pack('BBBB', 0x05, 0x02, 0x00, 0x02)) 1708d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi else: 1718d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # No username/password were entered, therefore we 1728d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # only support connections with no authentication. 1738d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.sendall(struct.pack('BBB', 0x05, 0x01, 0x00)) 1748d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # We'll receive the server's response to determine which 1758d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # method was selected 1768d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi chosenauth = self.__recvall(2) 1778d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if chosenauth[0:1] != chr(0x05).encode(): 1788d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.close() 1798d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi raise GeneralProxyError((1, _generalerrors[1])) 1808d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # Check the chosen authentication method 1818d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if chosenauth[1:2] == chr(0x00).encode(): 1828d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # No authentication is required 1838d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi pass 1848d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi elif chosenauth[1:2] == chr(0x02).encode(): 1858d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # Okay, we need to perform a basic username/password 1868d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # authentication. 1878d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.sendall(chr(0x01).encode() + chr(len(self.__proxy[4])) + self.__proxy[4] + chr(len(self.__proxy[5])) + self.__proxy[5]) 1888d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi authstat = self.__recvall(2) 1898d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if authstat[0:1] != chr(0x01).encode(): 1908d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # Bad response 1918d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.close() 1928d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi raise GeneralProxyError((1, _generalerrors[1])) 1938d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if authstat[1:2] != chr(0x00).encode(): 1948d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # Authentication failed 1958d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.close() 1968d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi raise Socks5AuthError((3, _socks5autherrors[3])) 1978d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # Authentication succeeded 1988d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi else: 1998d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # Reaching here is always bad 2008d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.close() 2018d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if chosenauth[1] == chr(0xFF).encode(): 2028d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi raise Socks5AuthError((2, _socks5autherrors[2])) 2038d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi else: 2048d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi raise GeneralProxyError((1, _generalerrors[1])) 2058d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # Now we can request the actual connection 2068d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi req = struct.pack('BBB', 0x05, 0x01, 0x00) 2078d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # If the given destination address is an IP address, we'll 2088d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # use the IPv4 address request even if remote resolving was specified. 2098d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi try: 2108d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi ipaddr = socket.inet_aton(destaddr) 2118d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi req = req + chr(0x01).encode() + ipaddr 2128d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi except socket.error: 2138d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # Well it's not an IP number, so it's probably a DNS name. 2148d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if self.__proxy[3]: 2158d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # Resolve remotely 2168d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi ipaddr = None 2178d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi req = req + chr(0x03).encode() + chr(len(destaddr)).encode() + destaddr 2188d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi else: 2198d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # Resolve locally 2208d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi ipaddr = socket.inet_aton(socket.gethostbyname(destaddr)) 2218d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi req = req + chr(0x01).encode() + ipaddr 2228d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi req = req + struct.pack(">H", destport) 2238d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.sendall(req) 2248d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # Get the response 2258d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi resp = self.__recvall(4) 2268d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if resp[0:1] != chr(0x05).encode(): 2278d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.close() 2288d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi raise GeneralProxyError((1, _generalerrors[1])) 2298d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi elif resp[1:2] != chr(0x00).encode(): 2308d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # Connection failed 2318d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.close() 2328d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if ord(resp[1:2])<=8: 2338d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi raise Socks5Error((ord(resp[1:2]), _socks5errors[ord(resp[1:2])])) 2348d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi else: 2358d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi raise Socks5Error((9, _socks5errors[9])) 2368d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # Get the bound address/port 2378d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi elif resp[3:4] == chr(0x01).encode(): 2388d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi boundaddr = self.__recvall(4) 2398d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi elif resp[3:4] == chr(0x03).encode(): 2408d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi resp = resp + self.recv(1) 2418d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi boundaddr = self.__recvall(ord(resp[4:5])) 2428d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi else: 2438d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.close() 2448d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi raise GeneralProxyError((1,_generalerrors[1])) 2458d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi boundport = struct.unpack(">H", self.__recvall(2))[0] 2468d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.__proxysockname = (boundaddr, boundport) 2478d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if ipaddr != None: 2488d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.__proxypeername = (socket.inet_ntoa(ipaddr), destport) 2498d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi else: 2508d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.__proxypeername = (destaddr, destport) 2518d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2528d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def getproxysockname(self): 2538d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """getsockname() -> address info 2548d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Returns the bound IP address and port number at the proxy. 2558d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 2568d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.__proxysockname 2578d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2588d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def getproxypeername(self): 2598d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """getproxypeername() -> address info 2608d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Returns the IP and port number of the proxy. 2618d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 2628d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return _orgsocket.getpeername(self) 2638d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2648d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def getpeername(self): 2658d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """getpeername() -> address info 2668d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Returns the IP address and port number of the destination 2678d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi machine (note: getproxypeername returns the proxy) 2688d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 2698d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi return self.__proxypeername 2708d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 2718d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def __negotiatesocks4(self,destaddr,destport): 2728d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """__negotiatesocks4(self,destaddr,destport) 2738d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Negotiates a connection through a SOCKS4 server. 2748d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 2758d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # Check if the destination address provided is an IP address 2768d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi rmtrslv = False 2778d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi try: 2788d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi ipaddr = socket.inet_aton(destaddr) 2798d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi except socket.error: 2808d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # It's a DNS name. Check where it should be resolved. 2818d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if self.__proxy[3]: 2828d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi ipaddr = struct.pack("BBBB", 0x00, 0x00, 0x00, 0x01) 2838d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi rmtrslv = True 2848d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi else: 2858d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi ipaddr = socket.inet_aton(socket.gethostbyname(destaddr)) 2868d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # Construct the request packet 2878d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi req = struct.pack(">BBH", 0x04, 0x01, destport) + ipaddr 2888d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # The username parameter is considered userid for SOCKS4 2898d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if self.__proxy[4] != None: 2908d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi req = req + self.__proxy[4] 2918d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi req = req + chr(0x00).encode() 2928d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # DNS name if remote resolving is required 2938d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # NOTE: This is actually an extension to the SOCKS4 protocol 2948d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # called SOCKS4A and may not be supported in all cases. 2958d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if rmtrslv: 2968d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi req = req + destaddr + chr(0x00).encode() 2978d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.sendall(req) 2988d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # Get the response from the server 2998d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi resp = self.__recvall(8) 3008d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if resp[0:1] != chr(0x00).encode(): 3018d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # Bad data 3028d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.close() 3038d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi raise GeneralProxyError((1,_generalerrors[1])) 3048d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if resp[1:2] != chr(0x5A).encode(): 3058d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # Server returned an error 3068d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.close() 3078d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if ord(resp[1:2]) in (91, 92, 93): 3088d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.close() 3098d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi raise Socks4Error((ord(resp[1:2]), _socks4errors[ord(resp[1:2]) - 90])) 3108d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi else: 3118d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi raise Socks4Error((94, _socks4errors[4])) 3128d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # Get the bound address/port 3138d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.__proxysockname = (socket.inet_ntoa(resp[4:]), struct.unpack(">H", resp[2:4])[0]) 3148d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if rmtrslv != None: 3158d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.__proxypeername = (socket.inet_ntoa(ipaddr), destport) 3168d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi else: 3178d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.__proxypeername = (destaddr, destport) 3188d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 3198d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def __negotiatehttp(self, destaddr, destport): 3208d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """__negotiatehttp(self,destaddr,destport) 3218d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Negotiates a connection through an HTTP server. 3228d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 3238d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # If we need to resolve locally, we do this now 3248d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if not self.__proxy[3]: 3258d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi addr = socket.gethostbyname(destaddr) 3268d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi else: 3278d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi addr = destaddr 3288d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.sendall(("CONNECT " + addr + ":" + str(destport) + " HTTP/1.1\r\n" + "Host: " + destaddr + "\r\n\r\n").encode()) 3298d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # We read the response until we get the string "\r\n\r\n" 3308d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi resp = self.recv(1) 3318d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi while resp.find("\r\n\r\n".encode()) == -1: 3328d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi recv = self.recv(1) 3338d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if not recv: 3348d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi raise GeneralProxyError((1, _generalerrors[1])) 3358d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi resp = resp + recv 3368d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # We just need the first line to check if the connection 3378d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # was successful 3388d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi statusline = resp.splitlines()[0].split(" ".encode(), 2) 3398d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if statusline[0] not in ("HTTP/1.0".encode(), "HTTP/1.1".encode()): 3408d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.close() 3418d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi raise GeneralProxyError((1, _generalerrors[1])) 3428d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi try: 3438d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi statuscode = int(statusline[1]) 3448d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi except ValueError: 3458d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.close() 3468d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi raise GeneralProxyError((1, _generalerrors[1])) 3478d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if statuscode != 200: 3488d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.close() 3498d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi raise HTTPError((statuscode, statusline[2])) 3508d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.__proxysockname = ("0.0.0.0", 0) 3518d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.__proxypeername = (addr, destport) 3528d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi 3538d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi def connect(self, destpair): 3548d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """connect(self, despair) 3558d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi Connects to the specified destination through a proxy. 3568d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi destpar - A tuple of the IP/DNS address and the port number. 3578d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi (identical to socket's connect). 3588d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi To select the proxy server use setproxy(). 3598d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi """ 3608d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi # Do a minimal input check first 3618d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if (not type(destpair) in (list,tuple)) or (len(destpair) < 2) or (type(destpair[0]) != type('')) or (type(destpair[1]) != int): 3628d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi raise GeneralProxyError((5, _generalerrors[5])) 3638d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if self.__proxy[0] == PROXY_TYPE_SOCKS5: 3648d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if self.__proxy[2] != None: 3658d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi portnum = self.__proxy[2] 3668d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi else: 3678d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi portnum = 1080 3688d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi _orgsocket.connect(self, (self.__proxy[1], portnum)) 3698d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.__negotiatesocks5(destpair[0], destpair[1]) 3708d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi elif self.__proxy[0] == PROXY_TYPE_SOCKS4: 3718d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if self.__proxy[2] != None: 3728d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi portnum = self.__proxy[2] 3738d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi else: 3748d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi portnum = 1080 3758d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi _orgsocket.connect(self,(self.__proxy[1], portnum)) 3768d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.__negotiatesocks4(destpair[0], destpair[1]) 3778d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi elif self.__proxy[0] == PROXY_TYPE_HTTP: 3788d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi if self.__proxy[2] != None: 3798d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi portnum = self.__proxy[2] 3808d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi else: 3818d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi portnum = 8080 3828d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi _orgsocket.connect(self,(self.__proxy[1], portnum)) 3838d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi self.__negotiatehttp(destpair[0], destpair[1]) 3848d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi elif self.__proxy[0] == None: 3858d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi _orgsocket.connect(self, (destpair[0], destpair[1])) 3868d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi else: 3878d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi raise GeneralProxyError((4, _generalerrors[4])) 388