§
    Ètºf¤]  ã                   óÄ   — 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„ Z G d„ de
¦  «        Z G 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                 óN   — t          j        | ¦  «                             ¦   «         S )N)Úbase64Ú	b64encodeÚstrip)Úss    ú`/var/www/surfInsights/venv3-11/lib/python3.11/site-packages/twisted/cred/test/test_digestauth.pyr   r      s   € ÝÔ˜AÑÔ×$Ò$Ñ&Ô&Ð&ó    c                   ó.   ‡ — e Zd ZdZˆ fd„Zd„ Zd„ Zˆ xZS )ÚFakeDigestCredentialFactoryz\
    A Fake Digest Credential Factory that generates a predictable
    nonce and opaque
    c                 óH   •—  t          ¦   «         j        |i |¤Ž d| _        d S )Nó   0)ÚsuperÚ__init__Ú
privateKey)ÚselfÚargsÚkwargsÚ	__class__s      €r   r   z$FakeDigestCredentialFactory.__init__'   s*   ø€ Ø�‰ŒÔ˜$Ð) &Ð)Ð)Ð)ØˆŒˆˆr   c                 ó   — dS )z)
        Generate a static nonce
        s   178288758716122392881254770685© ©r   s    r   Ú_generateNoncez*FakeDigestCredentialFactory._generateNonce+   s
   € ð 1Ð0r   c                 ó   — dS )z&
        Return a stable time
        r   r#   r$   s    r   Ú_getTimez$FakeDigestCredentialFactory._getTime1   s	   € ð ˆqr   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r%   r'   Ú__classcell__)r!   s   @r   r   r   !   s`   ø€ € € € € ðð ð
ð ð ð ð ð1ð 1ð 1ðð ð ð ð ð ð r   r   c                   ó  — e Zd ZdZd„ Zdefd„Zd„ Zd„ Zdefd„Z	defd„Z
d	„ Zd
„ Zd„ Zd„ Zdefd„Zd„ Zd„ Zdefd„Zd„ Zd„ Zd*d„Zd„ Zd*d„Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Z d „ Z!d!„ Z"d"„ Z#d#„ Z$d$„ Z%d%„ Z&d&„ Z'd'„ Z(d(„ Z)d)S )+Ú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                 óà   — 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/ÚTCPz10.2.3.4iu¨  ó   GETN)ÚusernameÚpasswordÚrealmÚ	algorithmÚcnonceÚqopÚurir   ÚclientAddressÚmethodr   ÚcredentialFactoryr$   s    r   ÚsetUpzDigestAuthTests.setUp?   sl   € ð "ˆŒØ"ˆŒØ"ˆŒ
ØˆŒØ9ˆŒØˆŒØˆŒÝ(¨°
¸EÑBÔBˆÔØˆŒÝ!8¸¼ÈÌÑ!TÔ!TˆÔÐÐr   r1   c                 ó(  — 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	   r5   r7   r6   r9   Újoinr   ÚdigestÚassertEqual)r   Ú
_algorithmÚ_hashÚnonceÚhashA1Úa1Úexpecteds          r   Útest_MD5HashA1zDigestAuthTests.test_MD5HashA1N   sŠ   € ð
 ˆÝØ˜œ t¤z°4´=À%ÈÌñ
ô 
ˆð �YŠY˜œ t¤z°4´=ÐAÑBÔBˆÝ˜5˜5 ™9œ9×+Ò+Ñ-Ô-Ñ.Ô.ˆØ×Ò˜ Ñ*Ô*Ð*Ð*Ð*r   c                 óž  — d}t          d| j        | j        | j        || j        ¦  «        }| j        dz   | j        z   dz   | j        z   }t          t          |¦  «                             ¦   «         ¦  «        }|dz   |z   dz   | j        z   }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-sessrA   N)	r	   r5   r7   r6   r9   r   r   rC   rD   )r   rG   rH   rI   Úha1rJ   s         r   Útest_MD5SessionHashA1z%DigestAuthTests.test_MD5SessionHashA1[   s¾   € ð
 ˆÝØ˜œ¨¬
°D´MÀ5È$Ì+ñ
ô 
ˆð Œ]˜TÑ! D¤JÑ.°Ñ5¸¼ÑEˆÝ•c˜"‘g”g—n’nÑ&Ô&Ñ'Ô'ˆØ�4‰Z˜%Ñ $Ñ&¨¬Ñ4ˆÝ�3˜r™7œ7Ÿ>š>Ñ+Ô+Ñ,Ô,ˆØ×Ò˜ Ñ*Ô*Ð*Ð*Ð*r   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)rK   r   r$   s    r   Útest_SHAHashA1zDigestAuthTests.test_SHAHashA1j   s    € ð
 	×Ò˜F¥DÑ)Ô)Ð)Ð)Ð)r   c                 óÔ   — d}t          ||| j        dd¦  «        }|dz   | j        z   }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'}.
        r4   r2   NrA   ©r
   r;   r   rC   rD   )r   rE   rF   r=   ÚhashA2Úa2rJ   s          r   Útest_MD5HashA2Authz"DigestAuthTests.test_MD5HashA2Authq   sm   € ð ˆÝ˜ V¨T¬X°wÀÑEÔEˆØ�d‰]˜TœXÑ%ˆÝ˜5˜5 ™9œ9×+Ò+Ñ-Ô-Ñ.Ô.ˆØ×Ò˜ Ñ*Ô*Ð*Ð*Ð*r   c                 óä   — d}d}t          ||| j        d|¦  «        }|dz   | j        z   dz   |z   }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'}.
        r4   s	   foobarbazs   auth-intrA   NrT   )r   rE   rF   r=   ÚhentityrU   rV   rJ   s           r   Útest_MD5HashA2AuthIntz%DigestAuthTests.test_MD5HashA2AuthInt}   s|   € ð
 ˆØˆÝ˜ V¨T¬X°{ÀGÑLÔLˆØ�d‰]˜TœXÑ%¨Ñ,¨wÑ6ˆÝ˜5˜5 ™9œ9×+Ò+Ñ-Ô-Ñ.Ô.ˆØ×Ò˜ Ñ*Ô*Ð*Ð*Ð*r   c                 ó0   — |                       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.
        rM   N)rW   r$   s    r   Útest_MD5SessHashA2Authz&DigestAuthTests.test_MD5SessHashA2Auth‰   s   € ð
 	×Ò Ñ,Ô,Ð,Ð,Ð,r   c                 ó0   — |                       d¦  «         dS )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.
        rM   N)rZ   r$   s    r   Útest_MD5SessHashA2AuthIntz)DigestAuthTests.test_MD5SessHashA2AuthInt�   s   € ð
 	×"Ò" ;Ñ/Ô/Ð/Ð/Ð/r   c                 ó<   — |                       dt          ¦  «         dS )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'}.
        rQ   N)rW   r   r$   s    r   Útest_SHAHashA2Authz"DigestAuthTests.test_SHAHashA2Auth—   s    € ð 	×Ò ­Ñ-Ô-Ð-Ð-Ð-r   c                 ó<   — |                       dt          ¦  «         dS )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'}.
        rQ   N)rZ   r   r$   s    r   Útest_SHAHashA2AuthIntz%DigestAuthTests.test_SHAHashA2AuthIntŸ   s    € ð
 	×"Ò" 6­4Ñ0Ô0Ð0Ð0Ð0r   c           	      óØ   — d}d}d}|dz   |z   dz   |z   }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ó   lmnopqrA   N©r   rC   r   rD   )	r   rE   rF   rH   rU   rG   ÚresponserJ   rC   s	            r   Útest_MD5HashResponsez$DigestAuthTests.test_MD5HashResponse¦   s�   € ð ˆØˆØˆà˜D‘= 5Ñ(¨4Ñ/°&Ñ8ˆÝ˜5˜5 ™?œ?×1Ò1Ñ3Ô3Ñ4Ô4ˆå˜f f¨j¸%ÀÀtÈTÑRÔRˆØ×Ò˜ 6Ñ*Ô*Ð*Ð*Ð*r   c                 ó0   — |                       d¦  «         dS )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}
        rM   N)ri   r$   s    r   Útest_MD5SessionHashResponsez+DigestAuthTests.test_MD5SessionHashResponse¶   s   € ð 	×!Ò! +Ñ.Ô.Ð.Ð.Ð.r   c                 ó<   — |                       dt          ¦  «         dS )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}
        rQ   N)ri   r   r$   s    r   Útest_SHAHashResponsez$DigestAuthTests.test_SHAHashResponse¾   s    € ð 	×!Ò! &­$Ñ/Ô/Ð/Ð/Ð/r   c           	      ó  — d}d}d}d}d}d}|dz   |z   dz   |z   dz   |z   dz   |z   dz   |z   }	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.
        rd   re   rf   s   00000004s	   abcxyz123r2   rA   Nrg   )r   rE   rF   rH   rU   rG   Ú
nonceCountÚclientNoncer:   rh   rJ   rC   s               r   Útest_MD5HashResponseExtraz)DigestAuthTests.test_MD5HashResponseExtraÆ   së   € ð ˆØˆØˆØ ˆ
Ø"ˆØˆð Øñàñð ñð ñ	ð
 ñð ñð ñð ñð ñ	ð ñ
ð 	õ ˜5˜5 ™?œ?×1Ò1Ñ3Ô3Ñ4Ô4ˆåØ�F˜J¨¨z¸;Èñ
ô 
ˆð 	×Ò˜ 6Ñ*Ô*Ð*Ð*Ð*r   c                 ó0   — |                       d¦  «         dS )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.
        rM   N)rq   r$   s    r   Ú test_MD5SessionHashResponseExtraz0DigestAuthTests.test_MD5SessionHashResponseExtraç   s   € ð 	×&Ò& {Ñ3Ô3Ð3Ð3Ð3r   c                 ó<   — |                       dt          ¦  «         dS )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.
        rQ   N)rq   r   r$   s    r   Útest_SHAHashResponseExtraz)DigestAuthTests.test_SHAHashResponseExtraï   s    € ð 	×&Ò& v­tÑ4Ô4Ð4Ð4Ð4r   Tc                 ó   ‡— 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r
| j        |d<   |rdŠndŠd	                     ˆf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.
        r5   r7   r8   r:   r9   r;   ó   "r   s   , c           	      óh   •— g | ].\  }}|®d                      t          |¦  «        d‰|‰f¦  «        ‘Œ/S )Nr   ó   =)rB   r   )Ú.0ÚkÚvÚquotes      €r   ú
<listcomp>z2DigestAuthTests.formatResponse.<locals>.<listcomp>  sI   ø€ ð ð ð á�Q˜Ø�=ð —’�-¨Ñ*Ô*¨D°%¸¸EÐBÑCÔCà �=�=r   )r5   r7   r8   r:   r9   r;   rB   Úitems)r   ÚquotesÚkwr}   s      @r   ÚformatResponsezDigestAuthTests.formatResponse÷   sÝ   ø€ ð ˜RÐÐØ!œ]ˆBˆz‰NØ˜"ÐÐØœ*ˆBˆw‰KØ˜bÐ Ð Ø"œnˆBˆ{‰OØ˜ˆ?ˆ?ØœˆBˆu‰IØ˜2ÐÐØœ;ˆBˆx‰LØ˜ˆ?ˆ?ØœˆBˆu‰IØð 	ØˆEˆEàˆEà�zŠzðð ð ð à Ÿhšh™jœjðñ ô ñ
ô 
ð 	
r   c           	      ó\  — |                      d¦  «        }|                      d¦  «                             ¦   «         }|                      d¦  «        }t          || j        | j        | j        || j        ¦  «        }t          |d| j        |d¦  «        }t          |||||| j        |¦  «        }|S )z@
        Calculate the response for the given challenge
        rG   r8   r:   r4   N)
ÚgetÚlowerr	   r5   r7   r6   r9   r
   r;   r   )	r   Ú	challengeÚncountrG   Úalgor:   rN   Úha2rJ   s	            r   ÚgetDigestResponsez!DigestAuthTests.getDigestResponse  s    € ð —’˜gÑ&Ô&ˆØ�}Š}˜[Ñ)Ô)×/Ò/Ñ1Ô1ˆØ�mŠm˜EÑ"Ô"ˆåØ�$”- ¤¨T¬]¸EÀ4Ä;ñ
ô 
ˆõ �d˜F D¤H¨c°4Ñ8Ô8ˆÝ  S¨$°°v¸t¼{ÈCÑPÔPˆØˆr   c                 óÖ  — | j                              | j        j        ¦  «        }d}|                      ||d         |                      ||¦  «        ||d         ¬¦  «        }| j                              || j        | j        j        ¦  «        }|                      | 	                    | j
        ¦  «        ¦  «         |                      | 	                    | j
        dz   ¦  «        ¦  «         dS )zš
        L{DigestCredentialFactory.decode} accepts a digest challenge response
        and parses it into an L{IUsernameHashedPassword} provider.
        ó   00000001rG   Úopaque)r€   rG   rh   Úncr�   ó   wrongN©r>   ÚgetChallenger<   Úhostr‚   rŠ   Údecoder=   Ú
assertTrueÚcheckPasswordr6   ÚassertFalse)r   r€   r†   rŽ   ÚclientResponseÚcredss         r   Útest_responsezDigestAuthTests.test_response.  sä   € ð
 Ô*×7Ò7¸Ô8JÔ8OÑPÔPˆ	àˆØ×,Ò,ØØ˜GÔ$Ø×+Ò+¨I°rÑ:Ô:ØØ˜XÔ&ð -ñ 
ô 
ˆð Ô&×-Ò-Ø˜DœK¨Ô);Ô)@ñ
ô 
ˆð 	�Š˜×+Ò+¨D¬MÑ:Ô:Ñ;Ô;Ð;Ø×Ò˜×,Ò,¨T¬]¸XÑ-EÑFÔFÑGÔGÐGÐGÐGr   c                 ó0   — |                       d¦  «         dS )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$   s    r   Útest_responseWithoutQuotesz*DigestAuthTests.test_responseWithoutQuotesC  s   € ð 	×Ò˜5Ñ!Ô!Ð!Ð!Ð!r   c                 ó>   — 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)r;   r™   r$   s    r   Útest_responseWithCommaURIz)DigestAuthTests.test_responseWithCommaURIL  s%   € ð "ˆŒØ×Ò˜4Ñ Ô Ð Ð Ð r   c                 ó<   — d| _         |                      ¦   «          dS )zs
        The case of the algorithm value in the response is ignored when
        checking the credentials.
        s   MD5N©r8   r™   r$   s    r   Útest_caseInsensitiveAlgorithmz-DigestAuthTests.test_caseInsensitiveAlgorithmU  s#   € ð
  ˆŒØ×ÒÑÔÐÐÐr   c                 ó<   — d| _         |                      ¦   «          dS )zV
        The algorithm defaults to MD5 if it is not supplied in the response.
        NrŸ   r$   s    r   Útest_md5DefaultAlgorithmz(DigestAuthTests.test_md5DefaultAlgorithm]  s#   € ð ˆŒØ×ÒÑÔÐÐÐr   c                 ó¬  — | j                              d¦  «        }d}|                      |d         |                      ||¦  «        ||d         ¬¦  «        }| j                              || j        d¦  «        }|                      |                     | j        ¦  «        ¦  «         |  	                    |                     | j        dz   ¦  «        ¦  «         dS )z“
        L{DigestCredentialFactory.decode} accepts a digest challenge response
        even if the client address it is passed is L{None}.
        NrŒ   rG   r�   ©rG   rh   rŽ   r�   r�   )
r>   r‘   r‚   rŠ   r“   r=   r”   r•   r6   r–   ©r   r†   rŽ   r—   r˜   s        r   Útest_responseWithoutClientIPz,DigestAuthTests.test_responseWithoutClientIPd  sÎ   € ð
 Ô*×7Ò7¸Ñ=Ô=ˆ	àˆØ×,Ò,Ø˜GÔ$Ø×+Ò+¨I°rÑ:Ô:ØØ˜XÔ&ð	 -ñ 
ô 
ˆð Ô&×-Ò-¨n¸d¼kÈ4ÑPÔPˆØ�Š˜×+Ò+¨D¬MÑ:Ô:Ñ;Ô;Ð;Ø×Ò˜×,Ò,¨T¬]¸XÑ-EÑFÔFÑGÔGÐGÐGÐGr   c                 óZ  — | j                              | j        j        ¦  «        }d}|                      |d         |                      ||¦  «        ||d         ¬¦  «        }| j                              || j        | j        j        ¦  «        }|                      | 	                    | j
        ¦  «        ¦  «         |                      | 	                    | j
        dz   ¦  «        ¦  «         d}|                      |d         |                      ||¦  «        ||d         ¬¦  «        }| j                              || j        | j        j        ¦  «        }|                      | 	                    | j
        ¦  «        ¦  «         |                      | 	                    | j
        dz   ¦  «        ¦  «         dS )zm
        L{DigestCredentialFactory.decode} handles multiple responses to a
        single challenge.
        rŒ   rG   r�   r¤   r�   s   00000002Nr�   r¥   s        r   Útest_multiResponsez"DigestAuthTests.test_multiResponsev  sœ  € ð
 Ô*×7Ò7¸Ô8JÔ8OÑPÔPˆ	àˆØ×,Ò,Ø˜GÔ$Ø×+Ò+¨I°rÑ:Ô:ØØ˜XÔ&ð	 -ñ 
ô 
ˆð Ô&×-Ò-Ø˜DœK¨Ô);Ô)@ñ
ô 
ˆð 	�Š˜×+Ò+¨D¬MÑ:Ô:Ñ;Ô;Ð;Ø×Ò˜×,Ò,¨T¬]¸XÑ-EÑFÔFÑGÔGÐGàˆØ×,Ò,Ø˜GÔ$Ø×+Ò+¨I°rÑ:Ô:ØØ˜XÔ&ð	 -ñ 
ô 
ˆð Ô&×-Ò-Ø˜DœK¨Ô);Ô)@ñ
ô 
ˆð 	�Š˜×+Ò+¨D¬MÑ:Ô:Ñ;Ô;Ð;Ø×Ò˜×,Ò,¨T¬]¸XÑ-EÑFÔFÑGÔGÐGÐGÐGr   c                 óÊ  — | j                              | j        j        ¦  «        }d}|                      |d         |                      ||¦  «        ||d         ¬¦  «        }| j                              |d| j        j        ¦  «        }|                      |                     | j	        ¦  «        ¦  «         |                      |                     | j	        dz   ¦  «        ¦  «         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.
        rŒ   rG   r�   r¤   s   POSTr�   N)
r>   r‘   r<   r’   r‚   rŠ   r“   r–   r•   r6   r¥   s        r   Útest_failsWithDifferentMethodz-DigestAuthTests.test_failsWithDifferentMethod™  sá   € ð Ô*×7Ò7¸Ô8JÔ8OÑPÔPˆ	àˆØ×,Ò,Ø˜GÔ$Ø×+Ò+¨I°rÑ:Ô:ØØ˜XÔ&ð	 -ñ 
ô 
ˆð Ô&×-Ò-Ø˜G TÔ%7Ô%<ñ
ô 
ˆð 	×Ò˜×,Ò,¨T¬]Ñ;Ô;Ñ<Ô<Ð<Ø×Ò˜×,Ò,¨T¬]¸XÑ-EÑFÔFÑGÔGÐGÐGÐGr   c                 ó¾  — |                       t          | j        j        |                      d¬¦  «        | j        | j        j        ¦  «        }|                      t          |¦  «        d¦  «         |                       t          | j        j        |                      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)r5   z$Invalid response, no username given.r   ©
ÚassertRaisesr   r>   r“   r‚   r=   r<   r’   rD   Ústr©r   Úes     r   Útest_noUsernamezDigestAuthTests.test_noUsername¯  sÐ   € ð ×ÒÝØÔ"Ô)Ø×Ò¨ÐÑ.Ô.ØŒKØÔÔ#ñ
ô 
ˆð 	×Ò�˜Q™œÐ!GÑHÔHÐHð ×ÒÝØÔ"Ô)Ø×Ò¨ÐÑ-Ô-ØŒKØÔÔ#ñ
ô 
ˆð 	×Ò�˜Q™œÐ!GÑHÔHÐHÐHÐHr   c                 óâ   — |                       t          | j        j        |                      d¬¦  «        | j        | j        j        ¦  «        }|                      t          |¦  «        d¦  «         dS )zo
        L{DigestCredentialFactory.decode} raises L{LoginFailed} if the response
        has no nonce.
        rd   )r�   z!Invalid response, no nonce given.Nr¬   r¯   s     r   Útest_noNoncezDigestAuthTests.test_noNonceÈ  sl   € ð
 ×ÒÝØÔ"Ô)Ø×Ò yÐÑ1Ô1ØŒKØÔÔ#ñ
ô 
ˆð 	×Ò�˜Q™œÐ!DÑEÔEÐEÐEÐEr   c                 óÞ   — |                       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¯   s     r   Útest_noOpaquezDigestAuthTests.test_noOpaqueÖ  sg   € ð
 ×ÒÝØÔ"Ô)Ø×ÒÑ!Ô!ØŒKØÔÔ#ñ
ô 
ˆð 	×Ò�˜Q™œÐ!EÑFÔFÐFÐFÐFr   c                 ó  — | j                              | j        j        ¦  «        }d}|                      |d         |                      ||¦  «        ||d         ¬¦  «        }| j                              || j        | j        j        ¦  «        }|                      t          t          |¦  «        ¦  «         | j        dz   | j        z   dz   | j        z   }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'.
        rŒ   rG   r�   r¤   rA   r�   N)r>   r‘   r<   r’   r‚   rŠ   r“   r=   r”   r   r   r5   r7   r6   r   Ú	checkHashr   rC   Úupdater–   )r   r†   rŽ   r—   r˜   Ú	cleartextÚhashs          r   Útest_checkHashzDigestAuthTests.test_checkHashä  sM  € ð
 Ô*×7Ò7¸Ô8JÔ8OÑPÔPˆ	àˆØ×,Ò,Ø˜GÔ$Ø×+Ò+¨I°rÑ:Ô:ØØ˜XÔ&ð	 -ñ 
ô 
ˆð Ô&×-Ò-Ø˜DœK¨Ô);Ô)@ñ
ô 
ˆð 	�Š�Õ%8¸%Ñ@Ô@ÑAÔAÐAà”M DÑ(¨4¬:Ñ5¸Ñ<¸t¼}ÑLˆ	Ý�9‰~Œ~ˆØ�Š˜Ÿš­°·²±´Ñ(>Ô(>Ñ?Ô?Ñ@Ô@Ð@Ø�Š�HÑÔÐØ×Ò˜Ÿš­°·²±´Ñ)?Ô)?Ñ@Ô@ÑAÔAÐAÐAÐAr   c           	      óÖ  — t          | j        | j        ¦  «        }|                     | j        j        ¦  «        }|                      t          |j        d|d         | j        j        ¦  «        }|  	                    t          |¦  «        d¦  «         dt          d¦  «        z   }|                      t          |j        ||d         | j        j        ¦  «        }|  	                    t          |¦  «        d¦  «         |                      t          |j        d|d         | j        j        ¦  «        }|  	                    t          |¦  «        d¦  «         dt          d                     |d         t          | j        j        ¦  «        df¦  «        ¦  «        z   }|                      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	   badOpaquerG   z&Invalid response, invalid opaque values   foo-s   nonce,clientipr   ó   ,r0   z,Invalid response, invalid opaque/time valuesN)r   r8   r7   r‘   r<   r’   r­   r   Ú_verifyOpaquerD   r®   r   rB   r   )r   r>   r†   ÚexcÚ	badOpaques        r   Útest_invalidOpaquez"DigestAuthTests.test_invalidOpaqueþ  sÔ  € õ
 8¸¼ÈÌ
ÑSÔSÐØ%×2Ò2°4Ô3EÔ3JÑKÔKˆ	à×ÒÝØÔ+ØØ�gÔØÔÔ#ñ
ô 
ˆð 	×Ò�˜S™œÐ#KÑLÔLÐLà�iÐ(9Ñ:Ô:Ñ:ˆ	à×ÒÝØÔ+ØØ�gÔØÔÔ#ñ
ô 
ˆð 	×Ò�˜S™œÐ#KÑLÔLÐLà×ÒÝØÔ+ØØ�gÔØÔÔ#ñ
ô 
ˆð 	×Ò�˜S™œÐ#KÑLÔLÐLà�iØ�IŠIØ˜7Ô#¥]°4Ô3EÔ3JÑ%KÔ%KÈYÐWñô ñ
ô 
ñ 
ˆ	ð
 ×ÒÝØÔ+ØØ�gÔØÔÔ#ñ
ô 
ˆð 	×Ò�˜S™œÐ#QÑRÔRÐRÐRÐRr   c                 ó  — 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
   1234567890rG   z2Invalid response, incompatible opaque/nonce valuesr   N)r   r8   r7   r‘   r<   r’   Ú_generateOpaquer­   r   r¾   rD   r®   )r   r>   r†   ÚbadNonceOpaquer¿   s        r   Útest_incompatibleNoncez&DigestAuthTests.test_incompatibleNonce1  sö   € õ
 8¸¼ÈÌ
ÑSÔSÐØ%×2Ò2°4Ô3EÔ3JÑKÔKˆ	à*×:Ò:Ø˜4Ô-Ô2ñ
ô 
ˆð ×ÒÝØÔ+ØØ�gÔØÔÔ#ñ
ô 
ˆð 	×Ò�˜S™œÐ#WÑXÔXÐXà×ÒÝØÔ+ØØØÔÔ#ñ
ô 
ˆð 	×Ò�˜S™œÐ#WÑXÔXÐXÐXÐXr   c                 óZ  — 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.1rG   N)r   r8   r7   r‘   r<   r’   ÚassertNotEqualrÃ   r­   r   r¾   )r   r>   r†   Ú
badAddressrÄ   s        r   Útest_incompatibleClientIPz)DigestAuthTests.test_incompatibleClientIPO  s²   € õ 8¸¼ÈÌ
ÑSÔSÐØ%×2Ò2°4Ô3EÔ3JÑKÔKˆ	àˆ
à×Ò˜DÔ.Ô3°ZÑ@Ô@Ð@à*×:Ò:Ø�gÔ 
ñ
ô 
ˆð 	×ÒÝØÔ+ØØ�gÔØÔÔ#ñ	
ô 	
ð 	
ð 	
ð 	
r   c                 ó&  — t          | j        | j        ¦  «        }|                     | j        j        ¦  «        }d                     |d         t          | j        j        ¦  «        df¦  «        }t          t          ||j
        z   ¦  «                             ¦   «         ¦  «        }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½   rG   s
   -137876876ó   -ó   
N)r   r8   r7   r‘   r<   r’   rB   r   r   r   r   rC   r   r   r­   r   r¾   )r   r>   r†   ÚkeyrC   ÚekeyÚoldNonceOpaques          r   Útest_oldNoncezDigestAuthTests.test_oldNonceh  sù   € õ
 8¸¼ÈÌ
ÑSÔSÐØ%×2Ò2°4Ô3EÔ3JÑKÔKˆ	à�iŠiØ�wÔ¥¨tÔ/AÔ/FÑ!GÔ!GÈÐWñ
ô 
ˆõ �˜SÐ#4Ô#?Ñ?Ñ@Ô@×GÒGÑIÔIÑJÔJˆÝ˜‰~Œ~ˆàŸš F¨D¯JªJ°uÑ,=Ô,=Ð#>Ñ?Ô?ˆà×ÒÝØÔ+ØØ�gÔØÔÔ#ñ	
ô 	
ð 	
ð 	
ð 	
r   c                 óò  — t          | j        | j        ¦  «        }|                     | j        j        ¦  «        }d                     |d         t          | j        j        ¦  «        df¦  «        }t          t          |dz   ¦  «         
                    ¦   «         ¦  «        }d                     |t          |¦  «        f¦  «        }|                      t          |j        ||d         | j        j        ¦  «         dS )z~
        L{DigestCredentialFactory.decode} raises L{LoginFailed} when the opaque
        checksum fails verification.
        r½   rG   r   s   this is not the right pkeyrË   N)r   r8   r7   r‘   r<   r’   rB   r   r   r   rC   r   r­   r   r¾   )r   r>   r†   rÍ   rC   ÚbadChecksums         r   Útest_mismatchedOpaqueChecksumz-DigestAuthTests.test_mismatchedOpaqueChecksum€  så   € õ
 8¸¼ÈÌ
ÑSÔSÐØ%×2Ò2°4Ô3EÔ3JÑKÔKˆ	à�iŠiØ�wÔ¥¨tÔ/AÔ/FÑ!GÔ!GÈÐNñ
ô 
ˆõ �˜SÐ#@Ñ@ÑAÔA×HÒHÑJÔJÑKÔKˆØ—i’i ­°3©¬Ð 8Ñ9Ô9ˆà×ÒÝØÔ+ØØ�gÔØÔÔ#ñ	
ô 	
ð 	
ð 	
ð 	
r   c                 ón   — d}|D ]/\  }}}}|                       t          t          d|||dd|¬¦	  «	         Œ0d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×   r1   s   nonces   cnonce)ÚpreHA1N)r­   Ú	TypeErrorr	   )r   Ú	argumentsÚpszUsernameÚpszRealmÚpszPasswordrØ   s         r   Útest_incompatibleCalcHA1Optionsz/DigestAuthTests.test_incompatibleCalcHA1Options—  sk   € ð
ˆ	ð ;Dð 	ð 	Ñ6ˆK˜ ;°Ø×ÒÝÝØØØØØØØð ñ 
ô 
ð 
ð 
ð	ð 	r   c                 óh   — | 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Ì   )r>   rÃ   ÚassertNotIn)r   r�   s     r   Útest_noNewlineOpaquez$DigestAuthTests.test_noNewlineOpaque°  s9   € ð
 Ô'×7Ò7Ð8KÈTÑRÔRˆØ×Ò˜ Ñ'Ô'Ð'Ð'Ð'r   N)T)*r(   r)   r*   r+   r?   r   rK   rO   rR   rW   rZ   r\   r^   r`   rb   ri   rk   rm   rq   rs   ru   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.   8   sµ  € € € € € ðð ðUð Uð Uð )/°cð +ð +ð +ð +ð+ð +ð +ð*ð *ð *ð -3¸#ð 
+ð 
+ð 
+ð 
+ð 06¸Sð 
+ð 
+ð 
+ð 
+ð-ð -ð -ð0ð 0ð 0ð.ð .ð .ð1ð 1ð 1ð /5¸Cð +ð +ð +ð +ð /ð /ð /ð0ð 0ð 0ð 4:Àð +ð +ð +ð +ðB4ð 4ð 4ð5ð 5ð 5ð&
ð &
ð &
ð &
ðPð ð ðHð Hð Hð Hð*"ð "ð "ð!ð !ð !ðð ð ðð ð ðHð Hð Hð$!Hð !Hð !HðFHð Hð Hð,Ið Ið Ið2Fð Fð FðGð Gð GðBð Bð Bð41Sð 1Sð 1SðfYð Yð Yð<
ð 
ð 
ð2
ð 
ð 
ð0
ð 
ð 
ð.ð ð ð2(ð (ð (ð (ð (r   r.   )r+   r   Úbinasciir   Úhashlibr   r   Úzope.interface.verifyr   Útwisted.cred.credentialsr   r   r	   r
   r   Útwisted.cred.errorr   Útwisted.internet.addressr   Útwisted.python.compatr   Útwisted.trial.unittestr   r   r   r.   r#   r   r   ú<module>rê      s^  ððð ð €€€Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ð Ð à .Ð .Ð .Ð .Ð .Ð .ðð ð ð ð ð ð ð ð ð ð ð ð ð ð +Ð *Ð *Ð *Ð *Ð *Ø 0Ð 0Ð 0Ð 0Ð 0Ð 0Ø /Ð /Ð /Ð /Ð /Ð /Ø +Ð +Ð +Ð +Ð +Ð +ð'ð 'ð 'ðð ð ð ð Ð"9ñ ô ð ð.~	(ð ~	(ð ~	(ð ~	(ð ~	(�hñ ~	(ô ~	(ð ~	(ð ~	(ð ~	(r   