summaryrefslogtreecommitdiff
path: root/wsgitools
diff options
context:
space:
mode:
authorHelmut Grohne <helmut@subdivi.de>2009-03-29 23:27:33 +0200
committerHelmut Grohne <helmut@subdivi.de>2009-03-29 23:27:33 +0200
commit56be1861917a9081a3883ae3b080d4683b52402c (patch)
tree9645dda500527e80bbc33470294a91344ea1f004 /wsgitools
parent58149dfd3d67399a47dbf3035ab0f5a866abcd23 (diff)
downloadwsgitools-56be1861917a9081a3883ae3b080d4683b52402c.tar.gz
improve digest module (killed isnonce method)
Prior to this change the digest module would check whether a nonce looks like a nonce, verify the response and then verify the nonce. This left a bit more room for brute forcing passwords, as the same nonce could be used in arbitrary many tries and a stale response would indicate an authentication success. Now authentication is only tried for valid nonces. This also makes the NonceStoreBase.isnonce method superfluous.
Diffstat (limited to 'wsgitools')
-rwxr-xr-xwsgitools/digest.py80
1 files changed, 13 insertions, 67 deletions
diff --git a/wsgitools/digest.py b/wsgitools/digest.py
index cbd374b..aa1dc83 100755
--- a/wsgitools/digest.py
+++ b/wsgitools/digest.py
@@ -98,22 +98,10 @@ class NonceStoreBase:
@rtype: str
"""
raise NotImplementedError
- def isnonce(self, nonce, ident=None):
- """
- This method is to be overridden and should do a quick check for whether
- the given nonce has a chance to be a valid one. This function must not
- return false for a stale nonce.
- @type nonce: str
- @type ident: str
- @param ident: it is also checked that the nonce was associated to this
- identifier when given
- @rtype: bool
- """
- raise NotImplementedError
def checknonce(self, nonce, count=1, ident=None):
"""
- This method is to be overridden and should do a thorough check for
- whether the given nonce is a valid as being used count times.
+ This method is to be overridden and should do a check for whether the
+ given nonce is valid as being used count times.
@type nonce: str
@type count: int
@param count: indicates how often the nonce has been used (including
@@ -147,8 +135,6 @@ class StatelessNonceStore(NonceStoreBase):
>>> n = s.newnonce()
>>> s.checknonce("spam")
False
- >>> s.isnonce(n)
- True
>>> s.checknonce(n)
True
>>> s.checknonce(n)
@@ -184,27 +170,10 @@ class StatelessNonceStore(NonceStoreBase):
token = md5(token).hexdigest()
return "%s:%s:%s" % (nonce_time, nonce_value, token)
- def isnonce(self, nonce, ident=None):
- """
- Do a quick a stateless check for whether the provides string might
- be a nonce.
- @type nonce: str
- @rtype: bool
- """
- try:
- nonce_time, nonce_value, nonce_hash = nonce.split(':')
- except ValueError:
- return False
- token = "%s:%s:%s" % (nonce_time, nonce_value, self.server_secret)
- if ident is not None:
- token = "%s:%s" % (token, ident)
- token = md5(token).hexdigest()
- return nonce_hash == token
-
def checknonce(self, nonce, count=1, ident=None):
"""
- Do a thorough check for whether the provided string is a nonce and
- increase usage count on returning True.
+ Do a check for whether the provided string is a nonce and increase usage
+ count on returning True.
@type nonce: str
@type count: int
@rtype: bool
@@ -235,8 +204,6 @@ class MemoryNonceStore(NonceStoreBase):
>>> n = s.newnonce()
>>> s.checknonce("spam")
False
- >>> s.isnonce(n)
- True
>>> s.checknonce(n)
True
>>> s.checknonce(n)
@@ -281,27 +248,10 @@ class MemoryNonceStore(NonceStoreBase):
token = md5(token).hexdigest()
return "%s:%s:%s" % (nonce_time, nonce_value, token)
- def isnonce(self, nonce, ident=None):
- """
- Do a quick a stateless check for whether the provides string might
- be a nonce.
- @type nonce: str
- @rtype: bool
- """
- try:
- nonce_time, nonce_value, nonce_hash = nonce.split(':')
- except ValueError:
- return False
- token = "%s:%s:%s" % (nonce_time, nonce_value, self.server_secret)
- if ident is not None:
- token = "%s:%s" % (nonce, ident)
- token = md5(token).hexdigest()
- return nonce_hash == token
-
def checknonce(self, nonce, count=1, ident=None):
"""
- Do a thorough check for whether the provided string is a nonce and
- increase usage count on returning True.
+ Do a check for whether the provided string is a nonce and increase usage
+ count on returning True.
@type nonce: str
@type count: int
@rtype: bool
@@ -367,7 +317,6 @@ class AuthDigestMiddleware:
self.noncestore = MemoryNonceStore(maxage, maxuses)
else:
assert hasattr(store, "newnonce")
- assert hasattr(store, "isnonce")
assert hasattr(store, "checknonce")
self.noncestore = store
@@ -419,16 +368,6 @@ class AuthDigestMiddleware:
"cnonce" not in credentials)):
raise AuthenticationRequired
- if not self.noncestore.isnonce(credentials["nonce"]):
- raise AuthenticationRequired
-
- # raises KeyError, ValueError
- response = self.auth_response(credentials,
- environ["REQUEST_METHOD"])
-
- if response is None or response != credentials["response"]:
- raise AuthenticationRequired
-
noncecount = 1
if credentials.get("qop") is not None:
# raises ValueError
@@ -438,6 +377,13 @@ class AuthDigestMiddleware:
return self.authorization_required(environ, start_response,
stale=True) # stale nonce!
+ # raises KeyError, ValueError
+ response = self.auth_response(credentials,
+ environ["REQUEST_METHOD"])
+
+ if response != credentials["response"]:
+ raise AuthenticationRequired
+
except (KeyError, ValueError, AuthenticationRequired):
return self.authorization_required(environ, start_response)
else: