3
,sY                 @   s  d Z ddlmZmZ ddlZddlmZmZ ddlm	Z	m
Z
 ddl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
    )divisionabsolute_importN)protocolreactor)HostnameEndpointconnectProtocol)log)_PY3unicode)commonchannelc               @   s   e Zd Zdd Zdd ZdS )SSHListenForwardingFactoryc             C   s   || _ || _|| _d S )N)connhostportklass)selfZ
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j|| |S )N)r   )	r   r   SSHForwardingClientclienthostportpackOpen_direct_tcpipr   ZopenChannel)r   Zaddrr   r   Z	addrTupleZ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   sF   t jd| j  t| jjdkr:| jjdd  }| j| d| j_d S )Nzopened forwarding channel %s       )r   msgidlenr   bufwrite)r   specificDatabr   r   r   channelOpen'   s
    
z&SSHListenForwardingChannel.channelOpenc             C   s   | j   d S )N)closed)r   reasonr   r   r   
openFailed.   s    z%SSHListenForwardingChannel.openFailedc             C   s   | j jj| d S )N)r   	transportr%   )r   datar   r   r   dataReceived1   s    z'SSHListenForwardingChannel.dataReceivedc             C   s   | j jj  d S )N)r   r,   loseConnection)r   r   r   r   eofReceived4   s    z&SSHListenForwardingChannel.eofReceivedc             C   s.   t | dr*tjd| j  | jjj  | `d S )Nr   z#closing local forwarding channel %s)hasattrr   r!   r"   r   r,   r/   )r   r   r   r   r)   7   s    
z!SSHListenForwardingChannel.closedN)r   r   r   r(   r+   r.   r0   r)   r   r   r   r   r   %   s
   r   c               @   s   e Zd ZdZdS ) SSHListenClientForwardingChannels   direct-tcpipN)r   r   r   namer   r   r   r   r2   =   s   r2   c               @   s   e Zd ZdZdS ) SSHListenServerForwardingChannels   forwarded-tcpipN)r   r   r   r3   r   r   r   r   r4   A   s   r4   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   s*   t jj| f|| || _d | _d| _d S )Nr    )r   
SSHChannelr   r   r   	clientBuf)r   r   argskwr   r   r   r   `   s    z$SSHConnectForwardingChannel.__init__c             C   sR   t jd| j  t| j| jd | jd }t|t| }|j| j| j	 || _
dS )z,
        See: L{channel.SSHChannel}
        zconnecting to %s:%ir   r   N)r   r!   r   r   _reactorr   r   ZaddCallbacks
_setClient_closeZ_channelOpenDeferred)r   r&   Zepdr   r   r   r(   g   s    z'SSHConnectForwardingChannel.channelOpenc             C   sd   || _ tjd| j  | jr2| j jj| j d| _| j jdd rX| j| 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 %s:%iNr   r    )r   r   r!   r   r7   r,   r%   r$   )r   r   r   r   r   r;   r   s    z&SSHConnectForwardingChannel._setClientc             C   s   t jd|  | j  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: %sN)r   r!   r/   )r   r*   r   r   r   r<      s    z"SSHConnectForwardingChannel._closec             C   s(   | j r| j jj| n|  j|7  _dS )z,
        See: L{channel.SSHChannel}
        N)r   r,   r%   r7   )r   r-   r   r   r   r.      s    z(SSHConnectForwardingChannel.dataReceivedc             C   s:   | j r6tjd| j  | j jr&| j  | j jj  | ` dS )z,
        See: L{channel.SSHChannel}
        z#closed remote forwarding channel %sN)r   r   r!   r"   r   r/   r,   )r   r   r   r   r)      s    z"SSHConnectForwardingChannel.closedN)r   r   r   __doc__r   r:   r   r(   r;   r<   r.   r)   r   r   r   r   r5   G   s   
r5   c             C   s   t |\}}t|| ||dS )N)remoteWindowremoteMaxPacketavatar)unpackOpen_direct_tcpipr5   )r?   r@   r-   rA   ZremoteHPZorigHPr   r   r   openConnectForwardingClient   s
    rC   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  _ n| jj| d S )N)r$   r   r%   )r   r-   r   r   r   r.      s    z SSHForwardingClient.dataReceivedc             C   s   | j r| j j  d | _ d S )N)r   r/   )r   r*   r   r   r   connectionLost   s    
z"SSHForwardingClient.connectionLostN)r   r   r   r   r.   rE   r   r   r   r   r      s   r   c             C   sl   | \}}|\}}t |tr$|jd}t |tr8|jd}tj|tjd| }tj|tj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.
    zutf-8z>L)
isinstancer
   encoder   NSstructpack)ZdestinationsourceconnHostconnPortorigHostorigPortr   Zorigr   r   r   r      s    




r   c             C   s   t j| \}}tr&t|tr&|jd}ttjd|dd d }t j|dd \}}trpt|trp|jd}ttjd|dd d }||f||ffS )z(Unpack the data to a usable format.
    zutf-8z>LN   r   )	r   getNSr	   rF   bytesdecodeintrI   unpack)r-   rL   restrM   rN   rO   r   r   r   rB      s    

rB   c             C   s   | \}}t j|tjd| S )zv
    Pack the data for tcpip forwarding.

    @param peer: A tuple of the (host, port) .
    @type peer: L{tuple}
    z>L)r   rH   rI   rJ   )Zpeerr   r   r   r   r   packGlobal_tcpip_forward   s    rW   c             C   sJ   t j| \}}tr&t|tr&|jd}ttjd|d d d }||fS )Nzutf-8z>LrP   r   )	r   rQ   r	   rF   rR   rS   rT   rI   rU   )r-   r   rV   r   r   r   r   unpackGlobal_tcpip_forward   s
    
rX   )#r>   Z
__future__r   r   rI   Ztwisted.internetr   r   Ztwisted.internet.endpointsr   r   Ztwisted.pythonr   Ztwisted.python.compatr	   r
   Ztwisted.conch.sshr   r   ZFactoryr   r6   r   r2   r4   r5   rC   ZProtocolr   r   ZpackOpen_forwarded_tcpiprB   ZunpackOpen_forwarded_tcpiprW   rX   r   r   r   r   <module>	   s*   _