def build_digest_header(username, password, challenge_header, method, path, nonce_count=1, cnonce=None): challenge_data = parse_dict_header(challenge_header.replace('Digest ', '')) realm = challenge_data['realm'] nonce = challenge_data['nonce'] qop = challenge_data['qop'] opaque = challenge_data['opaque'] def md5_utf8(x): if isinstance(x, str): x = x.encode('utf-8') return hashlib.md5(x).hexdigest() hash_utf8 = md5_utf8 KD = lambda s, d: hash_utf8("%s:%s" % (s, d)) A1 = '%s:%s:%s' % (username, realm, password) A2 = '%s:%s' % (method, path) ncvalue = '%08x' % nonce_count if cnonce is None: seed = str(nonce_count).encode('utf-8') seed += nonce.encode('utf-8') seed += time.ctime().encode('utf-8') seed += os.urandom(8) cnonce = (hashlib.sha1(seed).hexdigest()[:16]) noncebit = "%s:%s:%s:%s:%s" % (nonce, ncvalue, cnonce, qop, hash_utf8(A2)) respdig = KD(hash_utf8(A1), noncebit) base = 'username="******", realm="%s", nonce="%s", uri="%s", '\ 'response="%s", algorithm="MD5"' base = base % (username, realm, nonce, path, respdig) if opaque: base += ', opaque="%s"' % opaque if qop: base += ', qop=auth, nc=%s, cnonce="%s"' % (ncvalue, cnonce) return 'Digest %s' % base
def parse_authorization_header(self, auth_header): if not auth_header.startswith('Digest '): raise exceptions.ParseError('Header do not start with Digest') auth_header = auth_header.replace('Digest ', '') self.auth_header = parse_dict_header(auth_header)