o
    ¯bPÚ  ã                   @   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
mZ ddlZddlmZ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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'm(Z( ddl)m*Z*m+Z+ ddl,m-Z- ddl.m/Z/ ddl0m1Z1 ddl2m3Z3 ddl4m5Z5 ddl6m7Z7m8Z8 ddl9m:Z: e5dƒre5dƒrddl;m<Z< ddl=m>Z>m?Z? ddl@mAZAmBZB ddlCmDZDmEZEmFZFmGZGmHZHmIZImJZJ ddlKmLZL ddlMmNZN dd lOmPZP dd!lQmRZR dd"lSmTZT dd#lUmVZV dd$lWmXZX dd%lYmZZZ dd&l[m\Z\m]Z]m^Z^m_Z_ nd'Z`eaZTeaZZeaZReaZVeaZPeaZNeaZBeaZ?eaZ<dd(lbmcZcmdZd dd)l6meZe G d*d+„ d+ecƒZfG d,d-„ d-ePƒZgG d.d/„ d/ePƒZhG d0d1„ d1ePƒZiG d2d3„ d3ƒZjG d4d5„ d5e'ƒZkG d6d7„ d7ƒZlG d8d9„ d9eZƒZmG d:d;„ d;eTƒZnee$ƒG d<d=„ d=ƒƒZoee%ƒG d>d?„ d?ƒƒZpG d@dA„ dAƒZqG dBdC„ dCe:eqƒZrG dDdE„ dEe:eqƒZsG dFdG„ dGe:ƒZtG dHdI„ dIƒZuG dJdK„ dKe:ƒZvdS )Lz'
Tests for L{twisted.conch.endpoints}.
é    N)ÚENOSYS)Úpack)Úimplementer)ÚverifyClassÚverifyObject)Ú
ConchErrorÚHostKeyChangedÚUserRejectedKey)Ú
IConchUser)Ú'InMemoryUsernamePasswordDatabaseDontUse)ÚPortal)ÚIPv4Address)ÚCancelledErrorÚDeferredÚfailÚsucceed)ÚConnectingCancelledErrorÚConnectionDoneÚConnectionRefusedErrorÚProcessTerminated)ÚIAddressÚIStreamClientEndpoint)ÚFactoryÚProtocol)ÚLogLevelÚglobalLogPublisher)ÚnetworkString)ÚFailure)ÚFilePath)Úmsg)ÚrequireModule)ÚEventLoggingObserverÚMemoryReactorClock)ÚTestCaseÚcryptographyzpyasn1.type)Ú	ConchUser)ÚInMemorySSHKeyDBÚSSHPublicKeyChecker)Ú	ConsoleUIÚKnownHostsFile)ÚAuthenticationFailedÚSSHCommandAddressÚSSHCommandClientEndpointÚ_ExistingConnectionHelperÚ_ISSHConnectionCreatorÚ_NewConnectionHelperÚ	_ReadFile)Úcommon)ÚSSHAgentServer)Ú
SSHChannel)ÚSSHConnection)Ú
SSHFactory)ÚKey)ÚSSHClientTransport)ÚSSHUserAuthServer)ÚprivateDSA_opensshÚprivateRSA_opensshÚ privateRSA_openssh_encrypted_aesÚpublicRSA_opensshz%can't run w/o cryptography and pyasn1)ÚFakeTransportÚconnect)ÚStringTransportc                   @   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   ó
   d| _ dS )z}
        Abort the connection in a fake manner.

        This should really be implemented in the underlying module.
        TN©Úaborted©Úself© rF   úC/usr/lib/python3/dist-packages/twisted/conch/test/test_endpoints.pyÚabortConnectionZ   ó   
z&AbortableFakeTransport.abortConnectionN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rC   rH   rF   rF   rF   rG   r@   S   s    r@   c                   @   ó   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   ó   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   rF   ©rE   ÚdatarF   rF   rG   Úrequest_exech   ó   
zBrokenExecSession.request_execN©rJ   rK   rL   rM   rS   rF   rF   rF   rG   rO   c   ó    rO   c                   @   rN   )ÚWorkingExecSessionzS
    L{WorkingExecSession} is a session on which exec requests always succeed.
    c                 C   rP   )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}
        é   rF   rQ   rF   rF   rG   rS   z   rT   zWorkingExecSession.request_execNrU   rF   rF   rF   rG   rW   u   rV   rW   c                   @   rN   )Ú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   rQ   rF   rF   rG   rS      s   
z#UnsatisfiedExecSession.request_execNrU   rF   rF   rF   rG   rY   ‡   s    rY   c                   @   s   e Zd Zdd„ Zdd„ ZdS )ÚTrivialRealmc                 C   s
   i | _ d S ©N)ÚchannelLookuprD   rF   rF   rG   Ú__init__›   ó   
zTrivialRealm.__init__c                 G   s   t ƒ }| j|_t|dd„ fS )Nc                   S   ó   d S r[   rF   rF   rF   rF   rG   Ú<lambda>¡   ó    z,TrivialRealm.requestAvatar.<locals>.<lambda>)r%   r\   r
   )rE   ÚavatarIdÚmindÚ
interfacesÚavatarrF   rF   rG   ÚrequestAvatarž   s   zTrivialRealm.requestAvatarN)rJ   rK   rL   r]   rf   rF   rF   rF   rG   rZ   š   s    rZ   c                   @   s   e Zd ZdZdd„ ZdS )ÚAddressSpyFactoryNc                 C   s   || _ t | |¡S r[   )Úaddressr   ÚbuildProtocol)rE   rh   rF   rF   rG   ri   §   s   zAddressSpyFactory.buildProtocol)rJ   rK   rL   rh   ri   rF   rF   rF   rG   rg   ¤   ó    rg   c                   @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚFixedResponseUIc                 C   s
   || _ d S r[   ©Úresult)rE   rm   rF   rF   rG   r]   ­   r^   zFixedResponseUI.__init__c                 C   s
   t | jƒS r[   )r   rm   ©rE   ÚtextrF   rF   rG   Úprompt°   r^   zFixedResponseUI.promptc                 C   r_   r[   rF   rn   rF   rF   rG   Úwarn³   s   zFixedResponseUI.warnN)rJ   rK   rL   r]   rp   rq   rF   rF   rF   rG   rk   ¬   s    rk   c                   @   s$   e Zd Zedd„ ƒZedd„ ƒZdS )ÚFakeClockSSHUserAuthServerc                 C   ó
   | j jjS )zy
        Use the C{attemptsBeforeDisconnect} value defined by the factory to make
        it easier to override.
        )Ú	transportÚfactoryÚattemptsBeforeDisconnectrD   rF   rF   rG   rv   º   rI   z3FakeClockSSHUserAuthServer.attemptsBeforeDisconnectc                 C   rs   )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).
        )rt   ru   ÚreactorrD   rF   rF   rG   ÚclockÂ   s   
z FakeClockSSHUserAuthServer.clockN)rJ   rK   rL   Úpropertyrv   rx   rF   rF   rF   rG   rr   ·   s
    
rr   c                   @   s2   e Zd Zedd„ ƒZedd„ ƒZeedœZdZ	dS )ÚCommandFactoryc                 C   ó   dt jtdiS ©Nó   ssh-rsa)rR   )r6   Ú
fromStringr<   rD   rF   rF   rG   Ú
publicKeysÍ   ó   zCommandFactory.publicKeysc                 C   r{   r|   )r6   r~   r:   rD   rF   rF   rG   ÚprivateKeysÑ   r€   zCommandFactory.privateKeys)s   ssh-userauths   ssh-connectionr   N)
rJ   rK   rL   ry   r   r   rr   r4   Úservicesrv   rF   rF   rF   rG   rz   Ì   s    

þ	rz   c                   @   s   e Zd ZdS )ÚMemoryAddressN)rJ   rK   rL   rF   rF   rF   rG   rƒ   á   s    rƒ   c                   @   ó    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)rE   ÚserverrF   rF   rG   r]   ò   s   
z SingleUseMemoryEndpoint.__init__c                 C   sh   | j d ur	tdƒ‚z| tƒ ¡}W n ty   tƒ  Y S w t| jt| jdd|t|ddƒ| _ t	|ƒS )Nz(SingleUseMemoryEndpoint was already usedT©ÚisServerF)
r†   Ú	Exceptionri   rƒ   ÚBaseExceptionr   r>   r‡   r@   r   )rE   ru   ÚprotocolrF   rF   rG   r>   û   s   

ÿ
üzSingleUseMemoryEndpoint.connectN)rJ   rK   rL   rM   r]   r>   rF   rF   rF   rG   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#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   passwordÚTCPz10.0.0.1i90  z192.168.100.200i1Ô  )ÚhostnameÚportÚuserÚpasswordr"   rw   rZ   Úrealmr   Úportalr   ÚpasswdDBÚaddUserÚregisterCheckerrz   ru   ÚdoStartÚ
addCleanupÚdoStopr   ÚclientAddressÚserverAddressrD   rF   rF   rG   ÚsetUp  s"   


z(SSHCommandClientEndpointTestsMixin.setUpc                 C   ó   t | jj›dƒ‚)z£
        Create and return a new L{SSHCommandClientEndpoint} to be tested.
        Override this to implement creation in an interesting way the endpoint.
        z did not implement create©ÚNotImplementedErrorÚ	__class__rJ   rD   rF   rF   rG   Úcreate/  ó   ÿz)SSHCommandClientEndpointTestsMixin.createc                 C   s   t d| jjf ƒ‚)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 assertClientTransportStater    ©rE   ÚclientÚimmediateCloserF   rF   rG   ÚassertClientTransportState8  s
   ÿÿz=SSHCommandClientEndpointTestsMixin.assertClientTransportStatec                 C   rŸ   )zˆ
        Do any remaining work necessary to complete an in-memory connection
        attempted initiated using C{self.reactor}.
        z# did not implement finishConnectionr    rD   rF   rF   rG   ÚfinishConnectionH  r¤   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)rŠ   ÚhostAddressÚpeerAddressT)ri   r@   rœ   r   r>   )rE   ÚserverFactoryÚclientFactoryÚclientProtocolÚserverProtocolÚclientTransportÚserverTransportr†   rF   rF   rG   ÚconnectedServerAndClientQ  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   rX   ó   unknown channelFN)r£   r   r   r   r>   r©   ÚflushLoggedErrorsr   ÚassertInÚvaluerR   ÚassertEqualÚlenÚfailureResultOfÚtrapr¨   )	rE   Úendpointru   Ú	connectedrˆ   r¦   r†   ÚerrorsÚfrF   rF   rG   Ú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)rO   r”   r\   r£   r   r   r   r>   r©   rº   r»   r   r¸   r·   r¨   ©rE   r¼   ru   r½   rˆ   r¦   r†   r¿   rF   rF   rG   Ú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)rY   r”   r\   r£   r   r   r   r>   r©   Úcancelrº   r»   r   r¨   rÂ   rF   rF   rG   Ú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)rW   r”   r\   r£   rg   r   r   r>   r©   ÚassertIsInstancerh   r+   r¸   rt   ÚgetHostrˆ   r’   ÚusernameÚcommand)rE   r¼   ru   rˆ   r¦   r†   rF   rF   rG   Ú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)rW   r”   r\   r£   r   r   r   r>   r©   ÚsuccessResultOfÚassertIsNotNonert   ©rE   r¼   ru   r½   rˆ   r¦   r†   r   rF   rF   rG   Ú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, worldó    N)rW   r”   r\   r£   r   r   r   r>   r©   rÌ   ÚappendÚdataReceivedrt   ÚidÚserviceÚchannelsÚwriter†   r¸   Újoin)
rE   r¼   ru   r½   rˆ   r¦   r†   r   rÓ   Ú	channelIdrF   rF   rG   Ú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)rW   r”   r\   r£   r   r   r   r>   r©   rÌ   rÒ   ÚconnectionLostrt   rÔ   rÕ   rÖ   ÚloseConnectionr†   r»   r   r¨   )
rE   r¼   ru   r½   rˆ   r¦   r†   r   rÛ   rÙ   rF   rF   rG   Ú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   )rW   r”   r\   r£   r   r   r   r>   r©   rÌ   rÒ   rÛ   rt   rÔ   rÕ   rÖ   ÚsendRequestrÜ   r†   r¨   )rE   ÚrequestÚ
requestArgr¼   ru   r½   rˆ   r¦   r†   r   rÛ   rÙ   ÚchannelrF   rF   rG   Ú_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   )rE   ÚexitCodeÚexcrF   rF   rG   Útest_zeroExitCode0  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)rE   ræ   rê   rç   rF   rF   rG   Útest_nonZeroExitStatus:  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é   rÑ   s   TERMó   s   messages   en-USs   exit-signalz'twisted.conch.endpoints._CommandChannelTÚmessage)Ú	log_levelÚlog_namespaceÚshortSignalNameÚ
coreDumpedÚerrorMessageÚlanguageTag)r!   r   ÚaddObserverrš   ÚremoveObserverrØ   r1   ÚNSrâ   r»   r   r¸   r·   ræ   rê   ÚhamcrestÚassert_thatÚhas_itemÚhas_entriesÚequal_tor   Úinfo)rE   ÚlogObserverræ   rê   Úpacketrç   ÚlogNamespacerF   rF   rG   Útest_nonZeroExitSignalG  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 r[   )rÒ   rF   ©ÚrecorderrF   rG   r`   ‰  s   
 z;SSHCommandClientEndpointTestsMixin.record.<locals>.<lambda>)rt   rÔ   rÒ   ÚsetattrrÕ   rÖ   )rE   rˆ   r   ÚeventÚnoArgsrÙ   r¿   rF   r  rG   Úrecordu  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Ð   rÑ   N)rW   r”   r\   r£   r   r   r   r>   r©   rÌ   r  rt   r×   r†   r¸   rØ   ©	rE   r¼   ru   r½   rˆ   r¦   r†   r   rÓ   rF   rF   rG   Ú
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Ð   rÑ   N)rW   r”   r\   r£   r   r   r   r>   r©   rÌ   r  rt   ÚwriteSequencer†   r¸   rØ   r  rF   rF   rG   Útest_writeSequence¥  s   

z5SSHCommandClientEndpointTestsMixin.test_writeSequenceN)F)rJ   rK   rL   rM   rž   r£   r¨   r©   r²   rÀ   rÃ   rÅ   rË   rÏ   rÚ   rÝ   râ   rè   rë   r  r  r	  r  rF   rF   rF   rG   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.
        r}   N)rŽ   rž   r   ÚmktempÚhostKeyPathr)   Ú
knownHostsÚ
addHostKeyr   ru   r   r   r   ÚhostÚsaverD   rF   rF   rG   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)	r,   ÚnewConnectionrw   r’   r   r‘   r“   r  rk   rD   rF   rF   rG   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²   ru   rw   Ú
tcpClientsrD   rF   rF   rG   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  rt   rÜ   r†   r¸   ÚreportDisconnect)rE   rˆ   r¦   r   r†   r  rF   rF   rG   ÚloseConnectionToServeré  s   
z)NewConnectionTests.loseConnectionToServerc                 C   s(   |r|   |jj¡ dS |   |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)Ú
assertTruert   rC   Údisconnectingr¥   rF   rF   rG   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)r,   r  rw   r   r‘   r  r   r   ©rE   r¼   rF   rF   rG   Ú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©r,   r  rw   r   r¸   Ú_creatorr‘   r   rF   rF   rG   Ú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   rF   rF   rG   Útest_specifiedPort,  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   rX   N)r,   r  rw   r’   r   r‘   r“   r  rk   r   r   r   r>   r  r¸   r   r¹   )rE   r¼   ru   r  r‘   ÚtimeoutÚbindAddressrF   rF   rG   Útest_destination5  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)r,   r  rw   r   r‘   r  rk   r   r   r   r>   r  ÚclientConnectionFailedr   r   rº   r»   ©rE   r¼   ru   ÚdrF   rF   rG   Útest_connectionFailedM  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)r,   r  rw   r   r‘   r)   r  rk   r   r   r   r>   r²   ru   r  rº   r»   r	   rÂ   rF   rF   rG   Útest_userRejectedHostKeye  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)Ú
passphraseTrÆ   r  ó   dummy passwordr  r   r  N)r6   r~   r:   Úpublicr)   r   r  r  r   r   r  r;   r   rk   r,   r  rw   r‘   r   r   r   r>   r²   ru   r  rº   r»   r   )rE   ÚfirstKeyr  ÚdifferentKeyr  r¼   ru   r½   rˆ   r¦   r†   r¿   rF   rF   rG   Útest_mismatchedHostKey  s8   ÿþø

ÿ
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)r,   r  rw   r   r‘   r  rk   r   r   r   r>   r?   r  ri   ÚmakeConnectionrÛ   r   r   rº   r»   ©rE   r¼   ru   r-  rt   r¦   rF   rF   rG   Ú!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*  Nr‰   r   r  )r,   r  rw   r   r‘   r  rk   r   r   r   r>   r@   r  ri   r6  rÄ   rº   r»   r   r  rC   rÛ   r   r   r7  rF   rF   rG   Ú$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)r,   r  rw   r   r‘   r  rk   r   r   r   r>   rÄ   rº   r»   r   r  Ú
connectorsÚstoppedConnectingr,  rF   rF   rG   Ú'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  r1  Fr  r   r  N)r,   r  rw   r   r‘   r  rk   r   r   r   r>   r²   ru   r  ÚadvancerÕ   ÚpasswordDelayÚflushrº   r»   r*   r¨   rÂ   rF   rF   rG   Ú"test_passwordAuthenticationFailure  s*   ø

ÿ

z5NewConnectionTests.test_passwordAuthenticationFailurec                 C   s,   dd„ |  ¡ 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"   i | ]\}}|t  |¡ ¡ g“qS rF   )r6   r~   r2  )Ú.0ÚkÚvrF   rF   rG   Ú
<dictcomp>8  s   " z6NewConnectionTests.setupKeyChecker.<locals>.<dictcomp>N)Úitemsr'   r&   r˜   )rE   r•   ÚusersÚmappingÚcheckerrF   rF   rG   Ú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)r6   r~   r:   rI  r•   r’   r9   r,   r  rw   r   r‘   r  rk   r   r   r   r>   r²   ru   r  rº   r»   r*   r  rt   r  )	rE   ÚbadKeyr¼   ru   r½   rˆ   r¦   r†   r¿   rF   rF   rG   Ú#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)rK  r“   r  r  rX   r   r  r³   r´   N)$r6   r~   r:   rI  r•   r’   r9   r,   r  rw   r   r‘   r“   r  rk   r   r   r   r>   ru   rv   r²   r  r†   rµ   r   r¶   r·   rR   r¸   r¹   rº   r»   r  rt   r  )
rE   rL  r¼   ru   r½   rˆ   r¦   r†   r¾   r¿   rF   rF   rG   Útest_authenticationFallbacka  s8   
÷

ÿ
 

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Æ   FrJ  r   r  N)r6   r~   r9   rI  r•   r’   rW   r”   r\   r,   r  rw   r   r‘   r  rk   r   r   r   r>   r²   ru   r  rÌ   rÍ   rt   )	rE   Úkeyr¼   ru   r½   rˆ   r¦   r†   r   rF   rF   rG   Útest_publicKeyAuthentication‘  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)r,   r  rw   r’   r   r‘   r  rk   r   r   r   r>   r²   ru   r  r†   rº   r»   r*   r  rt   r  rÂ   rF   rF   rG   Ú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.
        rÑ   rÆ   F)r  r  ÚagentEndpointrÁ   r   r  é   N)$r6   r~   r:   r2   r   ru   ÚblobrK  rI  r•   r’   r…   r,   r  rw   r   r‘   r  rk   rW   r”   r\   r   r   r>   r²   r  Úranger†   rÌ   rÍ   rt   r  r  r  ÚclientIO)rE   rO  ÚagentServerrR  r¼   ru   r½   rˆ   r¦   r†   Úir   rF   rF   rG   Ú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)rW   r”   r\   r£   r   r   r   r>   r©   rÌ   r  r  rt   r  rÎ   rF   rF   rG   Útest_loseConnection  s   

z&NewConnectionTests.test_loseConnectionN)rJ   rK   rL   rM   rž   r£   r©   r  r¨   r!  r%  r&  r)  r.  r/  r5  r8  r9  r<  r@  rI  rM  rN  rP  rQ  rY  rZ  rF   rF   rF   rG   r  »  s2    	#	
	,"(%0!3r  c                   @   ó0   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  r}   rÆ   Fr  N)rŽ   rž   r)   r   r  r  r   ru   r   r   r   r  r,   r  rw   r’   r‘   r“   rk   r¼   )rE   r  rF   rF   rG   rž   !  s    
ÿøzExistingConnectionTests.setUpc           	   	   C   s¼   t ƒ }t|_| j |¡}| jj ¡ }z%t| jjd< |  	| j
| jjd d ¡\}}}W | jj ¡  | jj |¡ n| jj ¡  | jj |¡ w || _|| _|| _|  |¡}|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”   r\   ÚcopyrW   r²   ru   rw   r  ÚclearÚupdater‡   Ú_clientÚ_pumprÌ   rt   Úconnr,   ÚexistingConnection)	rE   ru   r½   r\   rˆ   r¦   r†   r   Ú
connectionrF   rF   rG   r£   9  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.
        )ra  r†   r‡   r`  rD   rF   rF   rG   r©   W  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)ÚassertFalsert   r  rC   r¥   rF   rF   rG   r¨   e  s   z2ExistingConnectionTests.assertClientTransportStateN)rJ   rK   rL   rM   rž   r£   r©   r¨   rF   rF   rF   rG   r\    s    r\  c                   @   r[  )ÚExistingConnectionHelperTestsz1
    Tests for L{_ExistingConnectionHelper}.
    c                 C   ó   |   tttƒ¡ dS )zT
        L{_ExistingConnectionHelper} implements L{_ISSHConnectionCreator}.
        N)r  r   r.   r-   rD   rF   rF   rG   r!  u  ó   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Ì   ÚsecureConnection)rE   rm   ÚhelperrF   rF   rG   Útest_secureConnection{  s   z3ExistingConnectionHelperTests.test_secureConnectionc                 C   ó   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-   ri  ÚcleanupConnection©rE   rl  rF   rF   rG   Ú$test_cleanupConnectionNotImmediately…  ó   
zBExistingConnectionHelperTests.test_cleanupConnectionNotImmediatelyc                 C   rn  )zœ
        L{_ExistingConnectionHelper.cleanupConnection} does nothing to the
        existing connection if called with C{immediate} set to C{True}.
        TNro  rq  rF   rF   rG   Ú!test_cleanupConnectionImmediately  rs  z?ExistingConnectionHelperTests.test_cleanupConnectionImmediatelyN)rJ   rK   rL   rM   r!  rm  rr  rt  rF   rF   rF   rG   rf  p  s    
rf  c                   @   r„   )Ú_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)rE   rv  rF   rF   rG   r]   ¢  s   
z_PTYPath.__init__c                 C   s   |dkr	t | jƒS ttdƒ‚)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 implemented)r0   rv  ÚOSErrorr   )rE   ÚmoderF   rF   rG   Úopen©  s   	

z_PTYPath.openN)rJ   rK   rL   rM   r]   ry  rF   rF   rF   rG   ru  œ  s    ru  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   rg  )zO
        L{_NewConnectionHelper} implements L{_ISSHConnectionCreator}.
        N)r  r   r.   r/   rD   rF   rF   rG   r!  ¼  rh  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_HOSTSrD   rF   rF   rG   Ú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 r[   rF   )Úclsrl   rF   rG   r`   Î  ra   zANewConnectionHelperTests.test_defaultKnownHosts.<locals>.<lambda>N)ri  Úpatchr/   rj  r  rq  rF   rl   rG   Útest_defaultKnownHostsÈ  s   ÿz/NewConnectionHelperTests.test_defaultKnownHostsc                 C   s˜   t ƒ jd }t|  ¡ ƒ}t|ƒ}| d|¡ | ¡  td|j›ƒ t	j 
d¡}|j |d¡}|  td|¡ td|›ƒ 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.
        r}   s	   127.0.0.1zCreated known_hosts file at z~/r{  zPatched _KNOWN_HOSTS with N)rz   r   r   r  r)   r  r  r   ÚpathÚosÚ
expanduserÚreplacer  r/   r}  r  Ú
hasHostKey)rE   rO  r  r  ÚhomeÚdefaultÚloadedrF   rF   rG   Ú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(   rq  rF   rF   rG   Ú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?)ru  r/   rÌ   r  rp   r  ©rE   Úttyrl  rm   rF   rF   rG   Ú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  rp   re  r‹  rF   rF   rG   Ú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   rŒ  rq  rF   rF   rG   Ú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/   r4   r?   rt   rp  r  r  )rE   rl  rd  rF   rF   rG   rr    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                   @   rN   )zMNewConnectionHelperTests.test_cleanupConnectionImmediately.<locals>.AbortableFc                 S   rA   )z7
                Abort the connection.
                TNrB   rD   rF   rF   rG   rH   1  s   
z]NewConnectionHelperTests.test_cleanupConnectionImmediately.<locals>.Abortable.abortConnectionN)rJ   rK   rL   rC   rH   rF   rF   rF   rG   Ú	Abortable.  rj   r  NT)r/   r4   r7   rt   rp  r  rC   )rE   r  rl  rd  rF   rF   rG   rt  (  s   	ÿ
z:NewConnectionHelperTests.test_cleanupConnectionImmediatelyN)rJ   rK   rL   rM   r!  r|  r€  r‰  rŠ  r  rŽ  r  rr  rt  rF   rF   rF   rG   rz  ·  s    

rz  )wrM   Úos.pathr‚  Úerrnor   Ústructr   Úzope.interfacer   Úzope.interface.verifyr   r   rø   Útwisted.conch.errorr   r   r	   Útwisted.conch.interfacesr
   Útwisted.cred.checkersr   Útwisted.cred.portalr   Útwisted.internet.addressr   Útwisted.internet.deferr   r   r   r   Útwisted.internet.errorr   r   r   r   Útwisted.internet.interfacesr   r   Útwisted.internet.protocolr   r   Útwisted.loggerr   r   Útwisted.python.compatr   Útwisted.python.failurer   Útwisted.python.filepathr   Útwisted.python.logr   Útwisted.python.reflectr    Útwisted.test.proto_helpersr!   r"   Útwisted.trial.unittestr#   Útwisted.conch.avatarr%   Útwisted.conch.checkersr&   r'   Útwisted.conch.client.knownhostsr(   r)   Útwisted.conch.endpointsr*   r+   r,   r-   r.   r/   r0   Útwisted.conch.sshr1   Útwisted.conch.ssh.agentr2   Útwisted.conch.ssh.channelr3   Útwisted.conch.ssh.connectionr4   Útwisted.conch.ssh.factoryr5   Útwisted.conch.ssh.keysr6   Útwisted.conch.ssh.transportr7   Útwisted.conch.ssh.userauthr8   Útwisted.conch.test.keydatar9   r:   r;   r<   Úskipri  Útwisted.test.iosimr=   r>   r?   r@   rO   rW   rY   rZ   rg   rk   rr   rz   rƒ   r…   rŽ   r  r\  rf  ru  rz  rF   rF   rF   rG   Ú<module>   s˜   $	
&   1    dU,