U
    W[y~                     @   s  d Z ddlmZmZ ddlZddlmZ edZedZerfddl	m
Z
mZmZmZ ddlmZmZ nG d	d
 d
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 ddlmZmZmZ ddlmZ ddl m!Z!m"Z" ddl#m$Z$ ddl%m&Z& G dd de'Z(G dd dej)Z*G dd de'Z+ddl m,Z, erHe,-e+e*ej. G dd dej/Z0G dd dZ1G dd  d Z2G d!d" d"Z3G d#d$ d$Z4edk	redk	rdd%lm5Z5 dd&l	m6Z6m7Z7m8Z8m9Z9 dd'l	m:Z:m;Z; G d(d) d)Z<G d*d+ d+e5j=Z>G d,d- d-e8j?Z@G d.d/ d/ZAG d0d1 d1eAe:jBZCG d2d3 d3eAe:jDZEG d4d5 d5e;jFZGG d6d7 d7e7jHZIG d8d9 d9e6jJZKd:d; ZLG d<d= d=e$jMZNG d>d? d?e$jMZOG d@dA dAe$jMZPG dBdC dCe$jMZQdS )Dz!
Tests for L{twisted.conch.ssh}.
    )divisionabsolute_importN)requireModulecryptographypyasn1)common
forwardingsession_kex)avatarerrorc                   @   s   e Zd ZG dd dZdS )r   c                   @   s   e Zd ZdS )zavatar.ConchUserN)__name__
__module____qualname__ r   r   =/usr/lib/python3/dist-packages/twisted/conch/test/test_ssh.py	ConchUser   s    r   N)r   r   r   r   r   r   r   r   r      s   r   )publicRSA_opensshprivateRSA_openssh)publicDSA_opensshprivateDSA_openssh)portal)UnauthorizedLogin)deferprotocolreactor)ProcessTerminated)failurelog)unittest)LoopbackRelayc                   @   s$   e Zd ZdZdZdd Zdd ZdS )ConchTestRealma"  
    A realm which expects a particular avatarId to log in once and creates a
    L{ConchTestAvatar} for that request.

    @ivar expectedAvatarID: The only avatarID that this realm will produce an
        avatar for.

    @ivar avatar: A reference to the avatar after it is requested.
    Nc                 C   s
   || _ d S N)expectedAvatarID)selfr#   r   r   r   __init__1   s    zConchTestRealm.__init__c                 G   sN   || j kr8| jdk	rtdt | _|d | j| jjfS td| j |f dS )z
        Return a new L{ConchTestAvatar} if the avatarID matches the expected one
        and this is the first avatar request.
        NzOnly one login allowedr   zOnly %r may log in, not %r)r#   r   r   ConchTestAvatarlogout)r$   ZavatarIDZmindZ
interfacesr   r   r   requestAvatar5   s    

zConchTestRealm.requestAvatar)r   r   r   __doc__r   r%   r(   r   r   r   r   r!   %   s   	r!   c                   @   sL   e Zd ZdZesdZdZdd Zdd Zdd	 Z	d
d Z
dd Zdd ZdS )r&   z
    An avatar against which various SSH features can be tested.

    @ivar loggedOut: A flag indicating whether the avatar logout method has been
        called.
    cannot run without cryptographyFc                 C   sB   t j|  i | _i | _| jtjt	j
d | jdti d S )N)   sessions   direct-tcpip   crazy)r   r   r%   	listenersglobalRequestsZchannelLookupupdater	   Z
SSHSessionr   ZopenConnectForwardingClientZsubsystemLookupCrazySubsystemr$   r   r   r   r%   P   s    zConchTestAvatar.__init__c                 C   s   || j d< dS )Nfoo   r.   r$   datar   r   r   
global_fooZ   s    
zConchTestAvatar.global_fooc                 C   s   || j d< dS )Nfoo_2)r3      datar4   r5   r   r   r   global_foo_2_   s    
zConchTestAvatar.global_foo_2c                 C   sf   t |\}}z&tj|t | j||ft j|d}W n   td d Y dS X || j	||f< dS d S )N)Z	interfacez2something went wrong with remote->local forwardingr   r3   )
r   unpackGlobal_tcpip_forwardr   Z	listenTCPZSSHListenForwardingFactoryconnZ SSHListenServerForwardingChannelr   errr-   r$   r6   ZhostZportlistenerr   r   r   global_tcpip_forwardd   s       
z$ConchTestAvatar.global_tcpip_forwardc                 C   s@   t |\}}| j||fd }|s(dS | j||f= |  dS )Nr   r3   )r   r;   r-   getstopListeningr>   r   r   r   global_cancel_tcpip_forwardt   s    z+ConchTestAvatar.global_cancel_tcpip_forwardc                 C   s0   d| _ | j D ]}td|  |  qd S )NTzstopListening %s)	loggedOutr-   valuesr   msgrB   )r$   r?   r   r   r   r'   ~   s    zConchTestAvatar.logoutN)r   r   r   r)   r   skiprD   r%   r7   r:   r@   rC   r'   r   r   r   r   r&   D   s   

r&   c                   @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )ConchSessionForTestAvatarz2
    An ISession adapter for ConchTestAvatar.
    c                 C   s4   || _ | | j _d| _d| _d| _d| _t | _dS )zq
        Initialize the session and create a reference to it on the avatar for
        later inspection.
        NFr   )	r   _testSessioncmdprotoptyReqeofr   DeferredonClose)r$   r   r   r   r   r%      s    z"ConchSessionForTestAvatar.__init__c                 C   s    t d || _|| _d| _d S )Nzpty reqT)r   rF   _terminalType_windowSizerL   )r$   ZtermZ
windowSizeZattrsr   r   r   getPty   s    
z ConchSessionForTestAvatar.getPtyc                 C   s"   t d || _t| d| _d S )Nzopening shell   shell)r   rF   rK   EchoTransportrJ   )r$   rK   r   r   r   	openShell   s    
z#ConchSessionForTestAvatar.openShellc                 C   s   || _ || _| d }|dkr8t|}td|j n|dkrdt|}||dd   |  nb|dkrt	|}||dd   |  n6|dkrt
|}||dd   |  n
tdd	| jjj_d S )
Nr      falses   echo   s   secho   s   eechobad execr3   )rJ   rK   splitFalseTransportr   Z	callLaterloseConnectionrT   writeSuperEchoTransportErrEchoTransportr   
ConchErrorr   r<   	transportexpectedLoseConnection)r$   rK   rJ   ftr   r   r   execCommand   s(    



z%ConchSessionForTestAvatar.execCommandc                 C   s
   d| _ d S Nr3   )rM   r1   r   r   r   eofReceived   s    z%ConchSessionForTestAvatar.eofReceivedc                 C   s,   t d| j  | jjj| _| jd  d S )Nzclosed cmd "%s")	r   rF   rJ   rK   r	   ZremoteWindowLeftremoteWindowLeftAtCloserO   callbackr1   r   r   r   closed   s    z ConchSessionForTestAvatar.closedN)
r   r   r   r)   r%   rR   rU   re   rg   rj   r   r   r   r   rH      s   rH   )
componentsc                   @   s   e Zd Zdd Zdd ZdS )r0   c                 O   s   d S r"   r   )r$   argskwr   r   r   r%      s    zCrazySubsystem.__init__c                 C   s   dS )z
        good ... good
        Nr   r1   r   r   r   connectionMade   s    zCrazySubsystem.connectionMadeN)r   r   r   r%   rn   r   r   r   r   r0      s   r0   c                   @   s    e Zd ZdZdd Zdd ZdS )r[   a  
    False transport should act like a /bin/false execution, i.e. just exit with
    nonzero status, writing nothing to the terminal.

    @ivar proto: The protocol associated with this transport.
    @ivar closed: A flag tracking whether C{loseConnection} has been called yet.
    c                 C   s   || _ ||  d| _dS )zY
        @type p L{twisted.conch.ssh.session.SSHSessionProcessProtocol} instance
        r   NrK   makeConnectionrj   r$   pr   r   r   r%      s    
zFalseTransport.__init__c                 C   sL   | j r
dS d| _ | j  | j  | j  | jttddd dS )zI
        Disconnect the protocol associated with this transport.
        Nr3      	rj   rK   ZinConnectionLostZoutConnectionLostZerrConnectionLostZprocessEndedr   ZFailurer   r1   r   r   r   r\      s    


zFalseTransport.loseConnectionN)r   r   r   r)   r%   r\   r   r   r   r   r[      s   	r[   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )rT   c                 C   s   || _ ||  d| _d S Nr   ro   rq   r   r   r   r%      s    
zEchoTransport.__init__c                 C   s:   t t| | j| | jd d|kr6|   d S )N   
    )r   rF   reprrK   outReceivedr\   r5   r   r   r   r]     s
    zEchoTransport.writec                 C   sL   | j r
d S d| _ | j  | j  | j  | jttdd d  d S Nr3   r   rt   r1   r   r   r   r\   	  s     


zEchoTransport.loseConnectionNr   r   r   r%   r]   r\   r   r   r   r   rT      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 ru   ro   rq   r   r   r   r%     s    
zErrEchoTransport.__init__c                 C   s   | j | | j d d S Nrv   )rK   errReceivedr5   r   r   r   r]     s    zErrEchoTransport.writec                 C   sL   | j r
d S d| _ | j  | j  | j  | jttdd d  d S rz   rt   r1   r   r   r   r\     s     


zErrEchoTransport.loseConnectionNr{   r   r   r   r   r_     s   r_   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )r^   c                 C   s   || _ ||  d| _d S ru   ro   rq   r   r   r   r%   &  s    
zSuperEchoTransport.__init__c                 C   s4   | j | | j d | j | | j d d S r|   )rK   ry   r}   r5   r   r   r   r]   +  s    zSuperEchoTransport.writec                 C   sL   | j r
d S d| _ | j  | j  | j  | jttdd d  d S rz   rt   r1   r   r   r   r\   1  s     


z!SuperEchoTransport.loseConnectionNr{   r   r   r   r   r^   $  s   r^   )checkers)channel
connectionfactorykeys)ra   userauthc                   @   s   e Zd ZejfZdd ZdS )ConchTestPasswordCheckerc                 C   s.   |j dkr |jdkr t|j S ttdS )N   testuser   testpasszBad credentials)ZusernameZpasswordr   succeedfail	Exception)r$   Zcredentialsr   r   r   requestAvatarIdB  s    z(ConchTestPasswordChecker.requestAvatarIdN)r   r   r   r~   ZIUsernamePasswordZcredentialInterfacesr   r   r   r   r   r   ?  s   r   c                   @   s   e Zd Zdd ZdS )ConchTestSSHCheckerc                 C   s"   |dkst | j| dk rdS dS )Nr      FT)lenZsuccessfulCredentials)r$   ZavatarIdr   r   r   areDoneJ  s    zConchTestSSHChecker.areDoneN)r   r   r   r   r   r   r   r   r   H  s   r   c                   @   sF   e Zd ZdZejejdZdd Z	dd Z
dd Zd	d
 Zdd ZdS )ConchTestServerFactoryr   )s   ssh-userauth   ssh-connectionc                 C   s4   t  }| j |_| |_t| dr*| j|_|| _|S )Nrb   )ConchTestServerZprivateKeysr   ZsupportedPublicKeysr   hasattrrb   rK   )r$   ZaddrrK   r   r   r   buildProtocolW  s    
z$ConchTestServerFactory.buildProtocolc                 C   s   t jtt jtdS N)s   ssh-rsas   ssh-dss)r   Key
fromStringr   r   r1   r   r   r   getPublicKeysb  s    

z$ConchTestServerFactory.getPublicKeysc                 C   s   t jtt jtdS r   )r   r   r   r   r   r1   r   r   r   getPrivateKeysh  s    

z%ConchTestServerFactory.getPrivateKeysc                 C   s   dt dgiS )a%  
            Diffie-Hellman primes that can be used for the
            diffie-hellman-group-exchange-sha1 key exchange.

            @return: The primes and generators.
            @rtype: L{dict} mapping the key size to a C{list} of
                C{(generator, prime)} tupple.
            i   s   diffie-hellman-group14-sha1)r
   ZgetDHGeneratorAndPrimer1   r   r   r   	getPrimesn  s    z ConchTestServerFactory.getPrimesc                 C   s   t j| ||S r"   )r   
SSHFactory
getService)r$   Ztransnamer   r   r   r     s    z!ConchTestServerFactory.getServiceN)r   r   r   Znoisyr   ZSSHUserAuthServerr   SSHConnectionservicesr   r   r   r   r   r   r   r   r   r   O  s   r   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	ConchTestBaser   c                 C   s0   | j r
d S t| ds&td| |f d| _ d S )Nrb   z"unexpectedly lost connection %s
%sr3   )doner   r   FailTestr$   reasonr   r   r   connectionLost  s    

zConchTestBase.connectionLostc                 C   s4   d| _ |tjkr(ttd| ||f  |   d S )Nr3   z*got disconnect for %s: reason %s, desc: %s)rb   ra   ZDISCONNECT_BY_APPLICATIONr   r=   r   r\   )r$   Z
reasonCodeZdescr   r   r   receiveError  s    
  zConchTestBase.receiveErrorc                 C   s"   t d|f d| _|   d S )Nzgot unimplemented: seqid %sr3   )r   r   rb   r\   )r$   ZseqIDr   r   r   receiveUnimplemented  s    z"ConchTestBase.receiveUnimplementedN)r   r   r   r   r   r   r   r   r   r   r   r     s   r   c                   @   s   e Zd Zdd ZdS )r   c                 C   s   t | | tj| | d S r"   )r   r   ra   SSHServerTransportr   r   r   r   r     s    zConchTestServer.connectionLostN)r   r   r   r   r   r   r   r   r     s   r   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )ConchTestClientz
        @ivar _channelFactory: A callable which accepts an SSH connection and
            returns a channel which will be attached to a new channel on that
            connection.
        c                 C   s
   || _ d S r"   )_channelFactoryr$   ZchannelFactoryr   r   r   r%     s    zConchTestClient.__init__c                 C   s   t | | tj| | d S r"   )r   r   ra   SSHClientTransportr   r   r   r   r     s    zConchTestClient.connectionLostc                 C   s<   |t jt k}|dk}|r.|r.tdS ttdS )Ns/   85:25:04:32:58:55:96:9f:57:ee:fb:a8:1a:ea:69:dar3   zKey or fingerprint mismatch)	r   r   r   r   Zblobr   r   r   r   )r$   keyfpZkeyMatchZfingerprintMatchr   r   r   verifyHostKey  s    
zConchTestClient.verifyHostKeyc                 C   s   |  tdt| j d S )Nr   )ZrequestServiceConchTestClientAuthConchTestClientConnectionr   r1   r   r   r   connectionSecure  s    z ConchTestClient.connectionSecureN)r   r   r   r)   r%   r   r   r   r   r   r   r   r     s
   r   c                   @   s8   e Zd ZdZdZdZdd Zdd Zdd Zdd	 Z	d
S )r   r   c                 C   s(   | j s| jrtdtj| | d S )Nz2got USERAUTH_SUCCESS before password and publickey)canSucceedPasswordcanSucceedPublicKeyr   r   r   SSHUserAuthClientssh_USERAUTH_SUCCESS)r$   Zpacketr   r   r   r     s
    z(ConchTestClientAuth.ssh_USERAUTH_SUCCESSc                 C   s   d| _ tdS )Nr3   r   )r   r   r   r1   r   r   r   getPassword  s    zConchTestClientAuth.getPasswordc                 C   s   d| _ ttjtS rf   )r   r   r   r   r   r   r   r1   r   r   r   getPrivateKey  s    z!ConchTestClientAuth.getPrivateKeyc                 C   s   t jtS r"   )r   r   r   r   r1   r   r   r   getPublicKey  s    z ConchTestClientAuth.getPublicKeyN)
r   r   r   ZhasTriedNoner   r   r   r   r   r   r   r   r   r   r     s   r   c                   @   s,   e Zd ZdZdZdZdZdd Zdd Zd	S )
r   z
        @ivar _completed: A L{Deferred} which will be fired when the number of
            results collected reaches C{totalResults}.
        r   r      c                 C   s   t j|  || _d S r"   )r   r   r%   r   r   r   r   r   r%     s    z"ConchTestClientConnection.__init__c                 C   s   |  | j| d d S )Nr<   )ZopenChannelr   r1   r   r   r   serviceStarted  s    z(ConchTestClientConnection.serviceStartedN)	r   r   r   r)   r   ZresultsZtotalResultsr%   r   r   r   r   r   r     s   r   c                   @   sL   e 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S )SSHTestChannelc                 O   s:   || _ || _g | _g | _t | _tjj	| f|| d S r"   )
r   _openedreceivedreceivedExtr   rN   rO   r   
SSHChannelr%   )r$   r   Zopenedrl   kwargsr   r   r   r%     s    
zSSHTestChannel.__init__c                 C   s   | j | d S r"   )r   Zerrbackr   r   r   r   
openFailed  s    zSSHTestChannel.openFailedc                 C   s   | j |  d S r"   )r   ri   )r$   ignorer   r   r   channelOpen  s    zSSHTestChannel.channelOpenc                 C   s   | j | d S r"   )r   appendr5   r   r   r   dataReceived   s    zSSHTestChannel.dataReceivedc                 C   s,   |t jkr| j| ntd|f  d S )NzUnrecognized extended data: %r)r   ZEXTENDED_DATA_STDERRr   r   r   rF   )r$   ZdataTyper6   r   r   r   extReceived  s    
zSSHTestChannel.extReceivedc                 C   s   t d|\| _d S )Nz>L)structZunpackstatus)r$   r   r   r   r   request_exit_status  s    z"SSHTestChannel.request_exit_statusc                 C   s
   d| _ d S )NT)	eofCalledr1   r   r   r   rg     s    zSSHTestChannel.eofReceivedc                 C   s   | j d  d S r"   )rO   ri   r1   r   r   r   rj     s    zSSHTestChannel.closedN)r   r   r   r%   r   r   r   r   r   rg   rj   r   r   r   r   r     s   	r   c                  C   s"   t dtjtgi} t | S )z
        Produces a SSHPublicKeyChecker with an in-memory key mapping with
        a single use: 'testuser'

        @return: L{twisted.conch.checkers.SSHPublicKeyChecker}
        r   )r~   ZInMemorySSHKeyDBr   r   r   r   ZSSHPublicKeyChecker)ZconchTestPublicKeyDBr   r   r   conchTestPublicKeyChecker  s    r   c                   @   sj   e Zd ZdZesdZes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S )SSHProtocolTestsz^
    Tests for communication between L{SSHServerTransport} and
    L{SSHClientTransport}.
    can't run without cryptographyCannot run without PyASN1r+   c                    s   t  td| _t| j}t }|t  |t	  || t
 }||_|  |d| _t| j| _t fdd| _t| j| _| j| j | j| j S )z
        Create a connected SSH client and server protocol pair and return a
        L{Deferred} which fires with an L{SSHTestChannel} instance connected to
        a channel on that SSH connection.
        r   Nc                    s   t fd| i S )Nr<   )r   r   r   r   resultr   r   <lambda>C      z:SSHProtocolTests._ourServerOurClientTest.<locals>.<lambda>)r   rN   r!   realmr   ZPortalr   ZregisterCheckerr   r   r   startFactoryr   Zserverr    ZclientTransportr   ZclientZserverTransportrp   )r$   r   r   rr   ZsshpcZfacr   r   r   _ourServerOurClientTest0  s&    

z(SSHProtocolTests._ourServerOurClientTestc                    sd      } fdd}||  fdd}||  fdd}||  fdd}|| |S )	z
        Run the Conch server against the Conch client.  Set up several different
        channels which exercise different behaviors and wait for them to
        complete.  Verify that the channels with errors log them.
        c              	      s&   |  _  | j| dtddtS )N	   subsystems	   not-crazyr3   r   assertFailurer<   sendRequestr   NSr   r   r1   r   r   cbSubsystemT  s       zFSSHProtocolTests.test_subsystemsAndGlobalRequests.<locals>.cbSubsystemc                    s    j }|j|dtddS )Nr   r,   r3   r   r<   r   r   r   ignoredr   r1   r   r   cbNotCrazyFailed\  s       zKSSHProtocolTests.test_subsystemsAndGlobalRequests.<locals>.cbNotCrazyFailedc                    s\    j }|jddd}|jddd}| jd  |jdddt}t|||gS )N   foo   barr3   s   foo-2   bar2r9   )	r   r<   ZsendGlobalRequestaddCallbackassertEqualr   r   r   gatherResults)r   r   Zd1Zd2Zd3r1   r   r   cbGlobalRequestsb  s    zKSSHProtocolTests.test_subsystemsAndGlobalRequests.<locals>.cbGlobalRequestsc                    s>      jjjddd  j}d|jj_|j  |	  d S )Nr   r   )r2   r8   T)
r   r   r   r.   r   r<   ra   rb   ZserviceStoppedr\   r   r1   r   r   
disconnectp  s    

zESSHProtocolTests.test_subsystemsAndGlobalRequests.<locals>.disconnectr   r   )r$   r   r   r   r   r   r   r1   r    test_subsystemsAndGlobalRequestsL  s    



z1SSHProtocolTests.test_subsystemsAndGlobalRequestsc                    st     }tddd  fdd}|| fdd}|| fdd	}|| fd
d}|| |S )z
        L{SSHChannel.sendRequest} can open a shell with a I{pty-req} request,
        specifying a terminal type and window size.
           conch-test-term   P   r   r   r   c                    s   | _ | j| d dS )Ns   pty-reqr3   )r   r<   r   r   r6   r$   r   r   	cbChannel  s    z.SSHProtocolTests.test_shell.<locals>.cbChannelc                    sd    j jjjd j} |j j j  |jd  |jd  	|j
  j}|j|dddS )Nr   r   r   rS   r   r3   )r   r   r<   Zchannelsr	   ZassertIsr   rP   rQ   
assertTruerL   r   r   )r   r	   r   r1   r   r   cbPty  s    z*SSHProtocolTests.test_shell.<locals>.cbPtyc                    s6    j d  j j j  t j j jjj	jgS )Ns   testing the shell! )
r   r]   r<   ZsendEOFr   r   rO   r   r   rI   r   r1   r   r   cbShell  s    
z,SSHProtocolTests.test_shell.<locals>.cbShellc                    sZ    j jdkr td j jf   d j jd   j j   j	j
jj d S )Nr   zshell exit status was not 0: %ir   s   testing the shell! 
)r   r   r   rF   r   joinr   r   r   r   r   rI   rM   r   r1   r   r   cbExited  s    
z-SSHProtocolTests.test_shell.<locals>.cbExited)r   r	   ZpackRequest_pty_reqr   )r$   r   r   r   r   r   r   r   r   
test_shell}  s      
	



zSSHProtocolTests.test_shellc                    s8      } fdd}||  fdd}|| |S )z
        If L{SSHChannel.sendRequest} issues an exec which the server responds to
        with an error, the L{Deferred} it returns fires its errback.
        c              	      s&   |  _  | j| dtddtS )N   execs	   jumboliahr3   r   r   r1   r   r   r     s       z3SSHProtocolTests.test_failedExec.<locals>.cbChannelc                    s$     tj} |d jjd d S )Nr   )rY   N)flushLoggedErrorsr   r`   r   valuerl   r   errorsr1   r   r   cbFailed  s    z2SSHProtocolTests.test_failedExec.<locals>.cbFailedr   )r$   r   r   r   r   r1   r   test_failedExec  s    

z SSHProtocolTests.test_failedExecc                    sN      } fdd}||  fdd}||  fdd}|| |S )z
        When the process started by a L{SSHChannel.sendRequest} exec request
        exits, the exit status is reported to the channel.
        c                    s   |  _ | j| dtddS )Nr   rV   r3   r   r   r1   r   r   r     s       z5SSHProtocolTests.test_falseChannel.<locals>.cbChannelc                    s    j jS r"   r   rO   r   r1   r   r   cbExec  s    z2SSHProtocolTests.test_falseChannel.<locals>.cbExecc                    s$      jjg    jjd d S ru   )r   r   r   ZassertNotEqualr   r   r1   r   r   cbClosed  s    z4SSHProtocolTests.test_falseChannel.<locals>.cbClosedr   r$   r   r   r  r  r   r1   r   test_falseChannel  s    


z"SSHProtocolTests.test_falseChannelc                    sT    j ddd} fdd}||  fdd}||  fdd	}|| |S )
z
        Bytes sent over the extended channel for stderr data are delivered to
        the channel's C{extReceived} method.
           rW   ZlocalWindowZlocalMaxPacketc                    s   |  _ | j| dtddS )Nr   s   eecho hellor3   r   r   r1   r   r   r     s       z5SSHProtocolTests.test_errorChannel.<locals>.cbChannelc                    s   t  jj jjjjgS r"   r   r   r   rO   r   r   rI   r   r1   r   r   r    s    
z2SSHProtocolTests.test_errorChannel.<locals>.cbExecc                    sp      jjg    d jjd    jjd   jj    jjd    jj j	j
jj d S )Nr      hello
r   r  )r   r   r   r   r   r   r   r   localWindowLeftr   r   rI   rh   r   r1   r   r   r    s    
z4SSHProtocolTests.test_errorChannel.<locals>.cbClosedr   r  r   r1   r   test_errorChannel  s    

	
z"SSHProtocolTests.test_errorChannelc                    s,      dt} fdd}|| |S )z
        When an attempt is made to open an unknown channel type, the L{Deferred}
        returned by L{SSHChannel.sendRequest} fires its errback.
        s   crazy-unknown-channelc                    s4     tj} |d jjd  t|d d S )Nr   )   zunknown channelr3   )r   r   r`   r   r   rl   r   r   r1   r   r   r     s    z6SSHProtocolTests.test_unknownChannel.<locals>.cbFailed)r   r   r   r   )r$   dr   r   r1   r   test_unknownChannel  s     
z$SSHProtocolTests.test_unknownChannelc                    sT    j ddd} fdd}||  fdd}||  fdd	}|| |S )
zc
        An L{SSHChannel} can be configured with a maximum packet size to
        receive.
           r3   r  c                    s   |  _ | j| dtddS )Nr   s   secho hellor3   r   r   r1   r   r   r     s       z2SSHProtocolTests.test_maxPacket.<locals>.cbChannelc                    s    j jS r"   r   r   r1   r   r   r    s    z/SSHProtocolTests.test_maxPacket.<locals>.cbExecc                    s^      jjd   d jjd   d jjd    jjd   jj d S )Nr   r   r  r  )	r   r   r   r   r   r   r	  r   r   r   r1   r   r   r     s
    z1SSHProtocolTests.test_maxPacket.<locals>.cbClosedr   r  r   r1   r   test_maxPacket  s     


zSSHProtocolTests.test_maxPacketc                    sT    j ddd} fdd}||  fdd}||  fdd	}|| |S )
ze
        Normal standard out bytes are sent to the channel's C{dataReceived}
        method.
        r  rW   r  c                    s   |  _ | j| dtddS )Nr   s
   echo hellor3   r   r   r1   r   r   r   1  s       z-SSHProtocolTests.test_echo.<locals>.cbChannelc                    s   t  jj jjjjgS r"   r  r   r1   r   r   cbEcho7  s    
z*SSHProtocolTests.test_echo.<locals>.cbEchoc                    s`      jjd   d jjd    jjd   jj    jj jj	j
j d S )Nr   r   r  r  )r   r   r   r   r   r	  r   r   r   r   rI   rh   r   r1   r   r   r  =  s    
z,SSHProtocolTests.test_echo.<locals>.cbClosedr   )r$   r   r   r  r  r   r1   r   	test_echo*  s    


zSSHProtocolTests.test_echoN)r+   )r   r   r   r)   r   rG   r   r   r   r   r   r  r
  r  r  r  r   r   r   r   r   $  s   
1/ r   c                   @   sF   e Zd ZesdZesdZdddZdd Zdd	 Zd
d Z	dd Z
dS )SSHFactoryTestsr   r   Nc                    s6   t  }dd } fdd|_| |_|_|  |S )Nc                   S   s   dt d iS )Nzssh-rsa)r   r   r   r   r   r   r   T  r   z0SSHFactoryTests.makeSSHFactory.<locals>.<lambda>c                      s    S r"   r   r   primesr   r   r   U  r   )r   r   r   r   r   r   )r$   r  Z
sshFactoryZgpkr   r  r   makeSSHFactoryR  s    zSSHFactoryTests.makeSSHFactoryc                 C   s$   |   }|d}| |tj dS )zc
        By default, buildProtocol() constructs an instance of
        SSHServerTransport.
        N)r  r   ZassertIsInstancera   r   )r$   r   r   r   r   r   test_buildProtocol[  s    
z"SSHFactoryTests.test_buildProtocolc                    s:   g   fdd}|   }||_|d | dg  dS )zc
        buildProtocol() calls 'self.protocol()' to construct a protocol
        instance.
        c                     s     |  t S r"   )r   ra   r   )rl   Zcallsr   r   makeProtocolk  s    
zHSSHFactoryTests.test_buildProtocolRespectsProtocol.<locals>.makeProtocolNr   )r  r   r   r   )r$   r  r   r   r  r   "test_buildProtocolRespectsProtocole  s    
z2SSHFactoryTests.test_buildProtocolRespectsProtocolc                 C   s6   | j dd}|d}| d|j | d|j dS )zg
        Group key exchanges are not supported when we don't have the primes
        database.
        Nr  "   diffie-hellman-group-exchange-sha1$   diffie-hellman-group-exchange-sha256)r  r   ZassertNotInsupportedKeyExchanges)r$   f1Zp1r   r   r   test_buildProtocolNoPrimest  s    
  z*SSHFactoryTests.test_buildProtocolNoPrimesc                 C   s:   | j ddid}|d}| d|j | d|j dS )zU
        Group key exchanges are supported when we have the primes database.
        r3   )r   r  r  Nr  r  )r  r   ZassertInr  )r$   f2Zp2r   r   r   test_buildProtocolWithPrimes  s    
  z,SSHFactoryTests.test_buildProtocolWithPrimes)N)r   r   r   r   rG   r   r  r  r  r  r   r   r   r   r   r  J  s   
	
r  c                   @   sV   e Zd ZdZesdZesdZer*eej	Z	dd Z
dd Zdd	 Zd
d Zdd ZdS )MPTestszs
    Tests for L{common.getMP}.

    @cvar getMP: a method providing a MP parser.
    @type getMP: C{callable}
    r   r   c                 C   s   |  | dd dS )z
        L{common.getMP} should parse the a multiple precision integer from a
        string: a 4-byte length followed by length bytes of the integer.
        s         )r3   r   Nr   getMPr1   r   r   r   
test_getMP  s    zMPTests.test_getMPc                 C   s   |  | dd dS )zv
        L{common.getMP} should be able to parse a big enough integer
        (that doesn't fit on one byte).
        s      )ir   Nr"  r1   r   r   r   test_getMPBigInteger  s    zMPTests.test_getMPBigIntegerc                 C   s   |  | ddd dS )zg
        L{common.getMP} has the ability to parse multiple integer in the same
        string.
        s               r   )r3   r   r   Nr"  r1   r   r   r   test_multipleGetMP  s    zMPTests.test_multipleGetMPc                 C   s   |  | dd dS )zu
        When more data than needed is sent to L{common.getMP}, it should return
        the remaining data.
        s         foo)r3   r   Nr"  r1   r   r   r   test_getMPRemainingData  s    zMPTests.test_getMPRemainingDatac                 C   s   |  tj| jd dS )z
        When the string passed to L{common.getMP} doesn't even make 5 bytes,
        it should raise a L{struct.error}.
        s    N)ZassertRaisesr   r   r#  r1   r   r   r   test_notEnoughData  s    zMPTests.test_notEnoughDataN)r   r   r   r)   r   rG   r   staticmethodr   r#  r$  r%  r&  r'  r(  r   r   r   r   r!    s   



r!  c                   @   s    e Zd ZdZesdZdd ZdS )GMPYInstallDeprecationTestszI
    Tests for the deprecation of former GMPY accidental public API.
    r*   c                 C   s>   t   | | jg}| t|d | |d d d dS )zD
        L{twisted.conch.ssh.common.install} is deprecated.
        r3   r   messagezAtwisted.conch.ssh.common.install was deprecated in Twisted 16.5.0N)r   installZflushWarningstest_deprecatedr   r   )r$   warningsr   r   r   r-    s    
z+GMPYInstallDeprecationTests.test_deprecatedN)r   r   r   r)   r   rG   r-  r   r   r   r   r*    s   r*  )Rr)   Z
__future__r   r   r   Ztwisted.python.reflectr   r   r   Ztwisted.conch.sshr   r   r	   r
   Ztwisted.conchr   r   Ztwisted.conch.test.keydatar   r   r   r   Ztwisted.credr   Ztwisted.cred.errorr   Ztwisted.internetr   r   r   Ztwisted.internet.errorr   Ztwisted.pythonr   r   Ztwisted.trialr   Ztwisted.conch.test.loopbackr    objectr!   r   r&   rH   rk   ZregisterAdapterZISessionZProtocolr0   r[   rT   r_   r^   r~   r   r   r   r   ra   r   r   ZSSHProtocolCheckerr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   ZTestCaser   r  r!  r*  r   r   r   r   <module>   sf   BC 	5*  (HA