o
    b&                     @   sT   d Z ddlmZ ddlmZ ddl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
    )implementer)
interfaces)Logger)logc                   @   s   e Zd ZU dZe ZdZeed< 							d0ddZ	de
fdd	Zdef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 )1
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}
    Nnamer   c                 C   sn   |pd| _ | j | _|pd| _|| _|| _d| _|| _|| _|| _d| _	d| _
g | _d| _d| _d| _d | _d S )Ni   i          r   )localWindowSizelocalWindowLeftlocalMaxPacketremoteWindowLeftremoteMaxPacket
areWritingconndataavatarspecificDatabufextBufclosinglocalClosedremoteClosedid)selflocalWindowr   remoteWindowr   r   r   r    r   ;/usr/lib/python3/dist-packages/twisted/conch/ssh/channel.py__init__9   s    



zSSHChannel.__init__returnc                 C   s   |   dS )Nascii)	__bytes__decoder   r   r   r   __str__T   s   zSSHChannel.__str__c                 C   s    | j }|sd}d|| j| jf S )zD
        Return a byte string representation of the channel
        s   Nones   <SSHChannel %b (lw %d rw %d)>)r   r   r   )r   r   r   r   r   r"   W   s   zSSHChannel.__bytes__c                 C   sL   | j d ur
t| j pd}| jr| jd}nd}d| d| d| j  S )Nunknownr!   NonezSSHChannel z (z) on )r   strr   r#   r   	logPrefix)r   r   r   r   r   r   r)   e   s
   zSSHChannel.logPrefixc                 C      | j 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_loginfo)r   r   r   r   r   channelOpenm   s   zSSHChannel.channelOpenc                 C      | j jd|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: {reason})reasonN)r,   error)r   r0   r   r   r   
openFailedv      zSSHChannel.openFailedc                 C   sv   | j | | _ | js| jsd| _|   | jr!| j}d| _| | | jr7| j}g | _|D ]\}}| || q,dS d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   sB   | ddd}t| d| d}|r||S | jjd|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}
           -   _r!   request_Nz#unhandled request for {requestType})requestTyper   )replacer#   getattrr,   r-   )r   r=   r   foofr   r   r   requestReceived   s   zSSHChannel.requestReceivedc                 C   r/   )zL
        Called when we receive data.

        @type data: L{bytes}
        zgot data {data})r   Nr,   debugr   r   r   r   r   dataReceived   s   zSSHChannel.dataReceivedc                 C   s   | j jd||d dS )z
        Called when we receive extended data (usually standard error).

        @type dataType: L{int}
        @type data:     L{str}
        z%got extended data {dataType} {data!r})dataTyper   NrC   r   rG   r   r   r   r   extReceived   s   
zSSHChannel.extReceivedc                 C   r*   )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   | j 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   r*   )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   rM      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 sa| 
  dS d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   sendDataranger   rK   )r   r   toprmpr5   roffsetr   r   r   r5      s(   
zSSHChannel.writec                 C   s  | j r#| j d d |kr| j d d  |7  < dS | j ||g dS t|| jkrD|d| j ||| jd gg}| _ d| _|   t|| jkrn| j| ||d| j  || jd }|  j| j8  _t|| jksK|r| j| || |  jt|8  _| j	r| 
  dS 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   appendrN   r   r   rO   r   r   sendExtendedDatar   rK   rH   r   r   r   r6      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)r5   joinrE   r   r   r   writeSequence
  r3   zSSHChannel.writeSequencec                 C   s*   d| _ | js| js| j|  dS dS dS )zr
        Close the channel if there is no buferred data.  Otherwise, note the
        request and return.
        r   N)r   r   r   r   	sendCloser$   r   r   r   rK     s   zSSHChannel.loseConnectionc                 C      | j j S )z
        See: L{ITransport.getPeer}

        @return: The remote address of this connection.
        @rtype: L{SSHTransportAddress}.
        )r   	transportgetPeerr$   r   r   r   r^        zSSHChannel.getPeerc                 C   r\   )z
        See: L{ITransport.getHost}

        @return: An address describing this side of the connection.
        @rtype: L{SSHTransportAddress}.
        )r   r]   getHostr$   r   r   r   r`   %  r_   zSSHChannel.getHostc                 C      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   rO   .      zSSHChannel.stopWritingc                 C   ra   )ze
        Called when the remote buffer has more room, as a hint to continue
        writing.
        Nr   r$   r   r   r   r4   4  rb   zSSHChannel.startWriting)r   r   r   r   NNN)__name__
__module____qualname____doc__r   r,   r   bytes__annotations__r   r(   r%   r"   r)   r.   r2   r9   rB   rF   rI   rJ   rL   rM   r5   r6   rZ   rK   r^   r`   rO   r4   r   r   r   r   r      s@   
  
		 				r   N)rf   zope.interfacer   twisted.internetr   twisted.loggerr   twisted.pythonr   
ITransportr   r   r   r   r   <module>   s   