home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / calibre-0.7.13.msi / file_1461 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-08-06  |  8.1 KB  |  172 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. __version__ = (1, 0, 1)
  5. __author__ = 'Tiago Cogumbreiro <cogumbreiro@users.sf.net>'
  6. __credits__ = '\n    Peter van Kampen for its recipe which implement most of Digest authentication:\n    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/302378\n'
  7. __license__ = '\nCopyright (c) 2005, Tiago Cogumbreiro <cogumbreiro@users.sf.net>\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification,\nare permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright notice,\n      this list of conditions and the following disclaimer in the documentation\n      and/or other materials provided with the distribution.\n    * Neither the name of Sylvain Hellegouarch nor the names of his contributors\n      may be used to endorse or promote products derived from this software\n      without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n'
  8. __all__ = ('digestAuth', 'basicAuth', 'doAuth', 'checkResponse', 'parseAuthorization', 'SUPPORTED_ALGORITHM', 'md5SessionKey', 'calculateNonce', 'SUPPORTED_QOP')
  9.  
  10. try:
  11.     from hashlib import md5
  12. except ImportError:
  13.     from md5 import new as md5
  14.  
  15. import time
  16. import base64
  17. import urllib2
  18. MD5 = 'MD5'
  19. MD5_SESS = 'MD5-sess'
  20. AUTH = 'auth'
  21. AUTH_INT = 'auth-int'
  22. SUPPORTED_ALGORITHM = ('md5', MD5, MD5_SESS)
  23. SUPPORTED_QOP = (AUTH, AUTH_INT)
  24. DIGEST_AUTH_ENCODERS = {
  25.     MD5: (lambda val: md5(val).hexdigest()),
  26.     'md5': (lambda val: md5(val).hexdigest()),
  27.     MD5_SESS: (lambda val: md5(val).hexdigest()) }
  28.  
  29. def calculateNonce(realm, algorithm = MD5):
  30.     
  31.     try:
  32.         encoder = DIGEST_AUTH_ENCODERS[algorithm]
  33.     except KeyError:
  34.         raise NotImplementedError('The chosen algorithm (%s) does not have an implementation yet' % algorithm)
  35.  
  36.     return encoder('%d:%s' % (time.time(), realm))
  37.  
  38.  
  39. def digestAuth(realm, algorithm = MD5, nonce = None, qop = AUTH):
  40.     if nonce is None:
  41.         nonce = calculateNonce(realm, algorithm)
  42.     
  43.     return 'Digest realm="%s", nonce="%s", algorithm="%s", qop="%s"' % (realm, nonce, algorithm, qop)
  44.  
  45.  
  46. def basicAuth(realm):
  47.     return 'Basic realm="%s"' % realm
  48.  
  49.  
  50. def doAuth(realm):
  51.     return digestAuth(realm) + ' ' + basicAuth(realm)
  52.  
  53.  
  54. def _parseDigestAuthorization(auth_params):
  55.     items = urllib2.parse_http_list(auth_params)
  56.     params = urllib2.parse_keqv_list(items)
  57.     required = [
  58.         'username',
  59.         'realm',
  60.         'nonce',
  61.         'uri',
  62.         'response']
  63.     for k in required:
  64.         if not params.has_key(k):
  65.             return None
  66.     
  67.     if params.has_key('qop'):
  68.         if params.has_key('cnonce'):
  69.             pass
  70.         if not params.has_key('nc'):
  71.             return None
  72.         if (params.has_key('cnonce') or params.has_key('nc')) and not params.has_key('qop'):
  73.             return None
  74.         return params
  75.  
  76.  
  77. def _parseBasicAuthorization(auth_params):
  78.     (username, password) = base64.decodestring(auth_params).split(':', 1)
  79.     return {
  80.         'username': username,
  81.         'password': password }
  82.  
  83. AUTH_SCHEMES = {
  84.     'basic': _parseBasicAuthorization,
  85.     'digest': _parseDigestAuthorization }
  86.  
  87. def parseAuthorization(credentials):
  88.     (auth_scheme, auth_params) = credentials.split(' ', 1)
  89.     auth_scheme = auth_scheme.lower()
  90.     parser = AUTH_SCHEMES[auth_scheme]
  91.     params = parser(auth_params)
  92.     if params is None:
  93.         return None
  94.     params['auth_scheme'] = auth_scheme
  95.     return params
  96.  
  97.  
  98. def md5SessionKey(params, password):
  99.     keys = ('username', 'realm', 'nonce', 'cnonce')
  100.     params_copy = { }
  101.     for key in keys:
  102.         params_copy[key] = params[key]
  103.     
  104.     params_copy['algorithm'] = MD5_SESS
  105.     return _A1(params_copy, password)
  106.  
  107.  
  108. def _A1(params, password):
  109.     algorithm = params.get('algorithm', MD5)
  110.     H = DIGEST_AUTH_ENCODERS[algorithm]
  111.     if algorithm in (MD5, 'md5'):
  112.         return '%s:%s:%s' % (params['username'], params['realm'], password)
  113.     if algorithm == MD5_SESS:
  114.         h_a1 = H('%s:%s:%s' % (params['username'], params['realm'], password))
  115.         return '%s:%s:%s' % (h_a1, params['nonce'], params['cnonce'])
  116.  
  117.  
  118. def _A2(params, method, kwargs):
  119.     qop = params.get('qop', 'auth')
  120.     if qop == 'auth':
  121.         return method + ':' + params['uri']
  122.     if qop == 'auth-int':
  123.         entity_body = kwargs.get('entity_body', '')
  124.         H = kwargs['H']
  125.         return '%s:%s:%s' % (method, params['uri'], H(entity_body))
  126.     raise NotImplementedError("The 'qop' method is unknown: %s" % qop)
  127.  
  128.  
  129. def _computeDigestResponse(auth_map, password, method = 'GET', A1 = None, **kwargs):
  130.     params = auth_map
  131.     algorithm = params.get('algorithm', MD5)
  132.     H = DIGEST_AUTH_ENCODERS[algorithm]
  133.     
  134.     KD = lambda secret, data: H(secret + ':' + data)
  135.     qop = params.get('qop', None)
  136.     H_A2 = H(_A2(params, method, kwargs))
  137.     if algorithm == MD5_SESS and A1 is not None:
  138.         H_A1 = H(A1)
  139.     else:
  140.         H_A1 = H(_A1(params, password))
  141.     if qop in ('auth', 'auth-int'):
  142.         request = '%s:%s:%s:%s:%s' % (params['nonce'], params['nc'], params['cnonce'], params['qop'], H_A2)
  143.     elif qop is None:
  144.         request = '%s:%s' % (params['nonce'], H_A2)
  145.     
  146.     return KD(H_A1, request)
  147.  
  148.  
  149. def _checkDigestResponse(auth_map, password, method = 'GET', A1 = None, **kwargs):
  150.     if auth_map['realm'] != kwargs.get('realm', None):
  151.         return False
  152.     response = _computeDigestResponse(auth_map, password, method, A1, **kwargs)
  153.     return response == auth_map['response']
  154.  
  155.  
  156. def _checkBasicResponse(auth_map, password, method = 'GET', encrypt = None, **kwargs):
  157.     
  158.     try:
  159.         return encrypt(auth_map['password'], auth_map['username']) == password
  160.     except TypeError:
  161.         return encrypt(auth_map['password']) == password
  162.  
  163.  
  164. AUTH_RESPONSES = {
  165.     'basic': _checkBasicResponse,
  166.     'digest': _checkDigestResponse }
  167.  
  168. def checkResponse(auth_map, password, method = 'GET', encrypt = None, **kwargs):
  169.     checker = AUTH_RESPONSES[auth_map['auth_scheme']]
  170.     return checker(auth_map, password, method = method, encrypt = encrypt, **kwargs)
  171.  
  172.