U
    
W[|&                     @   sh   d Z ddlmZmZ ddlmZ ddlmZ ddlm	Z	m
Z
 ddlmZ eejG dd dejZd	S )
z
The parent class for all the SSH Channels.  Currently implemented channels
are session, direct-tcp, and forwarded-tcp.

Maintainer: Paul Swartz
    )divisionabsolute_import)implementer)log)nativeString
intToBytes)
interfacesc                   @   s   e Zd ZdZdZd.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 Z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' Zd(d) Zd*d+ Zd,d- ZdS )/
SSHChannela  
    A class that represents a multiplexed channel over an SSH connection.
    The channel has a local window which is the maximum amount of data it will
    receive, and a remote which is the maximum amount of data the remote side
    will accept.  There is also a maximum packet size for any individual data
    packet going each way.

    @ivar name: the name of the channel.
    @type name: L{bytes}
    @ivar localWindowSize: the maximum size of the local window in bytes.
    @type localWindowSize: L{int}
    @ivar localWindowLeft: how many bytes are left in the local window.
    @type localWindowLeft: L{int}
    @ivar localMaxPacket: the maximum size of packet we will accept in bytes.
    @type localMaxPacket: L{int}
    @ivar remoteWindowLeft: how many bytes are left in the remote window.
    @type remoteWindowLeft: L{int}
    @ivar remoteMaxPacket: the maximum size of a packet the remote side will
        accept in bytes.
    @type remoteMaxPacket: L{int}
    @ivar conn: the connection this channel is multiplexed through.
    @type conn: L{SSHConnection}
    @ivar data: any data to send to the other side when the channel is
        requested.
    @type data: L{bytes}
    @ivar avatar: an avatar for the logged-in user (if a server channel)
    @ivar localClosed: True if we aren't accepting more data.
    @type localClosed: L{bool}
    @ivar remoteClosed: True if the other side isn't accepting more data.
    @type remoteClosed: L{bool}
    Nr   c                 C   sn   |pd| _ | j | _|pd| _|| _|| _d| _|| _|| _|| _d| _	d| _
g | _d| _d| _d| _d | _d S )Ni   i          r   )ZlocalWindowSizelocalWindowLeftlocalMaxPacketremoteWindowLeftremoteMaxPacket
areWritingconndataavatarspecificDatabufextBufclosingZlocalClosedZremoteClosedid)selfZlocalWindowr   ZremoteWindowr   r   r   r    r   ;/usr/lib/python3/dist-packages/twisted/conch/ssh/channel.py__init__:   s     

zSSHChannel.__init__c                 C   s   t |  S )N)r   	__bytes__r   r   r   r   __str__O   s    zSSHChannel.__str__c                 C   s6   | j }|sd}d| d t| j d t| j d S )zD
        Return a byte string representation of the channel
        s   Nones   <SSHChannel s    (lw s    rw s   )>)namer   r   r   )r   r    r   r   r   r   S   s    zSSHChannel.__bytes__c                 C   s>   | j d k	rt| j pd}| j}|r*t|}d||| j f S )NunknownzSSHChannel %s (%s) on %s)r   strr    r   r   	logPrefix)r   r   r    r   r   r   r#   a   s    zSSHChannel.logPrefixc                 C   s   t d dS )z
        Called when the channel is opened.  specificData is any data that the
        other side sent us when opening the channel.

        @type specificData: L{bytes}
        zchannel openNr   msg)r   r   r   r   r   channelOpenj   s    zSSHChannel.channelOpenc                 C   s   t d|  dS )z
        Called when the open failed for some reason.
        reason.desc is a string descrption, reason.code the SSH error code.

        @type reason: L{error.ConchError}
        z"other side refused open
reason: %sNr$   )r   reasonr   r   r   
openFailedt   s    zSSHChannel.openFailedc                 C   sr   | j | | _ | js&| js&d| _|   | jrB| j}d| _| | | jrn| j}g | _|D ]\}}| || qXdS )z
        Called when bytes are added to the remote window.  By default it clears
        the data buffers.

        @type data:    L{bytes}
        Tr   N)r   r   r   startWritingr   writer   writeExtended)r   r   btyper   r   r   addWindowBytes~   s    
zSSHChannel.addWindowBytesc                 C   s>   t |dd}t| d| d}|r,||S td|  dS )aJ  
        Called when a request is sent to this channel.  By default it delegates
        to self.request_<requestType>.
        If this function returns true, the request succeeded, otherwise it
        failed.

        @type requestType:  L{bytes}
        @type data:         L{bytes}
        @rtype:             L{bool}
           -   _z
request_%sNzunhandled request for %sr   )r   replacegetattrr   r%   )r   ZrequestTyper   Zfoofr   r   r   requestReceived   s    zSSHChannel.requestReceivedc                 C   s   t dt|  dS )zL
        Called when we receive data.

        @type data: L{bytes}
        zgot data %sNr   r%   reprr   r   r   r   r   dataReceived   s    zSSHChannel.dataReceivedc                 C   s   t d|t|f  dS )z
        Called when we receive extended data (usually standard error).

        @type dataType: L{int}
        @type data:     L{str}
        zgot extended data %s %sNr5   r   ZdataTyper   r   r   r   extReceived   s    zSSHChannel.extReceivedc                 C   s   t d dS )zD
        Called when the other side will send no more data.
        z
remote eofNr$   r   r   r   r   eofReceived   s    zSSHChannel.eofReceivedc                 C   s   t d |   dS )zD
        Called when the other side has closed the channel.
        zremote closeN)r   r%   loseConnectionr   r   r   r   closeReceived   s    
zSSHChannel.closeReceivedc                 C   s   t d dS )z
        Called when the channel is closed.  This means that both our side and
        the remote side have closed the channel.
        closedNr$   r   r   r   r   r>      s    zSSHChannel.closedc                 C   s   | j r|  j |7  _ dS t|}|| jkr^|d| j || jd  }| _ d| _|   | j}| j}| jj}td||}|D ]}|| ||||   q||  j|8  _| j	r| j s| 
  dS )z
        Write some data to the channel.  If there is not enough remote window
        available, buffer until it is.  Otherwise, split the data into
        packets of length remoteMaxPacket and send them.

        @type data: L{bytes}
        Nr   )r   lenr   r   stopWritingr   r   ZsendDataranger   r<   )r   r   topZrmpr*   roffsetr   r   r   r*      s&    
zSSHChannel.writec                 C   s  | j rD| j d d |kr0| j d d  |7  < n| j ||g dS t|| jkr|d| j ||| jd gg }| _ d| _|   t|| jkr| j| ||d| j  || jd }|  j| j8  _q|r| j| || |  jt|8  _| j	r| 
  dS )a  
        Send extended data to this channel.  If there is not enough remote
        window available, buffer until there is.  Otherwise, split the data
        into packets of length remoteMaxPacket and send them.

        @type dataType: L{int}
        @type data:     L{bytes}
        r   r
   N)r   appendr?   r   r   r@   r   r   ZsendExtendedDatar   r<   r9   r   r   r   r+      s,    	
zSSHChannel.writeExtendedc                 C   s   |  d| dS )z
        Part of the Transport interface.  Write a list of strings to the
        channel.

        @type data: C{list} of L{str}
        r   N)r*   joinr7   r   r   r   writeSequence  s    zSSHChannel.writeSequencec                 C   s"   d| _ | js| js| j|  dS )zr
        Close the channel if there is no buferred data.  Otherwise, note the
        request and return.
        r
   N)r   r   r   r   Z	sendCloser   r   r   r   r<     s    zSSHChannel.loseConnectionc                 C   s   | j j S )z
        See: L{ITransport.getPeer}

        @return: The remote address of this connection.
        @rtype: L{SSHTransportAddress}.
        )r   	transportgetPeerr   r   r   r   rJ   !  s    zSSHChannel.getPeerc                 C   s   | j j S )z
        See: L{ITransport.getHost}

        @return: An address describing this side of the connection.
        @rtype: L{SSHTransportAddress}.
        )r   rI   getHostr   r   r   r   rK   +  s    zSSHChannel.getHostc                 C   s   dS )z
        Called when the remote buffer is full, as a hint to stop writing.
        This can be ignored, but it can be helpful.
        Nr   r   r   r   r   r@   5  s    zSSHChannel.stopWritingc                 C   s   dS )ze
        Called when the remote buffer has more room, as a hint to continue
        writing.
        Nr   r   r   r   r   r)   <  s    zSSHChannel.startWriting)r   r   r   r   NNN)__name__
__module____qualname____doc__r    r   r   r   r#   r&   r(   r.   r4   r8   r:   r;   r=   r>   r*   r+   rH   r<   rJ   rK   r@   r)   r   r   r   r   r	      s:             
	

	
 



r	   N)rO   Z
__future__r   r   Zzope.interfacer   Ztwisted.pythonr   Ztwisted.python.compatr   r   Ztwisted.internetr   Z
ITransportZLoggerr	   r   r   r   r   <module>   s   