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
