ó @-ÓQc@sÔdZddlmZmZddlZddlZddlZddlZddlm Z ddl m Z ddl m Z mZmZddlmZdefd „ƒYZd efd „ƒYZd efd „ƒYZdefd„ƒYZdefd„ƒYZdefd„ƒYZdefd„ƒYZdd&d„ƒYZdd'd„ƒYZdd(d„ƒYZdd)d„ƒYZdefd„ƒYZd d*d!„ƒYZd"efd#„ƒYZ d$d+d%„ƒYZ!dS(,s½ 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. iÿÿÿÿ(t implementst InterfaceN(tmd5(t secureRandom(t calcResponsetcalcHA1tcalcHA2(terrort ICredentialscBseZdZRS(s¡ I check credentials. Implementors _must_ specify which sub-interfaces of ICredentials to which it conforms, using zope.interface.implements(). (t__name__t __module__t__doc__(((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyRstIUsernameDigestHashcBseZdZd„ZRS(s” This credential is used when a CredentialChecker has access to the hash of the username:realm:password as in an Apache .htdigest file. cCsdS(s- @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. N((t digestHash((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyt checkHash#s(R R R R(((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyR stIUsernameHashedPasswordcBseZdZd„ZRS(sò 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: C{str} @ivar username: The username associated with these credentials. cCsdS(s Validate these credentials against the correct password. @type password: C{str} @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. N((tpassword((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyt checkPassword<s(R R R R(((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyR.s tIUsernamePasswordcBseZdZd„ZRS(sG 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: C{str} @ivar username: The username associated with these credentials. @type password: C{str} @ivar password: The password associated with these credentials. cCsdS(s Validate these credentials against the correct password. @type password: C{str} @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. N((R((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyR]s(R R R R(((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyRLst IAnonymouscBseZdZRS(s: I am an explicitly anonymous request for access. (R R R (((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyRmstDigestedCredentialscBs6eZdZeeeƒd„Zd„Zd„ZRS(s? Yet Another Simple HTTP Digest authentication scheme. cCs(||_||_||_||_dS(N(tusernametmethodtrealmtfields(tselfRRRR((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyt__init__zs   c Csâ|jjdƒ}|jjdƒ}|jjdƒ}|jjdƒ}|jjdƒ}|jjddƒjƒ}|jjdd ƒ}tt||j|j|||ƒt||j||d ƒ|||||ƒ} | |kS( s 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. tresponseturitnoncetcnoncetnct algorithmRtqoptauthN( RtgettlowerRRRRRRtNone( RRRRRRRtalgoR!texpected((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyRsc Csâ|jjdƒ}|jjdƒ}|jjdƒ}|jjdƒ}|jjdƒ}|jjddƒjƒ}|jjdd ƒ}tt|d d d ||d |ƒt||j||d ƒ|||||ƒ} | |kS( s4 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. RRRRRR RR!R"tpreHA1N(RR#R$RRR%RR( RR RRRRRR&R!R'((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyR˜s( R R R RRR RRR(((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyRts    tDigestCredentialFactorycBsheZdZejdƒZd ZdZd„Zd„Z d„Z d„Z d „Z d „Z d „ZRS( sl Support for RFC2617 HTTP Digest Authentication @cvar CHALLENGE_LIFETIME_SECS: The number of seconds for which an opaque should be valid. @type privateKey: C{str} @ivar privateKey: A random string used for generating the secure opaque. @type algorithm: C{str} @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: C{str} @param authenticationRealm: case sensitive string that specifies the realm portion of the challenge s ([^= ]+)=(?:"([^"]*)"|([^,]+)),?ii<tdigestcCs%||_||_tdƒ|_dS(Ni (R tauthenticationRealmRt privateKey(RR R+((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyRÓs  cCsK|jƒ}|j||ƒ}i|d6|d6dd6|jd6|jd6S(s  Generate the challenge for use in the WWW-Authenticate header. @param address: The client address to which this challenge is being sent. @return: The C{dict} that can be used to generate a WWW-Authenticate header. RtopaqueR"R!R R(t_generateNoncet_generateOpaqueR R+(Rtaddresstcto((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyt getChallengeÙs   cCstdƒjdƒS(s Create a random value suitable for use as the nonce parameter of a WWW-Authenticate challenge. @rtype: C{str} i thex(Rtencode(R((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyR.íscCs tjƒS(s‰ Parameterize the time based seed used in C{_generateOpaque} so we can deterministically unittest it's behavior. (ttime(R((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyt_getTime÷scCs‚tt|jƒƒƒ}|dkr-d}nd|||f}t||jƒjƒ}|jdƒ}d||jddƒfS(sŒ Generate an opaque to be returned to the client. This is a unique string that can be returned to us and verified. ts%s,%s,%stbase64s%s-%ss N( tstrtintR7R%RR,t hexdigestR5treplace(RRtclientiptnowtkeyR*tekey((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyR/ÿs  c Csy|jdƒ}t|ƒdkr3tjdƒ‚n|dkrHd}n|djdƒ}|jdƒ}t|ƒdkrŽtjdƒ‚n|d |kr°tjd ƒ‚n|d|krÒtjd ƒ‚nyt|dƒ}Wn tk rtjd ƒ‚nXt|jƒƒ|t j kr:tjd ƒ‚nt ||j ƒj ƒ}||d krutjdƒ‚ntS(s· Given the opaque and nonce from the request, as well as the client IP that made the request, verify that the opaque was generated by us. And that it's not too old. @param opaque: The opaque value from the Digest response @param nonce: The nonce value from the Digest response @param clientip: The remote IP address of the client making the request or C{None} if the request was submitted over a channel where this does not make sense. @return: C{True} if the opaque was successfully verified. @raise error.LoginFailed: if C{opaque} could not be parsed or contained the wrong values. t-is&Invalid response, invalid opaque valueR8iR9t,iis2Invalid response, incompatible opaque/nonce valuess3Invalid response, incompatible opaque/client valuess,Invalid response, invalid opaque/time valuess3Invalid response, incompatible opaque/nonce too oldN(tsplittlenRt LoginFailedR%tdecodeR;t ValueErrorR7R)tCHALLENGE_LIFETIME_SECSRR,R<tTrue( RR-RR>t opaquePartsR@tkeyPartstwhenR*((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyt _verifyOpaques8        c Cs dj|jƒƒ}|jj|ƒ}i}x9|D]1\}}}|pL|jƒ} | ||jƒ(t challengetrandomt randrangeR6RU(Rtrtt((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyR3‚s   cCs"|jddƒ\|_|_dS(Ni(RDR%RR(RR((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyt setResponsescCstS(N(tFalse(R((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pytmoreChallenges“scCs(tj||jƒjƒ}||jkS(N(thmactHMACR^R<R(RRtverify((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyR–sN( R R RRR^RR%RR3RcReR(((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyR]ys     tUsernameHashedPasswordcBs$eZeeƒd„Zd„ZRS(cCs||_||_dS(N(Rthashed(RRRj((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyRžs cCs |j|kS(N(Rj(RR((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyR¢s(R R RRRR(((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyRi›s  tUsernamePasswordcBs$eZeeƒd„Zd„ZRS(cCs||_||_dS(N(RR(RRR((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyR©s cCs |j|kS(N(R(RR((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyR­s(R R RRRR(((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyRk¦s  t AnonymouscBseZeeƒRS((R R RR(((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyRl±stISSHPrivateKeycBseZdZRS(sd 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: C{str} @ivar algName: The algorithm name for the blob. @type algName: C{str} @ivar blob: The public key blob as sent by the client. @type blob: C{str} @ivar sigData: The data the signature was made from. @type sigData: C{str} @ivar signature: The signed data. This is checked to verify that the user owns the private key. @type signature: C{str} or C{NoneType} (R R R (((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyRm¶st SSHPrivateKeycBseZeeƒd„ZRS(cCs1||_||_||_||_||_dS(N(RtalgNametblobtsigDatat signature(RRRoRpRqRr((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyRÐs     (R R RRmR(((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyRnÎs tIPluggableAuthenticationModulescBseZdZRS(sFI encapsulate the authentication of a user via PAM (Pluggable Authentication Modules. I use PyPAM (available from http://www.tummy.com/Software/PyPam/index.html). @ivar username: The username for the user being logged in. @ivar pamConversion: A function that is called with a list of tuples (message, messageType). See the PAM documentation for the meaning of messageType. The function returns a Deferred which will fire with a list of (response, 0), one for each message. The 0 is currently unused, but is required by the PAM library. (R R R (((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyRsØs tPluggableAuthenticationModulescBseZeeƒd„ZRS(cCs||_||_dS(N(Rt pamConversion(RRRu((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyRês (R R RRsR(((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyRtçs ((((((("R tzope.interfaceRRRfR6R_RZthashlibRttwisted.python.randbytesRttwisted.cred._digestRRRt twisted.credRRR RRRtobjectRR)R]RiRkRlRmRnRsRt(((s</usr/lib/python2.7/dist-packages/twisted/cred/credentials.pyt s*0 !=È"