Your IP : 172.28.240.42


Current Path : /usr/lib/python2.7/dist-packages/twisted/test/
Upload File :
Current File : //usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyc


[XMc@sdZddlmZddlmZddlmZmZddlm	Z	ddl
mZddlm
Z
mZmZddlmZmZd	Zd
efdYZdefd
YZdS(s[
Tests for L{twisted.cred._digest} and the associated bits in
L{twisted.cred.credentials}.
i(tverifyObject(tTestCase(tmd5tsha1(tIPv4Address(tLoginFailed(tcalcHA1tcalcHA2tIUsernameDigestHash(tcalcResponsetDigestCredentialFactorycCs|jdjS(Ntbase64(tencodetstrip(ts((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyt	b64encodestFakeDigestCredentialFactorycBs)eZdZdZdZdZRS(s\
    A Fake Digest Credential Factory that generates a predictable
    nonce and opaque
    cOs&tt|j||d|_dS(Nt0(tsuperRt__init__t
privateKey(tselftargstkwargs((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyRscCsdS(s)
        Generate a static nonce
        t178288758716122392881254770685((R((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyt_generateNoncescCsdS(s&
        Return a stable time
        i((R((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyt_getTime&s(t__name__t
__module__t__doc__RRR(((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyRs		tDigestAuthTestscBsveZdZdZdedZdZdZdedZdedZ	dZ
d	Zd
ZdZ
dedZd
ZdZdedZdZdZedZdZedZdZdZdZdZdZdZdZdZdZ dZ!dZ"d Z#d!Z$d"Z%d#Z&d$Z'd%Z(RS(&s
    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}.
    cCsyd|_d|_d|_d|_d|_d|_d|_tdd	d
|_d|_	t
|j|j|_dS(
s>
        Create a DigestCredentialFactory for testing
        tfoobartbazquuxs
test realmRt 29fc54aa1641c6fa0e151419361c8f23tauths/write/tTCPs10.2.3.4iutGETN(tusernametpasswordtrealmt	algorithmtcnoncetqopturiRt
clientAddresstmethodR
tcredentialFactory(R((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pytsetUp4s								RcCsod}t||j|j|j||j}d|j|j|jf}||j}|j||dS(s
        L{calcHA1} accepts the C{'md5'} algorithm and returns an MD5 hash of
        its parameters, excluding the nonce and cnonce.
        t	abc123xyzs%s:%s:%sN(RR%R'R&R)t	hexdigesttassertEqual(Rt
_algorithmt_hashtnoncethashA1ta1texpected((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_MD5HashA1EscCsd}td|j|j|j||j}d|j|j|jf}t|j}d|||jf}t|j}|j||dS(s
        L{calcHA1} accepts the C{'md5-sess'} algorithm and returns an MD5 hash
        of its parameters, including the nonce and cnonce.
        t	xyz321abcsmd5-sesss%s:%s:%sN(	RR%R'R&R)RtdigestR1R2(RR5R6R7tha1R8((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_MD5SessionHashA1RscCs|jdtdS(s
        L{calcHA1} accepts the C{'sha'} algorithm and returns a SHA hash of its
        parameters, excluding the nonce and cnonce.
        tshaN(R9R(R((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_SHAHashA1ascCsZd}t|||jdd}d||jf}||j}|j||dS(s
        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"s%s:%sN(RR+tNoneR1R2(RR3R4R-thashA2ta2R8((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_MD5HashA2Authis
cCscd}d}t|||jd|}d||j|f}||j}|j||dS(s
        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$t	foobarbazsauth-ints%s:%s:%sN(RR+R1R2(RR3R4R-thentityRARBR8((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_MD5HashA2AuthIntvscCs|jddS(s
        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.
        smd5-sessN(RC(R((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_MD5SessHashA2AuthscCs|jddS(s
        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.
        smd5-sessN(RF(R((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_MD5SessHashA2AuthIntscCs|jdtdS(s
        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'}.
        R>N(RCR(R((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_SHAHashA2AuthscCs|jdtdS(s
        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'}.
        R>N(RFR(R((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_SHAHashA2AuthIntsc	Csid}d}d}d|||f}||j}t||||ddd}|j||dS(s
        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 C{None}
        tabc123t789xyztlmnopqs%s:%s:%sN(R1R	R@R2(	RR3R4R6RAR5tresponseR8R;((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_MD5HashResponses	cCs|jddS(s
        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 C{None}
        smd5-sessN(RO(R((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_MD5SessionHashResponsescCs|jdtdS(s
        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 C{None}
        R>N(ROR(R((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_SHAHashResponsescCsd}d}d}d}d}d}d||||||f}	||	j}
t|||||||}|j|
|dS(	s
        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.
        RKRLRMt00000004t	abcxyz123R"s%s:%s:%s:%s:%s:%sN(R1R	R2(RR3R4R6RAR5t
nonceCounttclientNonceR*RNR8R;((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_MD5HashResponseExtrascCs|jddS(s
        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.
        smd5-sessN(RV(R((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyt test_MD5SessionHashResponseExtrascCs|jdtdS(s
        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.
        R>N(RVR(R((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_SHAHashResponseExtrascKsd|kr|j|d<nd|kr8|j|d<nd|krT|j|d<nd|krp|j|d<nd|kr|j|d<nd|kr|j|d<n|rd}nd}d	jg|jD].\}}|dk	rd
||||f^qS(s
        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{str} values which will be treated as field
            name/value pairs to include in the result.

        @rtype: C{str}
        @return: The given fields formatted for use as an HTTP header value.
        R%R'R(R*R)R+t"ts, s	%s=%s%s%sN(	R%R'R(R*R)R+tjoint	iteritemsR@(Rtquotestkwtquotetktv((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pytformatResponses&	c	Cs|jd}|jdj}|jd}t||j|j|j||j}t|d|j|d}t
||||||j|}|S(s@
        Calculate the response for the given challenge
        R5R(R*R$N(tgettlowerRR%R'R&R)RR+R@R	(	Rt	challengetncountR5talgoR*R<tha2R8((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pytgetDigestResponses$!cCs|jj|jj}d}|jd|d|dd|j||d|d|d}|jj||j|jj}|j|j	|j
|j|j	|j
ddS(	s
        L{DigestCredentialFactory.decode} accepts a digest challenge response
        and parses it into an L{IUsernameHashedPassword} provider.
        t00000001R]R5RNtnctopaquetwrongN(R.tgetChallengeR,thostRbRitdecodeR-t
assertTruet
checkPasswordR&tassertFalse(RR]ReRktclientResponsetcreds((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyt
test_response%s	

	cCs|jtdS(s
        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.
        N(RvtFalse(R((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_responseWithoutQuotes9scCsd|_|jdS(ss
        The case of the algorithm value in the response is ignored when
        checking the credentials.
        tMD5N(R(Rv(R((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_caseInsensitiveAlgorithmCs	cCsd|_|jdS(sV
        The algorithm defaults to MD5 if it is not supplied in the response.
        N(R@R(Rv(R((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_md5DefaultAlgorithmLs	c
Cs|jjd}d}|jd|dd|j||d|d|d}|jj||jd}|j|j|j	|j
|j|j	ddS(s
        L{DigestCredentialFactory.decode} accepts a digest challenge response
        even if the client address it is passed is C{None}.
        RjR5RNRkRlRmN(R.RnR@RbRiRpR-RqRrR&Rs(RReRkRtRu((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_responseWithoutClientIPTs	

c
CsF|jj|jj}d}|jd|dd|j||d|d|d}|jj||j|jj}|j|j	|j
|j|j	|j
dd}|jd|dd|j||d|d|d}|jj||j|jj}|j|j	|j
|j|j	|j
ddS(	sm
        L{DigestCredentialFactory.decode} handles multiple responses to a
        single challenge.
        RjR5RNRkRlRmt00000002N(R.RnR,RoRbRiRpR-RqRrR&Rs(RReRkRtRu((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_multiResponsefs*	

	

c
Cs|jj|jj}d}|jd|dd|j||d|d|d}|jj|d|jj}|j|j|j	|j|j|j	ddS(	s&
        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.
        RjR5RNRkRltPOSTRmN(
R.RnR,RoRbRiRpRsRrR&(RReRkRtRu((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_failsWithDifferentMethods	

cCs|jt|jj|jdd|j|jj}|j	t
|d|jt|jj|jdd|j|jj}|j	t
|ddS(s
        L{DigestCredentialFactory.decode} raises L{LoginFailed} if the response
        has no username field or if the username field is empty.
        R%s$Invalid response, no username given.RZN(tassertRaisesRR.RpRbR@R-R,RoR2tstr(Rte((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_noUsernames		cCsP|jt|jj|jdd|j|jj}|jt	|ddS(so
        L{DigestCredentialFactory.decode} raises L{LoginFailed} if the response
        has no nonce.
        RlRKs!Invalid response, no nonce given.N(
RRR.RpRbR-R,RoR2R(RR((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_noNonces	cCsJ|jt|jj|j|j|jj}|jt	|ddS(sp
        L{DigestCredentialFactory.decode} raises L{LoginFailed} if the response
        has no opaque.
        s"Invalid response, no opaque given.N(
RRR.RpRbR-R,RoR2R(RR((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyt
test_noOpaques		c
Cs|jj|jj}d}|jd|dd|j||d|d|d}|jj||j|jj}|jt	t
|d|j|j|j
f}t|}|j|j|j|jd|j|j|jdS(	s
        L{DigestCredentialFactory.decode} returns an L{IUsernameDigestHash}
        provider which can verify a hash of the form 'username:realm:password'.
        RjR5RNRkRls%s:%s:%sRmN(R.RnR,RoRbRiRpR-RqRRR%R'R&Rt	checkHashR1tupdateRs(RReRkRtRut	cleartextthash((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_checkHashs	


cCsZt|j|j}|j|jj}|jt|jd|d|jj}|j	t
|ddtd}|jt|j||d|jj}|j	t
|d|jt|jd|d|jj}|j	t
|ddtd|d|jjf}|jt|j||d|jj}|j	t
|dd	S(
s
        L{DigestCredentialFactory.decode} raises L{LoginFailed} when the opaque
        value does not contain all the required parts.
        t	badOpaqueR5s&Invalid response, invalid opaque valuesfoo-snonce,clientipRZs%s,%s,foobars,Invalid response, invalid opaque/time valuesN(RR(R'RnR,RoRRt
_verifyOpaqueR2RR(RR.RetexcR((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_invalidOpaquesH		cCst|j|j}|j|jj}|jd|jj}|jt|j	||d|jj}|j
t|d|jt|j	|d|jj}|j
t|ddS(s
        L{DigestCredentialFactory.decode} raises L{LoginFailed} when the given
        nonce from the response does not match the nonce encoded in the opaque.
        t
1234567890R5s2Invalid response, incompatible opaque/nonce valuesRZN(RR(R'RnR,Rot_generateOpaqueRRRR2R(RR.RetbadNonceOpaqueR((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_incompatibleNonces.		cCst|j|j}|j|jj}d}|j|jj||j|d|}|jt	|j
||d|jjdS(s
        L{DigestCredentialFactory.decode} raises L{LoginFailed} when the
        request comes from a client IP other than what is encoded in the
        opaque.
        s10.0.0.1R5N(RR(R'RnR,RotassertNotEqualRRRR(RR.Ret
badAddressR((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_incompatibleClientIP6scCst|j|j}|j|jj}d|d|jjdf}t||jj}t	|}d||j
df}|jt|j
||d|jjdS(s
        L{DigestCredentialFactory.decode} raises L{LoginFailed} when the given
        opaque is older than C{DigestCredentialFactory.CHALLENGE_LIFETIME_SECS}
        s%s,%s,%sR5s
-137876876s%s-%ss
N(RR(R'RnR,RoRRR1RR
RRR(RR.RetkeyR;tekeytoldNonceOpaque((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyt
test_oldNonceNs	
	
cCst|j|j}|j|jj}d|d|jjdf}t|dj}d|t|f}|j	t
|j||d|jjdS(s~
        L{DigestCredentialFactory.decode} raises L{LoginFailed} when the opaque
        checksum fails verification.
        s%s,%s,%sR5Rsthis is not the right pkeys%s-%sN(RR(R'RnR,RoRR1RRRR(RR.ReRR;tbadChecksum((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_mismatchedOpaqueChecksumgs	
	
cCsXd	d
df}xB|D]:\}}}}|jttd|||ddd|qWdS(s
        L{calcHA1} raises L{TypeError} when any of the pszUsername, pszRealm,
        or pszPassword arguments are specified with the preHA1 keyword
        argument.
        tuserR'R&tpreHA1RR5R)N(susersrealmspasswordspreHA1(NsrealmNspreHA1(NNspasswordspreHA1(R@Rt	TypeErrorR(Rt	argumentstpszUsernametpszRealmtpszPasswordR((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_incompatibleCalcHA1Optionss	cCs-|jjddd}|jd|dS(s
        L{DigestCredentialFactory._generateOpaque} returns a value without
        newlines, regardless of the length of the nonce.
        slong nonce i
s
N(R.RR@tassertNotIn(RRl((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyttest_noNewlineOpaques	()RRRR/RR9R=R?RCRFRGRHRIRJRORPRQRVRWRXtTrueRbRiRvRxRzR{R|R~RRRRRRRRRRRR(((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyR.sJ	
		

													&		
					 			
	
		1	!				N(Rtzope.interface.verifyRttwisted.trial.unittestRttwisted.python.hashlibRRttwisted.internet.addressRttwisted.cred.errorRttwisted.cred.credentialsRRRR	R
RRR(((s@/usr/lib/python2.7/dist-packages/twisted/test/test_digestauth.pyt<module>s