ÿØÿàJFIFÿþ ÿÛC       ÿÛC ÿÀÿÄÿÄ"#QrÿÄÿÄ&1!A"2qQaáÿÚ ?Øy,æ/3JæÝ¹È߲؋5êXw²±ÉyˆR”¾I0ó2—PI¾IÌÚiMö¯–þrìN&"KgX:Šíµ•nTJnLK„…@!‰-ý ùúmë;ºgµŒ&ó±hw’¯Õ@”Ü— 9ñ-ë.²1<yà‚¹ïQÐU„ہ?.’¦èûbß±©Ö«Âw*VŒ) `$‰bØÔŸ’ëXÖ-ËTÜíGÚ3ð«g Ÿ§¯—Jx„–’U/ÂÅv_s(Hÿ@TñJÑãõçn­‚!ÈgfbÓc­:él[ðQe 9ÀPLbÃãCµm[5¿ç'ªjglå‡Ûí_§Úõl-;"PkÞÞÁQâ¼_Ñ^¢SŸx?"¸¦ùY騐ÒOÈ q’`~~ÚtËU¹CڒêV  I1Áß_ÿÙ ]c@sdZddlmZddlTyddlmZWn!ek rWddlmZnXddlZddlZddl m Z dZ dZ d Zd efd YZd efd YZeZdd gZdZdekrddlZejdejndS(s Digest HTTP/1.1 Authentication This module implements ``Digest`` authentication as described by RFC 2617 [1]_ . Basically, you just put this module before your application, and it takes care of requesting and handling authentication requests. This module has been tested with several common browsers "out-in-the-wild". >>> from paste.wsgilib import dump_environ >>> from paste.httpserver import serve >>> # from paste.auth.digest import digest_password, AuthDigestHandler >>> realm = 'Test Realm' >>> def authfunc(environ, realm, username): ... return digest_password(realm, username, username) >>> serve(AuthDigestHandler(dump_environ, realm, authfunc)) serving on... This code has not been audited by a security expert, please use with caution (or better yet, report security holes). At this time, this implementation does not provide for further challenges, nor does it support Authentication-Info header. It also uses md5, and an option to use sha would be a good thing. .. [1] http://www.faqs.org/rfcs/rfc2617.html i(tHTTPUnauthorized(t*(tmd5N(tquoteccsd}x|jdD]x}y/|jddkrJd||f}wnWn/tk r||dkrs|}qq}tnX|jV|}qW|jVtdS(s> split a digest auth string into individual key=value strings t,t"is%s,%sN(tNonetsplittcounttAttributeErrort StopIterationtstrip(t auth_stringtprevtitem((sB/opt/alt/python27/lib/python2.7/site-packages/paste/auth/digest.pyt_split_auth_string)s       ccs~xwt|D]i}|jdd\}}|jdrkt|dkrk|jdrk|dd!}n||fVq WdS(s2 split a digest auth string into key, value pairs t=iRiN(RRt startswithtlentendswith(R Rtktv((sB/opt/alt/python27/lib/python2.7/site-packages/paste/auth/digest.pyt_auth_to_kv_pairs=s 0cCstd|||fjS(s; construct the appropriate hashcode needed for HTTP digest s%s:%s:%s(Rt hexdigest(trealmtusernametpassword((sB/opt/alt/python27/lib/python2.7/site-packages/paste/auth/digest.pytdigest_passwordEstAuthDigestAuthenticatorcBs;eZdZdZddZdZdZeZRS(s9 implementation of RFC 2617 - HTTP Digest Authentication cCsi|_||_||_dS(N(tnoncetauthfuncR(tselfRR((sB/opt/alt/python27/lib/python2.7/site-packages/paste/auth/digest.pyt__init__Ks  tcCstdtjtjfj}tdtjtjfj}d|j| hashcode This module provides a 'digest_password' helper function which can help construct the hashcode; it is recommended that the hashcode is stored in a database, not the user's actual password (since you only need the hashcode). cCst|||_||_dS(N(RRNt application(RRTRR((sB/opt/alt/python27/lib/python2.7/site-packages/paste/auth/digest.pyR scCsvt|}|sf|j|}t|trStj|dtj||qf|j||Sn|j||S(NR=(t REMOTE_USERRNt isinstancetstrt AUTH_TYPEtupdatetwsgi_applicationRT(RRHtstart_responseRtresult((sB/opt/alt/python27/lib/python2.7/site-packages/paste/auth/digest.pyRRs (RORPRQR RR(((sB/opt/alt/python27/lib/python2.7/site-packages/paste/auth/digest.pyRSs/ RcKsVddlm}ddl}||}t||jsFtdt|||S(s Grant access via digest authentication Config looks like this:: [filter:grant] use = egg:Paste#auth_digest realm=myrealm authfunc=somepackage.somemodule:somefunction i(t eval_importNs#authfunc must resolve to a function(tpaste.util.import_stringR]ttypesRVt FunctionTypeRGRS(tappt global_confRRtkwR]R_((sB/opt/alt/python27/lib/python2.7/site-packages/paste/auth/digest.pyt make_digests   t__main__t optionflags(RQtpaste.httpexceptionsRtpaste.httpheadersthashlibRt ImportErrorR(R)turllibRRARRRtobjectRRSt middlewaret__all__RdROtdoctestttestmodtELLIPSIS(((sB/opt/alt/python27/lib/python2.7/site-packages/paste/auth/digest.pyts&     O?