Mercurial > p > roundup > code
changeset 5055:a2b7cfa8d7e9
Fixed changes file comments, merged with upstream.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Sat, 16 Apr 2016 22:58:13 -0400 |
| parents | f0f5293d9939 (diff) 737d3edee3ab (current diff) |
| children | d995ee7d49bf |
| files | CHANGES.txt |
| diffstat | 4 files changed, 43 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/CHANGES.txt Mon Apr 11 09:18:21 2016 +0200 +++ b/CHANGES.txt Sat Apr 16 22:58:13 2016 -0400 @@ -17,6 +17,11 @@ Features: - issue2550894: migrate test suite and run_test.py to py.test (John Kristensen) +- issue2550880: Ability to choose password store scheme and SSHA + support. Discussion on devel 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. (applied by John Rouillard) Fixed: @@ -30,10 +35,10 @@ customizing tracker section of doc/customizing.txt (John Rouillard) - issue2550601: gsoc-2009 "bug" class doesn't have "patches" property Added multilink to patches to the bug schema in the devel template. - (John Rouillard) + (applied by John Rouillard) - issue2550748: Crash when creating new issues with non-existing multilink values (in classic template). Applied patch so it - now errors the same way as an update does. (John Rouillard) + now errors the same way as an update does. (applied by John Rouillard) 2016-01-11: 1.5.1
--- a/roundup/cgi/form_parser.py Mon Apr 11 09:18:21 2016 +0200 +++ b/roundup/cgi/form_parser.py Sat Apr 16 22:58:13 2016 -0400 @@ -386,7 +386,8 @@ raise FormError, self._('Password and confirmation text ' 'do not match') try: - value = password.Password(value, config=self.db.config) + value = password.Password(value, scheme = proptype.scheme, + config=self.db.config) except hyperdb.HyperdbValueError, msg: raise FormError, msg
--- a/roundup/hyperdb.py Mon Apr 11 09:18:21 2016 +0200 +++ b/roundup/hyperdb.py Sat Apr 16 22:58:13 2016 -0400 @@ -71,11 +71,15 @@ class Password(_Type): """An object designating a Password property.""" + def __init__(self, scheme=None, required=False, default_value = None): + super(Password, self).__init__(required, default_value) + self.scheme = scheme + def from_raw(self, value, **kw): if not value: return None try: - return password.Password(encrypted=value, strict=True) + return password.Password(encrypted=value, scheme=self.scheme, strict=True) except password.PasswordValueError, message: raise HyperdbValueError, \ _('property %s: %s')%(kw['propname'], message)
--- a/roundup/password.py Mon Apr 11 09:18:21 2016 +0200 +++ b/roundup/password.py Sat Apr 16 22:58:13 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)
