o
    bIr                     @   s   d Z ddlZddlmZ ddlmZ ddlmZ ddlm	Z	 edZ
ddlmZ e
r3dd	lmZmZ nG d
d dZG dd dejZG dd dZG dd dejZG dd de	jZG dd de	jZdS )z1
This module tests twisted.conch.ssh.connection.
    N)channel)test_userauth)requireModule)unittestcryptography)error)common
connectionc                   @   s   e Zd ZG dd dZdS )r	   c                   @   s   e Zd ZdS )zconnection.SSHConnectionN)__name__
__module____qualname__ r   r   D/usr/lib/python3/dist-packages/twisted/conch/test/test_connection.pySSHConnection   s    r   N)r
   r   r   r   r   r   r   r   r	      s    r	   c                   @   sd   e Zd ZdZdZdZ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 )TestChannela  
    A mocked-up version of twisted.conch.ssh.channel.SSHChannel.

    @ivar gotOpen: True if channelOpen has been called.
    @type gotOpen: L{bool}
    @ivar specificData: the specific channel open data passed to channelOpen.
    @type specificData: L{bytes}
    @ivar openFailureReason: the reason passed to openFailed.
    @type openFailed: C{error.ConchError}
    @ivar inBuffer: a C{list} of strings received by the channel.
    @type inBuffer: C{list}
    @ivar extBuffer: a C{list} of 2-tuples (type, extended data) of received by
        the channel.
    @type extBuffer: C{list}
    @ivar numberRequests: the number of requests that have been made to this
        channel.
    @type numberRequests: L{int}
    @ivar gotEOF: True if the other side sent EOF.
    @type gotEOF: L{bool}
    @ivar gotOneClose: True if the other side closed the connection.
    @type gotOneClose: L{bool}
    @ivar gotClosed: True if the channel is closed.
    @type gotClosed: L{bool}
       TestChannelFc                 C   s
   d| j  S )NzTestChannel %i)idselfr   r   r   	logPrefix:   s   
zTestChannel.logPrefixc                 C   s4   d| _ || _g | _g | _d| _d| _d| _d| _dS )zF
        The channel is open.  Set up the instance variables.
        Tr   FN)gotOpenspecificDatainBuffer	extBuffernumberRequestsgotEOFgotOneClose	gotClosed)r   r   r   r   r   channelOpen=   s   
zTestChannel.channelOpenc                 C   s
   || _ dS )zD
        Opening the channel failed.  Store the reason why.
        N)openFailureReason)r   reasonr   r   r   
openFailedJ      
zTestChannel.openFailedc                 C   s   |  j d7  _ |dkS )z_
        A test request.  Return True if data is 'data'.

        @type data: L{bytes}
              data)r   r   datar   r   r   request_testP   s   zTestChannel.request_testc                 C   s   | j | dS )z=
        Data was received.  Store it in the buffer.
        N)r   appendr%   r   r   r   dataReceivedY   s   zTestChannel.dataReceivedc                 C   s   | j ||f dS )zF
        Extended data was received.  Store it in the buffer.
        N)r   r(   )r   coder&   r   r   r   extReceived_   s   zTestChannel.extReceivedc                 C   
   d| _ dS )z1
        EOF was received.  Remember it.
        TN)r   r   r   r   r   eofReceivede   r"   zTestChannel.eofReceivedc                 C   r,   )z3
        Close was received.  Remember it.
        TN)r   r   r   r   r   closeReceivedk   r"   zTestChannel.closeReceivedc                 C   r,   )z7
        The channel is closed.  Rembember it.
        TN)r   r   r   r   r   closedq   r"   zTestChannel.closedN)r
   r   r   __doc__namer   r   r   r   r!   r'   r)   r+   r-   r.   r/   r   r   r   r   r      s    	r   c                   @   s$   e Zd ZdZdZdd Zdd ZdS )
TestAvatarz?
    A mocked-up version of twisted.conch.avatar.ConchUser
    {   c                 C   s4   |t jkrt |||| dS |dkrt| jddS )z
        The server wants us to return a channel.  If the requested channel is
        our TestChannel, return it, otherwise return None.
        )remoteWindowremoteMaxPacketr&   avatar   conch-error-argserror args in wrong orderN)r   r1   r   
ConchError_ARGS_ERROR_CODE)r   channelType
windowSize	maxPacketr&   r   r   r   lookupChannel   s   
zTestAvatar.lookupChannelc                 C   s    |dkrdS |dkrd|fS dS )z
        The client has made a global request.  If the global request is
        'TestGlobal', return True.  If the global request is 'TestData',
        return True and the request-specific data we received.  Otherwise,
        return False.
        
   TestGlobalT   TestDataFr   )r   requestTyper&   r   r   r   gotGlobalRequest   s
   zTestAvatar.gotGlobalRequestN)r
   r   r   r0   r:   r>   rB   r   r   r   r   r2   x   s
    r2   c                   @   s@   e Zd ZdZes
dZdd Zdd Zdd Zd	d
 Z	dd Z
dS )TestConnectionz}
    A subclass of SSHConnection for testing.

    @ivar channel: the current channel.
    @type channel. C{TestChannel}
    Cannot run without cryptographyc                 C      dS )NrC   r   r   r   r   r   r      s   zTestConnection.logPrefixc                 C   rE   )zT
        The other side made the 'TestGlobal' global request.  Return True.
        Tr   r%   r   r   r   global_TestGlobal   s   z TestConnection.global_TestGlobalc                 C   s   d|fS )zt
        The other side made the 'Test-Data' global request.  Return True and
        the data we received.
        Tr   r%   r   r   r   global_Test_Data   s   zTestConnection.global_Test_Datac                 C   s   t |||d| _| jS )z
        The other side is requesting the TestChannel.  Create a C{TestChannel}
        instance, store it, and return it.
        )r4   r5   r&   )r   r   r   r<   r=   r&   r   r   r   channel_TestChannel   s   z"TestConnection.channel_TestChannelc                 C   s   t d)zU
        The other side is requesting the ErrorChannel.  Raise an exception.
        zno such thing)AssertionErrorrH   r   r   r   channel_ErrorChannel   s   z#TestConnection.channel_ErrorChannelN)r
   r   r   r0   r   skipr   rF   rG   rI   rK   r   r   r   r   rC      s    
rC   c                   @   s  e Zd Zes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*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Z d:d; Z!d<d= Z"d>d? Z#d@dA Z$dBdC Z%dDS )EConnectionTestsrD   c                 C   s6   t d | _t | j_t | _| j| j_| j  d S N)r   FakeTransport	transportr2   r6   rC   connserviceStartedr   r   r   r   setUp   s
   

zConnectionTests.setUpc                 C   s@   | j | | jjdd | j_| j td|jdd  dS )z?
        Open the channel with the default connection.
        Nz>2L   s         )rQ   openChannelrP   packetsssh_CHANNEL_OPEN_CONFIRMATIONstructpackr   r   r   r   r   r   _openChannel   s
   zConnectionTests._openChannelc                 C   s   | j   d S rN   )rQ   serviceStoppedr   r   r   r   tearDown      zConnectionTests.tearDownc                 C   s   |  | jjj| j dS )z_
        Test that the connection links itself to the avatar in the
        transport.
        N)assertIsrP   r6   rQ   r   r   r   r   test_linkAvatar   s   zConnectionTests.test_linkAvatarc                 C   s   t  }t  }| j| | j| | jd | |j | |j | |j | |j | j  | |j | |j | |j ddl	m
} | |j| dS )zF
        Test that serviceStopped() closes any open channels.
        s                   r   )ConnectionLostN)r   rQ   rV   rX   
assertTruer   assertFalser   r]   twisted.internet.errorrb   assertIsInstancer   )r   channel1channel2rb   r   r   r   test_serviceStopped   s   
z#ConnectionTests.test_serviceStoppedc                 C   s   | j tdd  | | jjtjdfg g | j_| j tdd d  | | jjtjdfg g | j_| j tdd  | | jjtj	dfg g | j_| j tdd  | | jjg  dS )	z
        Test that global request packets are dispatched to the global_*
        methods and the return values are translated into success or failure
        messages.
        r?          r@   s	   test datas   TestBad    N)
rQ   ssh_GLOBAL_REQUESTr   NSassertEqualrP   rW   r	   MSG_REQUEST_SUCCESSMSG_REQUEST_FAILUREr   r   r   r   test_GLOBAL_REQUEST  s"   z#ConnectionTests.test_GLOBAL_REQUESTc                    sB    j ddd} j d  fdd}|| | j |S )zh
        Test that global request success packets cause the Deferred to be
        called back.
           requestr$   Tc                    s     | d d S Nr$   )ro   )r&   r   r   r   check"  s   z3ConnectionTests.test_REQUEST_SUCCESS.<locals>.check)rQ   sendGlobalRequestssh_REQUEST_SUCCESSaddCallback
addErrbackfailr   dru   r   r   r   test_REQUEST_SUCCESS  s   
z$ConnectionTests.test_REQUEST_SUCCESSc                    sB    j ddd} j d  fdd}| j || |S )zg
        Test that global request failure packets cause the Deferred to be
        erred back.
        rs   r$   Tc                    s     | jjd d S rt   )ro   valuer&   )fr   r   r   ru   1     z3ConnectionTests.test_REQUEST_FAILURE.<locals>.check)rQ   rv   ssh_REQUEST_FAILURErx   rz   ry   r{   r   r   r   test_REQUEST_FAILURE)  s   
z$ConnectionTests.test_REQUEST_FAILUREc                 C   sH  | j `| jtdd  | | jjj | 	| jjj| j | 	| jjj
d | 	| jjjd | 	| jjjd | 	| jjjd | 	| j jtjdfg g | j _| jtdd  |   | 	| j jtjdtd	 td
 fg g | j _| jtdd  |   | 	| j jtjdtd td
 fg dS )z
        Test that open channel packets cause a channel to be created and
        opened or a failure message to be returned.
        r                        r#   s                
   BadChannels               s         s   unknown channelrk   s   ErrorChannels         s   unknown failureN)rP   r6   rQ   ssh_CHANNEL_OPENr   rn   rc   r   r   ro   r&   r   remoteWindowLeftr5   rW   r	   MSG_CHANNEL_OPEN_CONFIRMATIONflushLoggedErrorsMSG_CHANNEL_OPEN_FAILUREr   r   r   r   test_CHANNEL_OPEN8  sV   
z!ConnectionTests.test_CHANNEL_OPENc                 C   s   || j j_| jtdd  | tj	}| 
t|dd| | 
|d jjd | 
| j jtjdtd td	 fg d
S )z
        Deliver a request for a channel open which will result in an exception
        being raised during channel lookup.  Assert that an error response is
        delivered as a result.
        r7   r   r#   zExpected one error, got: r   )r3   r8   s         {s   error args in wrong orderrk   N)rP   r6   r:   rQ   r   r   rn   r   r   r9   ro   lenr~   argsrW   r	   r   )r   r*   errorsr   r   r   _lookupChannelErrorTestl  s$   
z'ConnectionTests._lookupChannelErrorTestc                 C   s   |  d dS )a  
        If a C{lookupChannel} implementation raises L{error.ConchError} with the
        arguments in the wrong order, a C{MSG_CHANNEL_OPEN} failure is still
        sent in response to the message.

        This is a temporary work-around until L{error.ConchError} is given
        better attributes and all of the Conch code starts constructing
        instances of it properly.  Eventually this functionality should be
        deprecated and then removed.
        r3   N)r   r   r   r   r   test_lookupChannelError  s   z'ConnectionTests.test_lookupChannelErrorc                 C   st   t  }| j| | jd | |jd | |jd | |jd | | jj| d | | jj	d d dS )zv
        Test that channel open confirmation packets cause the channel to be
        notified that it's open.
        s                       r          N)
r   rQ   rV   rX   ro   r   r5   r   channelsToRemoteChannellocalToRemoteChannelr[   r   r   r   test_CHANNEL_OPEN_CONFIRMATION  s   z.ConnectionTests.test_CHANNEL_OPEN_CONFIRMATIONc                 C   sP   t  }| j| | jdtd  | |jjd | 	| jj
| dS )zz
        Test that channel open failure packets cause the channel to be
        notified that its opening failed.
                     failure!)r   r#   N)r   rQ   rV   ssh_CHANNEL_OPEN_FAILUREr   rn   ro   r   r   assertIsNonechannelsgetr[   r   r   r   test_CHANNEL_OPEN_FAILURE  s   z)ConnectionTests.test_CHANNEL_OPEN_FAILUREc                 C   s8   t  }| | |j}| jd | |j|d  dS )zc
        Test that channel window adjust messages add bytes to the channel
        window.
        r   r#   N)r   r\   r   rQ   ssh_CHANNEL_WINDOW_ADJUSTro   )r   r   oldWindowSizer   r   r   test_CHANNEL_WINDOW_ADJUST  s
   
z*ConnectionTests.test_CHANNEL_WINDOW_ADJUSTc                 C   s  t ddd}| | | jdtd  | |jdg | | jj	t
jdfg g | j_	d|jd  }| jdt|  | |jdg | | jj	t
jd	fg t  }| | d|jd  }g | j_	| jd
t|  | |jg  | | jj	t
jd	fg dS )z
        Test that channel data messages are passed up to the channel, or
        cause the channel to be closed if the data is too large.
              localWindowlocalMaxPacketr   r$               ar#         r   N)r   r\   rQ   ssh_CHANNEL_DATAr   rn   ro   r   rP   rW   r	   MSG_CHANNEL_WINDOW_ADJUSTlocalWindowLeftMSG_CHANNEL_CLOSEr   r   r   longDatabigDatar   r   r   test_CHANNEL_DATA  s:   
	


z!ConnectionTests.test_CHANNEL_DATAc                 C   s  t ddd}| | | jdtd  | |jdg | | jj	t
jdfg g | j_	d|jd	  }| jdt|  | |jdg | | jj	t
jd
fg t  }| | d|jd	  }g | j_	| jdt|  | |jg  | | jj	t
jd
fg dS )z
        Test that channel extended data messages are passed up to the channel,
        or cause the channel to be closed if they're too big.
        r   r   r   s           r$   )r   r$   r   r   r#   r   s          N)r   r\   rQ   ssh_CHANNEL_EXTENDED_DATAr   rn   ro   r   rP   rW   r	   r   r   r   r   r   r   r   r   test_CHANNEL_EXTENDED_DATA  sF   
	


z*ConnectionTests.test_CHANNEL_EXTENDED_DATAc                 C   s,   t  }| | | jd | |j dS )zN
        Test that channel eof messages are passed up to the channel.
        r   N)r   r\   rQ   ssh_CHANNEL_EOFrc   r   r[   r   r   r   test_CHANNEL_EOF  s   
z ConnectionTests.test_CHANNEL_EOFc                 C   sh   t  }| | | |j | |j | |j | j| | j	d | |j | |j dS )z
        Test that channel close messages are passed up to the channel.  Also,
        test that channel.close() is called if both sides are closed when this
        message is received.
        r   N)
r   r\   rc   r   rd   r   r   rQ   	sendClosessh_CHANNEL_CLOSEr[   r   r   r   test_CHANNEL_CLOSE  s   
z"ConnectionTests.test_CHANNEL_CLOSEc                    sp   t  } |  jdtd d   |jd  jdtd d d } fdd}|| |S )	zS
        Test that channel requests that succeed send MSG_CHANNEL_SUCCESS.
        r      testrl   r#   rj   r$   c                          jjtjdfg d S Nr   )ro   rP   rW   r	   MSG_CHANNEL_SUCCESSresultr   r   r   ru   2     
z;ConnectionTests.test_CHANNEL_REQUEST_success.<locals>.check)	r   r\   rQ   ssh_CHANNEL_REQUESTr   rn   ro   r   rx   r   r   r|   ru   r   r   r   test_CHANNEL_REQUEST_success$  s   

z,ConnectionTests.test_CHANNEL_REQUEST_successc                    sP   t  } |  jdtd d } fdd}| j || |S )zP
        Test that channel requests that fail send MSG_CHANNEL_FAILURE.
        r   r   rj   c                    r   r   )ro   rP   rW   r	   MSG_CHANNEL_FAILUREr   r   r   r   ru   E  r   z;ConnectionTests.test_CHANNEL_REQUEST_failure.<locals>.check)	r   r\   rQ   r   r   rn   rx   rz   ry   r   r   r   r   test_CHANNEL_REQUEST_failure;  s   

z,ConnectionTests.test_CHANNEL_REQUEST_failurec                    s>   t  } |  j|ddd} jd  fdd}|S )zj
        Test that channel request success messages cause the Deferred to be
        called back.
        r   r$   Tr   c                    s     |  d S rN   )rc   r   r   r   r   ru   Y  r_   z;ConnectionTests.test_CHANNEL_REQUEST_SUCCESS.<locals>.check)r   r\   rQ   sendRequestssh_CHANNEL_SUCCESSr   r   r   r   test_CHANNEL_REQUEST_SUCCESSO  s   
z,ConnectionTests.test_CHANNEL_REQUEST_SUCCESSc                    sT   t  } |  j|ddd} jd  fdd}| j || |S )zi
        Test that channel request failure messages cause the Deferred to be
        erred back.
        r   rk   Tr   c                    s     | jjd d S )Nzchannel request failed)ro   r~   r   r   r   r   ru   h  r   z;ConnectionTests.test_CHANNEL_REQUEST_FAILURE.<locals>.check)r   r\   rQ   r   ssh_CHANNEL_FAILURErx   rz   ry   r   r   r   r   test_CHANNEL_REQUEST_FAILURE^  s   

z,ConnectionTests.test_CHANNEL_REQUEST_FAILUREc                 C   s|   | j ddd}|dd  | j ddd | | jjtjt	dd	 ftjt	dd
 fg | | j j
d|gi dS )zQ
        Test that global request messages are sent in the right format.
        s	   wantReplyr$   Tc                 S      d S rN   r   failurer   r   r   <lambda>u      z8ConnectionTests.test_sendGlobalRequest.<locals>.<lambda>s   noReplyrk   Fs   datarl   globalN)rQ   rv   ry   ro   rP   rW   r	   MSG_GLOBAL_REQUESTr   rn   	deferredsr   r|   r   r   r   test_sendGlobalRequesto  s   z&ConnectionTests.test_sendGlobalRequestc                 C   sX   t  }| j|d | | jjtjt	dd fg | |j
d | | jjd dS )zO
        Test that open channel messages are sent in the right format.
        s   aaaar   s             aaaar   r#   N)r   rQ   rV   ro   rP   rW   r	   MSG_CHANNEL_OPENr   rn   r   localChannelIDr[   r   r   r   test_openChannel  s   
z ConnectionTests.test_openChannelc              	   C   s   t  }| | | j|ddd}|dd  | j|ddd d|_| j|ddd | | jjt	j
d	td d
 ft	j
d	td d fg | | jjd |g dS )zR
        Test that channel request messages are sent in the right format.
        r   Tc                 S   r   rN   r   r   r   r   r   r     r   z2ConnectionTests.test_sendRequest.<locals>.<lambda>   test2rk   Fs   test3r   s   testrl   r   N)r   r\   rQ   r   ry   localClosedro   rP   rW   r	   MSG_CHANNEL_REQUESTr   rn   r   r   r   r|   r   r   r   test_sendRequest  s$   
z ConnectionTests.test_sendRequestc                 C   st   t dd}| | d|_| j|d | |jd d|_| j|d | |jd | | jjt	j
dfg dS )	zi
        Test that channel window adjust messages cause bytes to be added
        to the window.
        r   )r   r   r#   T            N)r   r\   r   rQ   adjustWindowro   r   rP   rW   r	   r   r[   r   r   r   test_adjustWindow  s   

z!ConnectionTests.test_adjustWindowc                 C   sX   t  }| | | j|d d|_| j|d | | jjtj	dt
d fg dS )zO
        Test that channel data messages are sent in the right format.
        r   T   br   N)r   r\   rQ   sendDatar   ro   rP   rW   r	   MSG_CHANNEL_DATAr   rn   r[   r   r   r   test_sendData  s   
zConnectionTests.test_sendDatac                 C   s\   t  }| | | j|dd d|_| j|dd | | jjtj	dt
d fg dS )zX
        Test that channel extended data messages are sent in the right format.
        r#   r   Tr   r   r   N)r   r\   rQ   sendExtendedDatar   ro   rP   rW   r	   MSG_CHANNEL_EXTENDED_DATAr   rn   r[   r   r   r   test_sendExtendedData  s   
z%ConnectionTests.test_sendExtendedDatac                 C   sb   t  }| | | j| | | jjtjdfg d|_	| j| | | jjtjdfg dS )zN
        Test that channel EOF messages are sent in the right format.
        r   TN)
r   r\   rQ   sendEOFro   rP   rW   r	   MSG_CHANNEL_EOFr   r[   r   r   r   test_sendEOF  s   
zConnectionTests.test_sendEOFc                 C   s   t  }| | | j| | |j | | jjt	j
dfg | j| | | jjt	j
dfg t  }| | | |j | |j d|_| j| | |j dS )zP
        Test that channel close messages are sent in the right format.
        r   TN)r   r\   rQ   r   rc   r   ro   rP   rW   r	   r   r   rd   r   remoteClosed)r   r   rh   r   r   r   test_sendClose  s(   



zConnectionTests.test_sendClosec                 C   sZ   | j dddd}| |jd | |jd | |jd | tj| j jdddd dS )z
        Test that getChannel dispatches to the avatar when an avatar is
        present. Correct functioning without the avatar is verified in
        test_CHANNEL_OPEN.
        r   2      r$   r   N)	rQ   
getChannelro   r&   r   r5   assertRaisesr   r9   r[   r   r   r   test_getChannelWithAvatar  s   z)ConnectionTests.test_getChannelWithAvatarc                 C   sH   | j `| | jdd | | jddd | | jdd dS )zW
        Test that gotGlobalRequests dispatches to global_* without an avatar.
        r?   r$   s	   Test-Data)Tr$   s	   BadGlobalN)rP   r6   rc   rQ   rB   ro   rd   r   r   r   r   "test_gotGlobalRequestWithoutAvatar  s   z2ConnectionTests.test_gotGlobalRequestWithoutAvatarc                 C   sB   t  }| | | jj|dddd}| |tj}| j| |S )z
        Whenever an SSH channel gets closed any Deferred that was returned by a
        sendRequest() on its parent connection must be errbacked.
           dummyrequest	   dummydatar#   	wantReply)r   r\   rQ   r   assertFailurer   r9   channelClosedr   r   r   r   9test_channelClosedCausesLeftoverChannelDeferredsToErrback)  s   
zIConnectionTests.test_channelClosedCausesLeftoverChannelDeferredsToErrbackN)&r
   r   r   r   rL   rS   r\   r^   ra   ri   rr   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rM      sH    
4%+	rM   c                   @   s(   e Zd ZdZes
dZdd Zdd ZdS )CleanConnectionShutdownTestszL
    Check whether correct cleanup is performed on connection shutdown.
    rD   c                 C   s,   t d | _t | j_t | _| j| j_d S rN   )r   rO   rP   r2   r6   rC   rQ   r   r   r   r   rS   ?  s   
z"CleanConnectionShutdownTests.setUpc                 C   s8   | j   | j jdddd}| |tj}| j   |S )z
        Once the service is stopped any leftover global deferred returned by
        a sendGlobalRequest() call must be errbacked.
        r   r   r#   r   )rQ   rR   rv   r   r   r9   r]   r   r   r   r   9test_serviceStoppedCausesLeftoverGlobalDeferredsToErrbackE  s
   

zVCleanConnectionShutdownTests.test_serviceStoppedCausesLeftoverGlobalDeferredsToErrbackN)r
   r   r   r0   r   rL   rS   r   r   r   r   r   r   7  s    r   )r0   rY   twisted.conch.sshr   twisted.conch.testr   twisted.python.reflectr   twisted.trialr   r   twisted.conchr   r   r	   
SSHChannelr   r2   r   rC   TestCaserM   r   r   r   r   r   <module>   s(   \),    n