U "@Wu @sdZdZddlZddlZddlmZmZmZddlm Z ddl m Z ddl m Z ddlmZd ZZd ZZd ZZeeed ZeeeeZejZZGd ddeZGdddeZ GdddeZ!GdddeZ"GdddeZ#GdddeZ$GdddeZ%ddddZ&dd d!d"d#d$d%d&d'Z'ed(ed(ed)iZ(d:d+d,Z)e)Z*d-d.Z+e+Z,d/d0Z-e-Z.d;d1d2Z/Gd3d4d4ejZ0d5d6Z1d7D]:Z2e3e0e2dZ4e5e4e se0j67e2e8e0e2e1e2qGd8d9d9e0Z9dS) SOCKS5 etc. -Improved exception handling and output -Removed irritating use of sequence indexes, replaced with tuple unpacked variables -Fixed up Python 3 bytestring handling - chr(0x03).encode() -> b"" -Other general fixes -Added clarification that the HTTP proxy connection method only supports CONNECT-style tunneling HTTP proxies -Various small bug fixes z1.5.7N) EOPNOTSUPPEINVALEAGAIN)BytesIO)SEEK_CUR)Callable) b64encode)SOCKS4SOCKS5HTTPc@s"eZdZdZdddZddZdS) ProxyErrorz> socket_err contains original socket.error exception. NcCs(||_||_|r$|jd|7_dS)Nz: {0})msg socket_errformat)selfrrr /socks.py__init__NszProxyError.__init__cCs|jSN)rrrrr__str__UszProxyError.__str__)N)__name__ __module__ __qualname____doc__rrrrrrrJs rc@s eZdZdS)GeneralProxyErrorNrrrrrrrrXsrc@s eZdZdS)ProxyConnectionErrorNrrrrrr Ysr c@s eZdZdS)SOCKS5AuthErrorNrrrrrr!Zsr!c@s eZdZdS) SOCKS5ErrorNrrrrrr"[sr"c@s eZdZdS) SOCKS4ErrorNrrrrrr#\sr#c@s eZdZdS) HTTPErrorNrrrrrr$]sr$zRequest rejected or failedzLRequest rejected because SOCKS server cannot connect to identd on the clientzPRequest rejected because the client program and identd report different user-ids)[\]zGeneral SOCKS server failurez!Connection not allowed by rulesetzNetwork unreachablezHost unreachablezConnection refusedz TTL expiredz(Command not supported, or protocol errorzAddress type not supported)r r r i8iTcCs.|||||r|nd|r"|ndft_dS)z set_default_proxy(proxy_type, addr[, port[, rdns[, username, password]]]) Sets a default proxy which all further socksocket objects will use, unless explicitly changed. All parameters are as for socket.set_proxy(). N)encode socksocket default_proxy) proxy_typeaddrportrdnsusernamepasswordrrrset_default_proxyssr6cCstjS)z> Returns the default proxy, set by set_default_proxy. )r.r/rrrrget_default_proxysr7cCstjrt|j_ntddS)a" Attempts to replace a module's socket library with a SOCKS socket. Must set a default proxy using set_default_proxy(...) first. This will only work on modules that import socket directly into the namespace; most of the Python Standard Library falls into this category. zNo default proxy specifiedN)r.r/socketr)modulerrr wrap_modules r:c  CsF|\} } | dr| d} |r4|dr4|d}d} t||dtjD]} | \}}}}}d}zt|||}| dk r| D]}|j|qzt|tt fr| ||dk r| |||||||dk r| || | | f|WStjk r&}z|} |dk r|d}W5d}~XYqJXqJ| dk r8| tddS)acreate_connection(dest_pair, *[, timeout], **proxy_args) -> socket object Like socket.create_connection(), but connects to proxy before returning the socket object. dest_pair - 2-tuple of (IP/hostname, port). **proxy_args - Same args passed to socksocket.set_proxy() if present. timeout - Optional socket timeout value, in seconds. source_address - tuple (host, port) for the socket to bind to as its source address before connecting (only for compatibility) [z[]Nrzgai returned empty list.) startswithstripr8 getaddrinfo SOCK_STREAMr.Z setsockopt isinstanceintfloatZ settimeout set_proxybindconnecterrorclose) dest_pairr0 proxy_addr proxy_portZ proxy_rdnsZproxy_usernameZproxy_passwordZtimeoutZsource_addressZsocket_optionsZ remote_hostZ remote_porterrrfamilyZ socket_typeprotoZ canonnameZsaZsockopterrrcreate_connectionsB           rQc@seZdZdZddZeZdS) _BaseSocketzJAllows Python 2's "delegated" methods such as send() to be overridden cOsDtj|f||t|_|jD]}t|||j|<t||q dSr) _orig_socketrdict _savedmethods _savenamesgetattrdelattr)rposkwnamerrrrs  z_BaseSocket.__init__N)rrrrrlistrVrrrrrRsrRcs fddS)Ncs|j||Sr)rU)rrYrZr[rrz_makemethod..rr]rr]r _makemethodsr`)sendtosendrecvfromrecvc@seZdZdZdZejejdfddZddZ d-d d Z e Z d d Z d dZ d.ddZd/ddZddZddZddZeZddZeZddZeZddZdd Zd!d"Zd#d$Zd%d&Zd'd(Zeeeee eiZ!d)d*Z"d+d,Z#dS)0r.a2socksocket([family[, type[, proto]]]) -> socket object Open a SOCKS enabled socket. The parameters are the same as those of the standard socket init. In order for SOCKS to work, you must specify family=AF_INET and proto=0. The "type" argument must be either SOCK_STREAM or SOCK_DGRAM. NrcOsf|tjtjfkr"d}t||tj||||f||d|_|jrP|j|_ nd|_ d|_ d|_ dS)Nz0Socket type must be stream or datagram, not {!r})NNNNNN) r8r? SOCK_DGRAM ValueErrorrrRr _proxyconnr/proxyproxy_socknameproxy_peername)rrMtyperNargskwargsrrrrrs zsocksocket.__init__cCs<d}t||kr8||t|}|s.td||7}q|S)z Receive EXACTLY the number of bytes requested from the file object. Blocks until the required number of bytes have been received. r_Connection closed unexpectedly)lenreadr)rfilecountdatadrrr_readalls  zsocksocket._readallTcCs.|||||r|nd|r"|ndf|_dS)aset_proxy(proxy_type, addr[, port[, rdns[, username[, password]]]]) Sets the proxy to be used. proxy_type - The type of the proxy to be used. Three types are supported: PROXY_TYPE_SOCKS4 (including socks4a), PROXY_TYPE_SOCKS5 and PROXY_TYPE_HTTP addr - The address of the server (IP or DNS). port - The port of the server. Defaults to 1080 for SOCKS servers and 8080 for HTTP proxy servers. rdns - Should DNS queries be performed on the remote side (rather than the local side). The default is True. Note: This has no effect with SOCKS4 servers. username - Username to authenticate with to the server. The default is no authentication. password - Password to authenticate with to the server. Only relevant when username is also provided. N)r-rh)rr0r1r2r3r4r5rrrrCszsocksocket.set_proxycOs|j\}}}}}}|r"|jtjkr4tj|f||S|jrFttd|t kr^d} tt | t j|f||| \} } d| f} t|_| } |j| d}||j|| \} }| \}} |\} } t ||| fd|_dS)zm Implements proxy connection for UDP sockets, which happens during the bind() phase. z"Socket already bound to an addressz'UDP only supported by SOCKS5 proxy type0)0.0.0.0rN)rhrkr8rerSrDrgrFrr rrRZ getsockname _proxy_addrrE_SOCKS5_requestri)rrYrZr0rIrJr3r4r5r_r2dstrhZ UDP_ASSOCIATEZrelayhostrrrrD*s(    zsocksocket.bindc Os|jtjkr tj||f||S|js0|d|d}|dd}t}d}||d}||| ||tj || |f||} | | S)Nrs) rkr8rerRrargrDrwrite_write_SOCKS5_addressrbgetvaluetell) rbytesrlrmZaddressflagsheaderZRSVZ STANDALONEZsentrrrraNs      zsocksocket.sendtocKs6|jtjkr |j|||jf|Stj|||f|SdSr)rkr8rerarjrRrb)rrrrmrrrrbas zsocksocket.sendc Cs|jtjkrt|||S|js*|dtt|||}| dt | d}t |rbt d||\}}|jr|j\}}||ks|d|fkrttd| ||ffS)Nr~r r zReceived UDP packet fragmentrzPacket filtered)rkr8rerRrcrgrDrrdseekrrpordNotImplementedError_read_SOCKS5_addressrjrFr) rbufsizerZbufZfragZfromhostZfromportZpeerhostZpeerportrrrrcgs      zsocksocket.recvfromcOs|j||\}}|Sr)rc)rrYrZrr{rrrrd{szsocksocket.recvcCs|jr|jt|Sr)rgrGrRrrrrrGs zsocksocket.closecCs|jS)zL Returns the bound IP address and port number at the proxy. )rirrrrget_proxy_socknameszsocksocket.get_proxy_socknamecCs t|S)z> Returns the IP and port number of the proxy. )rR getpeernamerrrrget_proxy_peernameszsocksocket.get_proxy_peernamecCs|jS)z Returns the IP address and port number of the destination machine (note: get_proxy_peername returns the proxy) )rjrrrr get_peernameszsocksocket.get_peernamecGsd}||||\|_|_dS)zI Negotiates a stream connection through a SOCKS5 server. N)rzrjri)r dest_addrZCONNECTrrr_negotiate_SOCKS5s zsocksocket._negotiate_SOCKS5cCs|j\}}}}}} |d} |dd} z|r@| r@| dn | d| || d} | dddkrvtd | ddd kr| d tt| |tt|  | | || d} | ddd krtd | ddd krt d n6| ddd kr4| dddkr,t dntd | d|d | || }| || d}|dddkrtd t |dd}|dkrt |d}td|||| }||fWS| | XdS)z Send SOCKS5 request with given command (CMD field) and address (DST field). Returns resolved DST address that was used. wbrbrssr r %SOCKS5 proxy server sent invalid datarrzSOCKS5 authentication failedz7All offered SOCKS5 authentication methods were rejectedr Unknown error {0:#04x}: {1}N)rhmakefilerGrflushrurchrror-r!rr SOCKS5_ERRORSgetr"rr)rZconncmdr|r0r1r2r3r4r5writerreaderZ chosen_authZ auth_statusZresolvedrespstatusrFZbndrrrrzsV              zsocksocket._SOCKS5_requestc CsL|\}}|j\}}}}}} tjdtjdi} tjtjfD]j} zJt| |} || | | t| | }|td|||fWStj k rYq6Yq6Xq6|r| d} |dt t |  | nbt ||tjtjtjtj}|d}|d} |dd}t| |} || | | t| | }|td|||fS)z~ Return the host and port packed for the SOCKS5 protocol, and the resolved address as a tuple object. r>Hidnarwrr()rhr8AF_INETAF_INET6Z inet_ptonr inet_ntopstructpackrFr-rror>Z AF_UNSPECr?Z IPPROTO_TCPZ AI_ADDRCONFIG)rr1rqr}r2r0r{r3r4r5Zfamily_to_byterM addr_bytesZ host_bytesZ addressesZ target_addrrrrrs0        z socksocket._write_SOCKS5_addresscCs||d}|dkr(t||d}nN|dkrN||d}||t|}n(|dkrnttj||d}ntdtd||d d }||fS) Nr rr(rwrrrr r) rur8 inet_ntoarrrrrunpack)rrqZatypr1Zlengthr2rrrr!s  zsocksocket._read_SOCKS5_addresscCs|j\}}}}}}|d} |dd} zLd} zt|} Wn4tjk rr|r^d} d} ntt|} YnX| t ddd || | |r| || d | r| | d d | | | d } | dd d krt d t| d d}|dkr&t|d}td||t| ddtd| dddf|_| rjt| |f|_n ||f|_W5| | XdS)zB Negotiates a connection through a SOCKS4 server. rrrFsTz>BBHr(r rrr,z%SOCKS4 proxy server sent invalid datar ZrrNr)rhrrGr8Z inet_atonrF gethostbynamerrrr-rrurr SOCKS4_ERRORSrr#rrrrirj)rr dest_portr0r1r2r3r4r5rrZremote_resolverrrrFrrr_negotiate_SOCKS40sB        ,zsocksocket._negotiate_SOCKS4cCsj|j\}}}}}}|r|nt|}d|ddt|dd|dg} |rv|rv| dt|d|| d|d| | } | } | | st dz| d d \} } }Wntk rt d YnX| d st d z t| } Wntk r$tdYnX| dkrVd| |}| dkrN|d7}t|d|_||f|_dS)z Negotiates a connection through an HTTP server. NOTE: This currently only supports HTTP CONNECT-style proxies. sCONNECT r:s HTTP/1.1sHost: sProxy-Authorization: basic s rn r z'HTTP proxy server sent invalid responsezHTTP/z0Proxy server does not appear to be an HTTP proxyz4HTTP proxy server did not return a valid HTTP statusz{0}: {1})iiiza [*] Note: The HTTP proxy server may not be supported by PySocks (must be a CONNECT tunnel proxy))s0.0.0.0rN)rhr8rr-strappendrZsendalljoinrreadlinerGrsplitrfr<rAr$rrirj)rrrr0r1r2r3r4r5Z http_headersZfobjZ status_linerNZ status_codeZ status_msgrFrrr_negotiate_HTTPks>        zsocksocket._negotiate_HTTPc Cst|dks|ddr$td|\}}|jtjkrt|jsH|dt|}|dkrf|sfd|_ n ||f|_ dS|j \}}}}}} t |t t frt|dks|rt |tstd|dkr||_ t|||fdS|}zt||Wn`tjk rP} z>||\}}d ||} t|} d | | } t| | W5d} ~ XYntXz|j|}||||WnVtjk r} z|td | W5d} ~ XYn tk r|YnXdS) z Connects to the specified destination through a proxy. Uses the same API as socket's connect(). To select the proxy server, use set_proxy(). dest_pair - 2-tuple of (IP/hostname, port). r rr;zPySocks doesn't support IPv6r~rxNz0Invalid destination-connection (host, port) pairz{0}:{1}z!Error connecting to {0} proxy {1}z Socket error)ror<r8rFrkrergrDrrjrhr@r\tuplerArrRrEryrGrPRINTABLE_PROXY_TYPESr _proxy_negotiatorsr)rrHrrr0rIrJr3r4r5rFZ proxy_serverZprintable_typerZ negotiaterrrrEsZ         zsocksocket.connectcCs4|j\}}}}}}|pt|}|s,td||fS)zD Return proxy address to connect to as tuple object zInvalid proxy type)rh DEFAULT_PORTSrr)rr0rIrJr3r4r5rrrrys zsocksocket._proxy_addr)NNNTNN)r)r)$rrrrr/r8rr?rrurCZsetproxyrDrarbrcrdrGrZgetproxysocknamerZgetproxypeernamerrrrzrrrrr r rrrEryrrrrr.sB $  R*;7Mr.)NNNTNN) NNNTNNNNN):r __version__r8rerrnorrriorosr collectionsrbase64rZPROXY_TYPE_SOCKS4r ZPROXY_TYPE_SOCKS5r ZPROXY_TYPE_HTTPrZ PROXY_TYPESrTzipvalueskeysrZ _orgsocketrSIOErrorrrr r!r"r#r$rrrr6Zsetdefaultproxyr7Zgetdefaultproxyr:Z wrapmodulerQrRr`r[rWmethodr@rVrsetattrr.rrrrs~6          ;