a
    |fny                  	   @   sr  d dl mZ zd dlmZ W n ey:   d dlmZ Y n0 d dlmZmZm	Z	 d dl
Z
d dlmZ d dlZd dlZd dlmZ d dlZd dlZd dlZdZejdkrejd	k rzd dlZW n ey   ed
Y n0 eeZd ZZd ZZd ZZeeedZ e!e"e # e $ Z%ej Z&Z'dd Z(G dd de)Z*G dd de*Z+G dd de*Z,G dd de*Z-G dd de*Z.G dd de*Z/G dd de*Z0dd d!d"Z1d#d$d%d&d'd(d)d*d+Z2ed,ed,ed-iZ3d@d/d0Z4d1d2 Z5d3d4 Z6e6Z7d5d6 Z8e8Z9dAd7d8Z:G d9d: d:ejZ;d;d< Z<d=D ]:Ze=e;edZ>e?e>es"e;j@Ae eBe;ee<e q"G d>d? d?e;ZCdS )B    )	b64encode)Callable)
EOPNOTSUPPEINVALEAGAINN)BytesIO)SEEK_CURz1.7.1nt)   r   z8To run PySocks on Windows you must install win_inet_pton      r
   )SOCKS4SOCKS5HTTPc                    s   t   fdd}|S )Nc               
      s   | d }z|z>|  }|dkr&|d  | i |W W |dkrH|d S  tyn } z W Y d }~n
d }~0 0 W |dkr|d n|dkr|d 0 d S )Nr   TF)
gettimeoutsetblocking	Exception)argskwargsselfZ_is_blockingefunction ?D:\Projects\storyit_web\backend\venv\Lib\site-packages\socks.pywrapper(   s    

z"set_self_blocking.<locals>.wrapper)	functoolswraps)r   r   r   r   r   set_self_blocking&   s    r   c                   @   s"   e Zd ZdZdddZdd ZdS )
ProxyErrorz4Socket_err contains original socket.error exception.Nc                 C   s(   || _ || _|r$|  j d|7  _ d S )Nz: {})msg
socket_errformat)r   r    r!   r   r   r   __init__;   s    zProxyError.__init__c                 C   s   | j S N)r    r   r   r   r   __str__B   s    zProxyError.__str__)N)__name__
__module____qualname____doc__r#   r&   r   r   r   r   r   9   s   
r   c                   @   s   e Zd ZdS )GeneralProxyErrorNr'   r(   r)   r   r   r   r   r+   F   s   r+   c                   @   s   e Zd ZdS )ProxyConnectionErrorNr,   r   r   r   r   r-   J   s   r-   c                   @   s   e Zd ZdS )SOCKS5AuthErrorNr,   r   r   r   r   r.   N   s   r.   c                   @   s   e Zd ZdS )SOCKS5ErrorNr,   r   r   r   r   r/   R   s   r/   c                   @   s   e Zd ZdS )SOCKS4ErrorNr,   r   r   r   r   r0   V   s   r0   c                   @   s   e Zd ZdS )	HTTPErrorNr,   r   r   r   r   r1   Z   s   r1   zRequest 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)[   \   ]   zGeneral SOCKS server failurez!Connection not allowed by rulesetzNetwork unreachablezHost unreachablezConnection refusedzTTL expiredz(Command not supported, or protocol errorzAddress type not supported)r   r   r
                  i8  i  Tc                 C   s.   | ||||r|  nd|r"|  ndft_dS )zSets a default proxy.

    All further socksocket objects will use the default unless explicitly
    changed. All parameters are as for socket.set_proxy().N)encode
socksocketdefault_proxy)
proxy_typeaddrportrdnsusernamepasswordr   r   r   set_default_proxys   s    rC   c                  O   s$   d|v r| d|d< t| i |S NZ	proxytyper=   )poprC   )r   r   r   r   r   setdefaultproxy~   s    rF   c                   C   s   t jS )z4Returns the default proxy, set by set_default_proxy.)r;   r<   r   r   r   r   get_default_proxy   s    rG   c                 C   s   t jrt | j_ntddS )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.zNo default proxy specifiedN)r;   r<   socketr+   )moduler   r   r   wrap_module   s    
rJ   c
                 C   s8  | \}
}|
 dr|
d}
|r4| dr4|d}d}t||dtjD ]}|\}}}}}d}zzt|||}|	r|	D ]}|j|  qvt|tt	fr|
| |r||||||| |r|| ||
|f |W   S  tjtfy } z"|}|r|  d}W Y d}~qJd}~0 0 qJ|r*|tddS )a  create_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[]Nr   zgai returned empty list.)
startswithstriprH   getaddrinfoSOCK_STREAMr;   
setsockopt
isinstanceintfloat
settimeout	set_proxybindconnecterrorr   close)	dest_pairtimeoutsource_addressr=   
proxy_addr
proxy_portZ
proxy_rdnsZproxy_usernameZproxy_passwordsocket_optionsZremote_hostZremote_porterrrfamilysocket_typeproto	canonnamesasockoptr   r   r   r   create_connection   s@    





ri   c                   @   s   e Zd ZdZdd Ze ZdS )_BaseSocketzBAllows Python 2 delegated methods such as send() to be overridden.c                 O   sJ   t j| g|R i | t | _| jD ]}t| || j|< t| | q&d S r$   )_orig_socketr#   dict_savedmethods
_savenamesgetattrdelattr)r   poskwnamer   r   r   r#      s
    
z_BaseSocket.__init__N)r'   r(   r)   r*   r#   listrn   r   r   r   r   rj      s   rj   c                    s    fddS )Nc                    s   | j   |i |S r$   )rm   )r   rq   rr   rs   r   r   <lambda>       z_makemethod.<locals>.<lambda>r   ru   r   ru   r   _makemethod   s    rx   )sendtosendrecvfromrecvc                       s<  e Zd ZdZdZejejdf fdd	Zdd Z	 fdd	Z
d
d Zdd Zd7ddZdd Z fddZ fddZd8 fdd	Zd9 fdd	Zdd Z fddZdd  ZeZd!d" ZeZd#d$ ZeZd%d& Z fd'd(Zd)d* Zd+d, Zd-d. Zd/d0 Z e!ee"ee#e iZ$e%d: fd1d2	Z&e%d3d4 Z'd5d6 Z(  Z)S );r;   a2  socksocket([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.
    Nr   c                    sv   |t jt jfvr"d}t||tt| j|||g|R i | d | _| j	rZ| j	| _
nd| _
d | _d | _d | _d S )Nz0Socket type must be stream or datagram, not {!r})NNNNNN)rH   rO   
SOCK_DGRAM
ValueErrorr"   superr;   r#   
_proxyconnr<   proxyproxy_socknameproxy_peername_timeout)r   rb   typerd   r   r   r    	__class__r   r   r#      s    "
zsocksocket.__init__c                 C   s<   d}t ||k r8||t | }|s.td||7 }q|S )zReceive EXACTLY the number of bytes requested from the file object.

        Blocks until the required number of bytes have been received.rw   Connection closed unexpectedly)lenreadr+   )r   filecountdatadr   r   r   _readall  s    
zsocksocket._readallc                    s>   || _ z|  }tt| | j  W n tjy8   Y n0 d S r$   )r   get_proxy_peernamer   r;   rT   rH   rX   )r   r[   Zpeerr   r   r   rT     s    zsocksocket.settimeoutc                 C   s   | j S r$   )r   r%   r   r   r   r   #  s    zsocksocket.gettimeoutc                 C   s   |r|  d  n
|  d d S )Ng        )rT   )r   vr   r   r   r   &  s    zsocksocket.setblockingTc                 C   s.   |||||r|  nd|r"|  ndf| _dS )a   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:   r   )r   r=   r>   r?   r@   rA   rB   r   r   r   rU   ,  s    zsocksocket.set_proxyc                 O   s&   d|v r| d|d< | j|i |S rD   )rE   rU   )r   r   r   r   r   r   setproxyA  s    zsocksocket.setproxyc                    s  | j \}}}}}}|r"| jtjkr:tj| g|R i |S | jrLttd|t	krdd}	tt
|	tt| j|i | |  \}
}d|f}t | _|  }| j| d}| | j||\}
}|\}}
|\}
}tt| ||f tt| | j d| _dS )zVImplements proxy connection for UDP sockets.

        Happens during the bind() phase.z"Socket already bound to an addressz'UDP only supported by SOCKS5 proxy type0   )0.0.0.0r   N)r   r   rH   r}   rk   rV   r   rX   r   r   r   r   r;   getsockname_proxy_addrrW   _SOCKS5_requestrT   r   r   )r   rq   rr   r=   r]   r^   r@   rA   rB   r    _r?   dstr   ZUDP_ASSOCIATEZrelayhostr   r   r   rV   F  s.    zsocksocket.bindc           
         s   | j tjkr*tt| j|g|R i |S | js:| d |d }|d d }t }d}|	| d}|	| | 
|| tt| j| | g|R i |}	|	|  S )N r   s         )r   rH   r}   r   r;   ry   r   rV   r   write_write_SOCKS5_addressrz   getvaluetell)
r   bytesr   r   addressflagsheaderZRSVZ
STANDALONEsentr   r   r   ry   k  s     


zsocksocket.sendtoc                    sB   | j tjkr$| j||| jfi |S tt| j||fi |S d S r$   )r   rH   r}   ry   r   r   r;   rz   )r   r   r   r   r   r   r   rz     s    zsocksocket.sendc           	         s   | j tjkrtt| ||S | js.| d ttt| 	|d |}|
dt |d}t|rntd| |\}}| jr| j\}}||ks|d|fvrttd||||ffS )Nr   i   r   r   zReceived UDP packet fragmentr   zPacket filtered)r   rH   r}   r   r;   r{   r   rV   r   r|   seekr   r   ordNotImplementedError_read_SOCKS5_addressr   rX   r   )	r   bufsizer   buffragZfromhostZfromportZpeerhostZpeerportr   r   r   r{     s    


zsocksocket.recvfromc                 O   s   | j |i |\}}|S r$   )r{   )r   rq   rr   r   r   r   r   r   r|     s    zsocksocket.recvc                    s   | j r| j   tt|  S r$   )r   rY   r   r;   r%   r   r   r   rY     s    
zsocksocket.closec                 C   s   | j S )z:Returns the bound IP address and port number at the proxy.)r   r%   r   r   r   get_proxy_sockname  s    zsocksocket.get_proxy_socknamec                 C   s   |   S )z>
        Returns the IP and port number of the proxy.
        )getpeernamer%   r   r   r   r     s    zsocksocket.get_proxy_peernamec                 C   s   | j S )zwReturns the IP address and port number of the destination machine.

        Note: get_proxy_peername returns the proxy.)r   r%   r   r   r   get_peername  s    zsocksocket.get_peernamec                 G   s   d}|  | ||\| _| _dS )z7Negotiates a stream connection through a SOCKS5 server.   N)r   r   r   )r   	dest_addrZCONNECTr   r   r   _negotiate_SOCKS5  s    zsocksocket._negotiate_SOCKS5c                    s  | j \}}}}}}	|d}
|dd}z|r@|	r@|
d n
|
d |
  | |d}|dd dkrvtd	|dd d
kr|r|	std|
dtt|	  | tt|		  |	  |
  | |d}|dd dkrtd	|dd dkrHtdn6|dd dkrH|dd dkr@tdntd	|
d| d  | 
||
}|
  | |d}|dd dkrtd	t|dd }|dkrt|d}td||| |}tt| | j ||fW |  |
  S |  |
  0 dS )z
        Send SOCKS5 request with given command (CMD field) and
        address (DST field). Returns resolved DST address that was used.
        wbrbr   s    s    r   r      %SOCKS5 proxy server sent invalid data   zPNo username/password supplied. Server requested username/password authenticationr   r   zSOCKS5 authentication failed   z7All offered SOCKS5 authentication methods were rejectedr
   Unknown error{:#04x}: {}N)r   makefiler   flushr   r+   r.   chrr   r:   r   r   SOCKS5_ERRORSgetr/   r"   r   r   r;   rT   r   rY   )r   conncmdr   r=   r>   r?   r@   rA   rB   writerreaderZchosen_authZauth_statusZresolvedrespstatusrX   Zbndr   r   r   r     sz    




  zsocksocket._SOCKS5_requestc              	   C   sJ  |\}}| j \}}}}}}	tjdtjdi}
tjtjfD ]h}zJt||}||
| |  t||}|td| ||fW   S  tj	y   Y q6Y q60 q6|r|
d}|dtt|
  |  nbt||tjtjtjtj}|d }|d }|d d }t||}||
| |  t||}|td| ||fS )z~
        Return the host and port packed for the SOCKS5 protocol,
        and the resolved address as a tuple object.
        r      >Hidnar   r   r5   )r   rH   AF_INETAF_INET6	inet_ptonr   	inet_ntopstructpackrX   r:   r   r   rN   	AF_UNSPECrO   IPPROTO_TCPAI_ADDRCONFIG)r   r>   r   r   r?   r=   r   r@   rA   rB   Zfamily_to_byterb   
addr_bytesZ
host_bytes	addressesZtarget_addrr   r   r   r      s8    
 z socksocket._write_SOCKS5_addressc                 C   s   |  |d}|dkr(t|  |d}nN|dkrN|  |d}|  |t|}n(|dkrnttj|  |d}ntdtd|  |d	d
 }||fS )Nr   r   r5   r   r      r   r   r   r   )	r   rH   	inet_ntoar   r   r   r+   r   unpack)r   r   Zatypr>   lengthr?   r   r   r   r   M  s    zsocksocket._read_SOCKS5_addressc                 C   s  | j \}}}}}}| d}	| dd}
zZd}zt|}W n2 tjyp   |r\d}d}ntt|}Y n0 |	tddd	| |	| |r|	| |	d
 |r|	|	dd
  |	
  | |
d}|dd	 d
krtdt|d	d }|dkr$t|d}td||t|dd td|dd d f| _|rht||f| _n
||f| _W |
  |	  n|
  |	  0 dS )z0Negotiates a connection through a SOCKS4 server.r   r   r   Fs      Tz>BBHr5   r   r   r   r9   z%SOCKS4 proxy server sent invalid datar   Z   r   r   Nr   )r   r   rH   	inet_atonrX   gethostbynamer   r   r   r:   r   r   r+   r   SOCKS4_ERRORSr   r0   r"   r   r   r   r   rY   )r   r   	dest_portr=   r>   r?   r@   rA   rB   r   r   Zremote_resolver   r   r   rX   r   r   r   _negotiate_SOCKS4\  sR    






zsocksocket._negotiate_SOCKS4c                 C   sf  | j \}}}}}}|r|nt|}d|d d t|  d d|d g}	|rv|rv|	dt|d |   |	d | d|	 | 	 }
|

 }|
  |stdz|d	d
\}}}W n ty   tdY n0 |dstdzt|}W n ty    tdY n0 |dkrRd||}|dv rJ|d7 }t|d| _||f| _dS )zwNegotiates a connection through an HTTP server.

        NOTE: This currently only supports HTTP CONNECT-style proxies.s   CONNECT r      :s	    HTTP/1.1s   Host: s   Proxy-Authorization: basic s   
r    r   z'HTTP proxy server sent invalid responsezHTTP/z0Proxy server does not appear to be an HTTP proxyz4HTTP proxy server did not return a valid HTTP status   z{}: {})i  i  i  za
[*] Note: The HTTP proxy server may not be supported by PySocks (must be a CONNECT tunnel proxy))s   0.0.0.0r   N)r   rH   r   r:   strappendr   sendalljoinr   readlinerY   r+   splitr~   rL   rR   r1   r"   r   r   )r   r   r   r=   r>   r?   r@   rA   rB   Zhttp_headersZfobjZstatus_linerd   status_codeZ
status_msgrX   r   r   r   _negotiate_HTTP  sR    





zsocksocket._negotiate_HTTPc              
      s&  t |dks|d dr,tdt| |\}}| jtjkr|| jsP| d t	|}|dkrn|snd| _
n
||f| _
dS | j\}}}}}	}
t|ttfrt |dks|rt|tstdtt| | j |du r
|| _
tt| | j tt| ||f dS |  }ztt| | W n| tjy } z`|   |s|\}}d	||}t| }d
||}td|| t||n|W Y d}~nd}~0 0 z| j| }|| || W nb tjy } z*|s|   td|n|W Y d}~n&d}~0  ty    |    Y n0 dS )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   r   rK   z PySocks doesn't support IPv6: %sr   r   Nz0Invalid destination-connection (host, port) pairz{}:{}zError connecting to {} proxy {}z%s due to: %szSocket error)r   rL   rH   rX   r   r   r}   r   rV   r   r   r   rQ   rt   tuplerR   r+   r   r;   rT   r   rW   r   rY   r"   PRINTABLE_PROXY_TYPESlogdebugr-   _proxy_negotiatorsr   )r   rZ   catch_errorsr   r   r=   r]   r^   r@   rA   rB   rX   Zproxy_serverZprintable_typer    Z	negotiater   r   r   rW     st    	





zsocksocket.connectc              
   C   sX   z| j |dd W dS  tyR } z&|jr<|jW  Y d}~S  W Y d}~n
d}~0 0 dS )a&   https://docs.python.org/3/library/socket.html#socket.socket.connect_ex
        Like connect(address), but return an error indicator instead of raising an exception for errors returned by the C-level connect() call (other problems, such as "host not found" can still raise exceptions).
        T)r   r   N)rW   OSErrorerrno)r   rZ   r   r   r   r   
connect_ex6  s    zsocksocket.connect_exc                 C   s4   | j \}}}}}}|pt|}|s,td||fS )zD
        Return proxy address to connect to as tuple object
        zInvalid proxy type)r   DEFAULT_PORTSr   r+   )r   r=   r]   r^   r@   rA   rB   r   r   r   r   F  s    zsocksocket._proxy_addr)NNNTNN)r   )r   )N)*r'   r(   r)   r*   r<   rH   r   rO   r#   r   rT   r   r   rU   r   rV   ry   rz   r{   r|   rY   r   Zgetproxysocknamer   Zgetproxypeernamer   r   r   r   r   r   r   r   r   r   r   r   r   rW   r   r   __classcell__r   r   r   r   r;      sP   	  
%b-<<\
r;   )NNNTNN)	NNNNNTNNN)Dbase64r   collections.abcr   ImportErrorcollectionsr   r   r   r   r   ior   loggingosr   rH   r   sys__version__rs   version_infoZwin_inet_pton	getLoggerr'   r   ZPROXY_TYPE_SOCKS4r   ZPROXY_TYPE_SOCKS5r   ZPROXY_TYPE_HTTPr   ZPROXY_TYPESrl   zipvalueskeysr   Z
_orgsocketrk   r   IOErrorr   r+   r-   r.   r/   r0   r1   r   r   r   rC   rF   rG   ZgetdefaultproxyrJ   Z
wrapmoduleri   rj   rx   ro   methodrQ   rn   r   setattrr;   r   r   r   r   <module>   s   


	  
     
=