Ë
    oj¤]  ã                   ó¶   — 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y)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                 óH   — t        j                  | «      j                  «       S )N)Úbase64Ú	b64encodeÚstrip)Úss    úC/usr/lib/python3/dist-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                 ó2   •— t        ‰| �  |i |¤Ž d| _        y )Nó   0)ÚsuperÚ__init__Ú
privateKey)ÚselfÚargsÚkwargsÚ	__class__s      €r   r   z$FakeDigestCredentialFactory.__init__'   s   ø€ Ü‰Ñ˜$Ð) &Ò)Øˆ�r   c                  ó   — y)z)
        Generate a static nonce
        s   178288758716122392881254770685© ©r   s    r   Ú_generateNoncez*FakeDigestCredentialFactory._generateNonce+   s   € ð 1r   c                  ó   — y)z&
        Return a stable time
        r   r#   r$   s    r   Ú_getTimez$FakeDigestCredentialFactory._getTime1   s   € ð r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r%   r'   Ú__classcell__)r!   s   @r   r   r   !   s   ø„ ñô
ò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)y()*Ú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                  «      | _        y)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?   sd   € ð "ˆŒØ"ˆŒØ"ˆŒ
ØˆŒØ9ˆŒØˆŒØˆŒÜ(¨°
¸EÓBˆÔØˆŒÜ!8¸¿¹ÈÏÉÓ!TˆÕr   r1   c                 ó>  — d}t        || j                  | j                  | j                  || j                  «      }dj                  | j                  | j                  | j                  f«      }t         ||«      j                  «       «      }| j                  ||«       y)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   sz   € ð
 ˆÜØ˜Ÿ™ t§z¡z°4·=±=À%ÈÏÉó
ˆð �Y‰Y˜Ÿ™ t§z¡z°4·=±=ÐAÓBˆÜ™5 ›9×+Ñ+Ó-Ó.ˆØ×Ñ˜ Õ*r   c                 ó¬  — d}t        d| j                  | j                  | j                  || j                  «      }| j                  dz   | j                  z   dz   | j                  z   }t        t        |«      j                  «       «      }|dz   |z   dz   | j                  z   }t        t        |«      j                  «       «      }| j                  ||«       y)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±MÀ5È$Ï+É+ó
ˆð �]‰]˜TÑ! D§J¡JÑ.°Ñ5¸¿¹ÑEˆÜ”c˜"“g—n‘nÓ&Ó'ˆØ�4‰Z˜%Ñ $Ñ&¨¯©Ñ4ˆÜœ3˜r›7Ÿ>™>Ó+Ó,ˆØ×Ñ˜ Õ*r   c                 ó0   — | j                  dt        «       y)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         ||«      j                  «       «      }| j	                  ||«       y)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   sX   € ð ˆÜ˜ V¨T¯X©X°wÀÓEˆØ�d‰]˜TŸX™XÑ%ˆÜ™5 ›9×+Ñ+Ó-Ó.ˆØ×Ñ˜ Õ*r   c                 óÐ   — d}d}t        ||| j                  d|«      }|dz   | j                  z   dz   |z   }t         ||«      j                  «       «      }| j	                  ||«       y)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}   sg   € ð
 ˆØˆÜ˜ V¨T¯X©X°{ÀGÓLˆØ�d‰]˜TŸX™XÑ%¨Ñ,¨wÑ6ˆÜ™5 ›9×+Ñ+Ó-Ó.ˆØ×Ñ˜ Õ*r   c                 ó&   — | j                  d«       y)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                 ó&   — | j                  d«       y)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                 ó0   — | j                  dt        «       y)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                 ó0   — | j                  dt        «       y)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Õ0r   c           	      ó°   — d}d}d}|dz   |z   dz   |z   }t         ||«      j                  «       «      }t        ||||ddd«      }| j                  ||«       y)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¦   sh   € ð ˆØˆØˆà˜D‘= 5Ñ(¨4Ñ/°&Ñ8ˆÜ™5 ›?×1Ñ1Ó3Ó4ˆä˜f f¨j¸%ÀÀtÈTÓRˆØ×Ñ˜ 6Õ*r   c                 ó&   — | j                  d«       y)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                 ó0   — | j                  dt        «       y)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         ||	«      j                  «       «      }
t        |||||||«      }| j                  |
|«       y)	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 ›?×1Ñ1Ó3Ó4ˆäØ�F˜J¨¨z¸;Èó
ˆð 	×Ñ˜ 6Õ*r   c                 ó&   — | j                  d«       y)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   € ð 	×&Ñ& {Õ3r   c                 ó0   — | j                  dt        «       y)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Õ4r   c                 ó¢  — 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	j                  |j                  «       D ��cg c]&  \  }}|�dj                  t        |«      d
|||f«      ‘Œ( c}}«      S c c}}w )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   , ó   =)	r5   r7   r8   r:   r9   r;   rB   Úitemsr   )r   ÚquotesÚkwÚquoteÚkÚvs         r   ÚformatResponsezDigestAuthTests.formatResponse÷   sã   € ð ˜RÑØ!Ÿ]™]ˆBˆz‰NØ˜"ÑØŸ*™*ˆBˆw‰KØ˜bÑ Ø"Ÿn™nˆBˆ{‰OØ˜‰?ØŸ™ˆBˆu‰IØ˜2ÑØŸ;™;ˆBˆx‰LØ˜‰?ØŸ™ˆBˆu‰IÙØ‰EàˆEà�z‰zð !Ÿh™h›j÷á�Q˜Ø�=ð —‘œ-¨Ó*¨D°%¸¸EÐBÕCóó
ð 	
ùós   Â+C
c           	      ó`  — |j                  d«      }|j                  d«      j                  «       }|j                  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ˆØ�m‰m˜EÓ"ˆäØ�$—-‘- §¡¨T¯]©]¸EÀ4Ç;Á;ó
ˆô �d˜F D§H¡H¨c°4Ó8ˆÜ  S¨$°°v¸t¿{¹{ÈCÓPˆØˆr   c                 óâ  — | j                   j                  | j                  j                  «      }d}| j	                  ||d   | j                  ||«      ||d   ¬«      }| j                   j                  || j                  | j                  j                  «      }| j                  |j                  | j                  «      «       | j                  |j                  | j                  dz   «      «       y)zš
        L{DigestCredentialFactory.decode} accepts a digest challenge response
        and parses it into an L{IUsernameHashedPassword} provider.
        ó   00000001rG   Úopaque)rz   rG   rh   ÚncrŠ   ó   wrongN©r>   ÚgetChallenger<   Úhostr   r‡   Údecoder=   Ú
assertTrueÚcheckPasswordr6   ÚassertFalse)r   rz   rƒ   r‹   ÚclientResponseÚcredss         r   Útest_responsezDigestAuthTests.test_response.  sÔ   € ð
 ×*Ñ*×7Ñ7¸×8JÑ8J×8OÑ8OÓPˆ	àˆØ×,Ñ,ØØ˜GÑ$Ø×+Ñ+¨I°rÓ:ØØ˜XÑ&ð -ó 
ˆð ×&Ñ&×-Ñ-Ø˜DŸK™K¨×);Ñ);×)@Ñ)@ó
ˆð 	�‰˜×+Ñ+¨D¯M©MÓ:Ô;Ø×Ñ˜×,Ñ,¨T¯]©]¸XÑ-EÓFÕGr   c                 ó&   — | j                  d«       y)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                 ó4   — d| _         | j                  d«       y)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                 ó2   — d| _         | j                  «        y)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                 ó2   — d| _         | j                  «        y)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                   j                  d«      }d}| j                  |d   | j                  ||«      ||d   ¬«      }| j                   j	                  || j
                  d«      }| j                  |j                  | j                  «      «       | j                  |j                  | j                  dz   «      «       y)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¹kÈ4ÓPˆØ�‰˜×+Ñ+¨D¯M©MÓ:Ô;Ø×Ñ˜×,Ñ,¨T¯]©]¸XÑ-EÓFÕGr   c                 ó^  — | j                   j                  | j                  j                  «      }d}| j	                  |d   | j                  ||«      ||d   ¬«      }| j                   j                  || j                  | j                  j                  «      }| j                  |j                  | j                  «      «       | j                  |j                  | j                  dz   «      «       d}| j	                  |d   | j                  ||«      ||d   ¬«      }| j                   j                  || j                  | j                  j                  «      }| j                  |j                  | j                  «      «       | j                  |j                  | j                  dz   «      «       y)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Ñ8J×8OÑ8OÓPˆ	àˆØ×,Ñ,Ø˜GÑ$Ø×+Ñ+¨I°rÓ:ØØ˜XÑ&ð	 -ó 
ˆð ×&Ñ&×-Ñ-Ø˜DŸK™K¨×);Ñ);×)@Ñ)@ó
ˆð 	�‰˜×+Ñ+¨D¯M©MÓ:Ô;Ø×Ñ˜×,Ñ,¨T¯]©]¸XÑ-EÓFÔGàˆØ×,Ñ,Ø˜GÑ$Ø×+Ñ+¨I°rÓ:ØØ˜XÑ&ð	 -ó 
ˆð ×&Ñ&×-Ñ-Ø˜DŸK™K¨×);Ñ);×)@Ñ)@ó
ˆð 	�‰˜×+Ñ+¨D¯M©MÓ:Ô;Ø×Ñ˜×,Ñ,¨T¯]©]¸XÑ-EÓFÕGr   c                 óÌ  — | j                   j                  | j                  j                  «      }d}| j	                  |d   | j                  ||«      ||d   ¬«      }| j                   j                  |d| j                  j                  «      }| j                  |j                  | j                  «      «       | j                  |j                  | j                  dz   «      «       y)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Ñ8J×8OÑ8OÓPˆ	àˆØ×,Ñ,Ø˜GÑ$Ø×+Ñ+¨I°rÓ:ØØ˜XÑ&ð	 -ó 
ˆð ×&Ñ&×-Ñ-Ø˜G T×%7Ñ%7×%<Ñ%<ó
ˆð 	×Ñ˜×,Ñ,¨T¯]©]Ó;Ô<Ø×Ñ˜×,Ñ,¨T¯]©]¸XÑ-EÓFÕGr   c                 óÜ  — | j                  t        | j                  j                  | j	                  d¬«      | j
                  | j                  j                  «      }| j                  t        |«      d«       | j                  t        | j                  j                  | j	                  d¬«      | j
                  | j                  j                  «      }| j                  t        |«      d«       y)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‰KØ×Ñ×#Ñ#ó
ˆð 	×Ñœ˜Q›Ð!GÔHð ×ÑÜØ×"Ñ"×)Ñ)Ø×Ñ¨ÐÓ-Ø�K‰KØ×Ñ×#Ñ#ó
ˆð 	×Ñœ˜Q›Ð!GÕHr   c                 óð   — | j                  t        | j                  j                  | j	                  d¬«      | j
                  | j                  j                  «      }| j                  t        |«      d«       y)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È  sd   € ð
 ×ÑÜØ×"Ñ"×)Ñ)Ø×Ñ yÐÓ1Ø�K‰KØ×Ñ×#Ñ#ó
ˆð 	×Ñœ˜Q›Ð!DÕEr   c                 óì   — | j                  t        | j                  j                  | j	                  «       | j
                  | j                  j                  «      }| j                  t        |«      d«       y)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Ö  s_   € ð
 ×ÑÜØ×"Ñ"×)Ñ)Ø×ÑÓ!Ø�K‰KØ×Ñ×#Ñ#ó
ˆð 	×Ñœ˜Q›Ð!EÕFr   c                 óÜ  — | j                   j                  | j                  j                  «      }d}| j	                  |d   | j                  ||«      ||d   ¬«      }| j                   j                  || j                  | j                  j                  «      }| j                  t        t        |«      «       | j                  dz   | j                  z   dz   | j                  z   }t        |«      }| j                  |j                  t!        |j#                  «       «      «      «       |j%                  d«       | j'                  |j                  t!        |j#                  «       «      «      «       y)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ä  s$  € ð
 ×*Ñ*×7Ñ7¸×8JÑ8J×8OÑ8OÓPˆ	àˆØ×,Ñ,Ø˜GÑ$Ø×+Ñ+¨I°rÓ:ØØ˜XÑ&ð	 -ó 
ˆð ×&Ñ&×-Ñ-Ø˜DŸK™K¨×);Ñ);×)@Ñ)@ó
ˆð 	�‰œÔ%8¸%Ó@ÔAà—M‘M DÑ(¨4¯:©:Ñ5¸Ñ<¸t¿}¹}ÑLˆ	Ü�9‹~ˆØ�‰˜Ÿ™¬°·±³Ó(>Ó?Ô@Ø�‰�HÔØ×Ñ˜Ÿ™¬°·±³Ó)?Ó@ÕAr   c           	      óÒ  — t        | j                  | j                  «      }|j                  | j                  j
                  «      }| j                  t        |j                  d|d   | j                  j
                  «      }| j                  t        |«      d«       dt        d«      z   }| j                  t        |j                  ||d   | j                  j
                  «      }| j                  t        |«      d«       | j                  t        |j                  d|d   | j                  j
                  «      }| j                  t        |«      d«       dt        dj                  |d   t        | j                  j
                  «      df«      «      z   }| j                  t        |j                  ||d   | j                  j
                  «      }| j                  t        |«      d	«       y
)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ÐØ%×2Ñ2°4×3EÑ3E×3JÑ3JÓKˆ	à×ÑÜØ×+Ñ+ØØ�gÑØ×Ñ×#Ñ#ó
ˆð 	×Ñœ˜S›Ð#KÔLàœiÐ(9Ó:Ñ:ˆ	à×ÑÜØ×+Ñ+ØØ�gÑØ×Ñ×#Ñ#ó
ˆð 	×Ñœ˜S›Ð#KÔLà×ÑÜØ×+Ñ+ØØ�gÑØ×Ñ×#Ñ#ó
ˆð 	×Ñœ˜S›Ð#KÔLàœiØ�I‰IØ˜7Ñ#¤]°4×3EÑ3E×3JÑ3JÓ%KÈYÐWóó
ñ 
ˆ	ð
 ×ÑÜØ×+Ñ+ØØ�gÑØ×Ñ×#Ñ#ó
ˆð 	×Ñœ˜S›Ð#QÕRr   c                 ó(  — t        | j                  | j                  «      }|j                  | j                  j
                  «      }|j                  d| j                  j
                  «      }| j                  t        |j                  ||d   | j                  j
                  «      }| j                  t        |«      d«       | j                  t        |j                  |d| j                  j
                  «      }| j                  t        |«      d«       y)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ÐØ%×2Ñ2°4×3EÑ3E×3JÑ3JÓKˆ	à*×:Ñ:Ø˜4×-Ñ-×2Ñ2ó
ˆð ×ÑÜØ×+Ñ+ØØ�gÑØ×Ñ×#Ñ#ó
ˆð 	×Ñœ˜S›Ð#WÔXà×ÑÜØ×+Ñ+ØØØ×Ñ×#Ñ#ó
ˆð 	×Ñœ˜S›Ð#WÕXr   c                 ó|  — t        | j                  | j                  «      }|j                  | j                  j
                  «      }d}| j                  | j                  j
                  |«       |j                  |d   |«      }| j                  t        |j                  ||d   | j                  j
                  «       y)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ÐØ%×2Ñ2°4×3EÑ3E×3JÑ3JÓKˆ	àˆ
à×Ñ˜D×.Ñ.×3Ñ3°ZÔ@à*×:Ñ:Ø�gÑ 
ó
ˆð 	×ÑÜØ×+Ñ+ØØ�gÑØ×Ñ×#Ñ#õ	
r   c                 ó"  — t        | j                  | j                  «      }|j                  | j                  j
                  «      }dj                  |d   t        | j                  j
                  «      df«      }t        t        ||j                  z   «      j                  «       «      }t        |«      }dj                  ||j                  d«      f«      }| j                  t        |j                   ||d   | j                  j
                  «       y)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ÐØ%×2Ñ2°4×3EÑ3E×3JÑ3JÓKˆ	à�i‰iØ�wÑ¤¨t×/AÑ/A×/FÑ/FÓ!GÈÐWó
ˆô œ˜SÐ#4×#?Ñ#?Ñ?Ó@×GÑGÓIÓJˆÜ˜‹~ˆàŸ™ F¨D¯J©J°uÓ,=Ð#>Ó?ˆà×ÑÜØ×+Ñ+ØØ�gÑØ×Ñ×#Ñ#õ	
r   c                 óì  — t        | j                  | j                  «      }|j                  | j                  j
                  «      }dj                  |d   t        | j                  j
                  «      df«      }t        t        |dz   «      j                  «       «      }dj                  |t        |«      f«      }| j                  t        |j                  ||d   | j                  j
                  «       y)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ÐØ%×2Ñ2°4×3EÑ3E×3JÑ3JÓKˆ	à�i‰iØ�wÑ¤¨t×/AÑ/A×/FÑ/FÓ!GÈÐNó
ˆô œ˜SÐ#@Ñ@ÓA×HÑHÓJÓKˆØ—i‘i ¬°3«Ð 8Ó9ˆà×ÑÜØ×+Ñ+ØØ�gÑØ×Ñ×#Ñ#õ	
r   c                 ód   — d}|D ])  \  }}}}| j                  t        t        d|||dd|¬«	       Œ+ y)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—  sR   € ð
ˆ	ð ;Dò 	Ñ6ˆK˜ ;°Ø×ÑÜÜØØØØØØØð õ 
ñ	r   c                 ó`   — | j                   j                  dd«      }| j                  d|«       y)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°  s-   € ð
 ×'Ñ'×7Ñ7Ð8KÈTÓ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ð )/°có +ò+ò*ð -3¸#ó 
+ð 06¸Só 
+ò-ò0ò.ò1ð /5¸Có +ò /ò0ð 4:Àó +òB4ò5ó&
òPóHò*"ò!òòòHò$!HòFHò,Iò2FòGòBò41Sòf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ç      sP   ðñó Ý ß å .÷õ õ +Ý 0Ý /Ý +ò'ôÐ"9ô ô.~	(�hõ ~	(r   