Skip to content

Commit ef59495

Browse files
committed
Refeactor PBKDF2 and PBKDF2S5 to reuse code; fix python password.py
90% of the code for these two paths in encodePassword is identical. Combine the identical parts of the code. When password.py is called directly, it runs tests. But the sys.path is messed up so that roundup/cgi is imported during execution rather than pythonlib/cgi.py leading to an import error during setup. This issue does not occur if the tests are run under pytest.
1 parent 1e701ed commit ef59495

File tree

1 file changed

+24
-20
lines changed

1 file changed

+24
-20
lines changed

roundup/password.py

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -227,21 +227,7 @@ def encodePassword(plaintext, scheme, other=None, config=None):
227227
"""
228228
if plaintext is None:
229229
plaintext = ""
230-
if scheme == "PBKDF2S5": # sha512 variant
231-
if other:
232-
rounds, salt, raw_salt, digest = pbkdf2_unpack(other)
233-
else:
234-
raw_salt = random_.token_bytes(20)
235-
salt = h64encode(raw_salt)
236-
if config:
237-
rounds = config.PASSWORD_PBKDF2_DEFAULT_ROUNDS
238-
else:
239-
rounds = 300000 # sha512 secure with fewer rounds than sha1
240-
if rounds < 1000:
241-
raise PasswordValueError("invalid PBKDF2 hash (rounds too low)")
242-
raw_digest = pbkdf2_sha512(plaintext, raw_salt, rounds, 64)
243-
return "%d$%s$%s" % (rounds, salt, h64encode(raw_digest))
244-
if scheme == "PBKDF2":
230+
if scheme in ["PBKDF2", "PBKDF2S5"]: # all PBKDF schemes
245231
if other:
246232
rounds, salt, raw_salt, digest = pbkdf2_unpack(other)
247233
else:
@@ -257,10 +243,10 @@ def encodePassword(plaintext, scheme, other=None, config=None):
257243
rounds = config.PASSWORD_PBKDF2_DEFAULT_ROUNDS
258244
else:
259245
# Use 1000 rounds unless the test signals it
260-
# wants the config numberby setting
261-
# PYTEST_USE_CONFIG Using the production 2M
262-
# round values makes testing increase from 12
263-
# minutes to 1 hour in CI.
246+
# wants the config number by setting
247+
# PYTEST_USE_CONFIG. Using the production
248+
# rounds value of 2,000,000 (for sha1) makes
249+
# testing increase from 12 minutes to 1 hour in CI.
264250
rounds = 1000
265251
else:
266252
if ("pytest" in sys.modules and
@@ -292,7 +278,10 @@ def encodePassword(plaintext, scheme, other=None, config=None):
292278

293279
if rounds < 1000:
294280
raise PasswordValueError("invalid PBKDF2 hash (rounds too low)")
295-
raw_digest = pbkdf2(plaintext, raw_salt, rounds, 20)
281+
if scheme == "PBKDF2S5":
282+
raw_digest = pbkdf2_sha512(plaintext, raw_salt, rounds, 64)
283+
else:
284+
raw_digest = pbkdf2(plaintext, raw_salt, rounds, 20)
296285
return "%d$%s$%s" % (rounds, salt, h64encode(raw_digest))
297286
elif scheme == 'SSHA':
298287
if other:
@@ -549,6 +538,21 @@ def test(config=None):
549538
assert 'not sekrit' != p
550539

551540
if __name__ == '__main__':
541+
# invoking this with:
542+
# PYTHONPATH=. python2 roundup/password.py
543+
# or with python3, results in sys.path starting with:
544+
# ['/path/to/./roundup',
545+
# '/path/to/.',
546+
# '/usr/lib/python2.7',
547+
# which makes import roundup.anypy.html fail in python2
548+
# when importing
549+
# from cgi import escape as html_escape
550+
# because cgi is not /usr/lib/python2.7/cgi but
551+
# roundup/cgi. Modify the path to remove the bogus trailing /roundup
552+
553+
sys.path[0] = sys.path[0][:sys.path[0].rindex('/')]
554+
555+
# we continue with our regularly scheduled tests
552556
from roundup.configuration import CoreConfig
553557
test(CoreConfig())
554558
crypt = None

0 commit comments

Comments
 (0)