o
    ¯bƒ  ã                   @   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‚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 d0d1„ d1ej3ƒZ7d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)Úloopback)ÚrequireModule)ÚunittestNÚkeysÚcryptographyÚpyasn1)ÚSSHProtocolChecker)r   Ú	transportÚuserauth)ÚNS)Úkeydatac                   @   ó   e Zd ZG dd„ dƒZdS )r   c                   @   ó   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#   úB/usr/lib/python3/dist-packages/twisted/conch/test/test_userauth.pyÚSSHTransportBase"   ó    r%   N)r   r    r!   r%   r#   r#   r#   r$   r   !   ó    r   c                   @   r   )r   c                   @   r   )zuserauth.SSHUserAuthClientr   Nr   r#   r#   r#   r$   ÚSSHUserAuthClient(   r&   r(   N)r   r    r!   r(   r#   r#   r#   r$   r   '   r'   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 )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.
        )	Ú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_opensshr0   r#   r#   r$   ÚgetPrivateKey>   ó   zClientUserAuth.getPrivateKeyNc                 C   ó
   t  d¡S )z/
        Return 'foo' as the password.
        ó   foo©r   r.   )r1   Úpromptr#   r#   r$   ÚgetPasswordD   ó   
zClientUserAuth.getPasswordc                 C   r6   )z>
        Return 'foo' as the answer to two questions.
        )Úfoor<   r8   )r1   ÚnameÚinformationÚanswersr#   r#   r$   ÚgetGenericAnswersJ   r;   z ClientUserAuth.getGenericAnswers©N)r   r    r!   r"   r2   r4   r:   r@   r#   r#   r#   r$   r)   .   s    
r)   c                   @   ó    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 rA   )r   r.   r   r+   r,   r   r3   Ú	keyObjectr0   r#   r#   r$   r4   W   ó   zOldClientAuth.getPrivateKeyc                 C   s   t j tj¡ ¡ S rA   )r   r+   r,   r   r-   Úblobr0   r#   r#   r$   r2   Z   s   zOldClientAuth.getPublicKeyN©r   r    r!   r"   r4   r2   r#   r#   r#   r$   rC   Q   s    rC   c                   @   rB   )ÚClientAuthWithoutPrivateKeyzP
    This client doesn't have a private key, but it does have a public key.
    c                 C   ó   d S rA   r#   r0   r#   r#   r$   r4   c   ó   z)ClientAuthWithoutPrivateKey.getPrivateKeyc                 C   s   t j tj¡S rA   )r   r+   r,   r   r-   r0   r#   r#   r$   r2   f   ó   z(ClientAuthWithoutPrivateKey.getPublicKeyNrG   r#   r#   r#   r$   rH   ^   s    rH   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   rI   rA   r#   r0   r#   r#   r$   ÚserviceStarted‚   rJ   z$FakeTransport.Service.serviceStartedN)r   r    r!   r"   r=   rN   r#   r#   r#   r$   ÚService{   s    rO   c                   @   ó   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)rL   rO   )r1   r   Úservicer#   r#   r$   Ú
getService‹   s   ÿz FakeTransport.Factory.getServiceN)r   r    r!   r"   rS   r#   r#   r#   r$   ÚFactory…   s    rT   c                 C   s(   |   ¡ | _|| j_d| _| | _g | _d S ©NF)rT   ÚfactoryÚportalÚlostConnectionr   Úpackets)r1   rW   r#   r#   r$   Ú__init__’   s
   

zFakeTransport.__init__c                 C   s   | j  ||f¡ dS )z8
        Record the packet sent by the service.
        N)rY   Úappend)r1   ÚmessageTypeÚmessager#   r#   r$   Ú
sendPacket™   r5   zFakeTransport.sendPacketc                 C   ó   dS )z»
        Pretend that this transport encrypts traffic in both directions. The
        SSHUserAuthServer disables password authentication if the transport
        isn't encrypted.
        Tr#   )r1   Ú	directionr#   r#   r$   ÚisEncryptedŸ   s   zFakeTransport.isEncryptedc                 C   s
   d| _ d S ©NT)rX   r0   r#   r#   r$   ÚloseConnection§   s   
zFakeTransport.loseConnectionN)
r   r    r!   r"   rO   rT   rZ   r^   ra   rc   r#   r#   r#   r$   rL   j   s    
rL   c                   @   rP   )Ú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   rI   rA   r#   r#   r#   r#   r$   Ú<lambda>µ   ó    z%Realm.requestAvatar.<locals>.<lambda>r8   )r1   ÚavatarIdÚmindÚ
interfacesr#   r#   r$   ÚrequestAvatar´   s   zRealm.requestAvatarN)r   r    r!   r"   rj   r#   r#   r#   r$   rd   «   s    rd   c                   @   ó   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   )r1   Úcredsr#   r#   r$   ÚrequestAvatarIdÁ   s   zPasswordChecker.requestAvatarIdN)r   r    r!   r"   r
   ÚcredentialInterfacesrq   r#   r#   r#   r$   rl   ¸   ó    rl   c                   @   rk   )Ú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r)|jd ur&tj |j ¡}| |j|j¡r#|j	S tƒ ‚t
ƒ ‚tƒ ‚rA   )rF   r   r+   r,   r   r-   Ú	signatureÚverifyÚsigDatarm   r   r   )r1   rp   Úobjr#   r#   r$   rq   Ð   s   
ÿz!PrivateKeyChecker.requestAvatarIdN)r   r    r!   r"   r	   rr   rq   r#   r#   r#   r$   rt   Ç   rs   rt   c                   @   rk   )ÚAnonymousCheckerzI
    A simple checker which isn't supported by L{SSHUserAuthServer}.
    c                 C   rI   rA   r#   )r1   Úcredentialsr#   r#   r$   rq   ã   s   z AnonymousChecker.requestAvatarIdN)r   r    r!   r"   r   rr   rq   r#   r#   r#   r$   ry   Û   s    ry   c                   @   s¼   e Zd ZdZedu 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 rA   )rd   Úrealmr   rW   ÚregisterCheckerrl   rt   r   ÚSSHUserAuthServerÚ
authServerrL   r   rN   ÚsupportedAuthenticationsÚsortr0   r#   r#   r$   ÚsetUpð   s   

zSSHUserAuthServerTests.setUpc                 C   ó   | j  ¡  d | _ d S rA   )r€   ÚserviceStoppedr0   r#   r#   r$   ÚtearDownû   ó   

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)ÚassertEqualr€   r   rY   r   ÚMSG_USERAUTH_FAILUREr   ©r1   Ú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.
        r7   s   servicerQ   )r€   Ússh_USERAUTH_REQUESTr   ÚaddCallbackrŽ   )r1   Ú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.
        ó    r7   rQ   ó   passwordr‰   c                    ó   ˆ   ˆ jjjtjdfg¡ d S ©Nr“   ©rŠ   r€   r   rY   r   ÚMSG_USERAUTH_SUCCESS©r�   r0   r#   r$   Úcheck  ó   
þzKSSHUserAuthServerTests.test_successfulPasswordAuthentication.<locals>.check)Újoinr   r€   r�   r�   ©r1   Úpacketr‘   rš   r#   r0   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.
        r“   r7   rQ   r”   r‰   ó   baré   )rœ   r   r   ÚClockr€   Úclockr�   rŠ   r   rY   Úadvancer�   rŽ   ©r1   rž   r‘   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,
        r7   rQ   ó	   publickeyó   ÿó   testc                    r•   r–   r—   r™   r0   r#   r$   rš   M  r›   zMSSHUserAuthServerTests.test_successfulPrivateKeyAuthentication.<locals>.check)r   r+   r,   r   r-   rF   r3   r   ÚsshTyper€   r   Ú	sessionIDÚsignÚbytesr   ÚMSG_USERAUTH_REQUESTr�   r�   )r1   rF   rx   rž   ru   r‘   rš   r#   r0   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)ro   rŒ   r#   r#   r$   ÚmockCbFinishedAuth\  rK   zOSSHUserAuthServerTests.test_requestRaisesConchError.<locals>.mockCbFinishedAuthc                 S   rI   rA   r#   )ÚkindÚuserÚdatar#   r#   r$   ÚmockTryAuth_  rJ   zHSSHUserAuthServerTests.test_requestRaisesConchError.<locals>.mockTryAuthc                    s   ˆ   | j¡ d S rA   )ÚerrbackÚvalue)Úreason©r‘   r#   r$   ÚmockEbBadAuthb  s   zJSSHUserAuthServerTests.test_requestRaisesConchError.<locals>.mockEbBadAuthÚtryAuthÚ_cbFinishedAuthÚ
_ebBadAuths   userrQ   s
   public-keys   data)r   ÚDeferredÚpatchr€   r   r�   ÚassertFailurer   )r1   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.
        r7   rQ   r§   r‰   ó   ssh-rsac                    s*   ˆ  ˆjjjtjtdƒtˆ ƒ fg¡ d S )NrÁ   )rŠ   r€   r   rY   r   ÚMSG_USERAUTH_PK_OKr   r™   ©rF   r1   r#   r$   rš   ~  s   þz@SSHUserAuthServerTests.test_verifyValidPrivateKey.<locals>.check)
r   r+   r,   r   r-   rF   r   r€   r�   r�   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.
        r7   rQ   r§   r‰   s   ssh-dsa©r   r+   r,   r   r/   rF   r   r€   r�   r�   rŽ   ©r1   rF   rž   r‘   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Å   r7   rQ   r§   r¨   rÁ   r©   )r   r+   r,   r   r-   rF   r3   r   r¬   r€   r   r«   r�   r�   rŽ   )r1   rF   rx   rž   r‘   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é   Nr7   rQ   r§   r‰   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.
        r”   r§   N)r   r   rL   rW   r   r~   ry   rN   r…   r�   r‚   rŠ   ©r1   Ú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.
        r”   c                 S   r_   rU   r#   ©Úxr#   r#   r$   re   Û  rf   zISSHUserAuthServerTests.test_removePasswordIfUnencrypted.<locals>.<lambda>c                 S   ó   | dkS ©NÚinr#   rÏ   r#   r#   r$   re   â  ó    N)ÚassertInr€   r�   r   r   rL   rW   r   ra   rN   r…   ÚassertNotIn)r1   Ú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   r_   rU   r#   rÏ   r#   r#   r$   re   ô  rf   zSSSHUserAuthServerTests.test_unencryptedConnectionWithoutPasswords.<locals>.<lambda>r§   c                 S   rÑ   rÒ   r#   rÏ   r#   r#   r$   re   ü  rÔ   N)r   r}   r~   rt   r   r   rL   r   ra   rN   r…   rŠ   r�   )r1   rW   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 longr“   N)r   r   r   r¢   r£   rL   rW   r   rN   r¤   r…   rŠ   rY   ÚMSG_DISCONNECTr­   Ú)DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLEr   Ú
assertTruerX   ©r1   Ú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   r   r   r¢   r£   rL   rW   r   rN   r…   r¤   rŠ   rY   ÚassertFalserX   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¡ q‡ fd	d
„}| 	|¡S )zm
        Test that the server disconnects if the client fails authentication
        too many times.
        r“   r7   rQ   r”   r‰   r    é   r¡   c                    s<   ˆ   ˆ jjjd tjdttjfƒ tdƒ tdƒ f¡ d S )Nrˆ   rÜ   s   too many bad authsr“   )rŠ   r€   r   rY   rÝ   r­   rÞ   r   r™   r0   r#   r$   rš   1  s   
ÿþýþþz:SSHUserAuthServerTests.test_tooManyAttempts.<locals>.check)
rœ   r   r   r¢   r€   r£   Úranger�   r¤   r�   )r1   rž   Úir‘   rš   r#   r0   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.
        r7   r“   r”   r‰   )r   r   r¢   r€   r£   r�   r�   rŽ   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   rI   rA   r#   )rž   r#   r#   r$   ÚmockAuthU  rJ   z>SSHUserAuthServerTests.test_tryAuthEdgeCases.<locals>.mockAuthÚauth_publickeyÚauth_passwordNc                    s   ˆ j  dd d ¡}ˆ  |t¡S )Nr”   )r€   rº   r¿   r   )r�   Úd2r0   r#   r$   Ú
secondTest[  s   z@SSHUserAuthServerTests.test_tryAuthEdgeCases.<locals>.secondTestr§   )r¾   r€   rº   r¿   r   r�   )r1   rê   rî   Úd1r#   r0   r$   Útest_tryAuthEdgeCasesI  s   z,SSHUserAuthServerTests.test_tryAuthEdgeCases)r   r    r!   r"   r   Úskiprƒ   r†   rŽ   r’   rŸ   r¦   r¯   rÀ   rÄ   rÈ   rÉ   rË   rÎ   rÙ   rÚ   râ   rä   rè   ré   rð   r#   r#   r#   r$   r{   è   s0    	
r{   c                   @   s”   e Zd ZdZedu 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.
    Nr|   c                 C   s4   t dt ¡ ƒ| _td ƒ| j_d| jj_| j ¡  d S )Nr7   r©   )r)   rL   rO   Ú
authClientr   r«   rN   r0   r#   r#   r$   rƒ   k  s   
zSSHUserAuthClientTests.setUpc                 C   r„   rA   )ró   r…   r0   r#   r#   r$   r†   q  r‡   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.
        r7   rM   rQ   N)
rŠ   ró   r²   Úinstancer=   r   rY   r   r®   r   r0   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#   )rR   ©rô   r#   r$   ÚstubSetService†  s   zDSSHUserAuthClientTests.test_USERAUTH_SUCCESS.<locals>.stubSetServicer“   r   )ró   r   Ú
setServiceÚssh_USERAUTH_SUCCESSrŠ   rô   )r1   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§   r‰   rˆ   r7   rM   s   ssh-dssrÁ   ó   N)ró   Ússh_USERAUTH_FAILUREr   rŠ   r   rY   r   r®   r   r+   r,   r   r/   rF   r-   Ússh_USERAUTH_PK_OKr«   r­   r3   r¬   )r1   rF   rw   rx   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.
        r7   Nr©   r§   r“   rM   rQ   )rH   rL   rO   r   r«   rN   rº   rY   ÚassertIsNonerý   rŠ   r   r®   r   )r1   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   rI   rA   r#   rÏ   r#   r#   r$   re   ã  rf   z:SSHUserAuthClientTests.test_no_publickey.<locals>.<lambda>r§   c                    s   ˆ   | ¡ d S rA   )rã   ©Úresultr0   r#   r$   rš   æ  rK   z7SSHUserAuthClientTests.test_no_publickey.<locals>.check)ró   r2   rº   r�   )r1   r‘   rš   r#   r0   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.
        r”   r‰   rˆ   r7   rM   r“   r¨   r¡   N)	ró   rü   r   rŠ   r   rY   r   r®   rý   r0   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   rI   rA   r#   r#   r#   r#   r$   re     rf   z9SSHUserAuthClientTests.test_no_password.<locals>.<lambda>r”   N)ró   r:   rã   rº   r0   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.
        r“   s      s
   Password: r‰   rˆ   s      r7   N)ró   Ú'ssh_USERAUTH_PK_OK_keyboard_interactiver   rŠ   r   rY   r   ÚMSG_USERAUTH_INFO_RESPONSEr0   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   unknownr“   r7   rM   rQ   N)	ró   ÚlastAuthr   rY   rý   rŠ   r   r®   r   r0   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   r^   r#   r0   r#   r$   Úauth_firstmethod2  s   zNSSHUserAuthClientTests.test_USERAUTH_FAILURE_sorting.<locals>.auth_firstmethodc                      s   ˆ j j dd¡ dS )Néþ   ó
   other dataTr  r#   r0   r#   r$   Úauth_anothermethod5  s   zPSSHUserAuthClientTests.test_USERAUTH_FAILURE_sorting.<locals>.auth_anothermethods   anothermethod,passwordr‰   rˆ   r7   rM   r”   s"   firstmethod,anothermethod,passwordr¨   éþÿÿÿN)r  r  )r  r  )
ró   r  r  rü   r   rŠ   r   rY   r   r®   )r1   r  r  r#   r0   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.
        r”   r‰   r¨   rˆ   s      s(   no more authentication methods availables       N)ró   rü   r   rŠ   r   rY   rÝ   r0   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.
        Nr7   rM   rQ   )ró   r   rY   Ú_ebAuthrŠ   r   r®   r   r0   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.
        r7   c                    s$   |   t¡ ˆ  ¡ }| ˆj¡ ˆ¡S rA   )ÚtrapÚNotImplementedErrorr:   r�   ro   Ú
addErrback©r  r‘   )ró   Úcheck2r1   r#   r$   rš   v  s   
z3SSHUserAuthClientTests.test_defaults.<locals>.checkc                    s*   |   t¡ ˆ  d d d ¡}| ˆj¡ ˆ¡S rA   )r  r  r@   r�   ro   r  r  )ró   Úcheck3r1   r#   r$   r  {  s   
z4SSHUserAuthClientTests.test_defaults.<locals>.check2c                 S   s   |   t¡ d S rA   )r  r  r  r#   r#   r$   r  €  rK   z4SSHUserAuthClientTests.test_defaults.<locals>.check3)
r   r(   rL   rO   rÿ   r2   r4   r�   ro   r  )r1   rš   r‘   r#   )ró   r  r  r1   r$   Útest_defaultsm  s   z$SSHUserAuthClientTests.test_defaults)r   r    r!   r"   r   rñ   rƒ   r†   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u r
dZG dd„ dƒZdd„ ZdS )ÚLoopbackTestsNú)cannot run without cryptography or PyASN1c                   @   s"   e Zd ZG dd„ dƒZdd„ ZdS )zLoopbackTests.Factoryc                   @   rB   )zLoopbackTests.Factory.Serviceó   TestServicec                 C   s   | j  ¡  d S rA   )r   rc   r0   r#   r#   r$   rN   �  rK   z,LoopbackTests.Factory.Service.serviceStartedc                 C   rI   rA   r#   r0   r#   r#   r$   r…   “  rJ   z,LoopbackTests.Factory.Service.serviceStoppedN)r   r    r!   r=   rN   r…   r#   r#   r#   r$   rO   �  s    rO   c                 C   s   | j S rA   )rO   )r1   Úavatarr=   r#   r#   r$   rS   –  s   z LoopbackTests.Factory.getServiceN)r   r    r!   rO   rS   r#   r#   r#   r$   rT   Œ  s    	rT   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.
        r7   c                 S   r_   rb   r#   rÏ   r#   r#   r$   re   £  rf   z-LoopbackTests.test_loopback.<locals>.<lambda>r“   c                   S   rI   rA   r#   r#   r#   r#   r$   re   ¨  rf   r   c                    s   t ˆ j|  ƒdkS )Nr¡   )ÚlenÚsuccessfulCredentials)ÚaId)Úcheckerr#   r$   re   ²  s    c                   S   r_   )NÚ_ServerLoopbackr#   r#   r#   r#   r$   re   ·  rf   c                   S   r_   )NÚ_ClientLoopbackr#   r#   r#   r#   r$   re   ¸  rf   c                    s   ˆ   ˆjjjd¡ d S )Nr   )rŠ   r   rR   r=   r™   rÌ   r#   r$   rš   ½  rE   z*LoopbackTests.test_loopback.<locals>.check)r   r   r)   rT   rO   r   r%   rR   ra   r«   ÚsendKexInitrV   ÚpasswordDelayrd   r   r   r~   rl   rt   ÚareDonerW   r   ÚloopbackAsyncÚ	logPrefixrN   r�   )r1   Úclientr}   rW   r‘   rš   r#   )r%  r1   rÍ   r$   Útest_loopback™  s4   




zLoopbackTests.test_loopback)r   r    r!   r   rñ   rT   r.  r#   r#   r#   r$   r  ‡  s
    r  c                   @   s    e Zd Zedu r
dZdd„ ZdS )ÚModuleInitializationTestsNr  c                 C   s,   |   tjjd d¡ |   tjjd d¡ d S )Né<   rÂ   )rŠ   r   r   ÚprotocolMessagesr(   r0   r#   r#   r$   Útest_messagesÇ  s   ÿÿz'ModuleInitializationTests.test_messages)r   r    r!   r   rñ   r2  r#   r#   r#   r$   r/  Ã  s    r/  )8r"   Útypesr   Útypingr   Úzope.interfacer   Útwisted.conch.errorr   r   Útwisted.cred.checkersr   Útwisted.cred.credentialsr   r	   r
   Útwisted.cred.errorr   Útwisted.cred.portalr   r   Útwisted.internetr   r   Útwisted.protocolsr   Útwisted.python.reflectr   Útwisted.trialr   r   Ú__annotations__Útwisted.conch.checkersr   Útwisted.conch.sshr   r   Útwisted.conch.ssh.commonr   Útwisted.conch.testr   r(   r)   rC   rH   r%   rL   rd   rl   rt   ry   ÚTestCaser{   rò   r  r/  r#   r#   r#   r$   Ú<module>   sR   #A  }  &<