U
     T‚g£^  ã                
   @   sä  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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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&m'Z'm(Z( zd dlm)Z)m*Z* W n e+k
�r   Y nX e"dƒZ,e,�rLd dl-m.Z. d dl/m0Z0m1Z1m2Z2 nd dl3m0Z0 G dd„ dƒZ.zd dl4m1Z5 W n2 e+k
�r¨ Z6 zdZ7e8e6ƒZ9[6W 5 dZ6[6X Y nX e5Z7G dd„ dƒZ:G dd„ de(ƒZ;G dd„ dej<ƒZ=G dd „ d ej>ƒZ?G d!d"„ d"ej@ƒZAG d#d$„ d$ej@ƒZBG d%d&„ d&ej<ƒZCd>d(d)„ZDG d*d+„ d+ƒZEG d,d-„ d-eEƒZFee0ƒG d.d/„ d/e.ƒƒZGG d0d1„ d1ƒZHG d2d3„ d3eEƒZIG d4d5„ d5ƒZJG d6d7„ d7eEeJe(ƒZKG d8d9„ d9eFeJe(ƒZLG d:d;„ d;eIeJe(ƒZMG d<d=„ d=eFe(ƒZNdS )?é    N)Úcount)Úimplementer)Ú
ConchError)ÚprivateRSA_opensshÚpublicRSA_openssh©ÚConchTestRealm)Úportal)ÚdeferÚprotocolÚreactor)ÚProcessExitedAlready)Ú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-1_7di8ic/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$   ÚloseWriteConnectionD   s    zFakeStdio.loseWriteConnectionN)r    r!   r"   Ú__doc__r&   r)   r#   r#   r#   r$   r%   9   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(   r-   Zchannelr#   r#   r$   Útest_eofReceivedS   s
    z-StdioInteractingSessionTests.test_eofReceived)r    r!   r"   r*   r,   Ú_reasonÚskipr0   r#   r#   r#   r$   r+   K   s   r+   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$   ÚconnectionMade`   s    zEcho.connectionMadec                 C   s   t  d¡ d S )NzECHO CONNECTION DONEr4   ©r(   Úreasonr#   r#   r$   ÚconnectionLostc   s    zEcho.connectionLostc                 C   s"   | j  |¡ d|kr| j  ¡  d S )Nó   
)Ú	transportÚwriteÚloseConnection©r(   Údatar#   r#   r$   ÚdataReceivedf   s    zEcho.dataReceivedN)r    r!   r"   r6   r9   r@   r#   r#   r#   r$   r3   _   s   r3   c                   @   s   e Zd ZeZdS )ÚEchoFactoryN)r    r!   r"   r3   r   r#   r#   r#   r$   rA   l   s   rA   c                   @   s<   e Zd ZdZdZdZdZdd„ Zdd„ Zdd	„ Z	d
d„ Z
d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.
    Nó    c                 C   s   | j d  }| _ |S ©N©Údeferred©r(   Údr#   r#   r$   Ú_getDeferred}   s    z$ConchTestOpenSSHProcess._getDeferredc                 C   s   |  j |7  _ d S rD   )Úbufr>   r#   r#   r$   ÚoutReceived�   s    z#ConchTestOpenSSHProcess.outReceivedc                 C   s   |  j |7  _ d S rD   )Úproblemsr>   r#   r#   r$   ÚerrReceived„   s    z#ConchTestOpenSSHProcess.errReceivedc              	   C   sT   |j jdkr4|  ¡  td |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.
        r   zexit code was not 0: {} ({})Úcharmaps   
r:   N)ÚvalueZexitCoderI   Zerrbackr   ÚformatrL   ÚdecoderJ   ÚreplaceÚcallback)r(   r8   rJ   r#   r#   r$   ÚprocessEnded‡   s    
þÿÿ	z$ConchTestOpenSSHProcess.processEnded)r    r!   r"   r*   rF   rJ   rL   rI   rK   rM   rT   r#   r#   r#   r$   rB   p   s   rB   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Úbufferr?   )r(   rV   r?   r#   r#   r$   Ú__init__ª   s    
z#ConchTestForwardingProcess.__init__c                 C   s   | j d  }| _ |S rD   rE   rG   r#   r#   r$   rI   ¸   s    z'ConchTestForwardingProcess._getDeferredc                 C   s   |   ¡  d S rD   )Ú_connectr'   r#   r#   r$   r6   ¼   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   ÚConchTestForwardingPortr?   Z
connectTCPrV   Z
addErrbackÚ
_ebConnect)r(   ÚccrH   r#   r#   r$   rY   ¿   s    z#ConchTestForwardingProcess._connectc                 C   s   t  d| j¡ d S )Ngš™™™™™¹?)r   Ú	callLaterrY   )r(   Úfr#   r#   r$   r\   Ë   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)rW   r;   r<   r=   r   r^   Ú
_reallyDie)r(   rW   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$   ra   Ù   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)rI   rS   rW   r7   r#   r#   r$   rT   ß   s    z'ConchTestForwardingProcess.processEnded)r    r!   r"   r*   rF   rX   rI   r6   rY   r\   rb   ra   rT   r#   r#   r#   r$   rU   ›   s   rU   c                   @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )r[   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   r?   )r(   r   r?   r#   r#   r$   rX   ï   s    z ConchTestForwardingPort.__init__c                 C   s   d| _ | j | j¡ d S )NrC   )rW   r;   r<   r?   r'   r#   r#   r$   r6   ú   s    z&ConchTestForwardingPort.connectionMadec                 C   s   |  j |7  _ d S rD   )rW   r>   r#   r#   r$   r@   þ   s    z$ConchTestForwardingPort.dataReceivedc                 C   s   | j  | j¡ d S rD   )r   rb   rW   r7   r#   r#   r$   r9     s    z&ConchTestForwardingPort.connectionLostN)r    r!   r"   r*   rX   r6   r@   r9   r#   r#   r#   r$   r[   ç   s
   r[   Úconchc                 C   sF   t jd| g}g }|t| ƒ D ]"}t|tƒr6| d¡}| |¡ q|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()úutf-8)ÚsysÚ
executableÚlistÚ
isinstanceÚstrÚencodeÚappend)ÚargsÚmodÚstartZmadeArgsÚargr#   r#   r$   Ú	_makeArgs  s    óþ

rp   c                   @   sH   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„ 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_testrs   Úwbrt   i€  zgprivate key readable by others despite chmod; possible windows permission issue? see https://tm.tl/9767ru   s
   127.0.0.1 )ÚosÚpathÚexistsÚremoveÚopenr<   r   r   Úchmodr   ZgetPermissionsÚgroupÚreadÚotherr   )r(   r_   Úpermissionsr#   r#   r$   Ú_createFiles'  s    ÿz"ConchServerSetupMixin._createFilesc                 C   s*   t   ¡ }| d¡ | ¡ d }| ¡  |S )N)Ú r   é   )ÚsocketÚbindÚgetsocknameÚclose)r(   ÚsrV   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.
        )rr   r	   ZPortalZregisterCheckerr   r   )r(   ÚrealmÚpÚfactoryr#   r#   r$   Ú_makeConchFactoryA  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   rZ   )Z	interfacez::1)r�   r�   ÚconchFactoryZexpectedLoseConnectionr   Z	listenTCPÚconchServerrA   Ú
echoServerÚgetHostrV   ÚechoPortr   ÚechoServerV6Ú
echoPortV6r'   r#   r#   r$   ÚsetUpM  s    
  ÿzConchServerSetupMixin.setUpc                 C   sp   zd| j j_W n tk
r"   Y nX | j jj ¡  t | jj	¡t | j
j	¡g}trf| t | jj	¡¡ t |¡S )Nrƒ   )rŽ   ÚprotoÚdoneÚAttributeErrorr;   r=   r
   ZmaybeDeferredr�   ÚstopListeningr�   r   rk   r“   ZgatherResults)r(   Z	deferredsr#   r#   r$   ÚtearDownZ  s    þzConchServerSetupMixin.tearDownN)r    r!   r"   r   r2   Ústaticmethodrr   r�   r‰   r�   r•   rš   r#   r#   r#   r$   rq     s   
rq   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
©ÚexecuterB   ÚaddCallbackÚassertEqualrG   r#   r#   r$   Ú	test_execx  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‰   rU   r    r’   r¡   r¢   ©r(   Z	localPortÚprocessrH   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œ   j  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   rX   r   ZchannelLookupr'   r#   r#   r$   rX   ª  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
rd   )ÚnextÚstopÚsessionÚconnZsendRequestr=   rj   r<   )ÚcounterÚiÚline©Úcallr;   r#   r$   r<   ¸  s      ÿ


z$RekeyAvatar.openShell.<locals>.writeg{®Gáz„?N)r   ÚProtocolZmakeConnectionr   r   r   rn   )r(   r;   r–   r<   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 rD   r#   r'   r#   r#   r$   r.   Ô  s    zRekeyAvatar.eofReceivedc                 C   s   d S rD   r#   )r(   r–   Úcommandr#   r#   r$   ÚexecCommandØ  s    zRekeyAvatar.execCommandc                 C   s   d S rD   r#   )r(   ZtermZ
windowSizeÚmodesr#   r#   r$   ÚgetPtyÜ  s    zRekeyAvatar.getPtyc                 C   s   d S rD   r#   )r(   ZnewWindowSizer#   r#   r$   ÚwindowChangedà  s    zRekeyAvatar.windowChangedN)r    r!   r"   r*   rX   r¸   r¹   r.   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 rD   r#   r#   r#   r#   r$   Ú<lambda>ë  rC   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#   )Ú.0r³   r#   r#   r$   Ú
<listcomp>ÿ  s     zFRekeyTestsMixin.test_clientRekey.<locals>.finished.<locals>.<listcomp>r­   rd   )ÚjoinÚrangerj   r¢   )ÚresultZexpectedResultr'   r#   r$   Úfinishedþ  s    
z2RekeyTestsMixin.test_clientRekey.<locals>.finished)rB   r    r¡   )r(   r©   rH   rÉ   r#   r'   r$   Útest_clientRekeyö  s
    
z RekeyTestsMixin.test_clientRekeyN)r    r!   r"   r*   r¿   rr   rÊ   r#   r#   r#   r$   rÂ   î  s   rÂ   c                   @   s"   e Zd ZedƒsdZddd„ZdS )ÚOpenSSHClientMixinÚsshz$no ssh command-line client availabler‚   c           	      C   sl   t  ¡ |_d| d | }| j ¡ j}||  ¡ }g }|D ]}| | d¡¡ q:t	 
|tdƒd |¡ |j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 ú 127.0.0.1 rd   rÌ   r   )r
   ÚDeferredrF   r�   r‘   rV   Úsplitrk   rj   r   ÚspawnProcessr   )	r(   ÚremoteCommandr©   r¦   ZcmdlinerV   ÚcmdsÚencodedCmdsÚcmdr#   r#   r$   r      s     

õôóÿzOpenSSHClientMixin.executeN)r‚   )r    r!   r"   r   r2   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)Ústderrrd   z not supported by ssh clientz
echo helloz-oKexAlgorithms=s   hello
)Ú
subprocessÚcheck_outputr   ÚSTDOUTrh   ri   rQ   rÏ   ÚBaseExceptionr   r    rB   r¡   r¢   )r(   ZkeyExchangeAlgoZkexAlgorithmsÚoutputrH   r#   r#   r$   ÚassertExecuteWithKexAlgorithm>  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_ECDHSHA256^  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_ECDHSHA384e  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_ECDHSHA521l  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_GROUP14s  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_SHA1z  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Õ   8  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‰   rU   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                   @   s8   e Zd ZdZejdkrdZddd„Zdd	„ Zd
d„ Z	dS )ÚCmdLineClientTestszP
    Connection forwarding tests run against the Conch command line client.
    Úwin32z!can't run cmdline client on win32r‚   Nc                 C   sð   |dkrg }t  ¡ |_| j ¡ j}d |¡| d | }t|| ¡  ƒ}t	j
 ¡ }t	j tj¡|d< g }	i }
|D ]"}t|tƒrˆ| d¡}|	 |¡ qp|D ]<}|| }t|tƒr¸| d¡}t|tƒrÌ| d¡}||
|< q˜tj|tj|	|
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 rÍ   Ú
PYTHONPATHrd   )Úenv)r
   rÎ   rF   r�   r‘   rV   rP   rp   rÏ   rw   ÚenvironÚcopyÚpathseprÆ   re   rx   rh   ri   rj   rk   r   rÐ   rf   )r(   rÑ   r©   r¦   Ú	conchArgsrV   rÔ   rÒ   rì   rÓ   Z
encodedEnvÚvarÚvalr#   r#   r$   r    µ  s@    
ûûûûÿ







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    rB   rx   r¡   r¢   )r(   rô   rH   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Ÿ   rG   r#   r#   r$   Ú%test_runWithNoHostAlgorithmsSpecifiedõ  s     ÿz8CmdLineClientTests.test_runWithNoHostAlgorithmsSpecified)r‚   N)
r    r!   r"   r*   r   ZplatformTyper2   r    rö   r÷   r#   r#   r#   r$   ré   ­  s   

%ré   )rc   )Orw   r„   r×   re   Ú	itertoolsr   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   r   Ztwisted.internet.errorr   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Úer,   ri   r1   r%   r+   r·   r3   ZFactoryrA   ZProcessProtocolrB   rU   r[   rp   rq   rœ   r¬   r¿   rÂ   rË   rÕ   ræ   rè   ré   r#   r#   r#   r$   Ú<module>   sl   +L
K6D	1\