o
    ¯bù  ã                   @   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   ó
   || _ d S ©N)Úsocks©Úselfr	   © r   ú9/usr/lib/python3/dist-packages/twisted/protocols/socks.pyÚ__init__   ó   
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   ó   | j j ¡  d S r   ©r	   r   ÚloseConnection©r   Úreasonr   r   r   ÚconnectionLost   ó   zSOCKSv4Outgoing.connectionLostc                 C   ó   | j  |¡ d S r   ©r	   Úwrite©r   Údatar   r   r   ÚdataReceived!   r    zSOCKSv4Outgoing.dataReceivedc                 C   ó   | j  | |¡ | j |¡ d S r   ©r	   r   r   r#   r$   r   r   r   r#   $   ó   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   r   r   r   r   r   r   r   r   .   r    zSOCKSv4Incoming.connectionLostc                 C   r!   r   r"   r$   r   r   r   r&   1   r    zSOCKSv4Incoming.dataReceivedc                 C   r'   r   r(   r$   r   r   r   r#   4   r)   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   ó   || _ || _d S r   )Úloggingr   )r   r0   r   r   r   r   r   M   ó   
zSOCKSv4.__init__c                 C   s   d| _ d | _d S )Nó    )Úbufr   )r   r   r   r   r   Q   r1   zSOCKSv4.connectionMadec           
      C   s2  | j r| j  |¡ dS | j| | _| j}d| jdd… v r—| 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vr^|| _dS | j dd¡\}| _| j |¡}	|	 | j	||||¡ |	 
| fd	d
„¡ dS t |dd… ¡}|  	|||||¡ dS 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   ó
   |  d¡S ©Né[   ©r   ©Úresultr   r   r   r   Ú<lambda>p   ó   
 z&SOCKSv4.dataReceived.<locals>.<lambda>)r   r#   r3   ÚstructÚunpackÚsplitr   ÚresolveÚaddCallbackÚ_dataReceived2Ú
addErrbackÚsocketÚ	inet_ntoa)
r   r%   ÚcompleteBufferÚheadÚversionÚcoder   ÚuserÚserverÚdr   r   r   r&   U   s*     
ìzSOCKSv4.dataReceivedc                 C   s¸   |dks
J d| ƒ‚|   ||||¡s|  d¡ dS |dkr/|  ||t| ¡}| | fdd„¡ n|dkrE|  d	t| |¡}| | fd
d„¡ ntd|› �ƒ‚| j	dksZJ 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.
        r7   zBad version code: %sr<   Nr8   c                 S   r:   r;   r=   r>   r   r   r   r@   ”   rA   z(SOCKSv4._dataReceived2.<locals>.<lambda>é   r   c                 S   s   |  dd| d | d ¡S )Nr   r   r8   r=   )Úxr   r   r   r   r@   —   s    zBad Connect Code: r2   z hmm, still stuff in buffer... %s)Ú	authorizer   ÚconnectClassr   rH   ÚlistenClassÚSOCKSv4IncomingFactoryrF   ÚRuntimeErrorr3   Úrepr)r   rP   rO   rM   rN   r   rQ   r   r   r   rG   w   s   
 zSOCKSv4._dataReceived2c                 C   s   | j r| j j ¡  d S 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) authorizedr8   )r   Úmsg)r   rN   rP   r   rO   r   r   r   rT       s   
ÿÿzSOCKSv4.authorizec                 G   s   t jt|g|¢R Ž  ||¡S r   )r   ÚClientCreatorr   Ú
connectTCP)r   r   r   ÚklassÚargsr   r   r   rU   §   s   zSOCKSv4.connectClassc                 G   s&   t  |||Ž ¡}t | ¡ dd … ¡S )Nr8   )r   Ú	listenTCPr   ÚsucceedÚgetHost)r   r   r]   r^   Úservr   r   r   rV   ª   s   zSOCKSv4.listenClassr   ú0.0.0.0c                 C   s<   | j  t d|||¡t |¡ ¡ |dkr| j  ¡  d S d S )Nr6   r   )r   r#   rB   ÚpackrI   Ú	inet_atonr   )r   ÚreplyrM   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r&dp'd|j|j	f ¡ |rz|d d… |dd … }}| t
 tdd„ |ƒd¡d ¡ | dt|ƒ d	 d ¡ |D ]}tt|ƒƒd	krm| d
¡ q]| |¡ q]| d¡ |s1| d¡ | ¡  d S )NÚaz%s	%s:%d %s %s:%d
ú<ú>é   c                 S   s   dt | ƒ S )Nz%02X)Úord)rS   r   r   r   r@   Ì   s    zSOCKSv4.log.<locals>.<lambda>ú é   Ú.Ú
)r0   r   r   r   Úopenr#   ÚtimeÚctimer   r   ÚstringÚjoinÚmapÚlenrY   Úclose)r   Úprotor%   r   Ú
their_peerÚfÚpÚcr   r   r   r   ¹   s8   
úÿÿ 
÷

zSOCKSv4.log)r   r   rc   )r*   r+   r,   Ú__doc__r   r   r   r&   rG   r   rT   rU   rV   r   r#   r   r   r   r   r   r.   9   s    "%
r.   c                   @   ó    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   r   r   )r0   )r   r   r   r   r   r   ß   r   zSOCKSv4Factory.__init__c                 C   s   t | jtƒS r   )r.   r0   r   ©r   Úaddrr   r   r   ÚbuildProtocolâ   s   zSOCKSv4Factory.buildProtocolN©r*   r+   r,   r}   r   r‚   r   r   r   r   r   Ø   s    r   c                   @   r~   )rW   zJ
    A utility class for building protocols for incoming connections.
    c                 C   r/   r   )r	   r   )r   r	   r   r   r   r   r   ë   r1   zSOCKSv4IncomingFactory.__init__c                 C   sR   |d | j krd| _ | j dd¡ t| jƒS | j dkrd S | j dd¡ d| _ d S )Nr   Ú r   r<   )r   r	   r   r-   r€   r   r   r   r‚   ï   s   

z$SOCKSv4IncomingFactory.buildProtocolNrƒ   r   r   r   r   rW   æ   s    rW   )r}   rI   rs   rB   rq   Útwisted.internetr   r   r   Útwisted.pythonr   ÚProtocolr   r-   r.   ÚFactoryr   rW   r   r   r   r   Ú<module>   s     