U
    Â“«j4y  ã                   @   s  U d Z ddlZddlmZ ddlmZ ddlmZ ddlm	Z	 e	e
 ed< zddlZW n ek
rn   dZY nX dZdd	lmZ dd
lmZ ddlmZmZ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 m!Z! ddl"m#Z# ddl$m%Z% ddl&m'Z' ddl(m)Z) e%dƒ�rPdZ*ddl+m,Z, ddl-m.Z.m/Z/ ddl0m1Z1 ddl2m3Z3 ndZ*e4eddƒdk	�rldZ5ndZ5G dd„ de)ƒZ6G dd„ de)ƒZ7G d d!„ d!e)ƒZ8G d"d#„ d#e)ƒZ9G d$d%„ d%e)ƒZ:G d&d'„ d'e)ƒZ;G d(d)„ d)e)ƒZ<ed*d+gƒZ=G d,d-„ d-e>ƒZ?G d.d/„ d/e)ƒZ@dS )0z&
Tests for L{twisted.conch.checkers}.
é    N)Úencodebytes)Ú
namedtuple)ÚBytesIO)ÚOptionalÚ	cryptSkipzcannot run without crypt module)ÚverifyObject)Ú'InMemoryUsernamePasswordDatabaseDontUse)ÚISSHPrivateKeyÚIUsernamePasswordÚSSHPrivateKeyÚUsernamePassword)ÚUnauthorizedLoginÚUnhandledCredentials)ÚDeferred)Úutil)ÚShadowDatabaseÚUserDatabase)ÚFilePath)ÚrequireModule)ÚMockOS)ÚTestCaseZcryptography)Úcheckers)ÚNotEnoughAuthenticationÚValidPublicKey)Úkeys)Úkeydatazcan't run without cryptographyÚgeteuidz0Cannot run without effective UIDs (questionable)c                   @   sX   e Zd ZdZepe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 )ÚHelperTestszl
    Tests for helper functions L{verifyCryptedPassword}, L{_pwdGetByName} and
    L{_shadowGetByName}.
    c                 C   s   t ƒ | _d S ©N)r   Úmockos©Úself© r"   úD/tmp/pip-unpacked-wheel-59kc99xd/twisted/conch/test/test_checkers.pyÚsetUp@   s    zHelperTests.setUpc                 C   s4   d}d}t   ||¡}|  t ||¡d ||¡¡ dS )z–
        L{verifyCryptedPassword} returns C{True} if the plaintext password
        passed to it matches the encrypted password passed to it.
        úsecret stringZsaltyz5{!r} supposed to be valid encrypted password for {!r}N©ÚcryptÚ
assertTruer   ÚverifyCryptedPasswordÚformat©r!   ÚpasswordÚsaltÚcryptedr"   r"   r#   Útest_verifyCryptedPasswordC   s    
 ÿþz&HelperTests.test_verifyCryptedPasswordc                 C   s4   d}d}t   ||¡}|  t ||¡d ||¡¡ dS )zŠ
        L{verifyCryptedPassword} returns True if the provided cleartext password
        matches the provided MD5 password hash.
        r,   z$1$saltz3{!r} supposed to be valid encrypted password for {}Nr&   r+   r"   r"   r#   Útest_verifyCryptedPasswordMD5R   s    
 ÿþz)HelperTests.test_verifyCryptedPasswordMD5c                 C   s8   d}d}d}t   ||¡}|  t ||¡d ||¡¡ dS )zž
        L{verifyCryptedPassword} returns C{False} if the plaintext password
        passed to it does not match the encrypted password passed to it.
        zstring secretZsomesaltr%   z7{!r} not supposed to be valid encrypted password for {}N)r'   ÚassertFalser   r)   r*   )r!   r,   r-   Úwrongr.   r"   r"   r#   Útest_refuteCryptedPassworda   s    
 ÿþz&HelperTests.test_refuteCryptedPasswordc              	   C   sF   t ƒ }| ddddddd¡ |  td|¡ |  t d¡| d¡¡ d	S )
z‡
        L{_pwdGetByName} returns a tuple of items from the UNIX /etc/passwd
        database if the L{pwd} module is present.
        ÚaliceZsecrité   é   ú
first lastú/fooú/bin/shÚpwdN)r   ÚaddUserÚpatchr   ÚassertEqualÚ_pwdGetByNameÚgetpwnam©r!   Úuserdbr"   r"   r#   Útest_pwdGetByNameq   s    zHelperTests.test_pwdGetByNamec                 C   s"   |   tdd¡ |  t d¡¡ dS )zW
        If the C{pwd} module isn't present, L{_pwdGetByName} returns L{None}.
        r:   Nr4   )r<   r   ÚassertIsNoner>   r    r"   r"   r#   Útest_pwdGetByNameWithoutPwd{   s    z'HelperTests.test_pwdGetByNameWithoutPwdc                 C   s’   t ƒ }| ddddddddd	¡	 |  td
|¡ d| j_d| j_|  td| j¡ |  t 	d¡| 
d¡¡ |  | jjddg¡ |  | jjddg¡ dS )z„
        L{_shadowGetByName} returns a tuple of items from the UNIX /etc/shadow
        database if the L{spwd} is present.
        ÚbobZ
passphraser5   r6   é   é   é   é   é   Úspwdé)	  éÒ  Úosr   N)r   r;   r<   r   r   ÚeuidÚegidr   r=   Ú_shadowGetByNameZgetspnamÚseteuidCallsÚsetegidCallsr@   r"   r"   r#   Útest_shadowGetByName‚   s    z HelperTests.test_shadowGetByNamec                 C   sB   |   tdd¡ |  t d¡¡ |  | jjg ¡ |  | jjg ¡ dS )zP
        L{_shadowGetByName} returns L{None} if C{spwd} is not present.
        rK   NrE   )r<   r   rC   rQ   r=   r   rR   rS   r    r"   r"   r#   Útest_shadowGetByNameWithoutSpwd“   s    z+HelperTests.test_shadowGetByNameWithoutSpwdN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ÚdependencySkipÚskipr$   r/   r0   r3   rB   rD   rT   rU   r"   r"   r"   r#   r   8   s   
r   c                   @   sv   e Zd ZdZepeZ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S )ÚSSHPublicKeyDatabaseTestsz,
    Tests for L{SSHPublicKeyDatabase}.
    N©Úreturnc              	   C   s´   t  ¡ | _tdƒ| _tdƒ| _d| j d | j d | _tƒ | _|  	t
d| j¡ t|  ¡ ƒ| _t| jjtƒspt‚| j d¡| _| j ¡  tƒ }| dd	d
dd| jjd¡ || j_d S )Nó   foobaró   eggspams   t1 s    foo
t2 s    egg
rN   ú.sshÚuserr,   r5   r6   r7   ú
/bin/shell)r   ÚSSHPublicKeyDatabaseÚcheckerr   Úkey1Úkey2Úcontentr   r   r<   r   r   ÚmktempÚpathÚ
isinstanceÚstrÚAssertionErrorÚchildÚsshDirÚmakedirsr   r;   Z_userdbr@   r"   r"   r#   r$   ¥   s*    



ù	zSSHPublicKeyDatabaseTests.setUpc                 C   sL   | j | jgd�}|  |d d t¡ |  |d d d¡ |  t|ƒd¡ dS )zJ
        L{SSHPublicKeyDatabase} is deprecated as of version 15.0
        )ZoffendingFunctionsr   ÚcategoryÚmessagezÜtwisted.conch.checkers.SSHPublicKeyDatabase was deprecated in Twisted 15.0.0: Please use twisted.conch.checkers.SSHPublicKeyChecker, initialized with an instance of twisted.conch.checkers.UNIXAuthorizedKeysFiles instead.r5   N)ZflushWarningsr$   r=   ÚDeprecationWarningÚlen)r!   ZwarningsShownr"   r"   r#   Útest_deprecated¿   s    
þz)SSHPublicKeyDatabaseTests.test_deprecatedc                 C   sj   | j  |¡ | j¡ tddƒ}d|_|  | j |¡¡ d|_|  | j |¡¡ d|_|  	| j |¡¡ d S )Nó   useró   passwordr_   r`   s
   notallowed)
ro   rn   Ú
setContentrh   r   Úblobr(   re   ÚcheckKeyr1   )r!   Úfilenamerb   r"   r"   r#   Ú_testCheckKeyÏ   s    
z'SSHPublicKeyDatabaseTests._testCheckKeyc                 C   s.   |   d¡ |  | jjg ¡ |  | jjg ¡ dS )z˜
        L{SSHPublicKeyDatabase.checkKey} should retrieve the content of the
        authorized_keys file and check the keys against that file.
        Úauthorized_keysN©r|   r=   r   rR   rS   r    r"   r"   r#   Útest_checkKeyÙ   s    
z'SSHPublicKeyDatabaseTests.test_checkKeyc                 C   s.   |   d¡ |  | jjg ¡ |  | jjg ¡ dS )z™
        L{SSHPublicKeyDatabase.checkKey} should retrieve the content of the
        authorized_keys2 file and check the keys against that file.
        Úauthorized_keys2Nr~   r    r"   r"   r#   Útest_checkKey2â   s    
z(SSHPublicKeyDatabaseTests.test_checkKey2c                    sÈ   | j  d¡‰ ˆ  | j¡ ˆ  d¡ |  ˆ jd¡ | jj‰‡ ‡fdd„}d| j_d| j_	|  
| jd|¡ |  
td	| j¡ td
dƒ}d|_|  | j |¡¡ |  | jjddddg¡ |  | jjddg¡ dS )z˜
        If the key file is readable, L{SSHPublicKeyDatabase.checkKey} should
        switch its uid/gid to the ones of the authenticated user.
        r}   r   éÿ  c                    s   ˆ   d¡ ˆ| ƒS )Nr‚   )Úchmod)rO   ©ZkeyFileZsavedSeteuidr"   r#   Úseteuidø   s    
z>SSHPublicKeyDatabaseTests.test_checkKeyAsRoot.<locals>.seteuidrL   rM   r…   rN   rv   rw   r_   r5   r6   N)ro   rn   rx   rh   rƒ   Z
addCleanupr   r…   rO   rP   r<   r   r   ry   r(   re   rz   r=   rR   rS   )r!   r…   rb   r"   r„   r#   Útest_checkKeyAsRootë   s    

z-SSHPublicKeyDatabaseTests.test_checkKeyAsRootc                    s\   dd„ }ˆ   ˆ jd|¡ tddtjdtj tj¡ 	d¡ƒ}ˆ j 
|¡}‡ fdd„}| |¡S )	z�
        L{SSHPublicKeyDatabase.requestAvatarId} should return the avatar id
        passed in if its C{_checkKey} method returns True.
        c                 S   s   dS ©NTr"   ©Zignoredr"   r"   r#   Ú	_checkKey  s    zASSHPublicKeyDatabaseTests.test_requestAvatarId.<locals>._checkKeyrz   ó   testó   ssh-rsaó   fooc                    s   ˆ   | d¡ d S ©NrŠ   ©r=   ©ZavatarIdr    r"   r#   Ú_verify  s    z?SSHPublicKeyDatabaseTests.test_requestAvatarId.<locals>._verify)r<   re   r   r   ÚpublicRSA_opensshr   ÚKeyÚ
fromStringÚprivateRSA_opensshÚsignÚrequestAvatarIdÚaddCallback)r!   r‰   ÚcredentialsÚdr�   r"   r    r#   Útest_requestAvatarId  s    ûz.SSHPublicKeyDatabaseTests.test_requestAvatarIdc                 C   sB   dd„ }|   | jd|¡ tddtjddƒ}| j |¡}|  |t¡S )a(  
        L{SSHPublicKeyDatabase.requestAvatarId} should raise L{ValidPublicKey}
        if the credentials represent a valid key without a signature.  This
        tells the user that the key is valid for login, but does not actually
        allow that user to do so without a signature.
        c                 S   s   dS r‡   r"   rˆ   r"   r"   r#   r‰   &  s    zQSSHPublicKeyDatabaseTests.test_requestAvatarIdWithoutSignature.<locals>._checkKeyrz   rŠ   r‹   N)r<   re   r   r   r‘   r–   ÚassertFailurer   ©r!   r‰   r˜   r™   r"   r"   r#   Ú$test_requestAvatarIdWithoutSignature  s        ÿz>SSHPublicKeyDatabaseTests.test_requestAvatarIdWithoutSignaturec                 C   s0   dd„ }|   | jd|¡ | j d¡}|  |t¡S )z…
        If L{SSHPublicKeyDatabase.checkKey} returns False,
        C{_cbRequestAvatarId} should raise L{UnauthorizedLogin}.
        c                 S   s   dS ©NFr"   rˆ   r"   r"   r#   r‰   6  s    zKSSHPublicKeyDatabaseTests.test_requestAvatarIdInvalidKey.<locals>._checkKeyrz   N)r<   re   r–   r›   r   )r!   r‰   r™   r"   r"   r#   Útest_requestAvatarIdInvalidKey0  s    z8SSHPublicKeyDatabaseTests.test_requestAvatarIdInvalidKeyc                 C   sR   dd„ }|   | jd|¡ tddtjdtj tj¡ 	d¡ƒ}| j 
|¡}|  |t¡S )z¡
        Valid keys with invalid signatures should cause
        L{SSHPublicKeyDatabase.requestAvatarId} to return a {UnauthorizedLogin}
        failure
        c                 S   s   dS r‡   r"   rˆ   r"   r"   r#   r‰   D  s    zQSSHPublicKeyDatabaseTests.test_requestAvatarIdInvalidSignature.<locals>._checkKeyrz   rŠ   r‹   rŒ   )r<   re   r   r   r‘   r   r’   r“   ÚprivateDSA_opensshr•   r–   r›   r   rœ   r"   r"   r#   Ú$test_requestAvatarIdInvalidSignature=  s    ûz>SSHPublicKeyDatabaseTests.test_requestAvatarIdInvalidSignaturec                    sV   dd„ }ˆ   ˆ jd|¡ tdddddƒ}ˆ j |¡}‡ fd	d
„}| |¡ ˆ  |t¡S )z~
        Exceptions raised while verifying the key should be normalized into an
        C{UnauthorizedLogin} failure.
        c                 S   s   dS r‡   r"   rˆ   r"   r"   r#   r‰   X  s    zSSSHPublicKeyDatabaseTests.test_requestAvatarIdNormalizeException.<locals>._checkKeyrz   rŠ   Ns   blobs   sigDatas   sigc                    s    ˆ   tj¡}ˆ  t|ƒd¡ | S )Nr5   )ÚflushLoggedErrorsr   ÚBadKeyErrorr=   rt   )ZfailureÚerrorsr    r"   r#   Ú_verifyLoggedException_  s    z`SSHPublicKeyDatabaseTests.test_requestAvatarIdNormalizeException.<locals>._verifyLoggedException)r<   re   r   r–   Z
addErrbackr›   r   )r!   r‰   r˜   r™   r¥   r"   r    r#   Ú&test_requestAvatarIdNormalizeExceptionR  s    
z@SSHPublicKeyDatabaseTests.test_requestAvatarIdNormalizeException)rV   rW   rX   rY   ÚeuidSkiprZ   r[   r$   ru   r|   r   r�   r†   rš   r�   rŸ   r¡   r¦   r"   r"   r"   r#   r\   ž   s   
		r\   c                   @   sD   e Zd ZdZeZdd„ Zdd„ Zdd„ Zdd	„ Z	d
d„ Z
dd„ ZdS )ÚSSHProtocolCheckerTestsz*
    Tests for L{SSHProtocolChecker}.
    c                 C   sL   t  ¡ }|  |jg ¡ | t  ¡ ¡ |  |jtg¡ |  |j t t j¡ dS )z€
        L{SSHProcotolChecker.registerChecker} should add the given checker to
        the list of registered checkers.
        N)r   ÚSSHProtocolCheckerr=   ÚcredentialInterfacesÚregisterCheckerrd   r	   ÚassertIsInstance©r!   re   r"   r"   r#   Útest_registerCheckero  s    ÿ ÿz,SSHProtocolCheckerTests.test_registerCheckerc                 C   sN   t  ¡ }|  |jg ¡ | t  ¡ t¡ |  |jtg¡ |  |j t t j¡ dS )zÙ
        If a specific interface is passed into
        L{SSHProtocolChecker.registerChecker}, that interface should be
        registered instead of what the checker specifies in
        credentialIntefaces.
        N)r   r©   r=   rª   r«   rd   r
   r¬   r­   r"   r"   r#   Ú!test_registerCheckerWithInterface~  s     ÿz9SSHProtocolCheckerTests.test_registerCheckerWithInterfacec                    sJ   t  ¡ }tƒ }| dd¡ | |¡ | tddƒ¡}‡ fdd„}| |¡S )z†
        L{SSHProtocolChecker.requestAvatarId} should defer to one if its
        registered checkers to authenticate a user.
        rŠ   c                    s   ˆ   | d¡ d S r�   rŽ   r�   r    r"   r#   Ú	_callback˜  s    z?SSHProtocolCheckerTests.test_requestAvatarId.<locals>._callback)r   r©   r   r;   r«   r–   r   r—   )r!   re   ÚpasswordDatabaser™   r°   r"   r    r#   rš   �  s    
z,SSHProtocolCheckerTests.test_requestAvatarIdc                 C   sV   t  ¡ }dd„ }|  |d|¡ tƒ }| dd¡ | |¡ | tddƒ¡}|  |t	¡S )zÂ
        If the client indicates that it is never satisfied, by always returning
        False from _areDone, then L{SSHProtocolChecker} should raise
        L{NotEnoughAuthentication}.
        c                 S   s   dS rž   r"   r�   r"   r"   r#   Ú_areDone¥  s    zYSSHProtocolCheckerTests.test_requestAvatarIdWithNotEnoughAuthentication.<locals>._areDoneÚareDonerŠ   )
r   r©   r<   r   r;   r«   r–   r   r›   r   )r!   re   r²   r±   r™   r"   r"   r#   Ú/test_requestAvatarIdWithNotEnoughAuthentication�  s    
zGSSHProtocolCheckerTests.test_requestAvatarIdWithNotEnoughAuthenticationc                 C   s$   t  ¡ }| tddƒ¡}|  |t¡S )z™
        If the passed credentials aren't handled by any registered checker,
        L{SSHProtocolChecker} should raise L{UnhandledCredentials}.
        rŠ   )r   r©   r–   r   r›   r   )r!   re   r™   r"   r"   r#   Ú%test_requestAvatarIdInvalidCredential°  s    z=SSHProtocolCheckerTests.test_requestAvatarIdInvalidCredentialc                 C   s   |   t ¡  d¡¡ dS )zV
        The default L{SSHProcotolChecker.areDone} should simply return True.
        N)r(   r   r©   r³   r    r"   r"   r#   Útest_areDone¹  s    z$SSHProtocolCheckerTests.test_areDoneN)rV   rW   rX   rY   rZ   r[   r®   r¯   rš   r´   rµ   r¶   r"   r"   r"   r#   r¨   h  s   	r¨   c                   @   sn   e Zd ZdZepeZee 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S )ÚUNIXPasswordDatabaseTestsz,
    Tests for L{UNIXPasswordDatabase}.
    N)r™   Úusernamer^   c                 C   s   |   |  |¡|¡ dS )zè
        Assert that the L{Deferred} passed in is called back with the value
        'username'.  This represents a valid login for this TestCase.

        @param d: a L{Deferred} from an L{IChecker.requestAvatarId} method.
        N)r=   ÚsuccessResultOf)r!   r™   r¸   r"   r"   r#   ÚassertLoggedInÇ  s    z(UNIXPasswordDatabaseTests.assertLoggedInc                 C   s<  t  ¡ }dd„ }tƒ }| d|ddƒddddd	¡ | d
dddddd	¡ tƒ }| ddddddddd¡	 | d
|d
dƒddddddd¡	 |  t d|¡ |  t d|¡ tƒ }|  td|¡ d|_d|_	t
d d!ƒ}|  | |¡d ¡ |  |jg ¡ |  |jg ¡ d"|_|  | |¡d"¡ |  |jd#dg¡ |  |jd#dg¡ d$S )%z�
        L{UNIXPasswordDatabase} with no arguments has checks the C{pwd} database
        and then the C{spwd} database.
        c                 S   s    t   || ¡}t   |d| ¡}|S )Nz$1$)r'   )r¸   r,   r-   r.   r"   r"   r#   r.   ×  s    z?UNIXPasswordDatabaseTests.test_defaultCheckers.<locals>.cryptedr4   r,   r5   r6   Úfoor8   r9   rE   ÚxÚbarú/barr2   rF   rG   rH   rI   rJ   é   é	   é
   é   é   é   é   r:   rK   rN   rL   rM   ó   alicerw   ó   bobr   N)r   ÚUNIXPasswordDatabaser   r;   r   r<   r   r   rO   rP   r   rº   r–   r=   rR   rS   r¸   )r!   re   r.   r:   rK   r   Úcredr"   r"   r#   Útest_defaultCheckersÐ  s<          ÿ 
z.UNIXPasswordDatabaseTests.test_defaultCheckersc                 C   s   |   |tj¡ dS )aÅ  
        Asserts that the L{Deferred} passed in is erred back with an
        L{UnauthorizedLogin} L{Failure}.  This reprsents an invalid login for
        this TestCase.

        NOTE: To work, this method's return value must be returned from the
        test method, or otherwise hooked up to the test machinery.

        @param d: a L{Deferred} from an L{IChecker.requestAvatarId} method.
        @type d: L{Deferred}
        @rtype: L{None}
        N)ÚfailureResultOfr   r   ©r!   r™   r"   r"   r#   ÚassertUnauthorizedLoginø  s    z1UNIXPasswordDatabaseTests.assertUnauthorizedLoginc              	   C   sR   t   dd¡}tƒ }| d|ddddd¡ t |jg¡}|  | tdd	ƒ¡d¡ d
S )zo
        L{UNIXPasswordDatabase} takes a list of functions to check for UNIX
        user information.
        ÚsecretZanybodyr5   r6   r»   r¾   r9   s   anybodys   secretN)	r'   r   r;   r   rÈ   r?   rº   r–   r   )r!   r,   rA   re   r"   r"   r#   Útest_passInCheckers  s     ÿz-UNIXPasswordDatabaseTests.test_passInCheckersc                 C   sJ   dd„ }dd„ }|   td|¡ t |g¡}tddƒ}|  | |¡d¡ dS )zÝ
        If the encrypted password provided by the getpwnam function is valid
        (verified by the L{verifyCryptedPassword} function), we callback the
        C{requestAvatarId} L{Deferred} with the username.
        c                 S   s   | |kS r   r"   ©r.   Úpwr"   r"   r#   r)     s    zLUNIXPasswordDatabaseTests.test_verifyPassword.<locals>.verifyCryptedPasswordc                 S   s   | | gS r   r"   ©r¸   r"   r"   r#   r?     s    z?UNIXPasswordDatabaseTests.test_verifyPassword.<locals>.getpwnamr)   ó   usernameN©r<   r   rÈ   r   rº   r–   ©r!   r)   r?   re   Ú
credentialr"   r"   r#   Útest_verifyPassword  s    
z-UNIXPasswordDatabaseTests.test_verifyPasswordc                 C   s2   dd„ }t  |g¡}tddƒ}|  | |¡¡ dS )z}
        If the getpwnam function raises a KeyError, the login fails with an
        L{UnauthorizedLogin} exception.
        c                 S   s   t | ƒ‚d S r   )ÚKeyErrorrÒ   r"   r"   r#   r?   ,  s    z?UNIXPasswordDatabaseTests.test_failOnKeyError.<locals>.getpwnamrÓ   rw   N)r   rÈ   r   rÍ   r–   )r!   r?   re   rÖ   r"   r"   r#   Útest_failOnKeyError&  s    
z-UNIXPasswordDatabaseTests.test_failOnKeyErrorc                 C   sH   dd„ }dd„ }|   td|¡ t |g¡}tddƒ}|  | |¡¡ dS )	z”
        If the verifyCryptedPassword function doesn't verify the password, the
        login fails with an L{UnauthorizedLogin} exception.
        c                 S   s   dS rž   r"   rÐ   r"   r"   r#   r)   9  s    zOUNIXPasswordDatabaseTests.test_failOnBadPassword.<locals>.verifyCryptedPasswordc                 S   s   | dgS )Nrw   r"   rÒ   r"   r"   r#   r?   <  s    zBUNIXPasswordDatabaseTests.test_failOnBadPassword.<locals>.getpwnamr)   rÓ   rw   N)r<   r   rÈ   r   rÍ   r–   rÕ   r"   r"   r#   Útest_failOnBadPassword3  s    
z0UNIXPasswordDatabaseTests.test_failOnBadPasswordc                 C   sT   dd„ }dd„ }dd„ }|   td|¡ t ||g¡}tdd	ƒ}|  | |¡d¡ d
S )a  
        UNIXPasswordDatabase.requestAvatarId loops through each getpwnam
        function associated with it and returns a L{Deferred} which fires with
        the result of the first one which returns a value other than None.
        ones do not verify the password.
        c                 S   s   | |kS r   r"   rÐ   r"   r"   r#   r)   L  s    zRUNIXPasswordDatabaseTests.test_loopThroughFunctions.<locals>.verifyCryptedPasswordc                 S   s   | dgS )Nznot the passwordr"   rÒ   r"   r"   r#   Ú	getpwnam1O  s    zFUNIXPasswordDatabaseTests.test_loopThroughFunctions.<locals>.getpwnam1c                 S   s   | dgS )Nr,   r"   rÒ   r"   r"   r#   Ú	getpwnam2R  s    zFUNIXPasswordDatabaseTests.test_loopThroughFunctions.<locals>.getpwnam2r)   rÓ   rw   NrÔ   )r!   r)   rÛ   rÜ   re   rÖ   r"   r"   r#   Útest_loopThroughFunctionsD  s    
z3UNIXPasswordDatabaseTests.test_loopThroughFunctionsc              	   C   s¶   t ƒ }| ddddddd¡ | ddddddd¡ | d	d
ddddd¡ |  td|¡ t tjg¡}tddƒ}|  | |¡¡ tddƒ}|  | |¡¡ tddƒ}|  | |¡¡ dS )z¨
        If the password returned by any function is C{""}, C{"x"}, or C{"*"} it
        is not compared against the supplied password.  Instead it is skipped.
        r4   Ú r5   r6   r»   r½   rE   r¼   ZcarolÚ*r:   rÆ   ó    rÇ   ó   xs   caroló   *N)	r   r;   r<   r   rÈ   r>   r   rÍ   r–   )r!   r:   re   rÉ   r"   r"   r#   Útest_failOnSpecialZ  s    


z,UNIXPasswordDatabaseTests.test_failOnSpecial)rV   rW   rX   rY   r   rZ   r[   r   Úbytesrº   rÊ   rÍ   rÏ   r×   rÙ   rÚ   rÝ   rã   r"   r"   r"   r#   r·   À  s   	(r·   c                   @   s,   e Zd ZdZeZdd„ Zdd„ Zdd„ ZdS )	ÚAuthorizedKeyFileReaderTestsz5
    Tests for L{checkers.readAuthorizedKeyFile}
    c                 C   s0   t dƒ}t |dd„ ¡}|  ddgt|ƒ¡ dS )zg
        L{checkers.readAuthorizedKeyFile} does not attempt to turn comments
        into keys
        sE   # this comment is ignored
this is not
# this is again
and this is notc                 S   s   | S r   r"   ©r¼   r"   r"   r#   Ú<lambda>‚  rà   zCAuthorizedKeyFileReaderTests.test_ignoresComments.<locals>.<lambda>s   this is nots   and this is notN©r   r   ZreadAuthorizedKeyFiler=   Úlist©r!   ÚfileobjÚresultr"   r"   r#   Útest_ignoresCommentsw  s
    ÿz1AuthorizedKeyFileReaderTests.test_ignoresCommentsc                 C   s0   t dƒ}tj|dd„ d�}|  dgt|ƒ¡ dS )zw
        L{checkers.readAuthorizedKeyFile} ignores leading whitespace in
        lines, as well as empty lines
        sg   
                           # ignore
                           not ignored
                           c                 S   s   | S r   r"   ræ   r"   r"   r#   rç   �  rà   zYAuthorizedKeyFileReaderTests.test_ignoresLeadingWhitespaceAndEmptyLines.<locals>.<lambda>©ZparseKeys   not ignoredNrè   rê   r"   r"   r#   Ú*test_ignoresLeadingWhitespaceAndEmptyLines…  s
    ÿzGAuthorizedKeyFileReaderTests.test_ignoresLeadingWhitespaceAndEmptyLinesc                 C   s4   dd„ }t dƒ}tj||d�}|  dgt|ƒ¡ dS )zÇ
        L{checkers.readAuthorizedKeyFile} does not raise an exception
        when a key fails to parse (raises a
        L{twisted.conch.ssh.keys.BadKeyError}), but rather just keeps going
        c                 S   s   |   d¡rt d¡‚| S )Nó   fzfailed to parse)Ú
startswithr   r£   )Úliner"   r"   r#   Ú
failOnSomeš  s    

zKAuthorizedKeyFileReaderTests.test_ignoresUnparsableKeys.<locals>.failOnSomes   failed key
good keyrî   s   good keyNrè   )r!   ró   rë   rì   r"   r"   r#   Útest_ignoresUnparsableKeys“  s    z7AuthorizedKeyFileReaderTests.test_ignoresUnparsableKeysN)	rV   rW   rX   rY   rZ   r[   rí   rï   rô   r"   r"   r"   r#   rå   p  s
   rå   c                   @   s,   e Zd ZdZeZdd„ Zdd„ Zdd„ ZdS )	ÚInMemorySSHKeyDBTestsz0
    Tests for L{checkers.InMemorySSHKeyDB}
    c                 C   s    t  ddgi¡}tt j|ƒ dS )z_
        L{checkers.InMemorySSHKeyDB} implements
        L{checkers.IAuthorizedKeysDB}
        rÆ   s   keyN)r   ÚInMemorySSHKeyDBr   ÚIAuthorizedKeysDB©r!   Úkeydbr"   r"   r#   Útest_implementsInterface«  s    z.InMemorySSHKeyDBTests.test_implementsInterfacec                 C   s*   t  ddgi¡}|  g t| d¡ƒ¡ dS )z½
        If the user is not in the mapping provided to
        L{checkers.InMemorySSHKeyDB}, an empty iterator is returned
        by L{checkers.InMemorySSHKeyDB.getAuthorizedKeys}
        rÆ   s   keysrÇ   N©r   rö   r=   ré   ÚgetAuthorizedKeysrø   r"   r"   r#   Útest_noKeysForUnauthorizedUser³  s    z4InMemorySSHKeyDBTests.test_noKeysForUnauthorizedUserc                 C   s0   t  dddgi¡}|  ddgt| d¡ƒ¡ dS )zÅ
        If the user is in the mapping provided to
        L{checkers.InMemorySSHKeyDB}, an iterator with all the keys
        is returned by L{checkers.InMemorySSHKeyDB.getAuthorizedKeys}
        rÆ   ó   aó   bNrû   rø   r"   r"   r#   Útest_allKeysForAuthorizedUser¼  s    z3InMemorySSHKeyDBTests.test_allKeysForAuthorizedUserN)	rV   rW   rX   rY   rZ   r[   rú   rý   r   r"   r"   r"   r#   rõ   ¤  s
   	rõ   c                   @   sJ   e Zd ZdZeZddœdd„Zdd„ Zdd	„ Zd
d„ Z	dd„ Z
dd„ ZdS )ÚUNIXAuthorizedKeysFilesTestsz8
    Tests for L{checkers.UNIXAuthorizedKeysFiles}.
    Nr]   c              	   C   sŠ   t |  ¡ ƒ| _t| jjtƒs t‚| j ¡  tƒ | _| j 	ddddd| jjd¡ | j 
d¡| _| j ¡  | j 
d¡}| d	¡ d
dg| _d S )Nr4   r,   r5   r6   zalice lastnamerc   ra   r}   s   key 1
key 2s   key 1s   key 2)r   ri   rj   rk   rl   rm   rp   r   rA   r;   rn   ro   rx   ÚexpectedKeys)r!   ZauthorizedKeysr"   r"   r#   r$   Í  s$    
ù


z"UNIXAuthorizedKeysFilesTests.setUpc                 C   s   t  | j¡}tt j|ƒ dS )zg
        L{checkers.UNIXAuthorizedKeysFiles} implements
        L{checkers.IAuthorizedKeysDB}.
        N)r   ÚUNIXAuthorizedKeysFilesrA   r   r÷   rø   r"   r"   r#   rú   ä  s    z5UNIXAuthorizedKeysFilesTests.test_implementsInterfacec                 C   s.   t j| jdd„ d�}|  g t| d¡ƒ¡ dS )zÒ
        If the user is not in the user database provided to
        L{checkers.UNIXAuthorizedKeysFiles}, an empty iterator is returned
        by L{checkers.UNIXAuthorizedKeysFiles.getAuthorizedKeys}.
        c                 S   s   | S r   r"   ræ   r"   r"   r#   rç   ò  rà   zMUNIXAuthorizedKeysFilesTests.test_noKeysForUnauthorizedUser.<locals>.<lambda>rî   rÇ   N)r   r  rA   r=   ré   rü   rø   r"   r"   r#   rý   ì  s    z;UNIXAuthorizedKeysFilesTests.test_noKeysForUnauthorizedUserc                 C   sH   | j  d¡ d¡ tj| jdd„ d�}|  | jdg t| 	d¡ƒ¡ dS )a  
        If the user is in the user database provided to
        L{checkers.UNIXAuthorizedKeysFiles}, an iterator with all the keys in
        C{~/.ssh/authorized_keys} and C{~/.ssh/authorized_keys2} is returned
        by L{checkers.UNIXAuthorizedKeysFiles.getAuthorizedKeys}.
        r€   s   key 3c                 S   s   | S r   r"   ræ   r"   r"   r#   rç   ý  rà   z`UNIXAuthorizedKeysFilesTests.test_allKeysInAllAuthorizedFilesForAuthorizedUser.<locals>.<lambda>rî   rÆ   N)
ro   rn   rx   r   r  rA   r=   r  ré   rü   rø   r"   r"   r#   Ú1test_allKeysInAllAuthorizedFilesForAuthorizedUserõ  s    
 ÿzNUNIXAuthorizedKeysFilesTests.test_allKeysInAllAuthorizedFilesForAuthorizedUserc                 C   s0   t j| jdd„ d�}|  | jt| d¡ƒ¡ dS )z¸
        L{checkers.UNIXAuthorizedKeysFiles.getAuthorizedKeys} returns only
        the keys in C{~/.ssh/authorized_keys} and C{~/.ssh/authorized_keys2}
        if they exist.
        c                 S   s   | S r   r"   ræ   r"   r"   r#   rç     rà   zJUNIXAuthorizedKeysFilesTests.test_ignoresNonexistantFile.<locals>.<lambda>rî   rÆ   N)r   r  rA   r=   r  ré   rü   rø   r"   r"   r#   Útest_ignoresNonexistantFile  s    z8UNIXAuthorizedKeysFilesTests.test_ignoresNonexistantFilec                 C   s@   | j  d¡ ¡  tj| jdd„ d�}|  | jt| 	d¡ƒ¡ dS )z¿
        L{checkers.UNIXAuthorizedKeysFiles.getAuthorizedKeys} returns only
        the keys in C{~/.ssh/authorized_keys} and C{~/.ssh/authorized_keys2}
        if they are readable.
        r€   c                 S   s   | S r   r"   ræ   r"   r"   r#   rç     rà   zIUNIXAuthorizedKeysFilesTests.test_ignoresUnreadableFile.<locals>.<lambda>rî   rÆ   N)
ro   rn   rp   r   r  rA   r=   r  ré   rü   rø   r"   r"   r#   Útest_ignoresUnreadableFile  s    z7UNIXAuthorizedKeysFilesTests.test_ignoresUnreadableFile)rV   rW   rX   rY   rZ   r[   r$   rú   rý   r  r  r  r"   r"   r"   r#   r  Æ  s   		r  Ú_KeyDBrü   c                   @   s   e Zd ZdZdS )Ú_DummyExceptionz0
    Fake exception to be used for testing.
    N)rV   rW   rX   rY   r"   r"   r"   r#   r    s   r  c                   @   sL   e Zd ZdZeZdd„ Zdd„ Zdd„ Zdd	„ Z	d
d„ Z
dd„ Zdd„ ZdS )ÚSSHPublicKeyCheckerTestsz4
    Tests for L{checkers.SSHPublicKeyChecker}.
    c                 C   sD   t ddtjdtj tj¡ d¡ƒ| _t	dd„ ƒ| _
t | j
¡| _d S )NrÆ   r‹   rŒ   c                 S   s   t j tj¡gS r   )r   r’   r“   r   r‘   )Ú_r"   r"   r#   rç   0  rà   z0SSHPublicKeyCheckerTests.setUp.<locals>.<lambda>)r   r   r‘   r   r’   r“   r”   r•   r˜   r  rù   r   ZSSHPublicKeyCheckerre   r    r"   r"   r#   r$   (  s    ûzSSHPublicKeyCheckerTests.setUpc                 C   s"   d| j _|  | j | j ¡t¡ dS )z�
        Calling L{checkers.SSHPublicKeyChecker.requestAvatarId} with
        credentials that do not have a signature fails with L{ValidPublicKey}.
        N)r˜   Ú	signaturerË   re   r–   r   r    r"   r"   r#   Ú test_credentialsWithoutSignature3  s
     ÿz9SSHPublicKeyCheckerTests.test_credentialsWithoutSignaturec                 C   s$   d| j _|  | j | j ¡tj¡ dS )z–
        Calling L{checkers.SSHPublicKeyChecker.requestAvatarId} with
        credentials that have a bad key fails with L{keys.BadKeyError}.
        rà   N)r˜   ry   rË   re   r–   r   r£   r    r"   r"   r#   Útest_credentialsWithBadKey=  s
     ÿz3SSHPublicKeyCheckerTests.test_credentialsWithBadKeyc                 C   s$   t j| j_|  | j | j¡t¡ dS )zÙ
        If L{checkers.IAuthorizedKeysDB.getAuthorizedKeys} returns no keys
        that match the credentials,
        L{checkers.SSHPublicKeyChecker.requestAvatarId} fails with
        L{UnauthorizedLogin}.
        N)r   ZpublicDSA_opensshr˜   ry   rË   re   r–   r   r    r"   r"   r#   Útest_credentialsNoMatchingKeyG  s
    
 ÿz6SSHPublicKeyCheckerTests.test_credentialsNoMatchingKeyc                 C   s2   t j tj¡ d¡| j_|  | j	 
| j¡t¡ dS )z§
        Calling L{checkers.SSHPublicKeyChecker.requestAvatarId} with
        credentials that are incorrectly signed fails with
        L{UnauthorizedLogin}.
        rŒ   N)r   r’   r“   r   r    r•   r˜   r  rË   re   r–   r   r    r"   r"   r#   Ú test_credentialsInvalidSignatureS  s    ÿþ ÿz9SSHPublicKeyCheckerTests.test_credentialsInvalidSignaturec                 C   s<   dd„ }|   tjd|¡ |  | j | j¡t¡ |  t	¡ dS )z�
        If L{keys.Key.verify} raises an exception,
        L{checkers.SSHPublicKeyChecker.requestAvatarId} fails with
        L{UnauthorizedLogin}.
        c                  _   s
   t ƒ ‚d S r   )r  )ÚargsÚkwargsr"   r"   r#   Úfailg  s    z?SSHPublicKeyCheckerTests.test_failureVerifyingKey.<locals>.failÚverifyN)
r<   r   r’   rË   re   r–   r˜   r   r¢   r  )r!   r  r"   r"   r#   Útest_failureVerifyingKey`  s     ÿz1SSHPublicKeyCheckerTests.test_failureVerifyingKeyc                 C   s$   | j  | j¡}|  d|  |¡¡ dS )zu
        L{checker.SSHPublicKeyChecker.requestAvatarId}, if successful,
        callbacks with the username.
        rÆ   N)re   r–   r˜   r=   r¹   rÌ   r"   r"   r#   Útest_usernameReturnedOnSuccessq  s    z7SSHPublicKeyCheckerTests.test_usernameReturnedOnSuccessN)rV   rW   rX   rY   rZ   r[   r$   r  r  r  r  r  r  r"   r"   r"   r#   r	  !  s   

r	  )ArY   rN   Úbase64r   Úcollectionsr   Úior   Útypingr   rl   Ú__annotations__r'   ÚImportErrorr   Zzope.interface.verifyr   Ztwisted.cred.checkersr   Ztwisted.cred.credentialsr	   r
   r   r   Ztwisted.cred.errorr   r   Ztwisted.internet.deferr   Ztwisted.pythonr   Ztwisted.python.fakepwdr   r   Ztwisted.python.filepathr   Ztwisted.python.reflectr   Ztwisted.test.test_processr   Ztwisted.trial.unittestr   rZ   Ztwisted.conchr   Ztwisted.conch.errorr   r   Ztwisted.conch.sshr   Ztwisted.conch.testr   Úgetattrr§   r   r\   r¨   r·   rå   rõ   r  r  Ú	Exceptionr  r	  r"   r"   r"   r#   Ú<module>   sX   

f KX 14"P