OwlCyberSecurity - MANAGER
Edit File: digest.py
# -*- test-case-name: txweb2.test.test_httpauth -*- ## # Copyright (c) 2006-2009 Twisted Matrix Laboratories. # Copyright (c) 2010-2017 Apple Inc. All rights reserved. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. # ## """ Implementation of RFC2617: HTTP Digest Authentication http://www.faqs.org/rfcs/rfc2617.html """ from zope.interface import implements from hashlib import md5, sha1 from twisted.cred import credentials # FIXME: Technically speaking - although you can't tell from looking at them - # these APIs are private, they're defined within twisted.cred._digest. There # should probably be some upstream bugs agains Twisted to more aggressively hide # implementation details like these if they're not supposed to be used, so we # can see the private-ness more clearly. The fix is really just to eliminate # this whole module though, and use the Twisted stuff via the public interface, # which should be sufficient to do digest auth. from twisted.cred.credentials import (calcHA1 as _origCalcHA1, calcResponse as _origCalcResponse, calcHA2 as _origCalcHA2) from twisted.internet.defer import maybeDeferred from txweb2.auth.interfaces import ICredentialFactory # The digest math algorithms = { 'md5': md5, 'md5-sess': md5, 'sha': sha1, } # DigestCalcHA1 def calcHA1(pszAlg, pszUserName, pszRealm, pszPassword, pszNonce, pszCNonce, preHA1=None): """ @param pszAlg: The name of the algorithm to use to calculate the digest. Currently supported are md5 md5-sess and sha. @param pszUserName: The username @param pszRealm: The realm @param pszPassword: The password @param pszNonce: The nonce @param pszCNonce: The cnonce @param preHA1: If available this is a str containing a previously calculated HA1 as a hex string. If this is given then the values for pszUserName, pszRealm, and pszPassword are ignored. """ return _origCalcHA1(pszAlg, pszUserName, pszRealm, pszPassword, pszNonce, pszCNonce, preHA1) # DigestCalcResponse def calcResponse( HA1, algo, pszNonce, pszNonceCount, pszCNonce, pszQop, pszMethod, pszDigestUri, pszHEntity, ): return _origCalcResponse(HA1, _origCalcHA2(algo, pszMethod, pszDigestUri, pszQop, pszHEntity), algo, pszNonce, pszNonceCount, pszCNonce, pszQop) DigestedCredentials = credentials.DigestedCredentials class DigestCredentialFactory(object): implements(ICredentialFactory) CHALLENGE_LIFETIME_SECS = ( credentials.DigestCredentialFactory.CHALLENGE_LIFETIME_SECS ) def __init__(self, algorithm, realm): self._real = credentials.DigestCredentialFactory(algorithm, realm) scheme = 'digest' def getChallenge(self, peer): return maybeDeferred(self._real.getChallenge, peer.host) def generateOpaque(self, *a, **k): return self._real._generateOpaque(*a, **k) def verifyOpaque(self, opaque, nonce, clientip): return self._real._verifyOpaque(opaque, nonce, clientip) def decode(self, response, request): method = getattr(request, "originalMethod", request.method) host = request.remoteAddr.host return self._real.decode(response, method, host)