U
    
W[                     @   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|| |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 d| j  t| jjdkr:| jjdd  }| | 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   |    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   dataReceived1   s    z'SSHListenForwardingChannel.dataReceivedc                 C   s   | j j  d S r   )r   r.   loseConnectionr   r   r   r   eofReceived4   s    z&SSHListenForwardingChannel.eofReceivedc                 C   s.   t | dr*td| j  | jj  | `d S )Nr   z#closing local forwarding channel %s)hasattrr   r"   r#   r   r.   r2   r3   r   r   r   r*   7   s    
z!SSHListenForwardingChannel.closedN)r   r   r   r)   r-   r1   r4   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   r6   =   s   r6   c                   @   s   e Zd ZdZdS ) SSHListenServerForwardingChannels   forwarded-tcpipNr7   r   r   r   r   r9   A   s   r9   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 d| j  t| j| jd | jd }t|t| }|| j| j	 || _
dS ),
        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d| j  | jr2| j j| j d| _| j jdd rX| | 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   r<   r.   r&   r%   )r   r   r   r   r   rA   r   s    z&SSHConnectForwardingChannel._setClientc                 C   s   t 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: %sN)r   r"   r2   r+   r   r   r   rB      s    z"SSHConnectForwardingChannel._closec                 C   s(   | j r| j j| n|  j|7  _dS )r?   N)r   r.   r&   r<   r/   r   r   r   r1      s    z(SSHConnectForwardingChannel.dataReceivedc                 C   s:   | j r6td| j  | j jr&|   | j j  | ` dS )r?   z#closed remote forwarding channel %sN)r   r   r"   r#   r   r2   r.   r3   r   r   r   r*      s    z"SSHConnectForwardingChannel.closedN)r   r   r   __doc__r   r@   r   r)   rA   rB   r1   r*   r   r   r   r   r:   G   s   
r:   c                 C   s   t |\}}t|| ||dS )N)remoteWindowremoteMaxPacketavatar)unpackOpen_direct_tcpipr:   )rE   rF   r0   rG   ZremoteHPZorigHPr   r   r   openConnectForwardingClient   s    rI   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| d S r   )r%   r   r&   r/   r   r   r   r1      s    z SSHForwardingClient.dataReceivedc                 C   s   | j r| j   d | _ d S r   )r   r2   r+   r   r   r   connectionLost   s    
z"SSHForwardingClient.connectionLostN)r   r   r   r   r1   rK   r   r   r   r   r      s   r   c                 C   sl   | \}}|\}}t |tr$|d}t |tr8|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)
isinstancer
   encoder   NSstructpack)ZdestinationsourceconnHostconnPortorigHostorigPortr   Zorigr   r   r   r      s    




r   c                 C   s   t | \}}tr&t|tr&|d}ttd|dd d }t |dd \}}trpt|trp|d}ttd|dd d }||f||ffS )z(Unpack the data to a usable format.
    rL   rM   N   r   	r   ZgetNSr	   rN   bytesdecodeintrQ   Zunpack)r0   rT   restrU   rV   rW   r   r   r   rH      s    

rH   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}
    rM   )r   rP   rQ   rR   )Zpeerr   r   r   r   r   packGlobal_tcpip_forward   s    r^   c                 C   sJ   t | \}}tr&t|tr&|d}ttd|d d d }||fS )NrL   rM   rX   r   rY   )r0   r   r]   r   r   r   r   unpackGlobal_tcpip_forward   s
    
r_   )#rD   Z
__future__r   r   rQ   Ztwisted.internetr   r   Ztwisted.internet.endpointsr   r   Ztwisted.pythonr   Ztwisted.python.compatr	   r
   Ztwisted.conch.sshr   r   ZFactoryr   r;   r   r6   r9   r:   rI   ZProtocolr   r   ZpackOpen_forwarded_tcpiprH   ZunpackOpen_forwarded_tcpipr^   r_   r   r   r   r   <module>   s*   _