o
    Òó·i¤]  ã                   @   s¬   d Z ddl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mZmZ ddlmZ ddlmZ dd	lmZ dd
lmZ dd„ ZG dd„ de
ƒZG dd„ deƒZdS )z[
Tests for L{twisted.cred._digest} and the associated bits in
L{twisted.cred.credentials}.
é    N)Úhexlify)Úmd5Úsha1)ÚverifyObject)ÚDigestCredentialFactoryÚIUsernameDigestHashÚcalcHA1ÚcalcHA2ÚcalcResponse)ÚLoginFailed)ÚIPv4Address)ÚnetworkString)ÚTestCasec                 C   s   t  | ¡ ¡ S )N)Úbase64Ú	b64encodeÚstrip)Ús© r   úgC:\Users\psant\Downloads\PAF backend\school\venv\Lib\site-packages\twisted/cred/test/test_digestauth.pyr      s   r   c                       s0   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Z‡  ZS )ÚFakeDigestCredentialFactoryz\
    A Fake Digest Credential Factory that generates a predictable
    nonce and opaque
    c                    s   t ƒ j|i |¤Ž d| _d S )Nó   0)ÚsuperÚ__init__Ú
privateKey)ÚselfÚargsÚkwargs©Ú	__class__r   r   r   '   s   
z$FakeDigestCredentialFactory.__init__c                 C   ó   dS )z)
        Generate a static nonce
        s   178288758716122392881254770685Nr   ©r   r   r   r   Ú_generateNonce+   ó   z*FakeDigestCredentialFactory._generateNoncec                 C   r   )z&
        Return a stable time
        r   Nr   r    r   r   r   Ú_getTime1   r"   z$FakeDigestCredentialFactory._getTime)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r!   r#   Ú__classcell__r   r   r   r   r   !   s
    r   c                   @   sZ  e Zd ZdZdd„ Zdefdd„Zdd„ Zd	d
„ Zdefdd„Z	defdd„Z
dd„ Zdd„ Zdd„ Zdd„ Zdefdd„Zdd„ Zdd„ Zdefdd„Zdd „ Zd!d"„ ZdOd$d%„Zd&d'„ ZdOd(d)„Zd*d+„ Zd,d-„ Zd.d/„ Zd0d1„ Zd2d3„ Zd4d5„ Zd6d7„ Zd8d9„ Zd:d;„ Z d<d=„ Z!d>d?„ Z"d@dA„ Z#dBdC„ Z$dDdE„ Z%dFdG„ Z&dHdI„ Z'dJdK„ Z(dLdM„ Z)dNS )PÚDigestAuthTestsz¸
    L{TestCase} mixin class which defines a number of tests for
    L{DigestCredentialFactory}.  Because this mixin defines C{setUp}, it
    must be inherited before L{TestCase}.
    c                 C   sR   d| _ d| _d| _d| _d| _d| _d| _tdd	d
ƒ| _d| _	t
| j| jƒ| _dS )z>
        Create a DigestCredentialFactory for testing
        ó   foobars   bazquuxs
   test realmó   md5s    29fc54aa1641c6fa0e151419361c8f23ó   auths   /write/ZTCPz10.2.3.4iu¨  ó   GETN)ÚusernameÚpasswordÚrealmÚ	algorithmÚcnonceÚqopÚurir   ÚclientAddressÚmethodr   ÚcredentialFactoryr    r   r   r   ÚsetUp?   s   zDigestAuthTests.setUpr+   c                 C   sT   d}t || j| j| j|| jƒ}d | j| j| jf¡}t||ƒ ¡ ƒ}|  ||¡ dS )zŽ
        L{calcHA1} accepts the C{'md5'} algorithm and returns an MD5 hash of
        its parameters, excluding the nonce and cnonce.
        s	   abc123xyzó   :N)	r   r.   r0   r/   r2   Újoinr   ÚdigestÚassertEqual)r   Ú
_algorithmÚ_hashÚnonceÚhashA1Úa1Úexpectedr   r   r   Útest_MD5HashA1N   s   ÿzDigestAuthTests.test_MD5HashA1c                 C   s~   d}t d| j| j| j|| jƒ}| jd | j d | j }tt|ƒ ¡ ƒ}|d | d | j }tt|ƒ ¡ ƒ}|  ||¡ dS )z“
        L{calcHA1} accepts the C{'md5-sess'} algorithm and returns an MD5 hash
        of its parameters, including the nonce and cnonce.
        s	   xyz321abcó   md5-sessr9   N)	r   r.   r0   r/   r2   r   r   r;   r<   )r   r?   r@   rA   Úha1rB   r   r   r   Útest_MD5SessionHashA1[   s   ÿz%DigestAuthTests.test_MD5SessionHashA1c                 C   ó   |   dt¡ dS )z�
        L{calcHA1} accepts the C{'sha'} algorithm and returns a SHA hash of its
        parameters, excluding the nonce and cnonce.
        ó   shaN)rC   r   r    r   r   r   Útest_SHAHashA1j   ó   zDigestAuthTests.test_SHAHashA1c                 C   sD   d}t ||| jddƒ}|d | j }t||ƒ ¡ ƒ}|  ||¡ dS )z±
        L{calcHA2} accepts the C{'md5'} algorithm and returns an MD5 hash of
        its arguments, excluding the entity hash for QOP other than
        C{'auth-int'}.
        r-   r,   Nr9   ©r	   r4   r   r;   r<   )r   r=   r>   r6   ÚhashA2Úa2rB   r   r   r   Útest_MD5HashA2Authq   s
   z"DigestAuthTests.test_MD5HashA2Authc                 C   sP   d}d}t ||| jd|ƒ}|d | j d | }t||ƒ ¡ ƒ}|  ||¡ dS )z¡
        L{calcHA2} accepts the C{'md5'} algorithm and returns an MD5 hash of
        its arguments, including the entity hash for QOP of C{'auth-int'}.
        r-   s	   foobarbazs   auth-intr9   NrK   )r   r=   r>   r6   ZhentityrL   rM   rB   r   r   r   Útest_MD5HashA2AuthInt}   s   z%DigestAuthTests.test_MD5HashA2AuthIntc                 C   ó   |   d¡ dS )zŸ
        L{calcHA2} accepts the C{'md5-sess'} algorithm and QOP of C{'auth'} and
        returns the same value as it does for the C{'md5'} algorithm.
        rD   N)rN   r    r   r   r   Útest_MD5SessHashA2Auth‰   ó   z&DigestAuthTests.test_MD5SessHashA2Authc                 C   rP   )z£
        L{calcHA2} accepts the C{'md5-sess'} algorithm and QOP of C{'auth-int'}
        and returns the same value as it does for the C{'md5'} algorithm.
        rD   N)rO   r    r   r   r   Útest_MD5SessHashA2AuthInt�   rR   z)DigestAuthTests.test_MD5SessHashA2AuthIntc                 C   rG   )z°
        L{calcHA2} accepts the C{'sha'} algorithm and returns a SHA hash of
        its arguments, excluding the entity hash for QOP other than
        C{'auth-int'}.
        rH   N)rN   r   r    r   r   r   Útest_SHAHashA2Auth—   ó   z"DigestAuthTests.test_SHAHashA2Authc                 C   rG   )z 
        L{calcHA2} accepts the C{'sha'} algorithm and returns a SHA hash of
        its arguments, including the entity hash for QOP of C{'auth-int'}.
        rH   N)rO   r   r    r   r   r   Útest_SHAHashA2AuthIntŸ   rJ   z%DigestAuthTests.test_SHAHashA2AuthIntc           	      C   sT   d}d}d}|d | d | }t ||ƒ ¡ ƒ}t||||dddƒ}|  ||¡ dS )zâ
        L{calcResponse} accepts the C{'md5'} algorithm and returns an MD5 hash
        of its parameters, excluding the nonce count, client nonce, and QoP
        value if the nonce count and client nonce are L{None}
        ó   abc123ó   789xyzó   lmnopqr9   N©r   r;   r
   r<   )	r   r=   r>   r@   rL   r?   ÚresponserB   r;   r   r   r   Útest_MD5HashResponse¦   s   z$DigestAuthTests.test_MD5HashResponsec                 C   rP   )zç
        L{calcResponse} accepts the C{'md5-sess'} algorithm and returns an MD5
        hash of its parameters, excluding the nonce count, client nonce, and
        QoP value if the nonce count and client nonce are L{None}
        rD   N)r\   r    r   r   r   Útest_MD5SessionHashResponse¶   ó   z+DigestAuthTests.test_MD5SessionHashResponsec                 C   rG   )zá
        L{calcResponse} accepts the C{'sha'} algorithm and returns a SHA hash
        of its parameters, excluding the nonce count, client nonce, and QoP
        value if the nonce count and client nonce are L{None}
        rH   N)r\   r   r    r   r   r   Útest_SHAHashResponse¾   rU   z$DigestAuthTests.test_SHAHashResponsec                 C   sx   d}d}d}d}d}d}|d | d | d | d | d | }	t ||	ƒ ¡ ƒ}
t|||||||ƒ}|  |
|¡ dS )	zÉ
        L{calcResponse} accepts the C{'md5'} algorithm and returns an MD5 hash
        of its parameters, including the nonce count, client nonce, and QoP
        value if they are specified.
        rW   rX   rY   s   00000004s	   abcxyz123r,   r9   NrZ   )r   r=   r>   r@   rL   r?   Z
nonceCountZclientNoncer3   r[   rB   r;   r   r   r   Útest_MD5HashResponseExtraÆ   sB   ÿþýüûúùø	÷
öÿÿz)DigestAuthTests.test_MD5HashResponseExtrac                 C   rP   )zÎ
        L{calcResponse} accepts the C{'md5-sess'} algorithm and returns an MD5
        hash of its parameters, including the nonce count, client nonce, and
        QoP value if they are specified.
        rD   N)r`   r    r   r   r   Ú test_MD5SessionHashResponseExtraç   r^   z0DigestAuthTests.test_MD5SessionHashResponseExtrac                 C   rG   )zÈ
        L{calcResponse} accepts the C{'sha'} algorithm and returns a SHA hash
        of its parameters, including the nonce count, client nonce, and QoP
        value if they are specified.
        rH   N)r`   r   r    r   r   r   Útest_SHAHashResponseExtraï   rU   z)DigestAuthTests.test_SHAHashResponseExtraTc                    s–   d|vr	| j |d< d|vr| j|d< d|vr| j|d< d|vr$| j|d< d|vr-| j|d< d|vr6| j|d< |r;d‰ nd‰ d	 ‡ fd
d„| ¡ D ƒ¡S )aþ  
        Format all given keyword arguments and their values suitably for use as
        the value of an HTTP header.

        @types quotes: C{bool}
        @param quotes: A flag indicating whether to quote the values of each
            field in the response.

        @param **kw: Keywords and C{bytes} values which will be treated as field
            name/value pairs to include in the result.

        @rtype: C{bytes}
        @return: The given fields formatted for use as an HTTP header value.
        r.   r0   r1   r3   r2   r4   ó   "ó    s   , c              	      s0   g | ]\}}|d urd  t|ƒdˆ |ˆ f¡‘qS )Nrd   ó   =)r:   r   )Ú.0ÚkÚv©Úquoter   r   Ú
<listcomp>  s    ýÿz2DigestAuthTests.formatResponse.<locals>.<listcomp>N)r.   r0   r1   r3   r2   r4   r:   Úitems)r   ÚquotesÚkwr   ri   r   ÚformatResponse÷   s(   






þÿzDigestAuthTests.formatResponsec           	      C   sh   |  d¡}|  d¡ ¡ }|  d¡}t|| j| j| j|| jƒ}t|d| j|dƒ}t	|||||| j|ƒ}|S )z@
        Calculate the response for the given challenge
        r?   r1   r3   r-   N)
ÚgetÚlowerr   r.   r0   r/   r2   r	   r4   r
   )	r   Ú	challengeZncountr?   Úalgor3   rE   Zha2rB   r   r   r   ÚgetDigestResponse  s   

ÿz!DigestAuthTests.getDigestResponsec                 C   sz   | j  | jj¡}d}| j||d |  ||¡||d d�}| j  || j| jj¡}|  | 	| j
¡¡ |  | 	| j
d ¡¡ dS )zš
        L{DigestCredentialFactory.decode} accepts a digest challenge response
        and parses it into an L{IUsernameHashedPassword} provider.
        ó   00000001r?   Úopaque)rm   r?   r[   Úncrv   ó   wrongN©r7   ÚgetChallenger5   Úhostro   rt   Údecoder6   Ú
assertTrueÚcheckPasswordr/   ÚassertFalse)r   rm   rr   rw   ÚclientResponseÚcredsr   r   r   Útest_response.  s   
ûÿzDigestAuthTests.test_responsec                 C   rP   )a  
        L{DigestCredentialFactory.decode} accepts a digest challenge response
        which does not quote the values of its fields and parses it into an
        L{IUsernameHashedPassword} provider in the same way it would a
        response which included quoted field values.
        FN)r‚   r    r   r   r   Útest_responseWithoutQuotesC  s   z*DigestAuthTests.test_responseWithoutQuotesc                 C   s   d| _ |  d¡ dS )z¶
        L{DigestCredentialFactory.decode} accepts a digest challenge response
        which quotes the values of its fields and includes a C{b","} in the URI
        field.
        s   /some,path/TN)r4   r‚   r    r   r   r   Útest_responseWithCommaURIL  s   z)DigestAuthTests.test_responseWithCommaURIc                 C   s   d| _ |  ¡  dS )zs
        The case of the algorithm value in the response is ignored when
        checking the credentials.
        s   MD5N©r1   r‚   r    r   r   r   Útest_caseInsensitiveAlgorithmU  s   z-DigestAuthTests.test_caseInsensitiveAlgorithmc                 C   s   d| _ |  ¡  dS )zV
        The algorithm defaults to MD5 if it is not supplied in the response.
        Nr…   r    r   r   r   Útest_md5DefaultAlgorithm]  s   z(DigestAuthTests.test_md5DefaultAlgorithmc                 C   sp   | j  d¡}d}| j|d |  ||¡||d d�}| j  || jd¡}|  | | j¡¡ |  	| | jd ¡¡ dS )z“
        L{DigestCredentialFactory.decode} accepts a digest challenge response
        even if the client address it is passed is L{None}.
        Nru   r?   rv   ©r?   r[   rw   rv   rx   )
r7   rz   ro   rt   r|   r6   r}   r~   r/   r   ©r   rr   rw   r€   r�   r   r   r   Útest_responseWithoutClientIPd  s   
üz,DigestAuthTests.test_responseWithoutClientIPc                 C   sÜ   | j  | jj¡}d}| j|d |  ||¡||d d�}| j  || j| jj¡}|  | 	| j
¡¡ |  | 	| j
d ¡¡ d}| j|d |  ||¡||d d�}| j  || j| jj¡}|  | 	| j
¡¡ |  | 	| j
d ¡¡ dS )zm
        L{DigestCredentialFactory.decode} handles multiple responses to a
        single challenge.
        ru   r?   rv   rˆ   rx   s   00000002Nry   r‰   r   r   r   Útest_multiResponsev  s2   
üÿ
üÿz"DigestAuthTests.test_multiResponsec                 C   sv   | j  | jj¡}d}| j|d |  ||¡||d d�}| j  |d| jj¡}|  | | j	¡¡ |  | | j	d ¡¡ dS )a&  
        L{DigestCredentialFactory.decode} returns an L{IUsernameHashedPassword}
        provider which rejects a correct password for the given user if the
        challenge response request is made using a different HTTP method than
        was used to request the initial challenge.
        ru   r?   rv   rˆ   s   POSTrx   N)
r7   rz   r5   r{   ro   rt   r|   r   r~   r/   r‰   r   r   r   Útest_failsWithDifferentMethod™  s   
ü
ÿz-DigestAuthTests.test_failsWithDifferentMethodc                 C   sl   |   t| jj| jdd�| j| jj¡}|  t	|ƒd¡ |   t| jj| jdd�| j| jj¡}|  t	|ƒd¡ dS )zš
        L{DigestCredentialFactory.decode} raises L{LoginFailed} if the response
        has no username field or if the username field is empty.
        N)r.   z$Invalid response, no username given.rd   ©
ÚassertRaisesr   r7   r|   ro   r6   r5   r{   r<   Ústr©r   Úer   r   r   Útest_noUsername¯  s    
û
ûzDigestAuthTests.test_noUsernamec                 C   s8   |   t| jj| jdd�| j| jj¡}|  t	|ƒd¡ dS )zo
        L{DigestCredentialFactory.decode} raises L{LoginFailed} if the response
        has no nonce.
        rW   )rv   z!Invalid response, no nonce given.Nr�   r�   r   r   r   Útest_noNonceÈ  s   
ûzDigestAuthTests.test_noNoncec                 C   s4   |   t| jj|  ¡ | j| jj¡}|  t	|ƒd¡ dS )zp
        L{DigestCredentialFactory.decode} raises L{LoginFailed} if the response
        has no opaque.
        z"Invalid response, no opaque given.Nr�   r�   r   r   r   Útest_noOpaqueÖ  s   ûzDigestAuthTests.test_noOpaquec                 C   s¼   | j  | jj¡}d}| j|d |  ||¡||d d�}| j  || j| jj¡}|  t	t
|ƒ¡ | jd | j d | j }t|ƒ}|  | t| ¡ ƒ¡¡ | d¡ |  | t| ¡ ƒ¡¡ dS )z¥
        L{DigestCredentialFactory.decode} returns an L{IUsernameDigestHash}
        provider which can verify a hash of the form 'username:realm:password'.
        ru   r?   rv   rˆ   r9   rx   N)r7   rz   r5   r{   ro   rt   r|   r6   r}   r   r   r.   r0   r/   r   Z	checkHashr   r;   Úupdater   )r   rr   rw   r€   r�   Z	cleartextÚhashr   r   r   Útest_checkHashä  s"   
üÿ
zDigestAuthTests.test_checkHashc                 C   s   t | j| jƒ}| | jj¡}|  t|jd|d | jj¡}|  	t
|ƒd¡ dtdƒ }|  t|j||d | jj¡}|  	t
|ƒd¡ |  t|jd|d | jj¡}|  	t
|ƒd¡ dtd |d t| jjƒdf¡ƒ }|  t|j||d | jj¡}|  	t
|ƒd	¡ d
S )z�
        L{DigestCredentialFactory.decode} raises L{LoginFailed} when the opaque
        value does not contain all the required parts.
        s	   badOpaquer?   z&Invalid response, invalid opaque values   foo-s   nonce,clientiprd   ó   ,r*   z,Invalid response, invalid opaque/time valuesN)r   r1   r0   rz   r5   r{   rŽ   r   Ú_verifyOpaquer<   r�   r   r:   r   )r   r7   rr   ÚexcZ	badOpaquer   r   r   Útest_invalidOpaqueþ  sP   ûûûÿÿûz"DigestAuthTests.test_invalidOpaquec                 C   s„   t | j| jƒ}| | jj¡}| d| jj¡}|  t|j	||d | jj¡}|  
t|ƒd¡ |  t|j	|d| jj¡}|  
t|ƒd¡ dS )z¨
        L{DigestCredentialFactory.decode} raises L{LoginFailed} when the given
        nonce from the response does not match the nonce encoded in the opaque.
        s
   1234567890r?   z2Invalid response, incompatible opaque/nonce valuesrd   N)r   r1   r0   rz   r5   r{   Ú_generateOpaquerŽ   r   r™   r<   r�   )r   r7   rr   ÚbadNonceOpaquerš   r   r   r   Útest_incompatibleNonce1  s*   ÿûûz&DigestAuthTests.test_incompatibleNoncec                 C   s`   t | j| jƒ}| | jj¡}d}|  | jj|¡ | |d |¡}|  t	|j
||d | jj¡ dS )z«
        L{DigestCredentialFactory.decode} raises L{LoginFailed} when the
        request comes from a client IP other than what is encoded in the
        opaque.
        z10.0.0.1r?   N)r   r1   r0   rz   r5   r{   ZassertNotEqualrœ   rŽ   r   r™   )r   r7   rr   Z
badAddressr�   r   r   r   Útest_incompatibleClientIPO  s   ÿûz)DigestAuthTests.test_incompatibleClientIPc                 C   sŠ   t | j| jƒ}| | jj¡}d |d t| jjƒdf¡}tt	||j
 ƒ ¡ ƒ}t|ƒ}d || d¡f¡}|  t|j||d | jj¡ dS )z¨
        L{DigestCredentialFactory.decode} raises L{LoginFailed} when the given
        opaque is older than C{DigestCredentialFactory.CHALLENGE_LIFETIME_SECS}
        r˜   r?   s
   -137876876ó   -ó   
N)r   r1   r0   rz   r5   r{   r:   r   r   r   r   r;   r   r   rŽ   r   r™   )r   r7   rr   Úkeyr;   ZekeyZoldNonceOpaquer   r   r   Útest_oldNonceh  s   ÿûzDigestAuthTests.test_oldNoncec                 C   s~   t | j| jƒ}| | jj¡}d |d t| jjƒdf¡}tt	|d ƒ 
¡ ƒ}d |t|ƒf¡}|  t|j||d | jj¡ dS )z~
        L{DigestCredentialFactory.decode} raises L{LoginFailed} when the opaque
        checksum fails verification.
        r˜   r?   r   s   this is not the right pkeyr    N)r   r1   r0   rz   r5   r{   r:   r   r   r   r;   r   rŽ   r   r™   )r   r7   rr   r¢   r;   ZbadChecksumr   r   r   Útest_mismatchedOpaqueChecksum€  s   ÿûz-DigestAuthTests.test_mismatchedOpaqueChecksumc                 C   s6   d}|D ]\}}}}| j ttd|||dd|d�	 qdS )z°
        L{calcHA1} raises L{TypeError} when any of the pszUsername, pszRealm,
        or pszPassword arguments are specified with the preHA1 keyword
        argument.
        ))s   useró   realmó   passwordó   preHA1)Nr¥   Nr§   )NNr¦   r§   r+   s   nonces   cnonce)ÚpreHA1N)rŽ   Ú	TypeErrorr   )r   Ú	argumentsZpszUsernameZpszRealmZpszPasswordr¨   r   r   r   Útest_incompatibleCalcHA1Options—  s   ÷ÿz/DigestAuthTests.test_incompatibleCalcHA1Optionsc                 C   s   | j  dd¡}|  d|¡ dS )z�
        L{DigestCredentialFactory._generateOpaque} returns a value without
        newlines, regardless of the length of the nonce.
        sn   long nonce long nonce long nonce long nonce long nonce long nonce long nonce long nonce long nonce long nonce Nr¡   )r7   rœ   ZassertNotIn)r   rv   r   r   r   Útest_noNewlineOpaque°  s   z$DigestAuthTests.test_noNewlineOpaqueN)T)*r$   r%   r&   r'   r8   r   rC   rF   rI   rN   rO   rQ   rS   rT   rV   r\   r]   r_   r`   ra   rb   ro   rt   r‚   rƒ   r„   r†   r‡   rŠ   r‹   rŒ   r’   r“   r”   r—   r›   rž   rŸ   r£   r¤   r«   r¬   r   r   r   r   r)   8   sN    !
(
		#3r)   )r'   r   Úbinasciir   Úhashlibr   r   Zzope.interface.verifyr   Ztwisted.cred.credentialsr   r   r   r	   r
   Ztwisted.cred.errorr   Ztwisted.internet.addressr   Ztwisted.python.compatr   Ztwisted.trial.unittestr   r   r   r)   r   r   r   r   Ú<module>   s   