Ϫf@BdZddlZddlZddlZddlZddlZddlmZddlm Z ddl m Z m Z ddl mZddlmZmZmZddlmZmZdd lmZdd lmZdd lmZGd d e ZGddeZGddeZGddeZGddeZ e eeGddZ!GddZ"e eGddZ#e eGddZ$e eGddZ%e e Gd d!Z&Gd"d#eZ'e e'Gd$d%Z(y)&z This module defines L{ICredentials}, an interface for objects that represent authentication credentials to provide, and also includes a number of useful implementations of that interface. N)hexlify)md5) Interface implementer)error)calcHA1calcHA2 calcResponse) nativeString networkString)deprecatedModuleAttribute) secureRandom)VersionceZdZdZy) ICredentialsz I check credentials. Implementors I{must} specify the sub-interfaces of ICredentials to which it conforms, using L{zope.interface.implementer}. N__name__ __module__ __qualname____doc__:/usr/lib/python3/dist-packages/twisted/cred/credentials.pyrrsrrceZdZdZdZy)IUsernameDigestHashz This credential is used when a CredentialChecker has access to the hash of the username:realm:password as in an Apache .htdigest file. cy)a- @param digestHash: The hashed username:realm:password to check against. @return: C{True} if the credentials represented by this object match the given hash, C{False} if they do not, or a L{Deferred} which will be called back with one of these values. Nr) digestHashs r checkHashzIUsernameDigestHash.checkHash-rN)rrrrrrrrrr's   rrceZdZdZdZy)IUsernameHashedPassworda I encapsulate a username and a hashed password. This credential is used when a hashed password is received from the party requesting authentication. CredentialCheckers which check this kind of credential must store the passwords in plaintext (or as password-equivalent hashes) form so that they can be hashed in a manner appropriate for the particular credentials class. @type username: L{bytes} @ivar username: The username associated with these credentials. cya Validate these credentials against the correct password. @type password: L{bytes} @param password: The correct, plaintext password against which to check. @rtype: C{bool} or L{Deferred} @return: C{True} if the credentials represented by this object match the given password, C{False} if they do not, or a L{Deferred} which will be called back with one of these values. Nrpasswords r checkPasswordz%IUsernameHashedPassword.checkPasswordErrN)rrrrr&rrrr!r!7s    rr!c6eZdZUdZeed<eed<dedefdZy)IUsernamePasswordaK I encapsulate a username and a plaintext password. This encapsulates the case where the password received over the network has been hashed with the identity function (That is, not at all). The CredentialsChecker may store the password in whatever format it desires, it need only transform the stored password in a similar way before performing the comparison. @type username: L{bytes} @ivar username: The username associated with these credentials. @type password: L{bytes} @ivar password: The password associated with these credentials. usernamer%returncyr#rr$s rr&zIUsernamePassword.checkPasswordhrrN)rrrrbytes__annotations__boolr&rrrr(r(Ts& OO    $  rr(ceZdZdZy) IAnonymouszs I am an explicitly anonymous request for access. @see: L{twisted.cred.checkers.AllowAnonymousAccess} Nrrrrr0r0wsrr0c"eZdZdZdZdZdZy)DigestedCredentialsz? Yet Another Simple HTTP Digest authentication scheme. c<||_||_||_||_yN)r)methodrealmfields)selfr)r5r6r7s r__init__zDigestedCredentials.__init__s     rc :|jjd}|jjd}|jjd}|jjd}|jjd}|jjddj}|jjdd }tt ||j |j |||t||j||d |||||} | |k(S) a Verify that the credentials represented by this object agree with the given plaintext C{password} by hashing C{password} in the same way the response hash represented by this object was generated and comparing the results. responseurinoncecnoncenc algorithmmd5qopauthN) r7getlowerr rr)r6r r5) r8r%r;r<r=r>r?algorBexpecteds rr&z!DigestedCredentials.checkPasswords;;??:.kkooe$ (* [[__T "{{{F399;kkooeW- D$--Xuf M D$++sC 6      8##rc |jjd}|jjd}|jjd}|jjd}|jjd}|jjddj}|jjdd }tt |d d d ||| t ||j ||d |||||} | |k(S) a4 Verify that the credentials represented by this object agree with the credentials represented by the I{H(A1)} given in C{digestHash}. @param digestHash: A precomputed H(A1) value based on the username, realm, and password associate with this credentials object. r;r<r=r>r?r@rArBrCN)preHA1)r7rDrEr rr r5) r8rr;r<r=r>r?rFrBrGs rrzDigestedCredentials.checkHashs;;??:.kkooe$ (* [[__T "{{{F399;kkooeW- D$dE6* M D$++sC 6      8##rN)rrrrr9r&rrrrr2r2s $6$rr2cfeZdZdZej dZdZdZdZ dZ dZ dZ d Z d Zd Zy ) DigestCredentialFactoryar Support for RFC2617 HTTP Digest Authentication @cvar CHALLENGE_LIFETIME_SECS: The number of seconds for which an opaque should be valid. @type privateKey: L{bytes} @ivar privateKey: A random string used for generating the secure opaque. @type algorithm: L{bytes} @param algorithm: Case insensitive string specifying the hash algorithm to use. Must be either C{'md5'} or C{'sha'}. C{'md5-sess'} is B{not} supported. @type authenticationRealm: L{bytes} @param authenticationRealm: case sensitive string that specifies the realm portion of the challenge s ([^= ]+)=(?:"([^"]*)"|([^,]+)),?isdigestc@||_||_td|_y)N )r@authenticationRealmr privateKey)r8r@rNs rr9z DigestCredentialFactory.__init__s"#6 &r*rc~|j}|j||}||d|j|jdS)a Generate the challenge for use in the WWW-Authenticate header. @param address: The client address to which this challenge is being sent. @return: The L{dict} that can be used to generate a WWW-Authenticate header. rC)r=opaquerBr@r6)_generateNonce_generateOpaquer@rN)r8addresscos r getChallengez$DigestCredentialFactory.getChallengesI    !  G ,--   rc*ttdS)z Create a random value suitable for use as the nonce parameter of a WWW-Authenticate challenge. @rtype: L{bytes} rM)rrr8s rrRz&DigestCredentialFactory._generateNonces|B'((rc*tjS)z Parameterize the time based seed used in C{_generateOpaque} so we can deterministically unittest it's behavior. )timerYs r_getTimez DigestCredentialFactory._getTime s yy{rc~dt|jfz}|sd}n!t|tr|j d}dj |||f}t t||jzj}tj|}dj ||jddfS)z Generate an opaque to be returned to the client. This is a unique string that can be returned to us and verified. s%drascii,- ) intr\ isinstancestrencodejoinrrrOdigestbase64 b64encodereplace)r8r=clientipnowkeyrgekeys rrSz'DigestCredentialFactory._generateOpaquess4==?+--H # &w/Hii#./S4??23::<=$yy&$,,uc":;<##E  S4??23::<= [^ ###$LM M! T##$RS S Ts "E??Fc8dj|j}|jj|}i}|D]6\}}}|xs|j } | |t |j <8|j d} | stjdd|vrtjdd|vrtjd|j|j d|j d|rt| ||j|Sy) a Decode the given response and attempt to generate a L{DigestedCredentials} from it. @type response: L{bytes} @param response: A string of comma separated key=value pairs @type method: L{bytes} @param method: The action requested to which this response is addressed (GET, POST, INVITE, OPTIONS, etc). @type host: L{bytes} @param host: The address the request was sent from. @raise error.LoginFailed: If the response does not contain a username, a nonce, an opaque, or if the opaque is invalid. @return: L{DigestedCredentials}  r)z$Invalid response, no username given.rQz"Invalid response, no opaque given.r=z!Invalid response, no nonce given.N) rf splitlines _parsepartsfindallstripr rDrrur|r2rN) r8r;r5hostpartsauthrmbarequotedvaluer)s rdecodezDigestCredentialFactory.decodecs(99X0023  ((2!& 4 Cv^t**,E.3Dciik* + 488J'##$JK K 4 ##$HI I $ ##$GH H   dhhx0$((72CT J&x9Q9QSWX X KrN)rrrrrecompilerrxschemer9rWrRr\rSr|rrrrrKrKsP&"**  K& F+  *)=&>@'YrrKc<eZdZdZdZdZdZd dZdZdZ dZ dZ y) CramMD5Credentialsas An encapsulation of some CramMD5 hashed credentials. @ivar challenge: The challenge to be sent to the client. @type challenge: L{bytes} @ivar response: The hashed response from the client. @type response: L{bytes} @ivar username: The username from the response from the client. @type username: L{bytes} or L{None} if not yet provided. Nrc||_yr4)r)r8rs rr9zCramMD5Credentials.__init__s  rc |jr |jStjd}tj}t d|||j rt |j ndfz|_|jS)Niz <%d.%d@%s>) challengerandom randranger[r rr )r8rts rrWzCramMD5Credentials.getChallengesh >>>> !   Z ( IIK& AqTYY,tyy"9DQ Q ~~rcB|jdd\|_|_y)Nrq)rsr)r;)r8r;s r setResponsezCramMD5Credentials.setResponses'/~~dA'>$ t}rcy)NFrrYs rmoreChallengesz!CramMD5Credentials.moreChallengessrcttj||jtj }||j k(S)N) digestmod)rhmacHMACrrrgr;)r8r%verifys rr&z CramMD5Credentials.checkPasswords58T^^sKRRTU&&rr4) rrrrr)rr;r9rWrrr&rrrrrs1 HIH ?'rrc@eZdZeeddddddddZdZy ) UsernameHashedPasswordTwistedrprz6Use twisted.cred.credentials.UsernamePassword instead.ztwisted.cred.credentialsc ||_||_yr4)r)hashed)r8r)rs rr9zUsernameHashedPassword.__init__s   rc |j|k(Sr4)rr8r%s rr&z$UsernameHashedPassword.checkPasswords{{h&&rN)rrrr rr9r&rrrrrs+ 2q!$@" 'rrc0eZdZdededdfdZdedefdZy)UsernamePasswordr)r%r*Nc ||_||_yr4)r)r%)r8r)r%s rr9zUsernamePassword.__init__s    rc |j|k(Sr4r$rs rr&zUsernamePassword.checkPasswords}}((r)rrrr,r9r.r&rrrrrs/!!%!D!)e))rrc eZdZy) AnonymousN)rrrrrrrrsrrceZdZdZy)ISSHPrivateKeyaj L{ISSHPrivateKey} credentials encapsulate an SSH public key to be checked against a user's private key. @ivar username: The username associated with these credentials. @type username: L{bytes} @ivar algName: The algorithm name for the blob. @type algName: L{bytes} @ivar blob: The public key blob as sent by the client. @type blob: L{bytes} @ivar sigData: The data the signature was made from. @type sigData: L{bytes} @ivar signature: The signed data. This is checked to verify that the user owns the private key. @type signature: L{bytes} or L{None} NrrrrrrsrrceZdZdZy) SSHPrivateKeycJ||_||_||_||_||_yr4)r)algNameblobsigData signature)r8r)rrrrs rr9zSSHPrivateKey.__init__s%     "rN)rrrr9rrrrrs#rr))rrhrrrr[binasciirhashlibrzope.interfacerr twisted.credrtwisted.cred._digestrr r twisted.python.compatr r twisted.python.deprecater twisted.python.randbytesrtwisted.python.versionsrrrr!r(r0r2rKrrrrrrrrrrsQ  1??=>1+9  ,   l :   F $&9:@$@$;@$FGYGYT $%-'-'&-'` $% ' '& '  )) ) Z   \. ^###r