U
    n5{i¹ƒ  ã                   @   s  U d 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mZmZ ddlmZ dd	lmZmZ dd
lmZmZ ddlmZ ddlmZ ddlmZ ddlmZ dZ ee e!d< edƒ�r
ddl"m#Z# ddl$m Z m%Z%m&Z& ddl'm(Z( ddl)m*Z* nG dd„ dƒZ%G dd„ dƒZ&G dd„ de&j+ƒZ,G dd„ de&j+ƒZ-G dd„ de&j+ƒZ.G d d!„ d!e%j/ƒZ0eeƒG d"d#„ d#ƒƒZ1eeƒG d$d%„ d%ƒƒZ2eeƒG d&d'„ d'ƒƒZ3eeƒG d(d)„ d)ƒƒZ4G d*d+„ d+ej5ƒZ6G d,d-„ d-ej5ƒZ7G d.d/„ d/ej5ƒZ8G d0d1„ d1ej5ƒZ9dS )2zT
Tests for the implementation of the ssh-userauth service.

Maintainer: Paul Swartz
é    )Ú
ModuleType)ÚOptional)Úimplementer)Ú
ConchErrorÚValidPublicKey)ÚICredentialsChecker)Ú
IAnonymousÚISSHPrivateKeyÚIUsernamePassword)ÚUnauthorizedLogin)ÚIRealmÚPortal)ÚdeferÚtask)ÚDeferred)Úloopback)ÚrequireModule)ÚunittestNÚkeysZcryptography)ÚSSHProtocolChecker)r   Ú	transportÚuserauth)ÚNS)Úkeydatac                   @   s   e Zd ZG dd„ dƒZdS )r   c                   @   s   e Zd ZdZdS )ztransport.SSHTransportBaseúQ
            A stub class so that later class definitions won't die.
            N©Ú__name__Ú
__module__Ú__qualname__Ú__doc__© r    r    úD/tmp/pip-unpacked-wheel-mnhg7r0q/twisted/conch/test/test_userauth.pyÚSSHTransportBase#   s   r"   N)r   r   r   r"   r    r    r    r!   r   "   s   r   c                   @   s   e Zd ZG dd„ dƒZdS )r   c                   @   s   e Zd ZdZdS )zuserauth.SSHUserAuthClientr   Nr   r    r    r    r!   ÚSSHUserAuthClient)   s   r#   N)r   r   r   r#   r    r    r    r!   r   (   s   r   c                   @   s2   e Zd ZdZdd„ Zdd„ Zddd„Zd	d
„ ZdS )ÚClientUserAuthz"
    A mock user auth client.
    c                 C   s,   | j rtj tj¡S t tj tj¡¡S dS )z˜
        If this is the first time we've been called, return a blob for
        the DSA key.  Otherwise, return a blob
        for the RSA key.
        N)	ZlastPublicKeyr   ÚKeyÚ
fromStringr   ÚpublicRSA_opensshr   ÚsucceedÚpublicDSA_openssh©Úselfr    r    r!   ÚgetPublicKey4   s    zClientUserAuth.getPublicKeyc                 C   s   t  tj tj¡¡S )z@
        Return the private key object for the RSA key.
        )r   r(   r   r%   r&   r   ÚprivateRSA_opensshr*   r    r    r!   ÚgetPrivateKey?   s    zClientUserAuth.getPrivateKeyNc                 C   s
   t  d¡S )z/
        Return 'foo' as the password.
        ó   foo©r   r(   )r+   Úpromptr    r    r!   ÚgetPasswordE   s    zClientUserAuth.getPasswordc                 C   s
   t  d¡S )z>
        Return 'foo' as the answer to two questions.
        )Úfoor3   r0   )r+   ÚnameZinformationZanswersr    r    r!   ÚgetGenericAnswersK   s    z ClientUserAuth.getGenericAnswers)N)r   r   r   r   r,   r.   r2   r5   r    r    r    r!   r$   /   s
   
r$   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚOldClientAuthz~
    The old SSHUserAuthClient returned a cryptography key object from
    getPrivateKey() and a string from getPublicKey
    c                 C   s   t  tj tj¡j¡S ©N)r   r(   r   r%   r&   r   r-   Z	keyObjectr*   r    r    r!   r.   X   s    zOldClientAuth.getPrivateKeyc                 C   s   t j tj¡ ¡ S r7   )r   r%   r&   r   r'   Úblobr*   r    r    r!   r,   [   s    zOldClientAuth.getPublicKeyN©r   r   r   r   r.   r,   r    r    r    r!   r6   R   s   r6   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚClientAuthWithoutPrivateKeyzP
    This client doesn't have a private key, but it does have a public key.
    c                 C   s   d S r7   r    r*   r    r    r!   r.   d   s    z)ClientAuthWithoutPrivateKey.getPrivateKeyc                 C   s   t j tj¡S r7   )r   r%   r&   r   r'   r*   r    r    r!   r,   g   s    z(ClientAuthWithoutPrivateKey.getPublicKeyNr9   r    r    r    r!   r:   _   s   r:   c                   @   sL   e Zd ZdZG dd„ dƒZG dd„ dƒZdd„ Zdd	„ Zd
d„ Zdd„ Z	dS )ÚFakeTransporta_  
    L{userauth.SSHUserAuthServer} expects an SSH transport which has a factory
    attribute which has a portal attribute. Because the portal is important for
    testing authentication, we need to be able to provide an interesting portal
    object to the L{SSHUserAuthServer}.

    In addition, we want to be able to capture any packets sent over the
    transport.

    @ivar packets: a list of 2-tuples: (messageType, data).  Each 2-tuple is
        a sent packet.
    @type packets: C{list}
    @param lostConnecion: True if loseConnection has been called on us.
    @type lostConnection: L{bool}
    c                   @   s   e Zd ZdZdZdd„ ZdS )zFakeTransport.ServicezW
        A mock service, representing the other service offered by the server.
        ó   nancyc                 C   s   d S r7   r    r*   r    r    r!   ÚserviceStartedƒ   s    z$FakeTransport.Service.serviceStartedN)r   r   r   r   r4   r=   r    r    r    r!   ÚService|   s   r>   c                   @   s   e Zd ZdZdd„ ZdS )zFakeTransport.Factoryzg
        A mock factory, representing the factory that spawned this user auth
        service.
        c                 C   s   |dkrt jS dS )z2
            Return our fake service.
            ó   noneN)r;   r>   )r+   r   Úservicer    r    r!   Ú
getServiceŒ   s    z FakeTransport.Factory.getServiceN)r   r   r   r   rA   r    r    r    r!   ÚFactory†   s   rB   c                 C   s(   |   ¡ | _|| j_d| _| | _g | _d S ©NF)rB   ÚfactoryÚportalÚlostConnectionr   Úpackets)r+   rE   r    r    r!   Ú__init__“   s
    
zFakeTransport.__init__c                 C   s   | j  ||f¡ dS )z8
        Record the packet sent by the service.
        N)rG   Úappend)r+   ZmessageTypeÚmessager    r    r!   Ú
sendPacketš   s    zFakeTransport.sendPacketc                 C   s   dS )z»
        Pretend that this transport encrypts traffic in both directions. The
        SSHUserAuthServer disables password authentication if the transport
        isn't encrypted.
        Tr    )r+   Ú	directionr    r    r!   ÚisEncrypted    s    zFakeTransport.isEncryptedc                 C   s
   d| _ d S ©NT)rF   r*   r    r    r!   ÚloseConnection¨   s    zFakeTransport.loseConnectionN)
r   r   r   r   r>   rB   rH   rK   rM   rO   r    r    r    r!   r;   k   s   
r;   c                   @   s   e Zd ZdZdd„ ZdS )ÚRealmz¿
    A mock realm for testing L{userauth.SSHUserAuthServer}.

    This realm is not actually used in the course of testing, so it returns the
    simplest thing that could possibly work.
    c                 G   s   t  |d d dd„ f¡S )Nr   c                   S   s   d S r7   r    r    r    r    r!   Ú<lambda>¶   ó    z%Realm.requestAvatar.<locals>.<lambda>r0   )r+   ZavatarIdZmindZ
interfacesr    r    r!   ÚrequestAvatarµ   s    zRealm.requestAvatarN)r   r   r   r   rS   r    r    r    r!   rP   ¬   s   rP   c                   @   s   e Zd ZdZefZdd„ ZdS )ÚPasswordCheckerzŽ
    A very simple username/password checker which authenticates anyone whose
    password matches their username and rejects all others.
    c                 C   s&   |j |jkrt |j ¡S t tdƒ¡S )NzInvalid username/password pair)ÚusernameÚpasswordr   r(   Úfailr   )r+   Úcredsr    r    r!   ÚrequestAvatarIdÂ   s    zPasswordChecker.requestAvatarIdN)r   r   r   r   r
   ÚcredentialInterfacesrY   r    r    r    r!   rT   ¹   s   rT   c                   @   s   e Zd ZdZefZdd„ ZdS )ÚPrivateKeyCheckerz•
    A very simple public key checker which authenticates anyone whose
    public/private keypair is the same keydata.public/privateRSA_openssh.
    c                 C   sX   |j tj tj¡  ¡ krN|jd k	rHtj |j ¡}| |j|j¡rN|j	S nt
ƒ ‚tƒ ‚d S r7   )r8   r   r%   r&   r   r'   Ú	signatureÚverifyÚsigDatarU   r   r   )r+   rX   Úobjr    r    r!   rY   Ñ   s    
z!PrivateKeyChecker.requestAvatarIdN)r   r   r   r   r	   rZ   rY   r    r    r    r!   r[   È   s   r[   c                   @   s   e Zd ZdZefZdd„ ZdS )ÚAnonymousCheckerzI
    A simple checker which isn't supported by L{SSHUserAuthServer}.
    c                 C   s   d S r7   r    )r+   Úcredentialsr    r    r!   rY   ä   s    z AnonymousChecker.requestAvatarIdN)r   r   r   r   r   rZ   rY   r    r    r    r!   r`   Ü   s   r`   c                   @   sÔ   e Zd ZdZedkrdZddœdd„Zdd„ Zedd	œd
d„Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$d%„ Zd&d'„ Zd(d)„ Zed dœd*d+„Zd,d-„ ZdS ).ÚSSHUserAuthServerTestsz&
    Tests for SSHUserAuthServer.
    Núcannot run without cryptography)Úreturnc                 C   sb   t ƒ | _t| jƒ| _| j tƒ ¡ | j tƒ ¡ t ¡ | _	t
| jƒ| j	_| j	 ¡  | j	j ¡  d S r7   )rP   Úrealmr   rE   ÚregisterCheckerrT   r[   r   ÚSSHUserAuthServerÚ
authServerr;   r   r=   ÚsupportedAuthenticationsÚsortr*   r    r    r!   ÚsetUpñ   s    

zSSHUserAuthServerTests.setUpc                 C   s   | j  ¡  d | _ d S r7   )rh   ÚserviceStoppedr*   r    r    r!   ÚtearDownü   s    
zSSHUserAuthServerTests.tearDown)Úignoredrd   c                 C   s>   t | jjtƒst‚| jjjd }|  |tjt	dƒd f¡ dS )z;
        Check that the authentication has failed.
        éÿÿÿÿs   password,publickeyó    N)
Ú
isinstancerh   r   r;   ÚAssertionErrorrG   ÚassertEqualr   ZMSG_USERAUTH_FAILUREr   )r+   rn   Z
lastPacketr    r    r!   Ú_checkFailed   s    þz#SSHUserAuthServerTests._checkFailedc                 C   s,   | j  tdƒtdƒ tdƒ ¡}| | j¡S )zÃ
        A client may request a list of authentication 'method name' values
        that may continue by using the "none" authentication 'method name'.

        See RFC 4252 Section 5.2.
        r/   s   servicer?   )rh   Ússh_USERAUTH_REQUESTr   ÚaddCallbackrt   )r+   Údr    r    r!   Útest_noneAuthentication  s    ÿz.SSHUserAuthServerTests.test_noneAuthenticationc                    sF   d  tdƒtdƒtdƒdtdƒg¡}ˆ j |¡}‡ fdd„}| |¡S )zÝ
        When provided with correct password authentication information, the
        server should respond by sending a MSG_USERAUTH_SUCCESS message with
        no other data.

        See RFC 4252, Section 5.1.
        rR   r/   r?   ó   passwordrp   c                    s   ˆ   ˆ jjjtjdfg¡ d S ©NrR   ©rs   rh   r   rG   r   ZMSG_USERAUTH_SUCCESS©rn   r*   r    r!   Úcheck"  s    
þzKSSHUserAuthServerTests.test_successfulPasswordAuthentication.<locals>.check)Újoinr   rh   ru   rv   ©r+   Úpacketrw   r}   r    r*   r!   Ú%test_successfulPasswordAuthentication  s    $z<SSHUserAuthServerTests.test_successfulPasswordAuthenticationc                 C   sh   d  tdƒtdƒtdƒdtdƒg¡}t ¡ | j_| j |¡}|  | jjj	g ¡ | jj 
d¡ | | j¡S )a;  
        When provided with invalid authentication details, the server should
        respond by sending a MSG_USERAUTH_FAILURE message which states whether
        the authentication was partially successful, and provides other, open
        options for authentication.

        See RFC 4252, Section 5.1.
        rR   r/   r?   ry   rp   ó   baré   )r~   r   r   ÚClockrh   Úclockru   rs   r   rG   Úadvancerv   rt   ©r+   r€   rw   r    r    r!   Ú!test_failedPasswordAuthentication*  s    
$z8SSHUserAuthServerTests.test_failedPasswordAuthenticationc                    s¦   t j tj¡ ¡ }t j tj¡}tdƒtdƒ tdƒ d t| ¡ ƒ t|ƒ }dˆ j	j
_| tdƒttjfƒ | ¡}|t|ƒ7 }ˆ j	 |¡}‡ fdd„}| |¡S )zN
        Test that private key authentication completes successfully,
        r/   r?   ó	   publickeyó   ÿó   testc                    s   ˆ   ˆ jjjtjdfg¡ d S rz   r{   r|   r*   r    r!   r}   P  s    
þzMSSHUserAuthServerTests.test_successfulPrivateKeyAuthentication.<locals>.check)r   r%   r&   r   r'   r8   r-   r   ZsshTyperh   r   Ú	sessionIDÚsignÚbytesr   ÚMSG_USERAUTH_REQUESTru   rv   )r+   r8   r_   r€   r\   rw   r}   r    r*   r!   Ú'test_successfulPrivateKeyAuthentication;  s,    ÿþý
üûÿ
ÿz>SSHUserAuthServerTests.test_successfulPrivateKeyAuthenticationc                    sŒ   t  ¡ ‰ dd„ }dd„ }‡ fdd„}|  | jd|¡ |  | jd|¡ |  | jd	|¡ td
ƒtdƒ tdƒ tdƒ }| j |¡ |  ˆ t¡S )z‹
        ssh_USERAUTH_REQUEST should raise a ConchError if tryAuth returns
        None. Added to catch a bug noticed by pyflakes.
        c                 S   s   |   d¡ d S )Nz&request should have raised ConochError)rW   )r+   rn   r    r    r!   ÚmockCbFinishedAuth_  s    zOSSHUserAuthServerTests.test_requestRaisesConchError.<locals>.mockCbFinishedAuthc                 S   s   d S r7   r    )ÚkindÚuserÚdatar    r    r!   ÚmockTryAuthb  s    zHSSHUserAuthServerTests.test_requestRaisesConchError.<locals>.mockTryAuthc                    s   ˆ   | j¡ d S r7   )ZerrbackÚvalue)Úreason©rw   r    r!   ÚmockEbBadAuthe  s    zJSSHUserAuthServerTests.test_requestRaisesConchError.<locals>.mockEbBadAuthÚtryAuthZ_cbFinishedAuthZ
_ebBadAuths   userr?   s
   public-keys   data)r   r   Úpatchrh   r   ru   ÚassertFailurer   )r+   r‘   r•   r™   r€   r    r˜   r!   Útest_requestRaisesConchErrorX  s     z3SSHUserAuthServerTests.test_requestRaisesConchErrorc                    sb   t j tj¡ ¡ ‰ tdƒtdƒ tdƒ d tdƒ tˆ ƒ }ˆj |¡}‡ ‡fdd„}| 	|¡S )z@
        Test that verifying a valid private key works.
        r/   r?   r‰   rp   ó   ssh-rsac                    s*   ˆ  ˆjjjtjtdƒtˆ ƒ fg¡ d S )Nrž   )rs   rh   r   rG   r   ÚMSG_USERAUTH_PK_OKr   r|   ©r8   r+   r    r!   r}   �  s    þz@SSHUserAuthServerTests.test_verifyValidPrivateKey.<locals>.check)
r   r%   r&   r   r'   r8   r   rh   ru   rv   r   r    r    r!   Útest_verifyValidPrivateKeyr  s     ÿþýüûÿz1SSHUserAuthServerTests.test_verifyValidPrivateKeyc                 C   sV   t j tj¡ ¡ }tdƒtdƒ tdƒ d tdƒ t|ƒ }| j |¡}| 	| j
¡S )úd
        Test that private key authentication fails when the public key
        is invalid.
        r/   r?   r‰   rp   s   ssh-dsa©r   r%   r&   r   r)   r8   r   rh   ru   rv   rt   ©r+   r8   r€   rw   r    r    r!   Ú3test_failedPrivateKeyAuthenticationWithoutSignature‰  s    ÿþýüûÿzJSSHUserAuthServerTests.test_failedPrivateKeyAuthenticationWithoutSignaturec                 C   s|   t j tj¡ ¡ }t j tj¡}tdƒtdƒ tdƒ d tdƒ t|ƒ t| |¡ƒ }d| j	j
_| j	 |¡}| | j¡S )r¢   r/   r?   r‰   rŠ   rž   r‹   )r   r%   r&   r   r'   r8   r-   r   r�   rh   r   rŒ   ru   rv   rt   )r+   r8   r_   r€   rw   r    r    r!   Ú0test_failedPrivateKeyAuthenticationWithSignatureš  s&    ÿþýüûúÿ	
zGSSHUserAuthServerTests.test_failedPrivateKeyAuthenticationWithSignaturec                 C   sj   t j tj¡ ¡ }tdƒ|dd…  }tdƒtdƒ tdƒ d tdƒ t|ƒ }| j |¡}| 	| j
¡S )	z€
        Private key authentication fails when the public key type is
        unsupported or the public key is corrupt.
        s   ssh-bad-typeé   Nr/   r?   r‰   rp   rž   r£   r¤   r    r    r!   Útest_unsupported_publickey®  s     ÿþýüûÿz1SSHUserAuthServerTests.test_unsupported_publickeyc                 C   sR   t  ¡ }t| jƒ|_| j tƒ ¡ | ¡  | ¡  |j	 
¡  |  |j	ddg¡ dS )ah  
        L{SSHUserAuthServer} sets up
        C{SSHUserAuthServer.supportedAuthentications} by checking the portal's
        credentials interfaces and mapping them to SSH authentication method
        strings.  If the Portal advertises an interface that
        L{SSHUserAuthServer} can't map, it should be ignored.  This is a white
        box test.
        ry   r‰   N)r   rg   r;   rE   r   rf   r`   r=   rl   ri   rj   rs   ©r+   Úserverr    r    r!   Ú test_ignoreUnknownCredInterfacesÄ  s    	
z7SSHUserAuthServerTests.test_ignoreUnknownCredInterfacesc                 C   s�   |   d| jj¡ t ¡ }t| jƒ|_dd„ |j_| 	¡  | 
¡  |  d|j¡ t ¡ }t| jƒ|_dd„ |j_| 	¡  | 
¡  |   d|j¡ dS )z�
        Test that the userauth service does not advertise password
        authentication if the password would be send in cleartext.
        ry   c                 S   s   dS rC   r    ©Úxr    r    r!   rQ   Þ  rR   zISSHUserAuthServerTests.test_removePasswordIfUnencrypted.<locals>.<lambda>c                 S   s   | dkS ©NÚinr    r¬   r    r    r!   rQ   å  rR   N)ZassertInrh   ri   r   rg   r;   rE   r   rM   r=   rl   ZassertNotIn)r+   ÚclearAuthServerÚhalfAuthServerr    r    r!   Ú test_removePasswordIfUnencryptedÕ  s    z7SSHUserAuthServerTests.test_removePasswordIfUnencryptedc                 C   s–   t | jƒ}| tƒ ¡ t ¡ }t|ƒ|_dd„ |j_| 	¡  | 
¡  |  |jdg¡ t ¡ }t|ƒ|_dd„ |j_| 	¡  | 
¡  |  |jdg¡ dS )zÁ
        If the L{SSHUserAuthServer} is not advertising passwords, then an
        unencrypted connection should not cause any warnings or exceptions.
        This is a white box test.
        c                 S   s   dS rC   r    r¬   r    r    r!   rQ   ÷  rR   zSSSHUserAuthServerTests.test_unencryptedConnectionWithoutPasswords.<locals>.<lambda>r‰   c                 S   s   | dkS r®   r    r¬   r    r    r!   rQ   ÿ  rR   N)r   re   rf   r[   r   rg   r;   r   rM   r=   rl   rs   ri   )r+   rE   r°   r±   r    r    r!   Ú*test_unencryptedConnectionWithoutPasswordsê  s    


zASSHUserAuthServerTests.test_unencryptedConnectionWithoutPasswordsc                 C   s€   t  ¡ }t ¡ |_t| jƒ|_| ¡  |j 	d¡ | 
¡  |  |jjtjdttjfƒ tdƒ tdƒ fg¡ |  |jj¡ dS )z0
        Test that the login times out.
        é°š  ó      s   you took too longrR   N)r   rg   r   r„   r…   r;   rE   r   r=   r†   rl   rs   rG   ÚMSG_DISCONNECTrŽ   Ú)DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLEr   Ú
assertTruerF   ©r+   ZtimeoutAuthServerr    r    r!   Útest_loginTimeout  s(    

ÿþýþÿþz(SSHUserAuthServerTests.test_loginTimeoutc                 C   s\   t  ¡ }t ¡ |_t| jƒ|_| ¡  | 	¡  |j 
d¡ |  |jjg ¡ |  |jj¡ dS )zN
        Test that stopping the service also stops the login timeout.
        r´   N)r   rg   r   r„   r…   r;   rE   r   r=   rl   r†   rs   rG   ÚassertFalserF   r¹   r    r    r!   Útest_cancelLoginTimeout  s    
z.SSHUserAuthServerTests.test_cancelLoginTimeoutc                    sn   d  tdƒtdƒtdƒdtdƒg¡}t ¡ ˆ j_tdƒD ]}ˆ j |¡}ˆ jj d¡ q8‡ fd	d
„}| 	|¡S )zm
        Test that the server disconnects if the client fails authentication
        too many times.
        rR   r/   r?   ry   rp   r‚   é   rƒ   c                    s<   ˆ   ˆ jjjd tjdttjfƒ tdƒ tdƒ f¡ d S )Nro   rµ   s   too many bad authsrR   )rs   rh   r   rG   r¶   rŽ   r·   r   r|   r*   r    r!   r}   4  s    
ÿþýþþz:SSHUserAuthServerTests.test_tooManyAttempts.<locals>.check)
r~   r   r   r„   rh   r…   Úrangeru   r†   rv   )r+   r€   Úirw   r}   r    r*   r!   Útest_tooManyAttempts)  s    $z+SSHUserAuthServerTests.test_tooManyAttemptsc                 C   sT   t dƒt dƒ t dƒ d t dƒ }t ¡ | j_| j |¡}|dk	sHt‚| | j¡S )zo
        If the user requests a service that we don't support, the
        authentication should fail.
        r/   rR   ry   rp   N)	r   r   r„   rh   r…   ru   rr   rv   rt   r‡   r    r    r!   Útest_failIfUnknownServiceB  s
    $z0SSHUserAuthServerTests.test_failIfUnknownServicec                    sV   dd„ }ˆ   ˆ jd|¡ ˆ   ˆ jdd¡ ‡ fdd„}ˆ j ddd¡}ˆ  |t¡ |¡S )	aZ  
        tryAuth() has two edge cases that are difficult to reach.

        1) an authentication method auth_* returns None instead of a Deferred.
        2) an authentication type that is defined does not have a matching
           auth_* method.

        Both these cases should return a Deferred which fails with a
        ConchError.
        c                 S   s   d S r7   r    )r€   r    r    r!   ÚmockAuthY  s    z>SSHUserAuthServerTests.test_tryAuthEdgeCases.<locals>.mockAuthZauth_publickeyZauth_passwordNc                    s   ˆ j  dd d ¡}ˆ  |t¡S )Nry   )rh   rš   rœ   r   )rn   Zd2r*   r    r!   Ú
secondTest_  s    z@SSHUserAuthServerTests.test_tryAuthEdgeCases.<locals>.secondTestr‰   )r›   rh   rš   rœ   r   rv   )r+   rÂ   rÃ   Úd1r    r*   r!   Útest_tryAuthEdgeCasesM  s    z,SSHUserAuthServerTests.test_tryAuthEdgeCases)r   r   r   r   r   Úskiprk   rm   Úobjectrt   rx   r�   rˆ   r�   r�   r¡   r¥   r¦   r¨   r«   r²   r³   rº   r¼   rÀ   r   rÁ   rÅ   r    r    r    r!   rb   é   s.   rb   c                   @   s”   e Zd ZdZedkr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S )"ÚSSHUserAuthClientTestsz&
    Tests for SSHUserAuthClient.
    Nrc   c                 C   s4   t dt ¡ ƒ| _td ƒ| j_d| jj_| j ¡  d S )Nr/   r‹   )r$   r;   r>   Ú
authClientr   rŒ   r=   r*   r    r    r!   rk   o  s    
zSSHUserAuthClientTests.setUpc                 C   s   | j  ¡  d | _ d S r7   )rÉ   rl   r*   r    r    r!   rm   u  s    
zSSHUserAuthClientTests.tearDownc                 C   sT   |   | jjd¡ |   | jjjd¡ |   | jjjtjt	dƒt	dƒ t	dƒ fg¡ dS )z;
        Test that client is initialized properly.
        r/   r<   r?   N)
rs   rÉ   r“   Úinstancer4   r   rG   r   r�   r   r*   r    r    r!   Ú	test_inity  s    þz SSHUserAuthClientTests.test_initc                    s@   dg‰ ‡ fdd„}|| j j_| j  d¡ |  ˆ d | j j¡ dS )z9
        Test that the client succeeds properly.
        Nc                    s   | ˆ d< d S )Nr   r    )r@   ©rÊ   r    r!   ÚstubSetServiceŠ  s    zDSSHUserAuthClientTests.test_USERAUTH_SUCCESS.<locals>.stubSetServicerR   r   )rÉ   r   Z
setServiceZssh_USERAUTH_SUCCESSrs   rÊ   )r+   rÍ   r    rÌ   r!   Útest_USERAUTH_SUCCESS„  s
    
z,SSHUserAuthClientTests.test_USERAUTH_SUCCESSc              	   C   s˜  | j  tdƒd ¡ |  | j jjd tjtdƒtdƒ tdƒ d tdƒ ttj	 
tj¡ ¡ ƒ f¡ | j  tdƒd ¡ ttj	 
tj¡ ¡ ƒ}|  | j jjd tjtdƒtdƒ tdƒ d tdƒ | f¡ | j  tdƒttj	 
tj¡ ¡ ƒ ¡ t| j jjƒttjfƒ tdƒ tdƒ tdƒ d tdƒ | }tj	 
tj¡}|  | j jjd tjtdƒtdƒ tdƒ d tdƒ | t| |¡ƒ f¡ d	S )
zJ
        Test that the client can authenticate with a public key.
        r‰   rp   ro   r/   r<   s   ssh-dssrž   ó   N)rÉ   Ússh_USERAUTH_FAILUREr   rs   r   rG   r   r�   r   r%   r&   r   r)   r8   r'   Ússh_USERAUTH_PK_OKrŒ   rŽ   r-   r�   )r+   r8   r^   r_   r    r    r!   Útest_publickey‘  s’    ÿþýüûþþÿþýüûýþÿ
ÿþýüûúùÿ
ÿþýüûúþþz%SSHUserAuthClientTests.test_publickeyc                 C   sz   t dt ¡ ƒ}tdƒ|_d|j_| ¡  | d¡ g |j_|  | 	d¡¡ |  
|jjtjtdƒtdƒ tdƒ fg¡ dS )z¼
        If the SSHUserAuthClient doesn't return anything from signData,
        the client should start the authentication over again by requesting
        'none' authentication.
        r/   Nr‹   r‰   rR   r<   r?   )r:   r;   r>   r   rŒ   r=   rš   rG   ÚassertIsNonerÑ   rs   r   r�   r   )r+   rÉ   r    r    r!   Ú!test_publickey_without_privatekeyÏ  s    

þz8SSHUserAuthClientTests.test_publickey_without_privatekeyc                    s.   dd„ ˆ j _ˆ j  d¡}‡ fdd„}| |¡S )z{
        If there's no public key, auth_publickey should return a Deferred
        called back with a False value.
        c                 S   s   d S r7   r    r¬   r    r    r!   rQ   ç  rR   z:SSHUserAuthClientTests.test_no_publickey.<locals>.<lambda>r‰   c                    s   ˆ   | ¡ d S r7   )r»   ©Úresultr*   r    r!   r}   ê  s    z7SSHUserAuthClientTests.test_no_publickey.<locals>.check)rÉ   r,   rš   rv   )r+   rw   r}   r    r*   r!   Útest_no_publickeyâ  s    z(SSHUserAuthClientTests.test_no_publickeyc                 C   s¬   | j  tdƒd ¡ |  | j jjd tjtdƒtdƒ tdƒ d tdƒ f¡ | j  tdƒtdƒ ¡ |  | j jjd tjtdƒtdƒ tdƒ d tdƒd  f¡ d	S )
zx
        Test that the client can authentication with a password.  This
        includes changing the password.
        ry   rp   ro   r/   r<   rR   rŠ   rƒ   N)	rÉ   rÐ   r   rs   r   rG   r   r�   rÑ   r*   r    r    r!   Útest_passwordï  s    "þþ&þþz$SSHUserAuthClientTests.test_passwordc                 C   s"   dd„ | j _|  | j  d¡¡ dS )zK
        If getPassword returns None, tryAuth should return False.
        c                   S   s   d S r7   r    r    r    r    r!   rQ   	  rR   z9SSHUserAuthClientTests.test_no_password.<locals>.<lambda>ry   N)rÉ   r2   r»   rš   r*   r    r    r!   Útest_no_password  s    z'SSHUserAuthClientTests.test_no_passwordc                 C   s`   | j  tdƒtdƒ tdƒ d tdƒ d ¡ |  | j jjd tjdtdƒ tdƒ f¡ dS )	zj
        Make sure that the client can authenticate with the keyboard
        interactive method.
        rR   s      s
   Password: rp   ro   s      r/   N)rÉ   Z'ssh_USERAUTH_PK_OK_keyboard_interactiver   rs   r   rG   r   ZMSG_USERAUTH_INFO_RESPONSEr*   r    r    r!   Útest_keyboardInteractive  s&    ÿþýüûÿþþz/SSHUserAuthClientTests.test_keyboardInteractivec                 C   sP   d| j _g | j j_| j  d¡ |  | j jjtjtdƒtdƒ tdƒ fg¡ dS )z¾
        If C{SSHUserAuthClient} gets a MSG_USERAUTH_PK_OK packet when it's not
        expecting it, it should fail the current authentication and move on to
        the next type.
        s   unknownrR   r/   r<   r?   N)	rÉ   ZlastAuthr   rG   rÑ   rs   r   r�   r   r*   r    r    r!   Ú"test_USERAUTH_PK_OK_unknown_method!  s    
þz9SSHUserAuthClientTests.test_USERAUTH_PK_OK_unknown_methodc                    s®   ‡ fdd„}‡ fdd„}|ˆ j _|ˆ j _ˆ j  tdƒd ¡ ˆ  ˆ j jjd tj	tdƒtd	ƒ td
ƒ d tdƒ f¡ ˆ j  tdƒd ¡ ˆ  ˆ j jjdd… ddg¡ dS )z×
        ssh_USERAUTH_FAILURE should sort the methods by their position
        in SSHUserAuthClient.preferredOrder.  Methods that are not in
        preferredOrder should be sorted at the end of that list.
        c                      s   ˆ j j dd¡ d S )Néÿ   ó   here is data©rÉ   r   rK   r    r*   r    r!   Úauth_firstmethod6  s    zNSSHUserAuthClientTests.test_USERAUTH_FAILURE_sorting.<locals>.auth_firstmethodc                      s   ˆ j j dd¡ dS )Néþ   ó
   other dataTrÞ   r    r*   r    r!   Úauth_anothermethod9  s    zPSSHUserAuthClientTests.test_USERAUTH_FAILURE_sorting.<locals>.auth_anothermethods   anothermethod,passwordrp   ro   r/   r<   ry   s"   firstmethod,anothermethod,passwordrŠ   éþÿÿÿN)rÜ   rÝ   )rà   rá   )
rÉ   rß   râ   rÐ   r   rs   r   rG   r   r�   )r+   rß   râ   r    r*   r!   Útest_USERAUTH_FAILURE_sorting/  s$    "þþ
ÿþz4SSHUserAuthClientTests.test_USERAUTH_FAILURE_sortingc                 C   sT   | j  tdƒd ¡ | j  tdƒd ¡ |  | j jjd tjdtdƒ d f¡ dS )	z»
        If there are no more available user authentication messages,
        the SSHUserAuthClient should disconnect with code
        DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE.
        ry   rp   rŠ   ro   s      s(   no more authentication methods availables       N)rÉ   rÐ   r   rs   r   rG   r¶   r*   r    r    r!   Ú%test_disconnectIfNoMoreAuthenticationS  s    ÿþþþz<SSHUserAuthClientTests.test_disconnectIfNoMoreAuthenticationc                 C   sH   g | j j_| j  d¡ |  | j jjtjtdƒtdƒ tdƒ fg¡ dS )zˆ
        _ebAuth (the generic authentication error handler) should send
        a request for the 'none' authentication method.
        Nr/   r<   r?   )rÉ   r   rG   Z_ebAuthrs   r   r�   r   r*   r    r    r!   Útest_ebAuthe  s    
þz"SSHUserAuthClientTests.test_ebAuthc                    s`   t  dt ¡ ¡‰ ˆ ˆ  ¡ ¡ ‡ ‡‡fdd„}‡ ‡‡fdd„‰dd„ ‰ˆ  ¡ }| ˆj¡ 	|¡S )zÛ
        getPublicKey() should return None.  getPrivateKey() should return a
        failed Deferred.  getPassword() should return a failed Deferred.
        getGenericAnswers() should return a failed Deferred.
        r/   c                    s$   |   t¡ ˆ  ¡ }| ˆj¡ ˆ¡S r7   )ÚtrapÚNotImplementedErrorr2   rv   rW   Ú
addErrback©rÖ   rw   )rÉ   Úcheck2r+   r    r!   r}   z  s    
z3SSHUserAuthClientTests.test_defaults.<locals>.checkc                    s*   |   t¡ ˆ  d d d ¡}| ˆj¡ ˆ¡S r7   )rç   rè   r5   rv   rW   ré   rê   )rÉ   Úcheck3r+   r    r!   rë     s    
z4SSHUserAuthClientTests.test_defaults.<locals>.check2c                 S   s   |   t¡ d S r7   )rç   rè   rÕ   r    r    r!   rì   „  s    z4SSHUserAuthClientTests.test_defaults.<locals>.check3)
r   r#   r;   r>   rÓ   r,   r.   rv   rW   ré   )r+   r}   rw   r    )rÉ   rë   rì   r+   r!   Útest_defaultsq  s    z$SSHUserAuthClientTests.test_defaults)r   r   r   r   r   rÆ   rk   rm   rË   rÎ   rÒ   rÔ   r×   rØ   rÙ   rÚ   rÛ   rä   rå   ræ   rí   r    r    r    r!   rÈ   g  s$   >$rÈ   c                   @   s.   e Zd ZedkrdZG dd„ dƒZdd„ ZdS )ÚLoopbackTestsNrc   c                   @   s"   e Zd ZG dd„ dƒZdd„ ZdS )zLoopbackTests.Factoryc                   @   s    e Zd ZdZdd„ Zdd„ ZdS )zLoopbackTests.Factory.Serviceó   TestServicec                 C   s   | j  ¡  d S r7   )r   rO   r*   r    r    r!   r=   “  s    z,LoopbackTests.Factory.Service.serviceStartedc                 C   s   d S r7   r    r*   r    r    r!   rl   –  s    z,LoopbackTests.Factory.Service.serviceStoppedN)r   r   r   r4   r=   rl   r    r    r    r!   r>   �  s   r>   c                 C   s   | j S r7   )r>   )r+   Zavatarr4   r    r    r!   rA   ™  s    z LoopbackTests.Factory.getServiceN)r   r   r   r>   rA   r    r    r    r!   rB   �  s   	rB   c                    s   t  ¡ ‰tdˆj ¡ ƒ}t ¡ ˆ_ˆˆj_dd„ ˆj_t ¡ |_||j_d ˆj_	|j_	dd„  ˆj_
|j_
ˆ ¡ ˆj_dˆ_tƒ }t|ƒ}tƒ ‰ ˆ  tƒ ¡ ˆ  tƒ ¡ ‡ fdd„ˆ _| ˆ ¡ |ˆjj_t ˆj|j¡}dd„ ˆjj_d	d„ |jj_ˆ ¡  | ¡  ‡‡fd
d„}| |¡S )zW
        Test that the userauth server and client play nicely with each other.
        r/   c                 S   s   dS rN   r    r¬   r    r    r!   rQ   ¦  rR   z-LoopbackTests.test_loopback.<locals>.<lambda>rR   c                   S   s   d S r7   r    r    r    r    r!   rQ   «  rR   r   c                    s   t ˆ j|  ƒdkS )Nrƒ   )ÚlenZsuccessfulCredentials)ZaId)Úcheckerr    r!   rQ   µ  rR   c                   S   s   dS )NZ_ServerLoopbackr    r    r    r    r!   rQ   º  rR   c                   S   s   dS )NZ_ClientLoopbackr    r    r    r    r!   rQ   »  rR   c                    s   ˆ   ˆjjjd¡ d S )Nrï   )rs   r   r@   r4   r|   r©   r    r!   r}   À  s    z*LoopbackTests.test_loopback.<locals>.check)r   rg   r$   rB   r>   r   r"   r@   rM   rŒ   ZsendKexInitrD   ZpasswordDelayrP   r   r   rf   rT   r[   ZareDonerE   r   ZloopbackAsyncZ	logPrefixr=   rv   )r+   Úclientre   rE   rw   r}   r    )rñ   r+   rª   r!   Útest_loopbackœ  s4    



zLoopbackTests.test_loopback)r   r   r   r   rÆ   rB   ró   r    r    r    r!   rî   ‹  s   rî   c                   @   s    e Zd ZedkrdZdd„ ZdS )ÚModuleInitializationTestsNrc   c                 C   s,   |   tjjd d¡ |   tjjd d¡ d S )Né<   rŸ   )rs   r   rg   ZprotocolMessagesr#   r*   r    r    r!   Útest_messagesÊ  s    
 ÿ
 ÿz'ModuleInitializationTests.test_messages)r   r   r   r   rÆ   rö   r    r    r    r!   rô   Æ  s   rô   ):r   Útypesr   Útypingr   Zzope.interfacer   Ztwisted.conch.errorr   r   Ztwisted.cred.checkersr   Ztwisted.cred.credentialsr   r	   r
   Ztwisted.cred.errorr   Ztwisted.cred.portalr   r   Ztwisted.internetr   r   Ztwisted.internet.deferr   Ztwisted.protocolsr   Ztwisted.python.reflectr   Ztwisted.trialr   r   Ú__annotations__Ztwisted.conch.checkersr   Ztwisted.conch.sshr   r   Ztwisted.conch.ssh.commonr   Ztwisted.conch.testr   r#   r$   r6   r:   r"   r;   rP   rT   r[   r`   ZTestCaserb   rÈ   rî   rô   r    r    r    r!   Ú<module>   sT   
#A     &;