U
    ¹êW[!Õ  ã                   @   sš  d Z ddlZddlmZ ddlmZ ddlZddlm	Z	m
Z
 ddlm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 ddlmZ ddlmZmZ ddlmZm Z  ddl!m"Z"m#Z#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/ ddl&m0Z0m1Z1 ddl2m3Z3 ddl4m5Z5 ddl6m7Z7 ddl8m9Z9m:Z:m;Z; edƒr.edƒr.ddl<m=Z= ddl>m?Z? ddl@mAZA ddlBmCZC ddlDmEZE dd lFmGZG dd!lHmIZI dd"lJmKZKmLZL dd#lMmNZNmOZO dd$lPmQZQ dd%lRmSZSmTZTmUZUmVZV dd&lWmXZXmYZYmZZZm[Z[m\Z\m]Z]m^Z^ dd'l_m`Z` n(d(Zaeb Z? ZA ZC ZE ZG ZI ZK ZNZQdd)l-mcZc dd*ldmeZemfZf G d+d,„ d,eeƒZgG d-d.„ d.eGƒZhG d/d0„ d0eGƒZiG d1d2„ d2eGƒZjG d3d4„ d4ebƒZkG d5d6„ d6eƒZlG d7d8„ d8ebƒZmG d9d:„ d:eAƒZnG d;d<„ d<e?ƒZoeeƒG d=d>„ d>ebƒƒZpeeƒG d?d@„ d@ebƒƒZqG dAdB„ dBebƒZrG dCdD„ dDe,erƒZsG dEdF„ dFe,erƒZtG dGdH„ dHe,ƒZuG dIdJ„ dJebƒZvG dKdL„ dLe,ƒZwdS )Mz'
Tests for L{twisted.conch.endpoints}.
é    N)Úpack)ÚENOSYS)ÚverifyObjectÚverifyClass)Úimplementer)ÚglobalLogPublisherÚLogLevel)Ú	iteritemsÚnetworkString)ÚFailure)ÚFilePath)Úmsg)ÚrequireModule)ÚIAddressÚIStreamClientEndpoint)ÚFactoryÚProtocol)ÚCancelledErrorÚDeferredÚsucceedÚfail)ÚConnectionDoneÚConnectionRefusedError)ÚIPv4Address)ÚTestCase)ÚEventLoggingObserverÚMemoryReactorClock)ÚProcessTerminatedÚConnectingCancelledError)ÚPortal)Ú'InMemoryUsernamePasswordDatabaseDontUse)Ú
IConchUser)Ú
ConchErrorÚUserRejectedKeyÚHostKeyChangedZcryptographyzpyasn1.type)Úcommon)Ú
SSHFactory)ÚSSHUserAuthServer)ÚSSHConnection)ÚKey)Ú
SSHChannel)ÚSSHAgentServer)ÚKnownHostsFileÚ	ConsoleUI)ÚSSHPublicKeyCheckerÚInMemorySSHKeyDB)Ú	ConchUser)ÚpublicRSA_opensshÚprivateRSA_opensshÚ privateRSA_openssh_encrypted_aesÚprivateDSA_openssh)Ú_ISSHConnectionCreatorÚAuthenticationFailedÚSSHCommandAddressÚSSHCommandClientEndpointÚ	_ReadFileÚ_NewConnectionHelperÚ_ExistingConnectionHelper)ÚSSHClientTransportz%can't run w/o cryptography and pyasn1)ÚStringTransport)ÚFakeTransportÚconnectc                   @   s   e Zd ZdZdZdd„ ZdS )ÚAbortableFakeTransportzC
    A L{FakeTransport} with added C{abortConnection} support.
    Fc                 C   s
   d| _ dS )z}
        Abort the connection in a fake manner.

        This should really be implemented in the underlying module.
        TN©Úaborted©Úself© rE   úC/usr/lib/python3/dist-packages/twisted/conch/test/test_endpoints.pyÚabortConnectionN   s    z&AbortableFakeTransport.abortConnectionN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rB   rG   rE   rE   rE   rF   r@   G   s   r@   c                   @   s   e Zd ZdZdd„ ZdS )ÚBrokenExecSessionzO
    L{BrokenExecSession} is a session on which exec requests always fail.
    c                 C   s   dS )zÈ
        Fail all exec requests.

        @param data: Information about what is being executed.
        @type data: L{bytes}

        @return: C{0} to indicate failure
        @rtype: L{int}
        r   rE   ©rD   ÚdatarE   rE   rF   Úrequest_exec\   s    
zBrokenExecSession.request_execN©rH   rI   rJ   rK   rO   rE   rE   rE   rF   rL   X   s   rL   c                   @   s   e Zd ZdZdd„ ZdS )ÚWorkingExecSessionzS
    L{WorkingExecSession} is a session on which exec requests always succeed.
    c                 C   s   dS )zË
        Succeed all exec requests.

        @param data: Information about what is being executed.
        @type data: L{bytes}

        @return: C{1} to indicate success
        @rtype: L{int}
        é   rE   rM   rE   rE   rF   rO   n   s    
zWorkingExecSession.request_execNrP   rE   rE   rE   rF   rQ   j   s   rQ   c                   @   s   e Zd ZdZdd„ ZdS )ÚUnsatisfiedExecSessionz‰
    L{UnsatisfiedExecSession} is a session on which exec requests are always
    delayed indefinitely, never succeeding or failing.
    c                 C   s   t ƒ S )zç
        Delay all exec requests indefinitely.

        @param data: Information about what is being executed.
        @type data: L{bytes}

        @return: A L{Deferred} which will never fire.
        @rtype: L{Deferred}
        )r   rM   rE   rE   rF   rO      s    
z#UnsatisfiedExecSession.request_execNrP   rE   rE   rE   rF   rS   |   s   rS   c                   @   s   e Zd Zdd„ Zdd„ ZdS )ÚTrivialRealmc                 C   s
   i | _ d S ©N)ÚchannelLookuprC   rE   rE   rF   Ú__init__   s    zTrivialRealm.__init__c                 G   s   t ƒ }| j|_t|dd„ fS )Nc                   S   s   d S rU   rE   rE   rE   rE   rF   Ú<lambda>—   ó    z,TrivialRealm.requestAvatar.<locals>.<lambda>)r0   rV   r!   )rD   ZavatarIdZmindZ
interfacesZavatarrE   rE   rF   ÚrequestAvatar”   s    zTrivialRealm.requestAvatarN)rH   rI   rJ   rW   rZ   rE   rE   rE   rF   rT      s   rT   c                   @   s   e Zd ZdZdd„ ZdS )ÚAddressSpyFactoryNc                 C   s   || _ t | |¡S rU   )Úaddressr   ÚbuildProtocol)rD   r\   rE   rE   rF   r]   ž   s    zAddressSpyFactory.buildProtocol)rH   rI   rJ   r\   r]   rE   rE   rE   rF   r[   ›   s   r[   c                   @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚFixedResponseUIc                 C   s
   || _ d S rU   ©Úresult)rD   r`   rE   rE   rF   rW   ¥   s    zFixedResponseUI.__init__c                 C   s
   t | jƒS rU   )r   r`   ©rD   ÚtextrE   rE   rF   Úprompt©   s    zFixedResponseUI.promptc                 C   s   d S rU   rE   ra   rE   rE   rF   Úwarn­   s    zFixedResponseUI.warnN)rH   rI   rJ   rW   rc   rd   rE   rE   rE   rF   r^   ¤   s   r^   c                   @   s$   e Zd Zedd„ ƒZedd„ ƒZdS )ÚFakeClockSSHUserAuthServerc                 C   s
   | j jjS )zy
        Use the C{attemptsBeforeDisconnect} value defined by the factory to make
        it easier to override.
        )Ú	transportÚfactoryÚattemptsBeforeDisconnectrC   rE   rE   rF   rh   µ   s    z3FakeClockSSHUserAuthServer.attemptsBeforeDisconnectc                 C   s
   | j jjS )zÈ
        Use the reactor defined by the factory, rather than the default global
        reactor, to simplify testing (by allowing an alternate implementation
        to be supplied by tests).
        )rf   rg   ÚreactorrC   rE   rE   rF   Úclock¾   s    z FakeClockSSHUserAuthServer.clockN)rH   rI   rJ   Úpropertyrh   rj   rE   rE   rE   rF   re   ²   s   
re   c                   @   s2   e Zd Zedd„ ƒZedd„ ƒZeedœZdZ	dS )ÚCommandFactoryc                 C   s   dt jtdiS ©Nó   ssh-rsa)rN   )r)   Ú
fromStringr1   rC   rE   rE   rF   Ú
publicKeysÊ   s     
ÿzCommandFactory.publicKeysc                 C   s   dt jtdiS rm   )r)   ro   r2   rC   rE   rE   rF   ÚprivateKeysÑ   s     
ÿzCommandFactory.privateKeys)s   ssh-userauths   ssh-connectionr   N)
rH   rI   rJ   rk   rp   rq   re   r(   Úservicesrh   rE   rE   rE   rF   rl   É   s   

þ	rl   c                   @   s   e Zd ZdS )ÚMemoryAddressN)rH   rI   rJ   rE   rE   rE   rF   rs   ä   s   rs   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚSingleUseMemoryEndpointa]  
    L{SingleUseMemoryEndpoint} is a client endpoint which allows one connection
    to be set up and then exposes an API for moving around bytes related to
    that connection.

    @ivar pump: L{None} until a connection is attempted, then a L{IOPump}
        instance associated with the protocol which is connected.
    @type pump: L{IOPump}
    c                 C   s   d| _ || _dS )z˜
        @param server: An L{IProtocol} provider to which the client will be
            connected.
        @type server: L{IProtocol} provider
        N)ÚpumpÚ_server)rD   ÚserverrE   rE   rF   rW   õ   s    z SingleUseMemoryEndpoint.__init__c                 C   sf   | j d k	rtdƒ‚z| tƒ ¡}W n   tƒ  Y S X t| jt| jdd|t|ddƒ| _ t|ƒS d S )Nz(SingleUseMemoryEndpoint was already usedT©ÚisServerF)	ru   Ú	Exceptionr]   rs   r   r?   rv   r@   r   )rD   rg   ÚprotocolrE   rE   rF   r?   ÿ   s     
  ÿ 
ýzSingleUseMemoryEndpoint.connectN)rH   rI   rJ   rK   rW   r?   rE   rE   rE   rF   rt   ê   s   	
rt   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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#d$„Zd%d&„ Zd'd(„ Zd)S )+Ú"SSHCommandClientEndpointTestsMixinaà  
    Tests for L{SSHCommandClientEndpoint}, an L{IStreamClientEndpoint}
    implementations which connects a protocol with the stdin and stdout of a
    command running in an SSH session.

    These tests apply to L{SSHCommandClientEndpoint} whether it is constructed
    using L{SSHCommandClientEndpoint.existingConnection} or
    L{SSHCommandClientEndpoint.newConnection}.

    Subclasses must override L{create}, L{assertClientTransportState}, and
    L{finishConnection}.
    c                 C   s°   d| _ d| _d| _d| _tƒ | _tƒ | _t| jƒ| _	t
ƒ | _| j | j| j¡ | j	 | j¡ tƒ | _| j| j_| j	| j_	| j ¡  |  | jj¡ tdddƒ| _tddd	ƒ| _d S )
Ns   ssh.example.comi&¤  s   users   passwordZTCPz10.0.0.1i90  z192.168.100.200i1Ô  )ÚhostnameÚportÚuserÚpasswordr   ri   rT   Úrealmr   Úportalr    ZpasswdDBZaddUserÚregisterCheckerrl   rg   ZdoStartÚ
addCleanupZdoStopr   ÚclientAddressÚserverAddressrC   rE   rE   rF   ÚsetUp  s"    


z(SSHCommandClientEndpointTestsMixin.setUpc                 C   s   t d| jjf ƒ‚dS )z£
        Create and return a new L{SSHCommandClientEndpoint} to be tested.
        Override this to implement creation in an interesting way the endpoint.
        z%r did not implement createN©ÚNotImplementedErrorÚ	__class__rH   rC   rE   rE   rF   Úcreate2  s    ÿz)SSHCommandClientEndpointTestsMixin.createc                 C   s   t d| jjf ƒ‚dS )a™  
        Make an assertion about the connectedness of the given protocol's
        transport.  Override this to implement either a check for the
        connection still being open or having been closed as appropriate.

        @param client: The client whose state is being checked.

        @param immediateClose: Boolean indicating whether the connection was
            closed immediately or not.
        z/%r did not implement assertClientTransportStateNrˆ   ©rD   ÚclientZimmediateCloserE   rE   rF   ÚassertClientTransportState;  s
    ÿÿz=SSHCommandClientEndpointTestsMixin.assertClientTransportStatec                 C   s   t d| jjf ƒ‚dS )zˆ
        Do any remaining work necessary to complete an in-memory connection
        attempted initiated using C{self.reactor}.
        z%%r did not implement finishConnectionNrˆ   rC   rE   rE   rF   ÚfinishConnectionK  s
    ÿÿz3SSHCommandClientEndpointTestsMixin.finishConnectionc                 C   sT   |  d¡}|  d¡}t|d| j| jd}t|d| j| jd}t||||ƒ}|||fS )aw  
        Set up an in-memory connection between protocols created by
        C{serverFactory} and C{clientFactory}.

        @return: A three-tuple.  The first element is the protocol created by
            C{serverFactory}.  The second element is the protocol created by
            C{clientFactory}.  The third element is the L{IOPump} connecting
            them.
        NF)ry   ZhostAddressZpeerAddressT)r]   r@   r…   r†   r?   )rD   ZserverFactoryZclientFactoryZclientProtocolZserverProtocolZclientTransportZserverTransportru   rE   rE   rF   ÚconnectedServerAndClientU  s*    


  þ  þ   ÿz;SSHCommandClientEndpointTestsMixin.connectedServerAndClientc           	      C   sš   |   ¡ }tƒ }t|_| |¡}|  ¡ \}}}|  t¡}|  d|d j	j
|d j	j	f¡ |  dt|ƒ¡ |  |¡}| t¡ |  d|j	j	¡ |  |d¡ dS )zå
        If a channel cannot be opened on the authenticated SSH connection, the
        L{Deferred} returned by L{SSHCommandClientEndpoint.connect} fires with
        a L{Failure} wrapping the reason given by the server.
        úunknown channelr   rR   ó   unknown channelFN)r‹   r   r   r{   r?   r   ÚflushLoggedErrorsr"   ÚassertInÚvaluerN   ÚassertEqualÚlenÚfailureResultOfÚtraprŽ   )	rD   Úendpointrg   Ú	connectedrw   r   ru   ÚerrorsÚfrE   rE   rF   Útest_channelOpenFailuren  s    

 ÿ

z:SSHCommandClientEndpointTestsMixin.test_channelOpenFailurec                 C   sl   t | jjd< |  ¡ }tƒ }t|_| |¡}|  ¡ \}}}|  	|¡}| 
t¡ |  d|jj¡ |  |d¡ dS )zÅ
        If execution of the command fails, the L{Deferred} returned by
        L{SSHCommandClientEndpoint.connect} fires with a L{Failure} wrapping
        the reason given by the server.
        ó   sessionzchannel request failedFN)rL   r   rV   r‹   r   r   r{   r?   r   r˜   r™   r"   r–   r•   rŽ   ©rD   rš   rg   r›   rw   r   ru   r   rE   rE   rF   Útest_execFailureŠ  s    


z3SSHCommandClientEndpointTestsMixin.test_execFailurec                 C   sd   t | jjd< |  ¡ }tƒ }t|_| |¡}|  ¡ \}}}| 	¡  |  
|¡}| t¡ |  |d¡ dS )zµ
        If execution of the command is cancelled via the L{Deferred} returned
        by L{SSHCommandClientEndpoint.connect}, the connection is closed
        immediately.
        rŸ   TN)rS   r   rV   r‹   r   r   r{   r?   r   Úcancelr˜   r™   r   rŽ   r    rE   rE   rF   Útest_execCancelled   s    


z5SSHCommandClientEndpointTestsMixin.test_execCancelledc                 C   s‚   t | jjd< |  ¡ }tƒ }t|_| |¡ |  ¡ \}}}|  	|j
t¡ |  |j ¡ |j
j¡ |  | j|j
j¡ |  d|j
j¡ dS )aD  
        Once the necessary SSH actions have completed successfully,
        L{SSHCommandClientEndpoint.connect} uses the factory passed to it to
        construct a protocol instance by calling its C{buildProtocol} method
        with an address object representing the SSH connection and command
        executed.
        rŸ   ó
   /bin/ls -lN)rQ   r   rV   r‹   r[   r   r{   r?   r   ÚassertIsInstancer\   r7   r–   rf   ZgetHostrw   r   ZusernameZcommand)rD   rš   rg   rw   r   ru   rE   rE   rF   Útest_buildProtocol¶  s    
z5SSHCommandClientEndpointTestsMixin.test_buildProtocolc                 C   sR   t | jjd< |  ¡ }tƒ }t|_| |¡}|  ¡ \}}}|  	|¡}|  
|j¡ dS )a  
        L{SSHCommandClientEndpoint} establishes an SSH connection, creates a
        channel in it, runs a command in that channel, and uses the protocol's
        C{makeConnection} to associate it with a protocol representing that
        command's stdin and stdout.
        rŸ   N)rQ   r   rV   r‹   r   r   r{   r?   r   ÚsuccessResultOfÚassertIsNotNonerf   ©rD   rš   rg   r›   rw   r   ru   r{   rE   rE   rF   Útest_makeConnectionÎ  s    

z6SSHCommandClientEndpointTestsMixin.test_makeConnectionc           
      C   s†   t | jjd< |  ¡ }tƒ }t|_| |¡}|  ¡ \}}}|  	|¡}g }|j
|_|jj}	|jj|	  d¡ | ¡  |  dd |¡¡ dS )z²
        After establishing the connection, when the command on the SSH server
        produces output, it is delivered to the protocol's C{dataReceived}
        method.
        rŸ   ó   hello, worldrY   N)rQ   r   rV   r‹   r   r   r{   r?   r   r§   ÚappendÚdataReceivedrf   ÚidÚserviceÚchannelsÚwriteru   r–   Újoin)
rD   rš   rg   r›   rw   r   ru   r{   r­   Ú	channelIdrE   rE   rF   Útest_dataReceivedâ  s    

z4SSHCommandClientEndpointTestsMixin.test_dataReceivedc           
      C   sŒ   t | jjd< |  ¡ }tƒ }t|_| |¡}|  ¡ \}}}|  	|¡}g }|j
|_|jj}	|jj|	  ¡  | ¡  |d  t¡ |  |d¡ dS )zq
        When the command closes the channel, the protocol's C{connectionLost}
        method is called.
        rŸ   r   FN)rQ   r   rV   r‹   r   r   r{   r?   r   r§   r¬   ÚconnectionLostrf   r®   r¯   r°   ÚloseConnectionru   r™   r   rŽ   )
rD   rš   rg   r›   rw   r   ru   r{   rµ   r³   rE   rE   rF   Útest_connectionLostþ  s    

z6SSHCommandClientEndpointTestsMixin.test_connectionLostc                 C   s–   t | jjd< |  ¡ }tƒ }t|_| |¡}|  ¡ \}}}|  	|¡}	g }
|
j
|	_|	jj}|jj| }|j |||¡ | ¡  | ¡  |  |d¡ |
d S )zJ
        Test handling of non-zero exit statuses or exit signals.
        rŸ   Fr   )rQ   r   rV   r‹   r   r   r{   r?   r   r§   r¬   rµ   rf   r®   r¯   r°   ZsendRequestr¶   ru   rŽ   )rD   ZrequestZ
requestArgrš   rg   r›   rw   r   ru   r{   rµ   r³   ZchannelrE   rE   rF   Ú_exitStatusTest  s     

z2SSHCommandClientEndpointTestsMixin._exitStatusTestc                 C   s$   d}|   dtd|ƒ¡}| t¡ dS )úÊ
        When the command exits with a non-zero status, the protocol's
        C{connectionLost} method is called with a L{Failure} wrapping an
        exception which encapsulates that status.
        r   ó   exit-statusú>LN)r¸   r   r™   r   )rD   ÚexitCodeÚexcrE   rE   rF   Útest_zeroExitCode9  s    z4SSHCommandClientEndpointTestsMixin.test_zeroExitCodec                 C   sH   d}d}|   dtd|ƒ¡}| t¡ |  ||jj¡ |  ||jj¡ dS )r¹   é{   Nrº   r»   )r¸   r   r™   r   r–   r•   r¼   Úsignal)rD   r¼   rÀ   r½   rE   rE   rF   Útest_nonZeroExitStatusD  s    
z9SSHCommandClientEndpointTestsMixin.test_nonZeroExitStatusc                 C   s¶   t ƒ }t |¡ |  tj|¡ d}d}d t d¡dt d¡t d¡g¡}|  d|¡}| 	t
¡ |  ||jj¡ |  ||jj¡ d	}t |t t t tj¡|dd
dddœ¡¡¡ dS )a  
        When the command exits with a non-zero signal, the protocol's
        C{connectionLost} method is called with a L{Failure} wrapping an
        exception which encapsulates that status.

        Additional packet contents are logged at the C{info} level.
        Né   rY   s   TERMó   s   messages   en-USs   exit-signalz'twisted.conch.endpoints._CommandChannelTÚmessage)Z	log_levelZlog_namespaceZshortSignalNameZ
coreDumpedZerrorMessageZlanguageTag)r   r   ZaddObserverr„   ZremoveObserverr²   r%   ZNSr¸   r™   r   r–   r•   r¼   rÀ   ÚhamcrestZassert_thatZhas_itemZhas_entriesZequal_tor   Úinfo)rD   ZlogObserverr¼   rÀ   Zpacketr½   ZlogNamespacerE   rE   rF   Útest_nonZeroExitSignalR  s<    
û

úÿÿþz9SSHCommandClientEndpointTestsMixin.test_nonZeroExitSignalFc                    s<   |j j}g ‰ |r‡ fdd„}nˆ j}t|jj| ||ƒ ˆ S )a  
        Hook into and record events which happen to C{protocol}.

        @param server: The SSH server protocol over which C{protocol} is
            running.
        @type server: L{IProtocol} provider

        @param protocol:

        @param event:

        @param noArgs:
        c                      s
   ˆ   d ¡S rU   )r¬   rE   ©ZrecorderrE   rF   rX   ‘  rY   z;SSHCommandClientEndpointTestsMixin.record.<locals>.<lambda>)rf   r®   r¬   Úsetattrr¯   r°   )rD   rw   r{   ZeventÚnoArgsr³   r   rE   rÈ   rF   Úrecord}  s    z)SSHCommandClientEndpointTestsMixin.recordc           	      C   sz   t | jjd< |  ¡ }tƒ }t|_| |¡}|  ¡ \}}}|  	|¡}|  
||d¡}|j d¡ | ¡  |  dd |¡¡ dS )z¢
        The transport connected to the protocol has a C{write} method which
        sends bytes to the input of the command executing on the SSH server.
        rŸ   r­   r«   rY   N)rQ   r   rV   r‹   r   r   r{   r?   r   r§   rË   rf   r±   ru   r–   r²   ©	rD   rš   rg   r›   rw   r   ru   r{   r­   rE   rE   rF   Ú
test_write™  s    

z-SSHCommandClientEndpointTestsMixin.test_writec           	      C   s|   t | jjd< |  ¡ }tƒ }t|_| |¡}|  ¡ \}}}|  	|¡}|  
||d¡}|j dg¡ | ¡  |  dd |¡¡ dS )zª
        The transport connected to the protocol has a C{writeSequence} method which
        sends bytes to the input of the command executing on the SSH server.
        rŸ   r­   r«   rY   N)rQ   r   rV   r‹   r   r   r{   r?   r   r§   rË   rf   ZwriteSequenceru   r–   r²   rÌ   rE   rE   rF   Útest_writeSequence¯  s    

z5SSHCommandClientEndpointTestsMixin.test_writeSequenceN)F)rH   rI   rJ   rK   r‡   r‹   rŽ   r   r   rž   r¡   r£   r¦   rª   r´   r·   r¸   r¾   rÁ   rÇ   rË   rÍ   rÎ   rE   rE   rE   rF   r|     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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d0S )1ÚNewConnectionTestsz`
    Tests for L{SSHCommandClientEndpoint} when using the C{newConnection}
    constructor.
    c                 C   sh   t  | ¡ t|  ¡ ƒ| _t| jƒ| _| j | j| j	j
d ¡ | j t| jjƒ| j	j
d ¡ | j ¡  dS )ú
        Configure an SSH server with password authentication enabled for a
        well-known (to the tests) account.
        rn   N)r|   r‡   r   ÚmktempZhostKeyPathr,   Ú
knownHostsÚ
addHostKeyr}   rg   rp   r
   r†   ÚhostÚsaverC   rE   rE   rF   r‡   Ë  s    
 
ÿ

þzNewConnectionTests.setUpc              
   C   s*   t j| jd| j| j| j| j| jtdƒdS )zu
        Create and return a new L{SSHCommandClientEndpoint} using the
        C{newConnection} constructor.
        r¤   F©r€   rÒ   Úui)	r8   ÚnewConnectionri   r   r}   r~   r€   rÒ   r^   rC   rE   rE   rF   r‹   Ü  s         ýzNewConnectionTests.createc                 C   s   |   | j| jjd d ¡S )z}
        Establish the first attempted TCP connection using the SSH server which
        C{self.factory} can create.
        r   é   )r   rg   ri   Ú
tcpClientsrC   rE   rE   rF   r   ç  s     ÿz#NewConnectionTests.finishConnectionc                 C   sH   | j ||ddd}|j ¡  | ¡  |  dg|¡ | ¡  |j ¡  dS )a×  
        Lose the connection to a server and pump the L{IOPump} sufficiently for
        the client to handle the lost connection. Asserts that the client
        disconnects its transport.

        @param server: The SSH server protocol over which C{protocol} is
            running.
        @type server: L{IProtocol} provider

        @param client: The SSH client protocol over which C{protocol} is
            running.
        @type client: L{IProtocol} provider

        @param protocol: The protocol created by calling connect on the ssh
            endpoint under test.
        @type protocol: L{IProtocol} provider

        @param pump: The L{IOPump} connecting client to server.
        @type pump: L{IOPump}
        ÚclosedT)rÊ   N)rË   rf   r¶   ru   r–   ZreportDisconnect)rD   rw   r   r{   ru   rÛ   rE   rE   rF   ÚloseConnectionToServerð  s    
z)NewConnectionTests.loseConnectionToServerc                 C   s&   |r|   |jj¡ n|   |jj¡ dS )zä
        Assert that the transport for the given protocol has been disconnected.
        L{SSHCommandClientEndpoint.newConnection} creates a new dedicated SSH
        connection and cleans it up after the command exits.
        N)Ú
assertTruerf   rB   ÚdisconnectingrŒ   rE   rE   rF   rŽ     s    z-NewConnectionTests.assertClientTransportStatec                 C   s,   t  | jdd| j| j¡}|  tt|ƒ¡ dS )zY
        L{SSHCommandClientEndpoint} instances provide L{IStreamClientEndpoint}.
        ó   dummy commandó
   dummy userN)r8   rØ   ri   r}   r~   rÝ   r   r   ©rD   rš   rE   rE   rF   Útest_interface"  s       þz!NewConnectionTests.test_interfacec                 C   s(   t  | jdd| j¡}|  d|jj¡ dS )z†
        L{SSHCommandClientEndpoint} uses the default port number for SSH when
        the C{port} argument is not specified.
        rß   rà   é   N©r8   rØ   ri   r}   r–   Z_creatorr~   rá   rE   rE   rF   Útest_defaultPort,  s       ÿz#NewConnectionTests.test_defaultPortc                 C   s,   t j| jdd| jdd}|  d|jj¡ dS )zU
        L{SSHCommandClientEndpoint} uses the C{port} argument if specified.
        rß   rà   i®  )r~   Nrä   rá   rE   rE   rF   Útest_specifiedPort6  s       þz%NewConnectionTests.test_specifiedPortc              
   C   sŽ   t j| jd| j| j| j| j| jtdƒd}t	ƒ }t
|_| |¡ | jjd \}}}}}|  | jt|ƒ¡ |  | j|¡ |  dt| jjƒ¡ dS )zž
        L{SSHCommandClientEndpoint} uses the L{IReactorTCP} passed to it to
        attempt a connection to the host/port address also passed to it.
        r¤   FrÖ   r   rR   N)r8   rØ   ri   r   r}   r~   r€   rÒ   r^   r   r   r{   r?   rÚ   r–   r
   r—   )rD   rš   rg   rÔ   r~   ZtimeoutZbindAddressrE   rE   rF   Útest_destination@  s"         ý
z#NewConnectionTests.test_destinationc              	   C   sp   t j| jdd| j| j| jtdƒd}tƒ }t|_	| 
|¡}| jjd d }| dttƒ ƒ¡ |  |¡ t¡ dS )zÚ
        If a connection cannot be established, the L{Deferred} returned by
        L{SSHCommandClientEndpoint.connect} fires with a L{Failure}
        representing the reason for the connection setup failure.
        r¤   rà   F©rÒ   r×   r   rÙ   N)r8   rØ   ri   r}   r~   rÒ   r^   r   r   r{   r?   rÚ   ZclientConnectionFailedr   r   r˜   r™   ©rD   rš   rg   ÚdrE   rE   rF   Útest_connectionFailedS  s        ý
z(NewConnectionTests.test_connectionFailedc              	   C   sx   t j| jdd| j| jt|  ¡ ƒtdƒd}tƒ }t	|_
| |¡}|  | j| jjd d ¡\}}}|  |¡}| t¡ dS )a"  
        If the L{KnownHostsFile} instance used to construct
        L{SSHCommandClientEndpoint} rejects the SSH public key presented by the
        server, the L{Deferred} returned by L{SSHCommandClientEndpoint.connect}
        fires with a L{Failure} wrapping L{UserRejectedKey}.
        r¤   rà   Frè   r   rÙ   N)r8   rØ   ri   r}   r~   r,   rÑ   r^   r   r   r{   r?   r   rg   rÚ   r˜   r™   r#   r    rE   rE   rF   Útest_userRejectedHostKeyg  s$        
ý
 ÿ

z+NewConnectionTests.test_userRejectedHostKeyc              
   C   sÈ   t  t¡ ¡ }tt|  ¡ ƒƒ}| t| j	j
ƒ|¡ t jtdd ¡ }| | j|¡ tdƒ}tj| jdd| j| jd||d}tƒ }t|_| |¡}|  | j| jjd d	 ¡\}}	}
|  |¡}| t¡ d
S )ac  
        If the SSH public key presented by the SSH server does not match the
        previously remembered key, as reported by the L{KnownHostsFile}
        instance use to construct the endpoint, for that server, the
        L{Deferred} returned by L{SSHCommandClientEndpoint.connect} fires with
        a L{Failure} wrapping L{HostKeyChanged}.
        s   testxp)Z
passphraseTr¤   rà   ó   dummy passwordrÖ   r   rÙ   N)r)   ro   r2   Úpublicr,   r   rÑ   rÓ   r
   r†   rÔ   r3   r}   r^   r8   rØ   ri   r~   r   r   r{   r?   r   rg   rÚ   r˜   r™   r$   )rD   ZfirstKeyrÒ   ZdifferentKeyr×   rš   rg   r›   rw   r   ru   r   rE   rE   rF   Útest_mismatchedHostKey~  s<    
 ÿÿ
     ý
 ÿ

z)NewConnectionTests.test_mismatchedHostKeyc              	   C   sˆ   t j| jdd| j| j| jtdƒd}tƒ }t|_	| 
|¡}tƒ }| jjd d }| d¡}| |¡ | ttƒ ƒ¡ |  |¡ t¡ dS )aU  
        If the connection closes at any point before the SSH transport layer
        has finished key exchange (ie, gotten to the point where we may attempt
        to authenticate), the L{Deferred} returned by
        L{SSHCommandClientEndpoint.connect} fires with a L{Failure} wrapping
        the reason for the lost connection.
        r¤   rà   Frè   r   rÙ   N)r8   rØ   ri   r}   r~   rÒ   r^   r   r   r{   r?   r=   rÚ   r]   ÚmakeConnectionrµ   r   r   r˜   r™   ©rD   rš   rg   rê   rf   r   rE   rE   rF   Ú!test_connectionClosedBeforeSecure¤  s$        ý


z4NewConnectionTests.test_connectionClosedBeforeSecurec              	   C   s¢   t j| jdd| j| j| jtdƒd}tƒ }t|_	| 
|¡}tddd}| jjd d }| d¡}| |¡ | ¡  |  |¡ t¡ |  |j¡ | ttƒ ƒ¡ dS )	a[  
        If the connection is cancelled before the SSH transport layer has
        finished key exchange (ie, gotten to the point where we may attempt to
        authenticate), the L{Deferred} returned by
        L{SSHCommandClientEndpoint.connect} fires with a L{Failure} wrapping
        L{CancelledError} and the connection is aborted.
        r¤   rà   Frè   Nrx   r   rÙ   )r8   rØ   ri   r}   r~   rÒ   r^   r   r   r{   r?   r@   rÚ   r]   rð   r¢   r˜   r™   r   rÝ   rB   rµ   r   r   rñ   rE   rE   rF   Ú$test_connectionCancelledBeforeSecure¾  s(        ý


z7NewConnectionTests.test_connectionCancelledBeforeSecurec              	   C   sj   t j| jdd| j| j| jtdƒd}tƒ }t|_	| 
|¡}| ¡  |  |¡ t¡ |  | jjd j¡ dS )zz
        If the connection is cancelled before it finishes connecting, the
        connection attempt is stopped.
        r¤   rà   Frè   r   N)r8   rØ   ri   r}   r~   rÒ   r^   r   r   r{   r?   r¢   r˜   r™   r   rÝ   Z
connectorsZstoppedConnectingré   rE   rE   rF   Ú'test_connectionCancelledBeforeConnectedÜ  s        ý
z:NewConnectionTests.test_connectionCancelledBeforeConnectedc              
   C   s˜   t j| jdd| j| jd| jtdƒd}tƒ }t|_	| 
|¡}|  | j| jjd d ¡\}}}| j |jj¡ | ¡  |  |¡}| t¡ |  |d¡ dS )	zã
        If the SSH server rejects the password presented during authentication,
        the L{Deferred} returned by L{SSHCommandClientEndpoint.connect} fires
        with a L{Failure} wrapping L{AuthenticationFailed}.
        r¤   rà   rí   FrÖ   r   rÙ   N)r8   rØ   ri   r}   r~   rÒ   r^   r   r   r{   r?   r   rg   rÚ   Zadvancer¯   ZpasswordDelayÚflushr˜   r™   r6   rŽ   r    rE   rE   rF   Ú"test_passwordAuthenticationFailureî  s,         ý
 ÿ


z5NewConnectionTests.test_passwordAuthenticationFailurec                 C   s0   t dd„ t|ƒD ƒƒ}tt|ƒƒ}| |¡ dS )a¼  
        Create an L{ISSHPrivateKey} checker which recognizes C{users} and add it
        to C{portal}.

        @param portal: A L{Portal} to which to add the checker.
        @type portal: L{Portal}

        @param users: The users and their keys the checker will recognize.  Keys
            are byte strings giving user names.  Values are byte strings giving
            OpenSSH-formatted private keys.
        @type users: L{dict}
        c                 S   s$   g | ]\}}|t  |¡ ¡ gf‘qS rE   )r)   ro   rî   )Ú.0ÚkÚvrE   rE   rF   Ú
<listcomp>  s   ÿz6NewConnectionTests.setupKeyChecker.<locals>.<listcomp>N)Údictr	   r.   r/   rƒ   )rD   r‚   ZusersÚmappingZcheckerrE   rE   rF   ÚsetupKeyChecker  s
    ÿz"NewConnectionTests.setupKeyCheckerc           	   
   C   s¤   t  t¡}|  | j| jti¡ tj| j	d| j| j
| j|g| jtdƒd}tƒ }t|_| |¡}|  | j| j	jd d ¡\}}}|  |¡}| t¡ |  |jj¡ dS )zã
        If the SSH server rejects the key pair presented during authentication,
        the L{Deferred} returned by L{SSHCommandClientEndpoint.connect} fires
        with a L{Failure} wrapping L{AuthenticationFailed}.
        r¤   F©ÚkeysrÒ   r×   r   rÙ   N)r)   ro   r2   rý   r‚   r   r4   r8   rØ   ri   r}   r~   rÒ   r^   r   r   r{   r?   r   rg   rÚ   r˜   r™   r6   rÝ   rf   rÞ   )	rD   ÚbadKeyrš   rg   r›   rw   r   ru   r   rE   rE   rF   Ú#test_publicKeyAuthenticationFailure#  s,    
     ý
 ÿ


z6NewConnectionTests.test_publicKeyAuthenticationFailurec           
      C   s
  t  t¡}|  | j| jti¡ tj| j	d| j| j
| j|g| j| jtdƒd	}tƒ }t|_| |¡}| j jd7  _|  | j| j	jd d ¡\}}}| ¡  |  t¡}|  d|d jj|d jjf¡ |  dt|ƒ¡ |  |¡}	|	  t¡ |  d|	jj¡ |  !|j"j#¡ d	S )
z{
        If the SSH server does not accept any of the specified SSH keys, the
        specified password is tried.
        r¤   F)rÿ   r€   rÒ   r×   rR   r   rÙ   r‘   r’   N)$r)   ro   r2   rý   r‚   r   r4   r8   rØ   ri   r}   r~   r€   rÒ   r^   r   r   r{   r?   rg   rh   r   rÚ   ru   r“   r"   r”   r•   rN   r–   r—   r˜   r™   rÝ   rf   rÞ   )
rD   r   rš   rg   r›   rw   r   ru   rœ   r   rE   rE   rF   Útest_authenticationFallbackB  s@    
      ý
 ÿ

 ÿ

z.NewConnectionTests.test_authenticationFallbackc           	   
   C   s¤   t  t¡}|  | j| jti¡ t| jjd< t	j
| jd| j| j| j|g| jtdƒd}tƒ }t|_| |¡}|  | j| jjd d ¡\}}}|  |¡}|  |j¡ dS )z›
        If L{SSHCommandClientEndpoint} is initialized with any private keys, it
        will try to use them to authenticate with the SSH server.
        rŸ   r¤   Frþ   r   rÙ   N)r)   ro   r4   rý   r‚   r   rQ   r   rV   r8   rØ   ri   r}   r~   rÒ   r^   r   r   r{   r?   r   rg   rÚ   r§   r¨   rf   )	rD   Úkeyrš   rg   r›   rw   r   ru   r{   rE   rE   rF   Útest_publicKeyAuthenticationl  s,    
      þ
 ÿ

z/NewConnectionTests.test_publicKeyAuthenticationc              	   C   sŠ   t j| jd| j| j| j| jtdƒd}tƒ }t	|_
| |¡}|  | j| jjd d ¡\}}}| ¡  |  |¡}| t¡ |  |jj¡ dS )z†
        If the password is not specified, L{SSHCommandClientEndpoint} doesn't
        try it as an authentication mechanism.
        r¤   Frè   r   rÙ   N)r8   rØ   ri   r   r}   r~   rÒ   r^   r   r   r{   r?   r   rg   rÚ   ru   r˜   r™   r6   rÝ   rf   rÞ   r    rE   rE   rF   Útest_skipPasswordAuthentication„  s(         þ
 ÿ


z2NewConnectionTests.test_skipPasswordAuthenticationc              
   C   s  t  t¡}tƒ }tƒ |_| ¡ |dfi|j_|  | j	| j
ti¡ t|ƒ}tj| jd| j
| j| j| jtdƒ|d}t| jjd< tƒ }t|_| |¡}|  | j| jjd d ¡\}}}	tdƒD ]}
|j ¡  |	 ¡  qº|  |¡}|  |j¡ |   ||||	¡ |  !|jj"¡ |  !|jj#j"¡ d	S )
a  
        If L{SSHCommandClientEndpoint} is initialized with an
        L{SSHAgentClient}, the agent is used to authenticate with the SSH
        server. Once the connection with the SSH server has concluded, the
        connection to the agent is disconnected.
        rY   r¤   F)rÒ   r×   ÚagentEndpointrŸ   r   rÙ   é   N)$r)   ro   r2   r+   r   rg   Zblobrÿ   rý   r‚   r   rt   r8   rØ   ri   r}   r~   rÒ   r^   rQ   r   rV   r   r{   r?   r   rÚ   Úrangeru   r§   r¨   rf   rÜ   rÝ   rÞ   ZclientIO)rD   r  ZagentServerr  rš   rg   r›   rw   r   ru   Úir{   rE   rE   rF   Útest_agentAuthenticationŸ  s@    
     ý
 ÿ



z+NewConnectionTests.test_agentAuthenticationc                 C   sd   t | jjd< |  ¡ }tƒ }t|_| |¡}|  ¡ \}}}|  	|¡}|  
||||¡ |  |jj¡ dS )zÓ
        The transport connected to the protocol has a C{loseConnection} method
        which causes the channel in which the command is running to close and
        the overall connection to be closed.
        rŸ   N)rQ   r   rV   r‹   r   r   r{   r?   r   r§   rÜ   rÝ   rf   rÞ   r©   rE   rE   rF   Útest_loseConnectionÌ  s    

z&NewConnectionTests.test_loseConnectionN)rH   rI   rJ   rK   r‡   r‹   r   rÜ   rŽ   râ   rå   ræ   rç   rë   rì   rï   rò   ró   rô   rö   rý   r  r  r  r  r
  r  rE   rE   rE   rF   rÏ   Æ  s0   	$


&"*-rÏ   c                   @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )ÚExistingConnectionTestsze
    Tests for L{SSHCommandClientEndpoint} when using the C{existingConnection}
    constructor.
    c              
   C   sz   t  | ¡ tt|  ¡ ƒƒ}| | j| jjd ¡ | t	| j
jƒ| jjd ¡ tj| jd| j| j| j| j|tdƒd| _dS )rÐ   rn   r¤   FrÖ   N)r|   r‡   r,   r   rÑ   rÓ   r}   rg   rp   r
   r†   rÔ   r8   rØ   ri   r   r~   r€   r^   rš   )rD   rÒ   rE   rE   rF   r‡   é  s(    
 
ÿ

þ     ýzExistingConnectionTests.setUpc           	   	   C   s¢   t ƒ }t|_| j |¡}| jj ¡ }z0t
| jjd< |  | j| jjd d ¡\}}}W 5 | jj ¡  | jj 	|¡ X || _|| _|| _|  |¡}|jj}t |d¡S )zz
        Create and return a new L{SSHCommandClientEndpoint} using the
        C{existingConnection} constructor.
        rŸ   r   rÙ   r¤   )r   r   r{   rš   r?   r   rV   ÚcopyÚclearÚupdaterQ   r   rg   ri   rÚ   rv   Ú_clientÚ_pumpr§   rf   Zconnr8   ZexistingConnection)	rD   rg   r›   rV   rw   r   ru   r{   Ú
connectionrE   rE   rF   r‹   ý  s*     ÿ
 ÿzExistingConnectionTests.createc                 C   s8   | j  ¡  | j  ¡  | j  ¡  | j  ¡  | j| j| j fS )z
        Give back the connection established in L{create} over which the new
        command channel being tested will exchange data.
        )r  ru   rv   r  rC   rE   rE   rF   r     s
    



z(ExistingConnectionTests.finishConnectionc                 C   s    |   |jj¡ |   |jj¡ dS )a  
        Assert that the transport for the given protocol is still connected.
        L{SSHCommandClientEndpoint.existingConnection} re-uses an SSH connected
        created by some other code, so other code is responsible for cleaning
        it up.
        N)ÚassertFalserf   rÞ   rB   rŒ   rE   rE   rF   rŽ   +  s    z2ExistingConnectionTests.assertClientTransportStateN)rH   rI   rJ   rK   r‡   r‹   r   rŽ   rE   rE   rE   rF   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 )ÚExistingConnectionHelperTestsz1
    Tests for L{_ExistingConnectionHelper}.
    c                 C   s   |   tttƒ¡ dS )zT
        L{_ExistingConnectionHelper} implements L{_ISSHConnectionCreator}.
        N)rÝ   r   r5   r;   rC   rE   rE   rF   râ   ;  s    ÿz,ExistingConnectionHelperTests.test_interfacec                 C   s(   t ƒ }t|ƒ}|  ||  | ¡ ¡¡ dS )z¸
        L{_ExistingConnectionHelper.secureConnection} returns a L{Deferred}
        which fires with whatever object was fed to
        L{_ExistingConnectionHelper.__init__}.
        N)Úobjectr;   ÚassertIsr§   ZsecureConnection)rD   r`   ÚhelperrE   rE   rF   Útest_secureConnectionC  s     ÿz3ExistingConnectionHelperTests.test_secureConnectionc                 C   s   t tƒ ƒ}| tƒ d¡ dS )z
        L{_ExistingConnectionHelper.cleanupConnection} does nothing to the
        existing connection if called with C{immediate} set to C{False}.
        FN©r;   r  ÚcleanupConnection©rD   r  rE   rE   rF   Ú$test_cleanupConnectionNotImmediatelyO  s    
zBExistingConnectionHelperTests.test_cleanupConnectionNotImmediatelyc                 C   s   t tƒ ƒ}| tƒ d¡ dS )zœ
        L{_ExistingConnectionHelper.cleanupConnection} does nothing to the
        existing connection if called with C{immediate} set to C{True}.
        TNr  r  rE   rE   rF   Ú!test_cleanupConnectionImmediately[  s    
z?ExistingConnectionHelperTests.test_cleanupConnectionImmediatelyN)rH   rI   rJ   rK   râ   r  r  r  rE   rE   rE   rF   r  7  s
   r  c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )Ú_PTYPathzk
    A L{FilePath}-like object which can be opened to create a L{_ReadFile} with
    certain contents.
    c                 C   s
   || _ dS )zz
        @param contents: L{bytes} which will be the contents of the
            L{_ReadFile} this path can open.
        N)Úcontents)rD   r  rE   rE   rF   rW   m  s    z_PTYPath.__init__c                 C   s    |dkrt | jƒS ttdƒ‚dS )zÕ
        If the mode is r+, return a L{_ReadFile} with the contents given to
        this path's initializer.

        @raise OSError: If the mode is unsupported.

        @return: A L{_ReadFile} instance
        zrb+zFunction not implementedN)r9   r  ÚOSErrorr   )rD   ÚmoderE   rE   rF   Úopenu  s    	
z_PTYPath.openN)rH   rI   rJ   rK   rW   r"  rE   rE   rE   rF   r  h  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d„ Z
dd„ Zdd„ Zdd„ ZdS )ÚNewConnectionHelperTestsz,
    Tests for L{_NewConnectionHelper}.
    c                 C   s   |   tttƒ¡ dS )zO
        L{_NewConnectionHelper} implements L{_ISSHConnectionCreator}.
        N)rÝ   r   r5   r:   rC   rE   rE   rF   râ   ˆ  s    ÿz'NewConnectionHelperTests.test_interfacec                 C   s   |   dtj¡ dS )zK
        The default I{known_hosts} path is I{~/.ssh/known_hosts}.
        z~/.ssh/known_hostsN)r–   r:   Ú_KNOWN_HOSTSrC   rE   rE   rF   Útest_defaultPath  s     ÿz)NewConnectionHelperTests.test_defaultPathc                    sH   t ƒ ‰ |  td‡ fdd„¡ tddddddddddƒ
}|  ˆ |j¡ dS )zŒ
        L{_NewConnectionHelper._knownHosts} is used to create a
        L{KnownHostsFile} if one is not passed to the initializer.
        Ú_knownHostsc                    s   ˆ S rU   rE   )Úclsr_   rE   rF   rX   ž  rY   zANewConnectionHelperTests.test_defaultKnownHosts.<locals>.<lambda>N)r  Úpatchr:   r  rÒ   r  rE   r_   rF   Útest_defaultKnownHosts˜  s             ÿz/NewConnectionHelperTests.test_defaultKnownHostsc                 C   s˜   t ƒ jd }t|  ¡ ƒ}t|ƒ}| d|¡ | ¡  td|jf ƒ t	j 
d¡}|j |d¡}|  td|¡ td|f ƒ t ¡ }|  | d|¡¡ dS )z´
        Existing entries in the I{known_hosts} file are reflected by the
        L{KnownHostsFile} created by L{_NewConnectionHelper} when none is
        supplied to it.
        rn   s	   127.0.0.1zCreated known_hosts file at %rz~/r$  zPatched _KNOWN_HOSTS with %rN)rl   rp   r   rÑ   r,   rÓ   rÕ   r   ÚpathÚosÚ
expanduserÚreplacer(  r:   r&  rÝ   Z
hasHostKey)rD   r  r*  rÒ   ÚhomeÚdefaultZloadedrE   rE   rF   Útest_readExisting¦  s    z*NewConnectionHelperTests.test_readExistingc                 C   s,   t ddddddddddƒ
}|  |jt¡ dS )zz
        If L{None} is passed for the C{ui} parameter to
        L{_NewConnectionHelper}, a L{ConsoleUI} is used.
        N)r:   r¥   r×   r-   r  rE   rE   rF   Útest_defaultConsoleUI¾  s             ÿz.NewConnectionHelperTests.test_defaultConsoleUIc                 C   sD   t dƒ}tdddddddddd|ƒ}|  |j d¡¡}|  |¡ dS )z·
        If L{None} is passed for the C{ui} parameter to L{_NewConnectionHelper}
        and /dev/tty is available, the L{ConsoleUI} used is associated with
        /dev/tty.
        s   yesNs   does this work?)r  r:   r§   r×   rc   rÝ   ©rD   Úttyr  r`   rE   rE   rF   Útest_ttyConsoleUIÈ  s               ÿz*NewConnectionHelperTests.test_ttyConsoleUIc                 C   sH   t |  ¡ ƒ}tdddddddddd|ƒ}|  |j d¡¡}|  |¡ dS )zæ
        If L{None} is passed for the C{ui} parameter to L{_NewConnectionHelper}
        and /dev/tty is not available, the L{ConsoleUI} used is associated with
        some file which always produces a C{b"no"} response.
        Ns   did this break?)r   rÑ   r:   r§   r×   rc   r  r2  rE   rE   rF   Útest_nottyUIÕ  s               ÿz%NewConnectionHelperTests.test_nottyUIc                 C   s0   t ddddddddddƒ
}|  tdƒ|j¡ dS )zy
        If not passed the name of a tty in the filesystem,
        L{_NewConnectionHelper} uses C{b"/dev/tty"}.
        Ns   /dev/tty)r:   r–   r   r3  r  rE   rE   rF   Útest_defaultTTYFilenameâ  s             ÿz0NewConnectionHelperTests.test_defaultTTYFilenamec                 C   sF   t ddddddddddƒ
}tƒ }tƒ |_| |d¡ |  |jj¡ dS )z
        L{_NewConnectionHelper.cleanupConnection} closes the transport cleanly
        if called with C{immediate} set to C{False}.
        NF)r:   r(   r=   rf   r  rÝ   rÞ   )rD   r  r  rE   rE   rF   r  ì  s              ÿz=NewConnectionHelperTests.test_cleanupConnectionNotImmediatelyc                 C   s`   G dd„ dƒ}t ddddddddddƒ
}tƒ }tƒ |_|ƒ |j_| |d¡ |  |jjj¡ dS )zœ
        L{_NewConnectionHelper.cleanupConnection} closes the transport with
        C{abortConnection} if called with C{immediate} set to C{True}.
        c                   @   s   e Zd ZdZdd„ ZdS )zMNewConnectionHelperTests.test_cleanupConnectionImmediately.<locals>.AbortableFc                 S   s
   d| _ dS )z7
                Abort the connection.
                TNrA   rC   rE   rE   rF   rG      s    z]NewConnectionHelperTests.test_cleanupConnectionImmediately.<locals>.Abortable.abortConnectionN)rH   rI   rJ   rB   rG   rE   rE   rE   rF   Ú	Abortableþ  s   r7  NT)r:   r(   r<   rf   r  rÝ   rB   )rD   r7  r  r  rE   rE   rF   r  ù  s$             ÿ
z:NewConnectionHelperTests.test_cleanupConnectionImmediatelyN)rH   rI   rJ   rK   râ   r%  r)  r0  r1  r4  r5  r6  r  r  rE   rE   rE   rF   r#  „  s   

r#  )xrK   Úos.pathr+  Zstructr   Úerrnor   rÅ   Zzope.interface.verifyr   r   Zzope.interfacer   Ztwisted.loggerr   r   Ztwisted.python.compatr	   r
   Ztwisted.python.failurer   Ztwisted.python.filepathr   Ztwisted.python.logr   Ztwisted.python.reflectr   Ztwisted.internet.interfacesr   r   Ztwisted.internet.protocolr   r   Ztwisted.internet.deferr   r   r   r   Ztwisted.internet.errorr   r   Ztwisted.internet.addressr   Ztwisted.trial.unittestr   Ztwisted.test.proto_helpersr   r   r   r   Ztwisted.cred.portalr   Ztwisted.cred.checkersr    Ztwisted.conch.interfacesr!   Ztwisted.conch.errorr"   r#   r$   Ztwisted.conch.sshr%   Ztwisted.conch.ssh.factoryr&   Ztwisted.conch.ssh.userauthr'   Ztwisted.conch.ssh.connectionr(   Ztwisted.conch.ssh.keysr)   Ztwisted.conch.ssh.channelr*   Ztwisted.conch.ssh.agentr+   Ztwisted.conch.client.knownhostsr,   r-   Ztwisted.conch.checkersr.   r/   Ztwisted.conch.avatarr0   Ztwisted.conch.test.keydatar1   r2   r3   r4   Ztwisted.conch.endpointsr5   r6   r7   r8   r9   r:   r;   Ztwisted.conch.ssh.transportr<   Úskipr  r=   Ztwisted.test.iosimr>   r?   r@   rL   rQ   rS   rT   r[   r^   re   rl   rs   rt   r|   rÏ   r  r  r  r#  rE   rE   rE   rF   Ú<module>   s–   $þÿÿ 	%   9    "S1