U
    �Acj½d  ã                
   @  s"  d dl mZ d dlZd dlZd dl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 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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#m$Z$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/m0Z0m1Z1 zd dlm2Z2m3Z3 W n e4k
�rN   Y nX e+dƒZ5e5�r€d dl6m7Z7 d dl8m9Z9m:Z:m;Z; nd dl<m9Z9 G dd„ dƒZ7zd dl=m:Z> W n2 e4k
�rÜ Z? zdZ@eAe?ƒZB[?W 5 dZ?[?X Y nX e>Z@G dd„ dƒZCG dd „ d e1ƒZDG d!d"„ d"ejEƒZFG d#d$„ d$ejGƒZHG d%d&„ d&ejIƒZJG d'd(„ d(ejIƒZKG d)d*„ d*ejEƒZLdFd,d-d.d/œd0d1„ZMG d2d3„ d3ƒZNG d4d5„ d5eNƒZOee9ƒG d6d7„ d7e7ƒƒZPG d8d9„ d9ƒZQG d:d;„ d;eNƒZRG d<d=„ d=ƒZSG d>d?„ d?eNeSe1ƒZTG d@dA„ dAeOeSe1ƒZUG dBdC„ dCeReSe1ƒZVG dDdE„ dEeOe1ƒZWdS )Gé    )ÚannotationsN)Úcount)ÚAny)Úimplementer)Ú
ConchError)ÚprivateRSA_opensshÚpublicRSA_openssh©ÚConchTestRealm)Úportal)ÚprotocolÚreactor)ÚDeferredÚgatherResultsÚmaybeDeferred)ÚProcessExitedAlready)ÚIReactorProcess)ÚLoopingCall)ÚfilepathÚlogÚruntime)ÚFilePath)Úwhich)ÚrequireModule)ÚHAS_IPV6ÚskipWithoutIPv6)ÚSkipTestÚTestCase)ÚConchTestServerFactoryÚconchTestPublicKeyCheckerÚcryptography)Ú	ConchUser)ÚISessionÚ
SSHSessionÚwrapProtocol)r"   c                   @  s   e Zd ZdS )r!   N)Ú__name__Ú
__module__Ú__qualname__© r(   r(   úA/tmp/pip-unpacked-wheel-nrvc_22y/twisted/conch/test/test_conch.pyr!   /   s   r!   )r#   c                   @  s   e Zd ZdZdZdd„ ZdS )Ú	FakeStdiozø
    A fake for testing L{twisted.conch.scripts.conch.SSHSession.eofReceived} and
    L{twisted.conch.scripts.cftp.SSHSession.eofReceived}.

    @ivar writeConnLost: A flag which records whether L{loserWriteConnection}
        has been called.
    Fc                 C  s
   d| _ dS )z9
        Record the call to loseWriteConnection.
        TN)ÚwriteConnLost©Úselfr(   r(   r)   ÚloseWriteConnectionH   s    zFakeStdio.loseWriteConnectionN)r%   r&   r'   Ú__doc__r+   r.   r(   r(   r(   r)   r*   =   s   r*   c                   @  s$   e Zd ZdZedkreZdd„ ZdS )ÚStdioInteractingSessionTestsz>
    Tests for L{twisted.conch.scripts.conch.SSHSession}.
    Nc                 C  s*   t ƒ }tƒ }||_| ¡  |  |j¡ dS )z}
        L{twisted.conch.scripts.conch.SSHSession.eofReceived} loses the
        write half of its stdio connection.
        N)r*   ÚStdioInteractingSessionÚstdioÚeofReceivedÚ
assertTruer+   )r-   r2   Zchannelr(   r(   r)   Útest_eofReceivedW   s
    z-StdioInteractingSessionTests.test_eofReceived)r%   r&   r'   r/   r1   Ú_reasonÚskipr5   r(   r(   r(   r)   r0   O   s   r0   c                   @  s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚEchoc                 C  s   t  d¡ d S )NzECHO CONNECTION MADE©r   Úmsgr,   r(   r(   r)   ÚconnectionMaded   s    zEcho.connectionMadec                 C  s   t  d¡ d S )NzECHO CONNECTION DONEr9   ©r-   Úreasonr(   r(   r)   ÚconnectionLostg   s    zEcho.connectionLostc                 C  s"   | j  |¡ d|kr| j  ¡  d S )Nó   
)Ú	transportÚwriteÚloseConnection©r-   Údatar(   r(   r)   ÚdataReceivedj   s    zEcho.dataReceivedN)r%   r&   r'   r;   r>   rE   r(   r(   r(   r)   r8   c   s   r8   c                   @  s   e Zd ZeZdS )ÚEchoFactoryN)r%   r&   r'   r8   r   r(   r(   r(   r)   rF   p   s   rF   c                   @  sR   e Zd ZU dZdZded< dZdZdZded< d	d
„ Z	dd„ Z
dd„ Zdd„ ZdS )ÚConchTestOpenSSHProcessaŒ  
    Test protocol for launching an OpenSSH client process.

    @ivar deferred: Set by whatever uses this object. Accessed using
    L{_getDeferred}, which destroys the value so the Deferred is not
    fired twice. Fires when the process is terminated.

    @ivar expectedExitCode: If the process exit code is not C{expectedExitCode}
    the set C{deferred} will by triggerd with a failure.
    NzDeferred[None] | NoneÚdeferredó    r   ÚintÚexpectedExitCodec                 C  s   | j d  }| _ |S ©N©rH   ©r-   Údr(   r(   r)   Ú_getDeferred…   s    z$ConchTestOpenSSHProcess._getDeferredc                 C  s   |  j |7  _ d S rL   )ÚbufrC   r(   r(   r)   ÚoutReceived‰   s    z#ConchTestOpenSSHProcess.outReceivedc                 C  s   |  j |7  _ d S rL   )ÚproblemsrC   r(   r(   r)   ÚerrReceivedŒ   s    z#ConchTestOpenSSHProcess.errReceivedc              
   C  sZ   |j j| jkr:|  ¡  td | j|j j| j d¡¡ƒ¡ n| j	 
dd¡}|  ¡  |¡ dS )z~
        Called when the process has ended.

        @param reason: a Failure giving the reason for the process' end.
        zexit code was not {}: {} ({})Úcharmaps   
r?   N)ÚvalueZexitCoderK   rP   Zerrbackr   ÚformatrS   ÚdecoderQ   ÚreplaceÚcallback)r-   r=   rQ   r(   r(   r)   ÚprocessEnded�   s    
ýÿÿ
z$ConchTestOpenSSHProcess.processEnded)r%   r&   r'   r/   rH   Ú__annotations__rQ   rS   rK   rP   rR   rT   r[   r(   r(   r(   r)   rG   t   s   
rG   c                   @  sT   e Zd ZdZdZdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Z	dd„ Z
dd„ Zdd„ ZdS )ÚConchTestForwardingProcessaæ  
    Manages a third-party process which launches a server.

    Uses L{ConchTestForwardingPort} to connect to the third-party server.
    Once L{ConchTestForwardingPort} has disconnected, kill the process and fire
    a Deferred with the data received by the L{ConchTestForwardingPort}.

    @ivar deferred: Set by whatever uses this object. Accessed using
    L{_getDeferred}, which destroys the value so the Deferred is not
    fired twice. Fires when the process is terminated.
    Nc                 C  s   || _ d| _|| _dS )aF  
        @type port: L{int}
        @param port: The port on which the third-party server is listening.
        (it is assumed that the server is running on localhost).

        @type data: L{str}
        @param data: This is sent to the third-party server. Must end with '
'
        in order to trigger a disconnect.
        N)ÚportÚbufferrD   )r-   r^   rD   r(   r(   r)   Ú__init__³   s    
z#ConchTestForwardingProcess.__init__c                 C  s   | j d  }| _ |S rL   rM   rN   r(   r(   r)   rP   Á   s    z'ConchTestForwardingProcess._getDeferredc                 C  s   |   ¡  d S rL   )Ú_connectr,   r(   r(   r)   r;   Å   s    z)ConchTestForwardingProcess.connectionMadec                 C  s0   t  tt| | j¡}| d| j¡}| | j¡ |S )a  
        Connect to the server, which is often a third-party process.
        Tries to reconnect if it fails because we have no way of determining
        exactly when the port becomes available for listening -- we can only
        know when the process starts.
        ú	127.0.0.1)	r   ZClientCreatorr   ÚConchTestForwardingPortrD   Z
connectTCPr^   Z
addErrbackÚ
_ebConnect)r-   ÚccrO   r(   r(   r)   ra   È   s    z#ConchTestForwardingProcess._connectc                 C  s   t  d| j¡ d S )Ngš™™™™™¹?)r   Ú	callLaterra   )r-   Úfr(   r(   r)   rd   Ô   s    z%ConchTestForwardingProcess._ebConnectc                 C  s.   || _ | j d¡ | j ¡  t d| j¡ dS )zÖ
        The network connection has died; save the buffer of output
        from the network and attempt to quit the process gracefully,
        and then (after the reactor has spun) send it a KILL signal.
        ó   r   N)r_   r@   rA   rB   r   rf   Ú
_reallyDie)r-   r_   r(   r(   r)   ÚforwardingPortDisconnected×   s    
z5ConchTestForwardingProcess.forwardingPortDisconnectedc                 C  s*   z| j  d¡ W n tk
r$   Y nX d S )NZKILL)r@   ZsignalProcessr   r,   r(   r(   r)   ri   â   s    z%ConchTestForwardingProcess._reallyDiec                 C  s   |   ¡  | j¡ dS )zŒ
        Fire the Deferred at self.deferred with the data collected
        from the L{ConchTestForwardingPort} connection, if any.
        N)rP   rZ   r_   r<   r(   r(   r)   r[   è   s    z'ConchTestForwardingProcess.processEnded)r%   r&   r'   r/   rH   r`   rP   r;   ra   rd   rj   ri   r[   r(   r(   r(   r)   r]   ¤   s   r]   c                   @  s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )rc   zë
    Connects to server launched by a third-party process (managed by
    L{ConchTestForwardingProcess}) sends data, then reports whatever it
    received back to the L{ConchTestForwardingProcess} once the connection
    is ended.
    c                 C  s   || _ || _dS )zè
        @type protocol: L{ConchTestForwardingProcess}
        @param protocol: The L{ProcessProtocol} which made this connection.

        @type data: str
        @param data: The data to be sent to the third-party server.
        N)r   rD   )r-   r   rD   r(   r(   r)   r`   ø   s    z ConchTestForwardingPort.__init__c                 C  s   d| _ | j | j¡ d S )NrI   )r_   r@   rA   rD   r,   r(   r(   r)   r;     s    z&ConchTestForwardingPort.connectionMadec                 C  s   |  j |7  _ d S rL   )r_   rC   r(   r(   r)   rE     s    z$ConchTestForwardingPort.dataReceivedc                 C  s   | j  | j¡ d S rL   )r   rj   r_   r<   r(   r(   r)   r>   
  s    z&ConchTestForwardingPort.connectionLostN)r%   r&   r'   r/   r`   r;   rE   r>   r(   r(   r(   r)   rc   ð   s
   rc   Úconchz	list[str]Ústrzlist[bytes])ÚargsÚmodÚreturnc                 C  s    t jd| g}dd„ || •D ƒS )Na$  -c
### Twisted Preamble
import sys, os
path = os.path.abspath(sys.argv[0])
while os.path.dirname(path) != path:
    if os.path.basename(path).startswith('Twisted'):
        sys.path.insert(0, path)
        break
    path = os.path.dirname(path)

from twisted.conch.scripts.%s import run
run()c                 S  s   g | ]}|  d ¡‘qS )úutf-8)Úencode)Ú.0Zeachr(   r(   r)   Ú
<listcomp>   s     z_makeArgs.<locals>.<listcomp>)ÚsysÚ
executable)rm   rn   Ústartr(   r(   r)   Ú	_makeArgs  s    óþrw   c                   @  sN   e Zd ZesdZedd„ ƒZdd„ Zdd„ Zdd	„ Z	d
d„ Z
ddœdd„ZdS )ÚConchServerSetupMixinzcan't run without cryptographyc                   C  s   t dƒS )Ns   testuserr	   r(   r(   r(   r)   ÚrealmFactory'  s    z"ConchServerSetupMixin.realmFactoryc              	   C  s¸   dD ]}t j |¡rt  |¡ qtddƒ�}| t¡ W 5 Q R X tddƒ�}| t¡ W 5 Q R X t  dd¡ t	dƒ 
¡ }|jjsˆ|jjr�tdƒ‚tddƒ�}| dt ¡ W 5 Q R X d S )	N)Úrsa_testúrsa_test.pubÚkh_testrz   Úwbr{   i€  zgprivate key readable by others despite chmod; possible windows permission issue? see https://tm.tl/9767r|   s
   127.0.0.1 )ÚosÚpathÚexistsÚremoveÚopenrA   r   r   Úchmodr   ZgetPermissionsÚgroupÚreadÚotherr   )r-   rg   Úpermissionsr(   r(   r)   Ú_createFiles+  s    ÿz"ConchServerSetupMixin._createFilesc                 C  s*   t   ¡ }| d¡ | ¡ d }| ¡  |S )N)Ú r   é   )ÚsocketÚbindÚgetsocknameÚclose)r-   Úsr^   r(   r(   r)   Ú_getFreePort>  s
    
z"ConchServerSetupMixin._getFreePortc                 C  s.   |   ¡ }t |¡}| tƒ ¡ tƒ }||_|S )zŽ
        Make a L{ConchTestServerFactory}, which allows us to start a
        L{ConchTestServer} -- i.e. an actually listening conch.
        )ry   r   ZPortalZregisterCheckerr   r   )r-   ÚrealmÚpÚfactoryr(   r(   r)   Ú_makeConchFactoryE  s    
z'ConchServerSetupMixin._makeConchFactoryc                 C  sv   |   ¡  |  ¡ | _d| j_tjd| jdd�| _t dtƒ ¡| _| j 	¡ j
| _trrtjdtƒ dd�| _| j 	¡ j
| _d S )NrŠ   r   rb   )Z	interfacez::1)rˆ   r”   ÚconchFactoryZexpectedLoseConnectionr   Z	listenTCPÚconchServerrF   Ú
echoServerÚgetHostr^   ÚechoPortr   ÚechoServerV6Ú
echoPortV6r,   r(   r(   r)   ÚsetUpQ  s    
  ÿzConchServerSetupMixin.setUpr   ©ro   c                 C  sh   zd| j j_W n tk
r"   Y nX | j jj ¡  t| jjƒt| j	jƒg}t
r`| t| jjƒ¡ t|ƒS )NrŠ   )r•   ÚprotoÚdoneÚAttributeErrorr@   rB   r   r–   ÚstopListeningr—   r   Úappendrš   r   )r-   Z	deferredsr(   r(   r)   ÚtearDown^  s    

þzConchServerSetupMixin.tearDownN)r%   r&   r'   r    r7   Ústaticmethodry   rˆ   r�   r”   rœ   r£   r(   r(   r(   r)   rx   #  s   
rx   c                   @  s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	ÚForwardingMixinaÏ  
    Template class for tests of the Conch server's ability to forward arbitrary
    protocols over SSH.

    These tests are integration tests, not unit tests. They launch a Conch
    server, a custom TCP server (just an L{EchoProtocol}) and then call
    L{execute}.

    L{execute} is implemented by subclasses of L{ForwardingMixin}. It should
    cause an SSH client to connect to the Conch server, asking it to forward
    data to the custom TCP server.
    c                 C  s   |   dtƒ ¡}| | jd¡S )z³
        Test that we can use whatever client to send the command "echo goodbye"
        to the Conch server. Make sure we receive "goodbye" back from the
        server.
        úecho goodbyeó   goodbye
©ÚexecuterG   ÚaddCallbackÚassertEqualrN   r(   r(   r)   Ú	test_exec}  s    zForwardingMixin.test_execc                 C  s>   |   ¡ }t|dƒ}| jd|d|| jf d�}| | jd¡ |S )zy
        Test that we can use whatever client to forward a local port to a
        specified port on the server.
        ó   test
r‰   z-N -L%i:127.0.0.1:%i©ÚsshArgs©r�   r]   r©   r™   rª   r«   ©r-   Z	localPortÚprocessrO   r(   r(   r)   Útest_localToRemoteForwarding†  s    
  ÿz,ForwardingMixin.test_localToRemoteForwardingc                 C  s>   |   ¡ }t|dƒ}| jd|d|| jf d�}| | jd¡ |S )zs
        Test that we can use whatever client to forward a port from the server
        to a port locally.
        r­   r‰   z-N -R %i:127.0.0.1:%ir®   r°   r±   r(   r(   r)   Útest_remoteToLocalForwarding“  s    
  ÿz,ForwardingMixin.test_remoteToLocalForwardingN)r%   r&   r'   r/   r¬   r³   r´   r(   r(   r(   r)   r¥   o  s   	r¥   c                   @  sH   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S )ÚRekeyAvatara#  
    This avatar implements a shell which sends 60 numbered lines to whatever
    connects to it, then closes the session with a 0 exit status.

    60 lines is selected as being enough to send more than 2kB of traffic, the
    amount the client is configured to initiate a rekey after.
    c                 C  s   t  | ¡ t| jd< d S )Ns   session)r!   r`   r#   ZchannelLookupr,   r(   r(   r)   r`   ¯  s    
zRekeyAvatar.__init__c                   sH   t  ¡ }| ˆ¡ ˆ t|ƒ¡ ‡ ‡fdd„}t|tƒ ƒ‰ ˆ  d¡ dS )zE
        Write 60 lines of data to the transport, then exit.
        c                   sX   t | ƒ}|dkr6ˆ  ¡  ˆjj ˆjdd¡ ˆ ¡  nd|f }| d¡}ˆ |¡ d S )Né<   s   exit-statuss       zline #%02d
rp   )ÚnextÚstopÚsessionÚconnZsendRequestrB   rq   rA   )ÚcounterÚiÚline©Úcallr@   r(   r)   rA   ½  s      ÿ


z$RekeyAvatar.openShell.<locals>.writeg{®Gáz„?N)r   ÚProtocolZmakeConnectionr$   r   r   rv   )r-   r@   rž   rA   r(   r¾   r)   Ú	openShell³  s    
zRekeyAvatar.openShellc                 C  s   dS )z2
        Ignore the close of the session.
        Nr(   r,   r(   r(   r)   ÚclosedÔ  s    zRekeyAvatar.closedc                 C  s   d S rL   r(   r,   r(   r(   r)   r3   Ù  s    zRekeyAvatar.eofReceivedc                 C  s   d S rL   r(   )r-   rž   Úcommandr(   r(   r)   ÚexecCommandÝ  s    zRekeyAvatar.execCommandc                 C  s   d S rL   r(   )r-   ZtermZ
windowSizeÚmodesr(   r(   r)   ÚgetPtyá  s    zRekeyAvatar.getPtyc                 C  s   d S rL   r(   )r-   ZnewWindowSizer(   r(   r)   ÚwindowChangedå  s    zRekeyAvatar.windowChangedN)r%   r&   r'   r/   r`   rÁ   rÂ   r3   rÄ   rÆ   rÇ   r(   r(   r(   r)   rµ   ¥  s   !rµ   c                   @  s   e Zd ZdZdd„ ZdS )Ú
RekeyRealmzS
    This realm gives out new L{RekeyAvatar} instances for any avatar request.
    c                 G  s   |d t ƒ dd„ fS )Nr   c                   S  s   d S rL   r(   r(   r(   r(   r)   Ú<lambda>ð  rI   z*RekeyRealm.requestAvatar.<locals>.<lambda>)rµ   )r-   ZavatarIDZmindZ
interfacesr(   r(   r)   ÚrequestAvatarï  s    zRekeyRealm.requestAvatarN)r%   r&   r'   r/   rÊ   r(   r(   r(   r)   rÈ   ê  s   rÈ   c                   @  s   e Zd ZdZeZdd„ ZdS )ÚRekeyTestsMixinzp
    TestCase mixin which defines tests exercising L{SSHTransportBase}'s handling
    of rekeying messages.
    c                   s.   t ƒ }ˆ  d|d¡}‡ fdd„}| |¡ |S )z‡
        After a client-initiated rekey is completed, application data continues
        to be passed over the SSH connection.
        r‰   z-o RekeyLimit=2Kc                   s6   d  dd„ tdƒD ƒ¡d }| d¡}ˆ  | |¡ d S )NÚ
c                 S  s   g | ]}d |f ‘qS )z
line #%02dr(   )rr   r¼   r(   r(   r)   rs     s     zFRekeyTestsMixin.test_clientRekey.<locals>.finished.<locals>.<listcomp>r¶   rp   )ÚjoinÚrangerq   r«   )ÚresultZexpectedResultr,   r(   r)   Úfinished  s    
z2RekeyTestsMixin.test_clientRekey.<locals>.finished)rG   r©   rª   )r-   r²   rO   rÐ   r(   r,   r)   Útest_clientRekeyû  s
    
z RekeyTestsMixin.test_clientRekeyN)r%   r&   r'   r/   rÈ   ry   rÑ   r(   r(   r(   r)   rË   ó  s   rË   c                   @  s.   e Zd ZedƒsdZddddddœdd	„Zd
S )ÚOpenSSHClientMixinÚsshz$no ssh command-line client availabler‰   rl   rG   úDeferred[None])ÚremoteCommandr²   r¯   ro   c           
      C  sp   t ƒ  }|_d| d | }| j ¡ j}||  ¡ }g }|D ]}	| |	 d¡¡ q<tt	ƒ 
|tdƒd |¡ |S )a¸  
        Connects to the SSH server started in L{ConchServerSetupMixin.setUp} by
        running the 'ssh' command line tool.

        @type remoteCommand: str
        @param remoteCommand: The command (with arguments) to run on the
        remote end.

        @type process: L{ConchTestOpenSSHProcess}

        @type sshArgs: str
        @param sshArgs: Arguments to pass to the 'ssh' process.

        @return: L{defer.Deferred}
        zŸssh -2 -l testuser -p %i -F /dev/null -oIdentitiesOnly=yes -oUserKnownHostsFile=kh_test -oPasswordAuthentication=no -oHostKeyAlgorithms=ssh-rsa -a -i rsa_test z 127.0.0.1 rp   rÓ   r   )r   rH   r–   r˜   r^   Úsplitr¢   rq   r   r   ÚspawnProcessr   )
r-   rÕ   r²   r¯   rÏ   Zcmdliner^   ZcmdsZencodedCmdsÚcmdr(   r(   r)   r©     s     
õôóÿzOpenSSHClientMixin.executeN)r‰   )r%   r&   r'   r   r7   r©   r(   r(   r(   r)   rÒ     s    ÿrÒ   c                   @  sP   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S )ÚOpenSSHKeyExchangeTestsz\
    Tests L{SSHTransportBase}'s key exchange algorithm compatibility with
    OpenSSH.
    c                 C  s�   g }z>t jtdƒd ddgt jd�}t|tƒs8| d¡}| ¡ }W n tk
rV   Y nX ||krnt	|› d�ƒ‚|  
dtƒ d	| ¡}| | jd
¡S )aI  
        Call execute() method of L{OpenSSHClientMixin} with an ssh option that
        forces the exclusive use of the key exchange algorithm specified by
        keyExchangeAlgo

        @type keyExchangeAlgo: L{str}
        @param keyExchangeAlgo: The key exchange algorithm to use

        @return: L{defer.Deferred}
        rÓ   r   z-QZkex)Ústderrrp   z not supported by ssh clientz
echo helloz-oKexAlgorithms=s   hello
)Ú
subprocessÚcheck_outputr   ÚSTDOUTÚ
isinstancerl   rX   rÖ   ÚBaseExceptionr   r©   rG   rª   r«   )r-   ZkeyExchangeAlgoZkexAlgorithmsÚoutputrO   r(   r(   r)   ÚassertExecuteWithKexAlgorithmF  s&     ÿ

ýz5OpenSSHKeyExchangeTests.assertExecuteWithKexAlgorithmc                 C  s
   |   d¡S )zb
        The ecdh-sha2-nistp256 key exchange algorithm is compatible with
        OpenSSH
        zecdh-sha2-nistp256©rá   r,   r(   r(   r)   Útest_ECDHSHA256f  s    z'OpenSSHKeyExchangeTests.test_ECDHSHA256c                 C  s
   |   d¡S )zb
        The ecdh-sha2-nistp384 key exchange algorithm is compatible with
        OpenSSH
        zecdh-sha2-nistp384râ   r,   r(   r(   r)   Útest_ECDHSHA384m  s    z'OpenSSHKeyExchangeTests.test_ECDHSHA384c                 C  s
   |   d¡S )zb
        The ecdh-sha2-nistp521 key exchange algorithm is compatible with
        OpenSSH
        zecdh-sha2-nistp521râ   r,   r(   r(   r)   Útest_ECDHSHA521t  s    z'OpenSSHKeyExchangeTests.test_ECDHSHA521c                 C  s
   |   d¡S )zl
        The diffie-hellman-group14-sha1 key exchange algorithm is compatible
        with OpenSSH.
        zdiffie-hellman-group14-sha1râ   r,   r(   r(   r)   Útest_DH_GROUP14{  s    z'OpenSSHKeyExchangeTests.test_DH_GROUP14c                 C  s
   |   d¡S )zs
        The diffie-hellman-group-exchange-sha1 key exchange algorithm is
        compatible with OpenSSH.
        z"diffie-hellman-group-exchange-sha1râ   r,   r(   r(   r)   Útest_DH_GROUP_EXCHANGE_SHA1‚  s    z3OpenSSHKeyExchangeTests.test_DH_GROUP_EXCHANGE_SHA1c                 C  s
   |   d¡S )zu
        The diffie-hellman-group-exchange-sha256 key exchange algorithm is
        compatible with OpenSSH.
        z$diffie-hellman-group-exchange-sha256râ   r,   r(   r(   r)   Útest_DH_GROUP_EXCHANGE_SHA256‰  s    ÿz5OpenSSHKeyExchangeTests.test_DH_GROUP_EXCHANGE_SHA256c                 C  s   |   t| jd¡ dS )zy
        The list of key exchange algorithms supported
        by OpenSSH client is obtained with C{ssh -Q kex}.
        zunsupported-algorithmN)ÚassertRaisesr   rá   r,   r(   r(   r)   Útest_unsupported_algorithm’  s
      ÿz2OpenSSHKeyExchangeTests.test_unsupported_algorithmN)r%   r&   r'   r/   rá   rã   rä   rå   ræ   rç   rè   rê   r(   r(   r(   r)   rÙ   @  s    	rÙ   c                   @  s   e Zd ZdZedd„ ƒZdS )ÚOpenSSHClientForwardingTestszR
    Connection forwarding tests run against the OpenSSL command line client.
    c                 C  s>   |   ¡ }t|dƒ}| jd|d|| jf d�}| | jd¡ |S )zG
        Forwarding of arbitrary IPv6 TCP connections via SSH.
        r­   r‰   z-N -L%i:[::1]:%ir®   )r�   r]   r©   r›   rª   r«   r±   r(   r(   r)   Útest_localToRemoteForwardingV6¡  s    
  ÿz;OpenSSHClientForwardingTests.test_localToRemoteForwardingV6N)r%   r&   r'   r/   r   rì   r(   r(   r(   r)   rë   œ  s   rë   c                   @  s   e Zd ZdZdS )ÚOpenSSHClientRekeyTestszE
    Rekeying tests run against the OpenSSL command line client.
    N)r%   r&   r'   r/   r(   r(   r(   r)   rí   ¯  s   rí   c                   @  sr   e Zd ZdZejdkrdZddddd	dd
dœdd„Zdd„ Zdd„ Z	d
dœdd„Z
d
dœdd„Zd
dœdd„ZdS )ÚCmdLineClientTestszP
    Connection forwarding tests run against the Conch command line client.
    Úwin32z!can't run cmdline client on win32r‰   Nrb   rl   rG   zlist[str] | NonerÔ   )rÕ   r²   r¯   Ú	conchArgsÚ
remoteHostro   c           
      C  sŒ   |dkrg }t ƒ |_| j ¡ j}d |¡| d|› d� | }t| ¡ ƒ}tj	 
¡ }	tj tj¡|	d< ttƒj|tjt|| ƒ|	d� |jS )z{
        As for L{OpenSSHClientTestCase.execute}, except it runs the 'conch'
        command line tool, not 'ssh'.
        Nz[-p {} -l testuser --known-hosts kh_test --user-authentications publickey -a -i rsa_test -v ú Ú
PYTHONPATH)Úenv)r   rH   r–   r˜   r^   rW   ÚlistrÖ   r~   ÚenvironÚcopyÚpathseprÍ   rt   r   r   r   r×   ru   rw   )
r-   rÕ   r²   r¯   rð   rñ   r^   ZcmdtemplaterÖ   rô   r(   r(   r)   r©   ½  s0    ûû
ûûÿ
  
 ÿzCmdLineClientTests.executec                   sV   ‡ ‡fdd„}t  ˆ ¡ ¡‰ ˆjdtƒ ddˆ jddgd�}| ˆjd	¡ | |¡ |S )
z4
        It can store logs to a local file.
        c                   s   ˆ   ¡ }ˆ d|¡ d S )Ns   Log opened.)Z
getContentZassertIn)rÏ   Z
logContent©ZlogPathr-   r(   r)   Úcb_check_logã  s    z<CmdLineClientTests.test_runWithLogFile.<locals>.cb_check_logr¦   z--logz	--logfilez--host-key-algorithmszssh-rsa©rÕ   r²   rð   r§   )r   r   Úmktempr©   rG   r   rª   r«   )r-   rú   rO   r(   rù   r)   Útest_runWithLogFileÞ  s    ûý
z&CmdLineClientTests.test_runWithLogFilec                 C  s"   | j dtƒ d�}| | jd¡ |S )zH
        Do not use --host-key-algorithms flag on command line.
        r¦   )rÕ   r²   r§   r¨   rN   r(   r(   r)   Ú%test_runWithNoHostAlgorithmsSpecifiedù  s     ÿz8CmdLineClientTests.test_runWithNoHostAlgorithmsSpecifiedr�   c                 C  s   | j dtƒ dgd� | jd¡S )zS
        Simple smoke test for '--compress' flag to ensure we can connect.
        zecho compressedz
--compressrû   s   compressed
r¨   r,   r(   r(   r)   Ú test_runWithCompressionSpecified  s    ý üz3CmdLineClientTests.test_runWithCompressionSpecifiedc                 C  s   t ƒ }d|_| jd|dd�S )z<
        Connecting to an invalid host should fail.
        rŠ   zecho nonfunctionalúnowhere.invalid©rÕ   r²   rñ   )rG   rK   r©   ©r-   ZexpectErrorr(   r(   r)   Útest_connectToInvalidHost  s    ýz,CmdLineClientTests.test_connectToInvalidHostc                 C  s   t ƒ }|  | jd|dd�t¡S )zm
        L{ConchTestOpenSSHProcess} fails with a L{ConchError} if an expectation
        is not met.
        zecho checkfailurer   r  )rG   ZassertFailurer©   r   r  r(   r(   r)   Útest_testFailure  s    ýúz#CmdLineClientTests.test_testFailure)r‰   Nrb   )r%   r&   r'   r/   r   ZplatformTyper7   r©   rý   rþ   rÿ   r  r  r(   r(   r(   r)   rî   µ  s   
   ú!
rî   )rk   )XÚ
__future__r   r~   r‹   rÛ   rt   Ú	itertoolsr   Útypingr   Zzope.interfacer   Ztwisted.conch.errorr   Ztwisted.conch.test.keydatar   r   Ztwisted.conch.test.test_sshr
   Ztwisted.credr   Ztwisted.internetr   r   Ztwisted.internet.deferr   r   r   Ztwisted.internet.errorr   Ztwisted.internet.interfacesr   Ztwisted.internet.taskr   Ztwisted.pythonr   r   r   Ztwisted.python.filepathr   Ztwisted.python.procutilsr   Ztwisted.python.reflectr   Ztwisted.test.testutilsr   r   Ztwisted.trial.unittestr   r   r   r   ÚImportErrorr    Ztwisted.conch.avatarr!   Ztwisted.conch.ssh.sessionr"   r#   r$   Ztwisted.conch.interfacesZtwisted.conch.scripts.conchZ_StdioInteractingSessionÚer1   rl   r6   r*   r0   rÀ   r8   ZFactoryrF   ZProcessProtocolrG   r]   rc   rw   rx   r¥   rµ   rÈ   rË   rÒ   rÙ   rë   rí   rî   r(   r(   r(   r)   Ú<module>   st   0LL6D	4\