U
     T‚gâ‚  ã                   @   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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-ƒZ.eeƒG d!d"„ d"ƒƒZ/eeƒG d#d$„ d$ƒƒZ0eeƒG d%d&„ d&ƒƒZ1eeƒG d'd(„ d(ƒƒZ2G d)d*„ d*ej3ƒZ4G d+d,„ d,ej3ƒZ5G d-d.„ d.ej3ƒZ6G d/d0„ d0ej3ƒZ7dS )1zT
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)Ú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-1_7di8ic/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    ÚgetPublicKey3   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    ÚgetPasswordD   s    zClientUserAuth.getPasswordc                 C   s
   t  d¡S )z>
        Return 'foo' as the answer to two questions.
        )Úfoor2   r/   )r*   ÚnameZinformationZanswersr   r   r    ÚgetGenericAnswersJ   s    z ClientUserAuth.getGenericAnswers)N)r   r   r   r   r+   r-   r1   r4   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-   W   s    zOldClientAuth.getPrivateKeyc                 C   s   t j tj¡ ¡ S r6   )r   r$   r%   r   r&   Úblobr)   r   r   r    r+   Z   s    zOldClientAuth.getPublicKeyN©r   r   r   r   r-   r+   r   r   r   r    r5   Q   s   r5   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 r6   r   r)   r   r   r    r-   c   s    z)ClientAuthWithoutPrivateKey.getPrivateKeyc                 C   s   t j tj¡S r6   )r   r$   r%   r   r&   r)   r   r   r    r+   f   s    z(ClientAuthWithoutPrivateKey.getPublicKeyNr8   r   r   r   r    r9   ^   s   r9   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 r6   r   r)   r   r   r    ÚserviceStarted‚   s    z$FakeTransport.Service.serviceStartedN)r   r   r   r   r3   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   r@   r   r   r   r    ÚFactory…   s   rA   c                 C   s(   |   ¡ | _|| j_d| _| | _g | _d S ©NF)rA   ÚfactoryÚportalÚlostConnectionr   Úpackets)r*   rD   r   r   r    Ú__init__’   s
    
zFakeTransport.__init__c                 C   s   | j  ||f¡ dS )z8
        Record the packet sent by the service.
        N)rF   Ú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)rE   r)   r   r   r    ÚloseConnection§   s    zFakeTransport.loseConnectionN)
r   r   r   r   r=   rA   rG   rJ   rL   rN   r   r   r   r    r:   j   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 r6   r   r   r   r   r    Ú<lambda>µ   ó    z%Realm.requestAvatar.<locals>.<lambda>r/   )r*   ZavatarIdZmindZ
interfacesr   r   r    ÚrequestAvatar´   s    zRealm.requestAvatarN)r   r   r   r   rR   r   r   r   r    rO   «   s   rO   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
   ÚcredentialInterfacesrX   r   r   r   r    rS   ¸   s   rS   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 r6   )r7   r   r$   r%   r   r&   Ú	signatureÚverifyÚsigDatarT   r   r   )r*   rW   Úobjr   r   r    rX   Ð   s    
z!PrivateKeyChecker.requestAvatarIdN)r   r   r   r   r	   rY   rX   r   r   r   r    rZ   Ç   s   rZ   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 r6   r   )r*   Úcredentialsr   r   r    rX   ã   s    z AnonymousChecker.requestAvatarIdN)r   r   r   r   r   rY   rX   r   r   r   r    r_   Û   s   r_   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"d#„ Zd$d%„ Zd&d'„ Zd(d)„ Zd*d+„ ZdS ),ÚSSHUserAuthServerTestsz&
    Tests for SSHUserAuthServer.
    Núcannot run without cryptographyc                 C   sb   t ƒ | _t| jƒ| _| j tƒ ¡ | j tƒ ¡ t ¡ | _	t
| jƒ| j	_| j	 ¡  | j	j ¡  d S r6   )rO   Úrealmr   rD   ÚregisterCheckerrS   rZ   r   ÚSSHUserAuthServerÚ
authServerr:   r   r<   ÚsupportedAuthenticationsÚsortr)   r   r   r    ÚsetUpð   s    

zSSHUserAuthServerTests.setUpc                 C   s   | j  ¡  d | _ d S r6   )rf   ÚserviceStoppedr)   r   r   r    ÚtearDownû   s    
zSSHUserAuthServerTests.tearDownc                 C   s(   |   | jjjd tjtdƒd f¡ dS )z;
        Check that the authentication has failed.
        éÿÿÿÿs   password,publickeyó    N)ÚassertEqualrf   r   rF   r   ZMSG_USERAUTH_FAILUREr   ©r*   Úignoredr   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>   )rf   Ússh_USERAUTH_REQUESTr   ÚaddCallbackrq   )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.
        rQ   r.   r>   ó   passwordrm   c                    s   ˆ   ˆ jjjtjdfg¡ d S ©NrQ   ©rn   rf   r   rF   r   ZMSG_USERAUTH_SUCCESS©rp   r)   r   r    Úcheck  s    
þzKSSHUserAuthServerTests.test_successfulPasswordAuthentication.<locals>.check)Újoinr   rf   rr   rs   ©r*   Úpacketrt   rz   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.
        rQ   r.   r>   rv   rm   ó   baré   )r{   r   r   ÚClockrf   Úclockrr   rn   r   rF   Úadvancers   rq   ©r*   r}   rt   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 rw   rx   ry   r)   r   r    rz   M  s    
þzMSSHUserAuthServerTests.test_successfulPrivateKeyAuthentication.<locals>.check)r   r$   r%   r   r&   r7   r,   r   ZsshTyperf   r   Ú	sessionIDÚsignÚbytesr   ÚMSG_USERAUTH_REQUESTrr   rs   )r*   r7   r^   r}   r[   rt   rz   r   r)   r    Ú'test_successfulPrivateKeyAuthentication8  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)rV   ro   r   r   r    ÚmockCbFinishedAuth\  s    zOSSHUserAuthServerTests.test_requestRaisesConchError.<locals>.mockCbFinishedAuthc                 S   s   d S r6   r   )ÚkindÚuserÚdatar   r   r    ÚmockTryAuth_  s    zHSSHUserAuthServerTests.test_requestRaisesConchError.<locals>.mockTryAuthc                    s   ˆ   | j¡ d S r6   )ZerrbackÚvalue)Úreason©rt   r   r    ÚmockEbBadAuthb  s    zJSSHUserAuthServerTests.test_requestRaisesConchError.<locals>.mockEbBadAuthÚtryAuthZ_cbFinishedAuthZ
_ebBadAuths   userr>   s
   public-keys   data)r   ZDeferredÚpatchrf   r   rr   ÚassertFailurer   )r*   rŽ   r’   r–   r}   r   r•   r    Útest_requestRaisesConchErrorU  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†   rm   ó   ssh-rsac                    s*   ˆ  ˆjjjtjtdƒtˆ ƒ fg¡ d S )Nr›   )rn   rf   r   rF   r   ÚMSG_USERAUTH_PK_OKr   ry   ©r7   r*   r   r    rz   ~  s    þz@SSHUserAuthServerTests.test_verifyValidPrivateKey.<locals>.check)
r   r$   r%   r   r&   r7   r   rf   rr   rs   r|   r   r�   r    Útest_verifyValidPrivateKeyo  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†   rm   s   ssh-dsa©r   r$   r%   r   r(   r7   r   rf   rr   rs   rq   ©r*   r7   r}   rt   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&   r7   r,   r   rŠ   rf   r   r‰   rr   rs   rq   )r*   r7   r^   r}   rt   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†   rm   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.
        rv   r†   N)r   re   r:   rD   r   rd   r_   r<   rj   rg   rh   rn   ©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.
        rv   c                 S   s   dS rB   r   ©Úxr   r   r    rP   Û  rQ   zISSHUserAuthServerTests.test_removePasswordIfUnencrypted.<locals>.<lambda>c                 S   s   | dkS ©NÚinr   r©   r   r   r    rP   â  rQ   N)ZassertInrf   rg   r   re   r:   rD   r   rL   r<   rj   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 rB   r   r©   r   r   r    rP   ô  rQ   zSSSHUserAuthServerTests.test_unencryptedConnectionWithoutPasswords.<locals>.<lambda>r†   c                 S   s   | dkS r«   r   r©   r   r   r    rP   ü  rQ   N)r   rc   rd   rZ   r   re   r:   r   rL   r<   rj   rn   rg   )r*   rD   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 longrQ   N)r   re   r   r�   r‚   r:   rD   r   r<   rƒ   rj   rn   rF   ÚMSG_DISCONNECTr‹   Ú)DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLEr   Ú
assertTruerE   ©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   re   r   r�   r‚   r:   rD   r   r<   rj   rƒ   rn   rF   ÚassertFalserE   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.
        rQ   r.   r>   rv   rm   r   é   r€   c                    s<   ˆ   ˆ jjjd tjdttjfƒ tdƒ tdƒ f¡ d S )Nrl   r²   s   too many bad authsrQ   )rn   rf   r   rF   r³   r‹   r´   r   ry   r)   r   r    rz   1  s    
ÿþýþþz:SSHUserAuthServerTests.test_tooManyAttempts.<locals>.check)
r{   r   r   r�   rf   r‚   Úrangerr   rƒ   rs   )r*   r}   Úirt   rz   r   r)   r    Útest_tooManyAttempts&  s    $z+SSHUserAuthServerTests.test_tooManyAttemptsc                 C   sH   t dƒt dƒ t dƒ d t dƒ }t ¡ | j_| j |¡}| | j¡S )zo
        If the user requests a service that we don't support, the
        authentication should fail.
        r.   rQ   rv   rm   )r   r   r�   rf   r‚   rr   rs   rq   r„   r   r   r    Útest_failIfUnknownService?  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 r6   r   )r}   r   r   r    ÚmockAuthU  s    z>SSHUserAuthServerTests.test_tryAuthEdgeCases.<locals>.mockAuthZauth_publickeyZauth_passwordNc                    s   ˆ j  dd d ¡}ˆ  |t¡S )Nrv   )rf   r—   r™   r   )rp   Zd2r)   r   r    Ú
secondTest[  s    z@SSHUserAuthServerTests.test_tryAuthEdgeCases.<locals>.secondTestr†   )r˜   rf   r—   r™   r   rs   )r*   r¿   rÀ   Úd1r   r)   r    Útest_tryAuthEdgeCasesI  s    z,SSHUserAuthServerTests.test_tryAuthEdgeCases)r   r   r   r   r   Úskipri   rk   rq   ru   r~   r…   r�   rš   rž   r¢   r£   r¥   r¨   r¯   r°   r·   r¹   r½   r¾   rÂ   r   r   r   r    ra   è   s.   	
ra   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.
    Nrb   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    ri   k  s    
zSSHUserAuthClientTests.setUpc                 C   s   | j  ¡  d | _ d S r6   )rÅ   rj   r)   r   r   r    rk   q  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)
rn   rÅ   r�   Úinstancer3   r   rF   r   rŒ   r   r)   r   r   r    Ú	test_initu  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>.stubSetServicerQ   r   )rÅ   r   Z
setServiceZssh_USERAUTH_SUCCESSrn   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†   rm   rl   r.   r;   s   ssh-dssr›   ó   N)rÅ   Ússh_USERAUTH_FAILUREr   rn   r   rF   r   rŒ   r   r$   r%   r   r(   r7   r&   Ússh_USERAUTH_PK_OKr‰   r‹   r,   rŠ   )r*   r7   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†   rQ   r;   r>   )r9   r:   r=   r   r‰   r<   r—   rF   ÚassertIsNonerÍ   rn   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 r6   r   r©   r   r   r    rP   ã  rQ   z:SSHUserAuthClientTests.test_no_publickey.<locals>.<lambda>r†   c                    s   ˆ   | ¡ d S r6   )r¸   ©Úresultr)   r   r    rz   æ  s    z7SSHUserAuthClientTests.test_no_publickey.<locals>.check)rÅ   r+   r—   rs   )r*   rt   rz   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.
        rv   rm   rl   r.   r;   rQ   r‡   r€   N)	rÅ   rÌ   r   rn   r   rF   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 r6   r   r   r   r   r    rP     rQ   z9SSHUserAuthClientTests.test_no_password.<locals>.<lambda>rv   N)rÅ   r1   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.
        rQ   s      s
   Password: rm   rl   s      r.   N)rÅ   Z'ssh_USERAUTH_PK_OK_keyboard_interactiver   rn   r   rF   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   unknownrQ   r.   r;   r>   N)	rÅ   ZlastAuthr   rF   rÍ   rn   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   rJ   r   r)   r   r    Úauth_firstmethod2  s    zNSSHUserAuthClientTests.test_USERAUTH_FAILURE_sorting.<locals>.auth_firstmethodc                      s   ˆ j j dd¡ dS )Néþ   ó
   other dataTrÚ   r   r)   r   r    Úauth_anothermethod5  s    zPSSHUserAuthClientTests.test_USERAUTH_FAILURE_sorting.<locals>.auth_anothermethods   anothermethod,passwordrm   rl   r.   r;   rv   s"   firstmethod,anothermethod,passwordr‡   éþÿÿÿN)rØ   rÙ   )rÜ   rÝ   )
rÅ   rÛ   rÞ   rÌ   r   rn   r   rF   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.
        rv   rm   r‡   rl   s      s(   no more authentication methods availables       N)rÅ   rÌ   r   rn   r   rF   r³   r)   r   r   r    Ú%test_disconnectIfNoMoreAuthenticationO  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   rF   Z_ebAuthrn   r   rŒ   r   r)   r   r   r    Útest_ebAutha  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 r6   )ÚtrapÚNotImplementedErrorr1   rs   rV   Ú
addErrback©rÒ   rt   )rÅ   Úcheck2r*   r   r    rz   v  s    
z3SSHUserAuthClientTests.test_defaults.<locals>.checkc                    s*   |   t¡ ˆ  d d d ¡}| ˆj¡ ˆ¡S r6   )rã   rä   r4   rs   rV   rå   ræ   )rÅ   Úcheck3r*   r   r    rç   {  s    
z4SSHUserAuthClientTests.test_defaults.<locals>.check2c                 S   s   |   t¡ d S r6   )rã   rä   rÑ   r   r   r    rè   €  s    z4SSHUserAuthClientTests.test_defaults.<locals>.check3)
r   r"   r:   r=   rÏ   r+   r-   rs   rV   rå   )r*   rz   rt   r   )rÅ   rç   rè   r*   r    Útest_defaultsm  s    z$SSHUserAuthClientTests.test_defaults)r   r   r   r   r   rÃ   ri   rk   rÇ   rÊ   rÎ   rÐ   rÓ   rÔ   rÕ   rÖ   r×   rà   rá   râ   ré   r   r   r   r    rÄ   c  s$   >$rÄ   c                   @   s.   e Zd ZedkrdZG dd„ dƒZdd„ ZdS )ÚLoopbackTestsNrb   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 r6   )r   rN   r)   r   r   r    r<   �  s    z,LoopbackTests.Factory.Service.serviceStartedc                 C   s   d S r6   r   r)   r   r   r    rj   ’  s    z,LoopbackTests.Factory.Service.serviceStoppedN)r   r   r   r3   r<   rj   r   r   r   r    r=   Œ  s   r=   c                 C   s   | j S r6   )r=   )r*   Zavatarr3   r   r   r    r@   •  s    z LoopbackTests.Factory.getServiceN)r   r   r   r=   r@   r   r   r   r    rA   ‹  s   	rA   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 rM   r   r©   r   r   r    rP   ¢  rQ   z-LoopbackTests.test_loopback.<locals>.<lambda>rQ   c                   S   s   d S r6   r   r   r   r   r    rP   §  rQ   r   c                    s   t ˆ j|  ƒdkS )Nr€   )ÚlenZsuccessfulCredentials)ZaId)Úcheckerr   r    rP   ±  rQ   c                   S   s   dS )NZ_ServerLoopbackr   r   r   r   r    rP   ¶  rQ   c                   S   s   dS )NZ_ClientLoopbackr   r   r   r   r    rP   ·  rQ   c                    s   ˆ   ˆjjjd¡ d S )Nrë   )rn   r   r?   r3   ry   r¦   r   r    rz   ¼  s    z*LoopbackTests.test_loopback.<locals>.check)r   re   r#   rA   r=   r   r!   r?   rL   r‰   ZsendKexInitrC   ZpasswordDelayrO   r   r   rd   rS   rZ   ZareDonerD   r   ZloopbackAsyncZ	logPrefixr<   rs   )r*   Úclientrc   rD   rt   rz   r   )rí   r*   r§   r    Útest_loopback˜  s4    



zLoopbackTests.test_loopback)r   r   r   r   rÃ   rA   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 )ÚModuleInitializationTestsNrb   c                 C   s,   |   tjjd d¡ |   tjjd d¡ d S )Né<   rœ   )rn   r   re   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ð   )8r   Ú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.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#   r5   r9   r!   r:   rO   rS   rZ   r_   ZTestCasera   rÄ   rê   rð   r   r   r   r    Ú<module>   sP   #A  }  &;