U
     T‚gù  ã                   @   s¢   d Z ddlZddlZddlZddlZddlmZmZmZ ddl	m
Z
 G dd„ dejƒZG dd„ dejƒZG d	d
„ d
ejƒZG dd„ dejƒZG dd„ dejƒZdS )z)
Implementation of the SOCKSv4 protocol.
é    N)ÚdeferÚprotocolÚreactor)Úlogc                   @   s4   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ ZdS )ÚSOCKSv4Outgoingc                 C   s
   || _ d S ©N)Úsocks©Úselfr   © r   ú;/tmp/pip-unpacked-wheel-1_7di8ic/twisted/protocols/socks.pyÚ__init__   s    zSOCKSv4Outgoing.__init__c                 C   s.   | j  ¡ }| jjdd|j|jd� | | j_d S )NéZ   r   )ÚportÚip)Ú	transportÚgetPeerr   Ú	makeReplyr   ÚhostÚ	otherConn)r
   Úpeerr   r   r   ÚconnectionMade   s    
zSOCKSv4Outgoing.connectionMadec                 C   s   | j j ¡  d S r   ©r   r   ÚloseConnection©r
   Úreasonr   r   r   ÚconnectionLost   s    zSOCKSv4Outgoing.connectionLostc                 C   s   | j  |¡ d S r   ©r   Úwrite©r
   Údatar   r   r   ÚdataReceived!   s    zSOCKSv4Outgoing.dataReceivedc                 C   s   | j  | |¡ | j |¡ d S r   ©r   r   r   r   r   r   r   r   r   $   s    zSOCKSv4Outgoing.writeN)Ú__name__Ú
__module__Ú__qualname__r   r   r   r!   r   r   r   r   r   r      s
   r   c                   @   s,   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	S )
ÚSOCKSv4Incomingc                 C   s   || _ | | j _d S r   )r   r   r	   r   r   r   r   *   s    zSOCKSv4Incoming.__init__c                 C   s   | j j ¡  d S r   r   r   r   r   r   r   .   s    zSOCKSv4Incoming.connectionLostc                 C   s   | j  |¡ d S r   r   r   r   r   r   r!   1   s    zSOCKSv4Incoming.dataReceivedc                 C   s   | j  | |¡ | j |¡ d S r   r"   r   r   r   r   r   4   s    zSOCKSv4Incoming.writeN)r#   r$   r%   r   r   r!   r   r   r   r   r   r&   )   s   r&   c                   @   sp   e Zd ZdZdefdd„Zdd„ Zdd„ Zd	d
„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zddd„Zdd„ Zdd„ ZdS )ÚSOCKSv4aË  
    An implementation of the SOCKSv4 protocol.

    @type logging: L{str} or L{None}
    @ivar logging: If not L{None}, the name of the logfile to which connection
        information will be written.

    @type reactor: object providing L{twisted.internet.interfaces.IReactorTCP}
    @ivar reactor: The reactor used to create connections.

    @type buf: L{str}
    @ivar buf: Part of a SOCKSv4 connection request.

    @type otherConn: C{SOCKSv4Incoming}, C{SOCKSv4Outgoing} or L{None}
    @ivar otherConn: Until the connection has been established, C{otherConn} is
        L{None}. After that, it is the proxy-to-destination protocol instance
        along which the client's connection is being forwarded.
    Nc                 C   s   || _ || _d S r   )Úloggingr   )r
   r(   r   r   r   r   r   M   s    zSOCKSv4.__init__c                 C   s   d| _ d | _d S )Nó    )Úbufr   )r
   r   r   r   r   Q   s    zSOCKSv4.connectionMadec           
      C   s4  | j r| j  |¡ dS | j| | _| j}d| jdd… k�r0| jdd… | jdd…  }| _t d|dd… ¡\}}}| j dd¡\}| _|dd… dk�r|dd… dk�rd| jkrÂ|| _dS | j dd¡\}| _| j |¡}	|	 | j	||||¡ |	 
| fd	d
„¡ dS t |dd… ¡}|  	|||||¡ dS )z‡
        Called whenever data is received.

        @type data: L{bytes}
        @param data: Part or all of a SOCKSv4 packet.
        Nó    é   ú!BBHé   é   é   s      c                 S   s
   |  d¡S ©Né[   ©r   ©Úresultr
   r   r   r   Ú<lambda>p   r)   z&SOCKSv4.dataReceived.<locals>.<lambda>)r   r   r*   ÚstructÚunpackÚsplitr   ÚresolveÚaddCallbackÚ_dataReceived2Ú
addErrbackÚsocketÚ	inet_ntoa)
r
   r    ZcompleteBufferÚheadÚversionÚcoder   ÚuserÚserverÚdr   r   r   r!   U   s(     $
zSOCKSv4.dataReceivedc                 C   s¸   |dkst d| ƒ‚|  ||||¡s2|  d¡ dS |dkr^|  ||t| ¡}| | fdd„¡ n:|dkrŠ|  d	t| |¡}| | fd
d„¡ nt	d|› �ƒ‚| j
dks´t dt| j
ƒ ƒ‚dS )a4  
        The second half of the SOCKS connection setup. For a SOCKSv4 packet this
        is after the server address has been extracted from the header. For a
        SOCKSv4a packet this is after the host name has been resolved.

        @type server: L{str}
        @param server: The IP address of the destination, represented as a
            dotted quad.

        @type user: L{str}
        @param user: The username associated with the connection.

        @type version: L{int}
        @param version: The SOCKS protocol version number.

        @type code: L{int}
        @param code: The command code. 1 means establish a TCP/IP stream
            connection, and 2 means establish a TCP/IP port binding.

        @type port: L{int}
        @param port: The port number associated with the connection.
        r.   zBad version code: %sr2   Nr/   c                 S   s
   |  d¡S r1   r3   r4   r   r   r   r6   ”   r)   z(SOCKSv4._dataReceived2.<locals>.<lambda>é   r   c                 S   s   |  dd| d | d ¡S )Nr   r   r/   r3   )Úxr
   r   r   r   r6   —   r)   zBad Connect Code: r)   z hmm, still stuff in buffer... %s)ÚAssertionErrorÚ	authorizer   ÚconnectClassr   r=   ÚlistenClassÚSOCKSv4IncomingFactoryr;   ÚRuntimeErrorr*   Úrepr)r
   rD   rC   rA   rB   r   rE   r   r   r   r<   w   s    
zSOCKSv4._dataReceived2c                 C   s   | j r| j j ¡  d S r   )r   r   r   r   r   r   r   r   œ   s    zSOCKSv4.connectionLostc                 C   s   t  d||||f ¡ dS )Nz0code %s connection to %s:%s (user %s) authorizedr/   )r   Úmsg)r
   rB   rD   r   rC   r   r   r   rI       s    
ÿÿzSOCKSv4.authorizec                 G   s   t jt|f|žŽ  ||¡S r   )r   ZClientCreatorr   Z
connectTCP)r
   r   r   ÚklassÚargsr   r   r   rJ   §   s    zSOCKSv4.connectClassc                 G   s&   t  |||Ž ¡}t | ¡ dd … ¡S )Nr/   )r   Z	listenTCPr   ZsucceedZgetHost)r
   r   rP   rQ   Zservr   r   r   rK   ª   s    zSOCKSv4.listenClassr   ú0.0.0.0c                 C   s8   | j  t d|||¡t |¡ ¡ |dkr4| j  ¡  d S )Nr-   r   )r   r   r7   Úpackr>   Ú	inet_atonr   )r
   ZreplyrA   r   r   r   r   r   r   ®   s
    ÿzSOCKSv4.makeReplyc                 C   s   |   | |¡ | j |¡ d S r   )r   r   r   r   r   r   r   r   µ   s    zSOCKSv4.writec              	   C   s  | j s
d S | j ¡ }| jj ¡ }t| j dƒ}| dt ¡ |j|j	|| krLdpNd|j|j	f ¡ |rò|d d… |dd …  }}| t
 tdd„ |ƒd¡d ¡ | dt|ƒ d	 d ¡ |D ]*}tt|ƒƒd	krÚ| d
¡ qº| |¡ qº| d¡ q^| d¡ | ¡  d S )NÚaz%s	%s:%d %s %s:%d
ú<ú>é   c                 S   s   dt | ƒ S )Nz%02X)Úord)rG   r   r   r   r6   Ì   r)   zSOCKSv4.log.<locals>.<lambda>ú é   Ú.Ú
)r(   r   r   r   Úopenr   ÚtimeÚctimer   r   ÚstringÚjoinÚmapÚlenrN   Úclose)r
   Úprotor    r   Z
their_peerÚfÚpÚcr   r   r   r   ¹   s6    
úÿÿ 
zSOCKSv4.log)r   r   rR   )r#   r$   r%   Ú__doc__r   r   r   r!   r<   r   rI   rJ   rK   r   r   r   r   r   r   r   r'   9   s   "%
r'   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚSOCKSv4Factoryz`
    A factory for a SOCKSv4 proxy.

    Constructor accepts one argument, a log file name.
    c                 C   s
   || _ d S r   )r(   )r
   r   r   r   r   r   ß   s    zSOCKSv4Factory.__init__c                 C   s   t | jtƒS r   )r'   r(   r   ©r
   Úaddrr   r   r   ÚbuildProtocolâ   s    zSOCKSv4Factory.buildProtocolN©r#   r$   r%   rj   r   rn   r   r   r   r   rk   Ø   s   rk   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )rL   zJ
    A utility class for building protocols for incoming connections.
    c                 C   s   || _ || _d S r   )r   r   )r
   r   r   r   r   r   r   ë   s    zSOCKSv4IncomingFactory.__init__c                 C   sV   |d | j kr,d| _ | j dd¡ t| jƒS | j dkr:d S | j dd¡ d| _ d S d S )Nr   Ú r   r2   )r   r   r   r&   rl   r   r   r   rn   ï   s    

z$SOCKSv4IncomingFactory.buildProtocolNro   r   r   r   r   rL   æ   s   rL   )rj   r>   ra   r7   r_   Ztwisted.internetr   r   r   Ztwisted.pythonr   ÚProtocolr   r&   r'   ZFactoryrk   rL   r   r   r   r   Ú<module>   s     