<s> """<STR_LIT>""" <EOL> from zope . interface . verify import verifyObject <EOL> from twisted . trial . unittest import TestCase <EOL> from twisted . python . hashlib import md5 , sha1 <EOL> from twisted . internet . address import IPv4Address <EOL> from twisted . cred . error import LoginFailed <EOL> from twisted . cred . credentials import calcHA1 , calcHA2 , IUsernameDigestHash <EOL> from twisted . cred . credentials import calcResponse , DigestCredentialFactory <EOL> def b64encode ( s ) : <EOL> return s . encode ( '<STR_LIT>' ) . strip ( ) <EOL> class FakeDigestCredentialFactory ( DigestCredentialFactory ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> super ( FakeDigestCredentialFactory , self ) . __init__ ( * args , ** kwargs ) <EOL> self . privateKey = "<STR_LIT:0>" <EOL> def _generateNonce ( self ) : <EOL> """<STR_LIT>""" <EOL> return '<STR_LIT>' <EOL> def _getTime ( self ) : <EOL> """<STR_LIT>""" <EOL> return <NUM_LIT:0> <EOL> class DigestAuthTests ( TestCase ) : <EOL> """<STR_LIT>""" <EOL> def setUp ( self ) : <EOL> """<STR_LIT>""" <EOL> self . username = "<STR_LIT>" <EOL> self . password = "<STR_LIT>" <EOL> self . realm = "<STR_LIT>" <EOL> self . algorithm = "<STR_LIT>" <EOL> self . cnonce = "<STR_LIT>" <EOL> self . qop = "<STR_LIT>" <EOL> self . uri = "<STR_LIT>" <EOL> self . clientAddress = IPv4Address ( '<STR_LIT>' , '<STR_LIT>' , <NUM_LIT> ) <EOL> self . method = '<STR_LIT:GET>' <EOL> self . credentialFactory = DigestCredentialFactory ( <EOL> self . algorithm , self . realm ) <EOL> def test_MD5HashA1 ( self , _algorithm = '<STR_LIT>' , _hash = md5 ) : <EOL> """<STR_LIT>""" <EOL> nonce = '<STR_LIT>' <EOL> hashA1 = calcHA1 ( _algorithm , self . username , self . realm , self . password , <EOL> nonce , self . cnonce ) <EOL> a1 = '<STR_LIT>' % ( self . username , self . realm , self . password ) <EOL> expected = _hash ( a1 ) . hexdigest ( ) <EOL> self . assertEqual ( hashA1 , expected ) <EOL> def test_MD5SessionHashA1 ( self ) : <EOL> """<STR_LIT>""" <EOL> nonce = '<STR_LIT>' <EOL> hashA1 = calcHA1 ( '<STR_LIT>' , self . username , self . realm , self . password , <EOL> nonce , self . cnonce ) <EOL> a1 = '<STR_LIT>' % ( self . username , self . realm , self . password ) <EOL> ha1 = md5 ( a1 ) . digest ( ) <EOL> a1 = '<STR_LIT>' % ( ha1 , nonce , self . cnonce ) <EOL> expected = md5 ( a1 ) . hexdigest ( ) <EOL> self . assertEqual ( hashA1 , expected ) <EOL> def test_SHAHashA1 ( self ) : <EOL> """<STR_LIT>""" <EOL> self . test_MD5HashA1 ( '<STR_LIT>' , sha1 ) <EOL> def test_MD5HashA2Auth ( self , _algorithm = '<STR_LIT>' , _hash = md5 ) : <EOL> """<STR_LIT>""" <EOL> method = '<STR_LIT:GET>' <EOL> hashA2 = calcHA2 ( _algorithm , method , self . uri , '<STR_LIT>' , None ) <EOL> a2 = '<STR_LIT>' % ( method , self . uri ) <EOL> expected = _hash ( a2 ) . hexdigest ( ) <EOL> self . assertEqual ( hashA2 , expected ) <EOL> def test_MD5HashA2AuthInt ( self , _algorithm = '<STR_LIT>' , _hash = md5 ) : <EOL> """<STR_LIT>""" <EOL> method = '<STR_LIT:GET>' <EOL> hentity = '<STR_LIT>' <EOL> hashA2 = calcHA2 ( _algorithm , method , self . uri , '<STR_LIT>' , hentity ) <EOL> a2 = '<STR_LIT>' % ( method , self . uri , hentity ) <EOL> expected = _hash ( a2 ) . hexdigest ( ) <EOL> self . assertEqual ( hashA2 , expected ) <EOL> def test_MD5SessHashA2Auth ( self ) : <EOL> """<STR_LIT>""" <EOL> self . test_MD5HashA2Auth ( '<STR_LIT>' ) <EOL> def test_MD5SessHashA2AuthInt ( self ) : <EOL> """<STR_LIT>""" <EOL> self . test_MD5HashA2AuthInt ( '<STR_LIT>' ) <EOL> def test_SHAHashA2Auth ( self ) : <EOL> """<STR_LIT>""" <EOL> self . test_MD5HashA2Auth ( '<STR_LIT>' , sha1 ) <EOL> def test_SHAHashA2AuthInt ( self ) : <EOL> """<STR_LIT>""" <EOL> self . test_MD5HashA2AuthInt ( '<STR_LIT>' , sha1 ) <EOL> def test_MD5HashResponse ( self , _algorithm = '<STR_LIT>' , _hash = md5 ) : <EOL> """<STR_LIT>""" <EOL> hashA1 = '<STR_LIT>' <EOL> hashA2 = '<STR_LIT>' <EOL> nonce = '<STR_LIT>' <EOL> response = '<STR_LIT>' % ( hashA1 , nonce , hashA2 ) <EOL> expected = _hash ( response ) . hexdigest ( ) <EOL> digest = calcResponse ( hashA1 , hashA2 , _algorithm , nonce , None , None , <EOL> None ) <EOL> self . assertEqual ( expected , digest ) <EOL> def test_MD5SessionHashResponse ( self ) : <EOL> """<STR_LIT>""" <EOL> self . test_MD5HashResponse ( '<STR_LIT>' ) <EOL> def test_SHAHashResponse ( self ) : <EOL> """<STR_LIT>""" <EOL> self . test_MD5HashResponse ( '<STR_LIT>' , sha1 ) <EOL> def test_MD5HashResponseExtra ( self , _algorithm = '<STR_LIT>' , _hash = md5 ) : <EOL> """<STR_LIT>""" <EOL> hashA1 = '<STR_LIT>' <EOL> hashA2 = '<STR_LIT>' <EOL> nonce = '<STR_LIT>' <EOL> nonceCount = '<STR_LIT>' <EOL> clientNonce = '<STR_LIT>' <EOL> qop = '<STR_LIT>' <EOL> response = '<STR_LIT>' % ( <EOL> hashA1 , nonce , nonceCount , clientNonce , qop , hashA2 ) <EOL> expected = _hash ( response ) . hexdigest ( ) <EOL> digest = calcResponse ( <EOL> hashA1 , hashA2 , _algorithm , nonce , nonceCount , clientNonce , qop ) <EOL> self . assertEqual ( expected , digest ) <EOL> def test_MD5SessionHashResponseExtra ( self ) : <EOL> """<STR_LIT>""" <EOL> self . test_MD5HashResponseExtra ( '<STR_LIT>' ) <EOL> def test_SHAHashResponseExtra ( self ) : <EOL> """<STR_LIT>""" <EOL> self . test_MD5HashResponseExtra ( '<STR_LIT>' , sha1 ) <EOL> def formatResponse ( self , quotes = True , ** kw ) : <EOL> """<STR_LIT>""" <EOL> if '<STR_LIT:username>' not in kw : <EOL> kw [ '<STR_LIT:username>' ] = self . username <EOL> if '<STR_LIT>' not in kw : <EOL> kw [ '<STR_LIT>' ] = self . realm <EOL> if '<STR_LIT>' not in kw : <EOL> kw [ '<STR_LIT>' ] = self . algorithm <EOL> if '<STR_LIT>' not in kw : <EOL> kw [ '<STR_LIT>' ] = self . qop <EOL> if '<STR_LIT>' not in kw : <EOL> kw [ '<STR_LIT>' ] = self . cnonce <EOL> if '<STR_LIT>' not in kw : <EOL> kw [ '<STR_LIT>' ] = self . uri <EOL> if quotes : <EOL> quote = '<STR_LIT:">' <EOL> else : <EOL> quote = '<STR_LIT>' <EOL> return '<STR_LIT:U+002CU+0020>' . join ( [ <EOL> '<STR_LIT>' % ( k , quote , v , quote ) <EOL> for ( k , v ) <EOL> in kw . iteritems ( ) <EOL> if v is not None ] ) <EOL> def getDigestResponse ( self , challenge , ncount ) : <EOL> """<STR_LIT>""" <EOL> nonce = challenge . get ( '<STR_LIT>' ) <EOL> algo = challenge . get ( '<STR_LIT>' ) . lower ( ) <EOL> qop = challenge . get ( '<STR_LIT>' ) <EOL> ha1 = calcHA1 ( <EOL> algo , self . username , self . realm , self . password , nonce , self . cnonce ) <EOL> ha2 = calcHA2 ( algo , "<STR_LIT:GET>" , self . uri , qop , None ) <EOL> expected = calcResponse ( ha1 , ha2 , algo , nonce , ncount , self . cnonce , qop ) <EOL> return expected <EOL> def test_response ( self , quotes = True ) : <EOL> """<STR_LIT>""" <EOL> challenge = self . credentialFactory . getChallenge ( self . clientAddress . host ) <EOL> nc = "<STR_LIT>" <EOL> clientResponse = self . formatResponse ( <EOL> quotes = quotes , <EOL> nonce = challenge [ '<STR_LIT>' ] , <EOL> response = self . getDigestResponse ( challenge , nc ) , <EOL> nc = nc , <EOL> opaque = challenge [ '<STR_LIT>' ] ) <EOL> creds = self . credentialFactory . decode ( <EOL> clientResponse , self . method , self . clientAddress . host ) <EOL> self . assertTrue ( creds . checkPassword ( self . password ) ) <EOL> self . assertFalse ( creds . checkPassword ( self . password + '<STR_LIT>' ) ) <EOL> def test_responseWithoutQuotes ( self ) : <EOL> """<STR_LIT>""" <EOL> self . test_response ( False ) <EOL> def test_caseInsensitiveAlgorithm ( self ) : <EOL> """<STR_LIT>""" <EOL> self . algorithm = '<STR_LIT>' <EOL> self . test_response ( ) <EOL> def test_md5DefaultAlgorithm ( self ) : <EOL> """<STR_LIT>""" <EOL> self . algorithm = None <EOL> self . test_response ( ) <EOL> def test_responseWithoutClientIP ( self ) : <EOL> """<STR_LIT>""" <EOL> challenge = self . credentialFactory . getChallenge ( None ) <EOL> nc = "<STR_LIT>" <EOL> clientResponse = self . formatResponse ( <EOL> nonce = challenge [ '<STR_LIT>' ] , <EOL> response = self . getDigestResponse ( challenge , nc ) , <EOL> nc = nc , <EOL> opaque = challenge [ '<STR_LIT>' ] ) <EOL> creds = self . credentialFactory . decode ( clientResponse , self . method , None ) <EOL> self . assertTrue ( creds . checkPassword ( self . password ) ) <EOL> self . assertFalse ( creds . checkPassword ( self . password + '<STR_LIT>' ) ) <EOL> def test_multiResponse ( self ) : <EOL> """<STR_LIT>""" <EOL> challenge = self . credentialFactory . getChallenge ( self . clientAddress . host ) <EOL> nc = "<STR_LIT>" <EOL> clientResponse = self . formatResponse ( <EOL> nonce = challenge [ '<STR_LIT>' ] , <EOL> response = self . getDigestResponse ( challenge , nc ) , <EOL> nc = nc , <EOL> opaque = challenge [ '<STR_LIT>' ] ) <EOL> creds = self . credentialFactory . decode ( clientResponse , self . method , <EOL> self . clientAddress . host ) <EOL> self . assertTrue ( creds . checkPassword ( self . password ) ) <EOL> self . assertFalse ( creds . checkPassword ( self . password + '<STR_LIT>' ) ) <EOL> nc = "<STR_LIT>" <EOL> clientResponse = self . formatResponse ( <EOL> nonce = challenge [ '<STR_LIT>' ] , <EOL> response = self . getDigestResponse ( challenge , nc ) , <EOL> nc = nc , <EOL> opaque = challenge [ '<STR_LIT>' ] ) <EOL> creds = self . credentialFactory . decode ( clientResponse , self . method , <EOL> self . clientAddress . host ) <EOL> self . assertTrue ( creds . checkPassword ( self . password ) ) <EOL> self . assertFalse ( creds . checkPassword ( self . password + '<STR_LIT>' ) ) <EOL> def test_failsWithDifferentMethod ( self ) : <EOL> """<STR_LIT>""" <EOL> challenge = self . credentialFactory . getChallenge ( self . clientAddress . host ) <EOL> nc = "<STR_LIT>" <EOL> clientResponse = self . formatResponse ( <EOL> nonce = challenge [ '<STR_LIT>' ] , <EOL> response = self . getDigestResponse ( challenge , nc ) , <EOL> nc = nc , <EOL> opaque = challenge [ '<STR_LIT>' ] ) <EOL> creds = self . credentialFactory . decode ( clientResponse , '<STR_LIT:POST>' , <EOL> self . clientAddress . host ) <EOL> self . assertFalse ( creds . checkPassword ( self . password ) ) <EOL> self . assertFalse ( creds . checkPassword ( self . password + '<STR_LIT>' ) ) <EOL> def test_noUsername ( self ) : <EOL> """<STR_LIT>""" <EOL> e = self . assertRaises ( <EOL> LoginFailed , <EOL> self . credentialFactory . decode , <EOL> self . formatResponse ( username = None ) , <EOL> self . method , self . clientAddress . host ) <EOL> self . assertEqual ( str ( e ) , "<STR_LIT>" ) <EOL> e = self . assertRaises ( <EOL> LoginFailed , <EOL> self . credentialFactory . decode , <EOL> self . formatResponse ( username = "<STR_LIT>" ) , <EOL> self . method , self . clientAddress . host ) <EOL> self . assertEqual ( str ( e ) , "<STR_LIT>" ) <EOL> def test_noNonce ( self ) : <EOL> """<STR_LIT>""" <EOL> e = self . assertRaises ( <EOL> LoginFailed , <EOL> self . credentialFactory . decode , <EOL> self . formatResponse ( opaque = "<STR_LIT>" ) , <EOL> self . method , self . clientAddress . host ) <EOL> self . assertEqual ( str ( e ) , "<STR_LIT>" ) <EOL> def test_noOpaque ( self ) : <EOL> """<STR_LIT>""" <EOL> e = self . assertRaises ( <EOL> LoginFailed , <EOL> self . credentialFactory . decode , <EOL> self . formatResponse ( ) , <EOL> self . method , self . clientAddress . host ) <EOL> self . assertEqual ( str ( e ) , "<STR_LIT>" ) <EOL> def test_checkHash ( self ) : <EOL> """<STR_LIT>""" <EOL> challenge = self . credentialFactory . getChallenge ( self . clientAddress . host ) <EOL> nc = "<STR_LIT>" <EOL> clientResponse = self . formatResponse ( <EOL> nonce = challenge [ '<STR_LIT>' ] , <EOL> response = self . getDigestResponse ( challenge , nc ) , <EOL> nc = nc , <EOL> opaque = challenge [ '<STR_LIT>' ] ) <EOL> creds = self . credentialFactory . decode ( clientResponse , self . method , <EOL> self . clientAddress . host ) <EOL> self . assertTrue ( verifyObject ( IUsernameDigestHash , creds ) ) <EOL> cleartext = '<STR_LIT>' % ( self . username , self . realm , self . password ) <EOL> hash = md5 ( cleartext ) <EOL> self . assertTrue ( creds . checkHash ( hash . hexdigest ( ) ) ) <EOL> hash . update ( '<STR_LIT>' ) <EOL> self . assertFalse ( creds . checkHash ( hash . hexdigest ( ) ) ) <EOL> def test_invalidOpaque ( self ) : <EOL> """<STR_LIT>""" <EOL> credentialFactory = FakeDigestCredentialFactory ( self . algorithm , <EOL> self . realm ) <EOL> challenge = credentialFactory . getChallenge ( self . clientAddress . host ) <EOL> exc = self . assertRaises ( <EOL> LoginFailed , <EOL> credentialFactory . _verifyOpaque , <EOL> '<STR_LIT>' , <EOL> challenge [ '<STR_LIT>' ] , <EOL> self . clientAddress . host ) <EOL> self . assertEqual ( str ( exc ) , '<STR_LIT>' ) <EOL> badOpaque = '<STR_LIT>' + b64encode ( '<STR_LIT>' ) <EOL> exc = self . assertRaises ( <EOL> LoginFailed , <EOL> credentialFactory . _verifyOpaque , <EOL> badOpaque , <EOL> challenge [ '<STR_LIT>' ] , <EOL> self . clientAddress . host ) <EOL> self . assertEqual ( str ( exc ) , '<STR_LIT>' ) <EOL> exc = self . assertRaises ( <EOL> LoginFailed , <EOL> credentialFactory . _verifyOpaque , <EOL> '<STR_LIT>' , <EOL> challenge [ '<STR_LIT>' ] , <EOL> self . clientAddress . host ) <EOL> self . assertEqual ( str ( exc ) , '<STR_LIT>' ) <EOL> badOpaque = ( <EOL> '<STR_LIT>' + b64encode ( '<STR_LIT>' % ( <EOL> challenge [ '<STR_LIT>' ] , <EOL> self . clientAddress . host ) ) ) <EOL> exc = self . assertRaises ( <EOL> LoginFailed , <EOL> credentialFactory . _verifyOpaque , <EOL> badOpaque , <EOL> challenge [ '<STR_LIT>' ] , <EOL> self . clientAddress . host ) <EOL> self . assertEqual ( <EOL> str ( exc ) , '<STR_LIT>' ) <EOL> def test_incompatibleNonce ( self ) : <EOL> """<STR_LIT>""" <EOL> credentialFactory = FakeDigestCredentialFactory ( self . algorithm , self . realm ) <EOL> challenge = credentialFactory . getChallenge ( self . clientAddress . host ) <EOL> badNonceOpaque = credentialFactory . _generateOpaque ( <EOL> '<STR_LIT>' , <EOL> self . clientAddress . host ) <EOL> exc = self . assertRaises ( <EOL> LoginFailed , <EOL> credentialFactory . _verifyOpaque , <EOL> badNonceOpaque , <EOL> challenge [ '<STR_LIT>' ] , <EOL> self . clientAddress . host ) <EOL> self . assertEqual ( <EOL> str ( exc ) , <EOL> '<STR_LIT>' ) <EOL> exc = self . assertRaises ( <EOL> LoginFailed , <EOL> credentialFactory . _verifyOpaque , <EOL> badNonceOpaque , <EOL> '<STR_LIT>' , <EOL> self . clientAddress . host ) <EOL> self . assertEqual ( <EOL> str ( exc ) , <EOL> '<STR_LIT>' ) <EOL> def test_incompatibleClientIP ( self ) : <EOL> """<STR_LIT>""" <EOL> credentialFactory = FakeDigestCredentialFactory ( self . algorithm , self . realm ) <EOL> challenge = credentialFactory . getChallenge ( self . clientAddress . host ) <EOL> badAddress = '<STR_LIT>' <EOL> self . assertNotEqual ( self . clientAddress . host , badAddress ) <EOL> badNonceOpaque = credentialFactory . _generateOpaque ( <EOL> challenge [ '<STR_LIT>' ] , badAddress ) <EOL> self . assertRaises ( <EOL> LoginFailed , <EOL> credentialFactory . _verifyOpaque , <EOL> badNonceOpaque , <EOL> challenge [ '<STR_LIT>' ] , <EOL> self . clientAddress . host ) <EOL> def test_oldNonce ( self ) : <EOL> """<STR_LIT>""" <EOL> credentialFactory = FakeDigestCredentialFactory ( self . algorithm , <EOL> self . realm ) <EOL> challenge = credentialFactory . getChallenge ( self . clientAddress . host ) <EOL> key = '<STR_LIT>' % ( challenge [ '<STR_LIT>' ] , <EOL> self . clientAddress . host , <EOL> '<STR_LIT>' ) <EOL> digest = md5 ( key + credentialFactory . privateKey ) . hexdigest ( ) <EOL> ekey = b64encode ( key ) <EOL> oldNonceOpaque = '<STR_LIT>' % ( digest , ekey . strip ( '<STR_LIT:\n>' ) ) <EOL> self . assertRaises ( <EOL> LoginFailed , <EOL> credentialFactory . _verifyOpaque , <EOL> oldNonceOpaque , <EOL> challenge [ '<STR_LIT>' ] , <EOL> self . clientAddress . host ) <EOL> def test_mismatchedOpaqueChecksum ( self ) : <EOL> """<STR_LIT>""" <EOL> credentialFactory = FakeDigestCredentialFactory ( self . algorithm , <EOL> self . realm ) <EOL> challenge = credentialFactory . getChallenge ( self . clientAddress . host ) <EOL> key = '<STR_LIT>' % ( challenge [ '<STR_LIT>' ] , <EOL> self . clientAddress . host , <EOL> '<STR_LIT:0>' ) <EOL> digest = md5 ( key + '<STR_LIT>' ) . hexdigest ( ) <EOL> badChecksum = '<STR_LIT>' % ( digest , b64encode ( key ) ) <EOL> self . assertRaises ( <EOL> LoginFailed , <EOL> credentialFactory . _verifyOpaque , <EOL> badChecksum , <EOL> challenge [ '<STR_LIT>' ] , <EOL> self . clientAddress . host ) <EOL> def test_incompatibleCalcHA1Options ( self ) : <EOL> """<STR_LIT>""" <EOL> arguments = ( <EOL> ( "<STR_LIT:user>" , "<STR_LIT>" , "<STR_LIT:password>" , "<STR_LIT>" ) , <EOL> ( None , "<STR_LIT>" , None , "<STR_LIT>" ) , <EOL> ( None , None , "<STR_LIT:password>" , "<STR_LIT>" ) , <EOL> ) <EOL> for pszUsername , pszRealm , pszPassword , preHA1 in arguments : <EOL> self . assertRaises ( <EOL> TypeError , <EOL> calcHA1 , <EOL> "<STR_LIT>" , <EOL> pszUsername , <EOL> pszRealm , <EOL> pszPassword , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> preHA1 = preHA1 ) <EOL> def test_noNewlineOpaque ( self ) : <EOL> """<STR_LIT>""" <EOL> opaque = self . credentialFactory . _generateOpaque ( <EOL> "<STR_LIT>" * <NUM_LIT:10> , None ) <EOL> self . assertNotIn ( '<STR_LIT:\n>' , opaque ) </s>
