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