o
    ¯b!   ã                   @   sØ   d Z ddlZddlmZmZ ddlmZmZ ddlm	Z	m
Z
 G dd„ dejƒZG dd	„ d	ejƒZG d
d„ deƒZG dd„ deƒZG dd„ dejƒZdd„ ZG dd„ dejƒZdd„ ZeZdd„ ZeZdd„ Zdd„ ZdS )z¯
This module contains the implementation of the TCP forwarding, which allows
clients and servers to forward arbitrary TCP data across the connection.

Maintainer: Paul Swartz
é    N)ÚchannelÚcommon)ÚprotocolÚreactor)ÚHostnameEndpointÚconnectProtocolc                   @   s   e Zd Zdd„ Zdd„ ZdS )ÚSSHListenForwardingFactoryc                 C   s   || _ || _|| _d S ©N)ÚconnÚhostportÚklass)ÚselfÚ
connectionr   r   © r   ú>/usr/lib/python3/dist-packages/twisted/conch/ssh/forwarding.pyÚ__init__   s   
z#SSHListenForwardingFactory.__init__c                 C   sF   | j | jd�}t|ƒ}||_|j|jf}t| j|ƒ}| j ||¡ |S )N)r
   )	r   r
   ÚSSHForwardingClientÚclientÚhostÚportÚpackOpen_direct_tcpipr   ÚopenChannel)r   Úaddrr   r   Ú	addrTupleÚchannelOpenDatar   r   r   ÚbuildProtocol   s   z(SSHListenForwardingFactory.buildProtocolN)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   r      s    r   c                   @   s4   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ ZdS )ÚSSHListenForwardingChannelc                 C   sH   | j jd| jd� t| jjƒdkr| jjdd … }|  |¡ d| j_d S )Nzopened forwarding channel {id}©Úidé   ó    )Ú_logÚinfor!   Úlenr   ÚbufÚwrite)r   ÚspecificDataÚbr   r   r   ÚchannelOpen$   s
   
z&SSHListenForwardingChannel.channelOpenc                 C   s   |   ¡  d S r	   )Úclosed©r   Úreasonr   r   r   Ú
openFailed+   s   z%SSHListenForwardingChannel.openFailedc                 C   s   | j j |¡ d S r	   )r   Ú	transportr(   ©r   Údatar   r   r   ÚdataReceived.   s   z'SSHListenForwardingChannel.dataReceivedc                 C   s   | j j ¡  d S r	   )r   r0   ÚloseConnection©r   r   r   r   ÚeofReceived1   s   z&SSHListenForwardingChannel.eofReceivedc                 C   s4   t | dƒr| jjd| jd� | jj ¡  | `d S d S )Nr   z%closing local forwarding channel {id}r    )Úhasattrr$   r%   r!   r   r0   r4   r5   r   r   r   r,   4   s
   
ýz!SSHListenForwardingChannel.closedN)r   r   r   r+   r/   r3   r6   r,   r   r   r   r   r   #   s    r   c                   @   ó   e Zd ZdZdS )Ú SSHListenClientForwardingChannels   direct-tcpipN©r   r   r   Únamer   r   r   r   r9   ;   ó    r9   c                   @   r8   )Ú SSHListenServerForwardingChannels   forwarded-tcpipNr:   r   r   r   r   r=   @   r<   r=   c                   @   sD   e Zd ZdZeZdd„ Zdd„ Zdd„ Zdd	„ Z	d
d„ Z
dd„ ZdS )ÚSSHConnectForwardingChannelaó  
    Channel used for handling server side forwarding request.
    It acts as a client for the remote forwarding destination.

    @ivar hostport: C{(host, port)} requested by client as forwarding
        destination.
    @type hostport: L{tuple} or a C{sequence}

    @ivar client: Protocol connected to the forwarding destination.
    @type client: L{protocol.Protocol}

    @ivar clientBuf: Data received while forwarding channel is not yet
        connected.
    @type clientBuf: L{bytes}

    @var  _reactor: Reactor used for TCP connections.
    @type _reactor: A reactor.

    @ivar _channelOpenDeferred: Deferred used in testing to check the
        result of C{channelOpen}.
    @type _channelOpenDeferred: L{twisted.internet.defer.Deferred}
    c                 O   s0   t jj| g|¢R i |¤Ž || _d | _d| _d S )Nr#   )r   Ú
SSHChannelr   r   r   Ú	clientBuf)r   r   ÚargsÚkwr   r   r   r   _   s   
z$SSHConnectForwardingChannel.__init__c                 C   s`   | j jd| jd | jd d� t| j| jd | jd ƒ}t|t| ƒƒ}| | j| j	¡ || _
dS )ú,
        See: L{channel.SSHChannel}
        zconnecting to {host}:{port}r   r"   ©r   r   N)r$   r%   r   r   Ú_reactorr   r   ÚaddCallbacksÚ
_setClientÚ_closeÚ_channelOpenDeferred)r   r)   ÚepÚdr   r   r   r+   e   s   ÿ
z'SSHConnectForwardingChannel.channelOpenc                 C   sr   || _ | jjd| jd | jd d� | jr | j j | j¡ d| _| j jdd… r3|  | j jdd… ¡ d| j _dS )zà
        Called when the connection was established to the forwarding
        destination.

        @param client: Client protocol connected to the forwarding destination.
        @type  client: L{protocol.Protocol}
        zconnected to {host}:{port}r   r"   rD   Nr#   )r   r$   r%   r   r@   r0   r(   r'   )r   r   r   r   r   rG   q   s   ÿz&SSHConnectForwardingChannel._setClientc                 C   s,   | j jd| jd | jd |d� |  ¡  dS )z½
        Called when failed to connect to the forwarding destination.

        @param reason: Reason why connection failed.
        @type  reason: L{twisted.python.failure.Failure}
        z,failed to connect to {host}:{port}: {reason}r   r"   )r   r   r.   N)r$   Úerrorr   r4   r-   r   r   r   rH   „   s   üz"SSHConnectForwardingChannel._closec                 C   s*   | j r| j j |¡ dS |  j|7  _dS )rC   N)r   r0   r(   r@   r1   r   r   r   r3   “   s   z(SSHConnectForwardingChannel.dataReceivedc                 C   s@   | j r| jjd| jd� | j jr|  ¡  | j j ¡  | ` dS dS )rC   z%closed remote forwarding channel {id}r    N)r   r$   r%   r!   r   r4   r0   r5   r   r   r   r,   œ   s   ûz"SSHConnectForwardingChannel.closedN)r   r   r   Ú__doc__r   rE   r   r+   rG   rH   r3   r,   r   r   r   r   r>   E   s    	r>   c                 C   s   t |ƒ\}}t|| ||d�S )N)ÚremoteWindowÚremoteMaxPacketÚavatar)ÚunpackOpen_direct_tcpipr>   )rN   rO   r2   rP   ÚremoteHPÚorigHPr   r   r   ÚopenConnectForwardingClient¨   s   ürT   c                   @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )r   c                 C   s   || _ d| _d S )Nó    )r   r'   )r   r   r   r   r   r   ³   s   
zSSHForwardingClient.__init__c                 C   s(   | j r|  j |7  _ d S | j |¡ d S r	   )r'   r   r(   r1   r   r   r   r3   ·   s   z SSHForwardingClient.dataReceivedc                 C   s   | j r| j  ¡  d | _ d S d S r	   )r   r4   r-   r   r   r   ÚconnectionLost½   s   

þz"SSHForwardingClient.connectionLostN)r   r   r   r   r3   rV   r   r   r   r   r   ²   s    r   c                 C   sl   | \}}|\}}t |tƒr| d¡}t |tƒr| d¡}t |¡t d|¡ }t |¡t d|¡ }|| S )a  
    Pack the data suitable for sending in a CHANNEL_OPEN packet.

    @type destination: L{tuple}
    @param destination: A tuple of the (host, port) of the destination host.

    @type source: L{tuple}
    @param source: A tuple of the (host, port) of the source host.
    úutf-8ú>L)Ú
isinstanceÚstrÚencoder   ÚNSÚstructÚpack)ÚdestinationÚsourceÚconnHostÚconnPortÚorigHostÚorigPortr
   Úorigr   r   r   r   Ã   s   




r   c                 C   s”   t  | ¡\}}t|tƒr| d¡}tt d|dd… ¡d ƒ}t  |dd… ¡\}}t|tƒr4| d¡}tt d|dd… ¡d ƒ}||f||ffS )z#Unpack the data to a usable format.rW   rX   Né   r   ©r   ÚgetNSrY   ÚbytesÚdecodeÚintr]   Úunpack)r2   ra   Úrestrb   rc   rd   r   r   r   rQ   Û   s   



rQ   c                 C   s   | \}}t  |¡t d|¡ S )zv
    Pack the data for tcpip forwarding.

    @param peer: A tuple of the (host, port) .
    @type peer: L{tuple}
    rX   )r   r\   r]   r^   )Úpeerr   r   r   r   r   ÚpackGlobal_tcpip_forwardë   s   ro   c                 C   sF   t  | ¡\}}t|tƒr| d¡}tt d|d d… ¡d ƒ}||fS )NrW   rX   rf   r   rg   )r2   r   rm   r   r   r   r   ÚunpackGlobal_tcpip_forwardö   s
   

rp   )rM   r]   Útwisted.conch.sshr   r   Útwisted.internetr   r   Útwisted.internet.endpointsr   r   ÚFactoryr   r?   r   r9   r=   r>   rT   ÚProtocolr   r   ÚpackOpen_forwarded_tcpiprQ   ÚunpackOpen_forwarded_tcpipro   rp   r   r   r   r   Ú<module>   s&   c
