Mercurial > p > roundup > code
diff roundup/password.py @ 5053:9792b18e0b19
issue 2550880: Ability to choose password store scheme and SSHA support.
Discussion on list is tending in favor of this patch.
Embedded test works, my manual test with a SSHA password
assigned to a user allowed the user to log in.
Ran the test suite and the tests that were not skipped passed.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Sat, 16 Apr 2016 22:49:38 -0400 |
| parents | 9ba03348f923 |
| children | 66a17c80e035 |
line wrap: on
line diff
--- a/roundup/password.py Sat Apr 09 01:15:22 2016 -0400 +++ b/roundup/password.py Sat Apr 16 22:49:38 2016 -0400 @@ -20,6 +20,7 @@ __docformat__ = 'restructuredtext' import re, string, random +import os from base64 import b64encode, b64decode from hashlib import md5, sha1 @@ -81,6 +82,16 @@ out += block return out[:keylen] +def ssha(password, salt): + ''' Make ssha digest from password and salt. + Based on code of Roberto Aguilar <roberto@baremetal.io> + https://gist.github.com/rca/7217540 + ''' + shaval = sha1(password) + shaval.update( salt ) + ssha_digest = b64encode( '{}{}'.format(shaval.digest(), salt) ).strip() + return ssha_digest + def pbkdf2(password, salt, rounds, keylen): """pkcs#5 password-based key derivation v2.0 @@ -149,6 +160,16 @@ raise PasswordValueError, "invalid PBKDF2 hash (rounds too low)" raw_digest = pbkdf2(plaintext, raw_salt, rounds, 20) return "%d$%s$%s" % (rounds, salt, h64encode(raw_digest)) + elif scheme == 'SSHA': + if other: + raw_other = b64decode(other) + salt = raw_other[20:] + else: + #new password + # variable salt length + salt_len = random.randrange(36, 52) + salt = os.urandom(salt_len) + s = ssha(plaintext, salt) elif scheme == 'SHA': s = sha1(plaintext).hexdigest() elif scheme == 'MD5': @@ -241,7 +262,7 @@ #TODO: code to migrate from old password schemes. deprecated_schemes = ["SHA", "MD5", "crypt", "plaintext"] - known_schemes = ["PBKDF2"] + deprecated_schemes + known_schemes = ["PBKDF2", "SSHA"] + deprecated_schemes def __init__(self, plaintext=None, scheme=None, encrypted=None, strict=False, config=None): """Call setPassword if plaintext is not None.""" @@ -319,6 +340,13 @@ assert 'sekrit' == p assert 'not sekrit' != p + # SSHA + p = Password('sekrit', 'SSHA') + assert p == 'sekrit' + assert p != 'not sekrit' + assert 'sekrit' == p + assert 'not sekrit' != p + # PBKDF2 - low level function from binascii import unhexlify k = pbkdf2("password", "ATHENA.MIT.EDUraeburn", 1200, 32)
