Skip to content

Commit

Permalink
encode the input string (being the hashed password) to ascii in check…
Browse files Browse the repository at this point in the history
…Password()
  • Loading branch information
janwijbrand committed May 26, 2010
1 parent 743d3e2 commit 726a1c2
Showing 1 changed file with 20 additions and 8 deletions.
28 changes: 20 additions & 8 deletions src/zope/password/password.py
Expand Up @@ -73,7 +73,7 @@ class SSHAPasswordManager(PlainTextPasswordManager):
SSHA is regularly used in LDAP databases and we should be
compatible with passwords used there.
>>> from zope.interface.verify import verifyObject
>>> manager = SSHAPasswordManager()
Expand All @@ -96,13 +96,13 @@ class SSHAPasswordManager(PlainTextPasswordManager):
Our password manager generates the same value when seeded with the
same salt, so we can be sure, our output is compatible with
standard LDAP tools that also use SSHA::
>>> from base64 import urlsafe_b64decode
>>> salt = urlsafe_b64decode('XkOZbw==')
>>> encoded = manager.encodePassword('secret', salt)
>>> encoded
'{SSHA}J4mrr3NQHXzLVaT0h9TuEWoJOrxeQ5lv'
>>> encoded = manager.encodePassword(password)
>>> manager.checkPassword(encoded, password)
True
Expand All @@ -111,6 +111,15 @@ class SSHAPasswordManager(PlainTextPasswordManager):
>>> manager.encodePassword(password) != manager.encodePassword(password)
True
The password manager should be able to cope with unicode strings for input::
>>> passwd = u'foobar\u2211' # sigma-sign.
>>> manager.checkPassword(manager.encodePassword(passwd), passwd)
True
>>> manager.checkPassword(unicode(manager.encodePassword(passwd)), passwd)
True
"""

implements(IPasswordManager)
Expand All @@ -120,10 +129,13 @@ def encodePassword(self, password, salt=None):
salt = urandom(4)
hash = sha1(_encoder(password)[0])
hash.update(salt)
return '{SSHA}' + urlsafe_b64encode(
hash.digest() + salt)
return '{SSHA}' + urlsafe_b64encode(hash.digest() + salt)

def checkPassword(self, encoded_password, password):
# urlsafe_b64decode() cannot handle unicode input string. We
# encode to ascii. This is safe as the encoded_password string
# should not contain non-ascii characters anyway.
encoded_password = encoded_password.encode('ascii')
byte_string = urlsafe_b64decode(encoded_password[6:])
salt = byte_string[20:]
return encoded_password == self.encodePassword(password, salt)
Expand All @@ -134,7 +146,7 @@ class MD5PasswordManager(PlainTextPasswordManager):
Note: use of salt in this password manager is purely
cosmetical. Use SSHA if you want increased security.
>>> from zope.interface.verify import verifyObject
>>> manager = MD5PasswordManager()
Expand All @@ -160,7 +172,7 @@ class MD5PasswordManager(PlainTextPasswordManager):
>>> manager.encodePassword(password) != manager.encodePassword(password)
True
The old version of this password manager didn't add the {MD5} to
passwords. Let's check if it can work with old stored passwords.
Expand Down Expand Up @@ -193,7 +205,7 @@ class SHA1PasswordManager(PlainTextPasswordManager):
Note: use of salt in this password manager is purely
cosmetical. Use SSHA if you want increased security.
>>> from zope.interface.verify import verifyObject
>>> manager = SHA1PasswordManager()
Expand Down

0 comments on commit 726a1c2

Please sign in to comment.