U
    
W[ˆ  ã                   @   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)ÚreactorÚprotocolÚdefer)Ú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   ú9/usr/lib/python3/dist-packages/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   3   s    zSOCKSv4Incoming.connectionLostc                 C   s   | j  |¡ d S r   r   r   r   r   r   r!   7   s    zSOCKSv4Incoming.dataReceivedc                 C   s   | j  | |¡ | j |¡ d S r   r"   r   r   r   r   r   ;   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   T   s    zSOCKSv4.__init__c                 C   s   d| _ d | _d S )Nó    )Úbufr   )r
   r   r   r   r   Y   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>z   r)   z&SOCKSv4.dataReceived.<locals>.<lambda>)r   r   r*   ÚstructZunpackÚsplitr   ZresolveÚaddCallbackÚ_dataReceived2Ú
addErrbackÚsocketZ	inet_ntoa)
r
   r    ZcompleteBufferÚheadÚversionÚcoder   ÚuserÚserverÚdr   r   r   r!   ^   s0     $

  ÿ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|f ƒ‚| j
dks´t dt| j
ƒ ƒ‚dS )a3  
        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 comand 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   ¢   s    zBad Connect Code: %sr)   z hmm, still stuff in buffer... %s)ÚAssertionErrorÚ	authorizer   ÚconnectClassr   r;   ÚlistenClassÚSOCKSv4IncomingFactoryr9   ÚRuntimeErrorr*   Úrepr)r
   rA   r@   r>   r?   r   rB   r   r   r   r:   ‚   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
   r?   rA   r   r@   r   r   r   rF   ¯   s    zSOCKSv4.authorizec                 G   s   t jt|f|žŽ  ||¡S r   )r   ZClientCreatorr   Z
connectTCP)r
   r   r   ÚklassÚargsr   r   r   rG   ´   s    zSOCKSv4.connectClassc                 G   s&   t  |||Ž ¡}t | ¡ dd … ¡S )Nr/   )r   Z	listenTCPr   ZsucceedZgetHost)r
   r   rM   rN   Zservr   r   r   rH   ¸   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   Zpackr<   Z	inet_atonr   )r
   Zreplyr>   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)rD   r   r   r   r6   Ò   r)   zSOCKSv4.log.<locals>.<lambda>ú é   Ú.Ú
)r(   r   r   r   Úopenr   ÚtimeÚctimer   r   ÚstringÚjoinÚmapÚlenrK   Úclose)r
   Úprotor    r   Z
their_peerÚfÚpÚcr   r   r   r   Ç   s.     
  ý  
zSOCKSv4.log)r   r   rO   )r#   r$   r%   Ú__doc__r   r   r   r!   r:   r   rF   rG   rH   r   r   r   r   r   r   r   r'   A   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
   Zaddrr   r   r   ÚbuildProtocolç   s    zSOCKSv4Factory.buildProtocolN©r#   r$   r%   re   r   rh   r   r   r   r   rf   Ý   s   rf   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )rI   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&   rg   r   r   r   rh   õ   s    

z$SOCKSv4IncomingFactory.buildProtocolNri   r   r   r   r   rI   ì   s   rI   )re   r7   r\   r<   rZ   Ztwisted.internetr   r   r   Ztwisted.pythonr   ZProtocolr   r&   r'   ZFactoryrf   rI   r   r   r   r   Ú<module>   s    