24
24
import string
25
25
import sys
26
26
import warnings
27
-
28
- from base64 import b64encode , b64decode
27
+ from base64 import b64decode , b64encode
29
28
from hashlib import md5 , sha1 , sha512
30
29
31
30
from roundup .anypy import random_
32
-
33
- from roundup .anypy .strings import us2s , b2s , s2b
31
+ from roundup .anypy .strings import b2s , s2b , us2s
34
32
from roundup .exceptions import RoundupException
35
33
36
34
try :
@@ -49,7 +47,7 @@ class ConfigNotSet(RoundupException):
49
47
50
48
51
49
def bchr (c ):
52
- if bytes == str :
50
+ if bytes is str :
53
51
# Python 2.
54
52
return chr (c )
55
53
else :
@@ -58,7 +56,7 @@ def bchr(c):
58
56
59
57
60
58
def bord (c ):
61
- if bytes == str :
59
+ if bytes is str :
62
60
# Python 2.
63
61
return ord (c )
64
62
else :
@@ -97,8 +95,8 @@ def _pbkdf2_sha512(password, salt, rounds, keylen):
97
95
return pbkdf2_hmac ('sha512' , password , salt , rounds , keylen )
98
96
except ImportError :
99
97
# no hashlib.pbkdf2_hmac - make our own pbkdf2 function
100
- from struct import pack
101
98
from hmac import HMAC
99
+ from struct import pack
102
100
103
101
def xor_bytes (left , right ):
104
102
"perform bitwise-xor of two byte-strings"
@@ -114,14 +112,14 @@ def _pbkdf2(password, salt, rounds, keylen, sha=sha1):
114
112
else :
115
113
digest_size = 20 # sha1 generates 20-byte blocks
116
114
117
- total_blocks = int ((keylen + digest_size - 1 ) / digest_size )
115
+ total_blocks = int ((keylen + digest_size - 1 ) / digest_size )
118
116
hmac_template = HMAC (password , None , sha )
119
117
out = _bempty
120
- for i in range (1 , total_blocks + 1 ):
118
+ for i in range (1 , total_blocks + 1 ):
121
119
hmac = hmac_template .copy ()
122
120
hmac .update (salt + pack (">L" , i ))
123
121
block = tmp = hmac .digest ()
124
- for _j in range (rounds - 1 ):
122
+ for _j in range (rounds - 1 ):
125
123
hmac = hmac_template .copy ()
126
124
hmac .update (tmp )
127
125
tmp = hmac .digest ()
@@ -139,7 +137,7 @@ def ssha(password, salt):
139
137
Based on code of Roberto Aguilar <[email protected] >
140
138
https://gist.github.com/rca/7217540
141
139
'''
142
- shaval = sha1 (password ) # nosec
140
+ shaval = sha1 (password ) # noqa: S324
143
141
shaval .update (salt )
144
142
ssha_digest = b2s (b64encode (shaval .digest () + salt ).strip ())
145
143
return ssha_digest
@@ -232,7 +230,7 @@ def encodePassword(plaintext, scheme, other=None, config=None):
232
230
plaintext = ""
233
231
if scheme in ["PBKDF2" , "PBKDF2S5" ]: # all PBKDF schemes
234
232
if other :
235
- rounds , salt , raw_salt , digest = pbkdf2_unpack (other )
233
+ rounds , salt , raw_salt , _digest = pbkdf2_unpack (other )
236
234
else :
237
235
raw_salt = random_ .token_bytes (20 )
238
236
salt = h64encode (raw_salt )
@@ -251,33 +249,34 @@ def encodePassword(plaintext, scheme, other=None, config=None):
251
249
# rounds value of 2,000,000 (for sha1) makes
252
250
# testing increase from 12 minutes to 1 hour in CI.
253
251
rounds = 1000
252
+ elif ("pytest" in sys .modules and
253
+ "PYTEST_CURRENT_TEST" in os .environ ):
254
+ # Set rounds to 1000 if no config is passed and
255
+ # we are running within a pytest test.
256
+ rounds = 1000
254
257
else :
255
- if ("pytest" in sys .modules and
256
- "PYTEST_CURRENT_TEST" in os .environ ):
257
- # Set rounds to 1000 if no config is passed and
258
- # we are running within a pytest test.
259
- rounds = 1000
258
+ import logging
259
+ # Log and abort. Initialize rounds and log (which
260
+ # will probably be ignored) with traceback in case
261
+ # ConfigNotSet exception is removed in the
262
+ # future.
263
+ rounds = 2000000
264
+ logger = logging .getLogger ('roundup' )
265
+ if sys .version_info [0 ] > 2 :
266
+ logger .critical (
267
+ "encodePassword called without config." ,
268
+ stack_info = True )
260
269
else :
261
- import logging
262
- # Log and abort. Initialize rounds and log (which
263
- # will probably be ignored) with traceback in case
264
- # ConfigNotSet exception is removed in the
265
- # future.
266
- rounds = 2000000
267
- logger = logging .getLogger ('roundup' )
268
- if sys .version_info [0 ] > 2 :
269
- logger .critical (
270
- "encodePassword called without config." ,
271
- stack_info = True )
272
- else :
273
- import inspect , traceback # noqa: E401
274
- where = inspect .currentframe ()
275
- trace = traceback .format_stack (where )
276
- logger .critical (
277
- "encodePassword called without config. %s" ,
278
- trace [:- 1 ]
279
- )
280
- raise ConfigNotSet ("encodePassword called without config." )
270
+ import inspect
271
+ import traceback
272
+
273
+ where = inspect .currentframe ()
274
+ trace = traceback .format_stack (where )
275
+ logger .critical (
276
+ "encodePassword called without config. %s" ,
277
+ trace [:- 1 ]
278
+ )
279
+ raise ConfigNotSet ("encodePassword called without config." )
281
280
282
281
if rounds < 1000 :
283
282
raise PasswordValueError ("invalid PBKDF2 hash (rounds too low)" )
@@ -293,21 +292,21 @@ def encodePassword(plaintext, scheme, other=None, config=None):
293
292
else :
294
293
# new password
295
294
# variable salt length
296
- salt_len = random_ .randbelow (52 - 36 ) + 36
295
+ salt_len = random_ .randbelow (52 - 36 ) + 36
297
296
salt = random_ .token_bytes (salt_len )
298
297
s = ssha (s2b (plaintext ), salt )
299
298
elif scheme == 'SHA' :
300
- s = sha1 (s2b (plaintext )).hexdigest () # nosec
299
+ s = sha1 (s2b (plaintext )).hexdigest () # noqa: S324
301
300
elif scheme == 'MD5' :
302
- s = md5 (s2b (plaintext )).hexdigest () # nosec
301
+ s = md5 (s2b (plaintext )).hexdigest () # noqa: S324
303
302
elif scheme == 'crypt' :
304
303
if crypt is None :
305
304
raise PasswordValueError (
306
305
'Unsupported encryption scheme %r' % scheme )
307
306
if other is not None :
308
307
salt = other
309
308
else :
310
- saltchars = './0123456789' + string .ascii_letters
309
+ saltchars = './0123456789' + string .ascii_letters
311
310
salt = random_ .choice (saltchars ) + random_ .choice (saltchars )
312
311
s = crypt .crypt (plaintext , salt )
313
312
elif scheme == 'plaintext' :
@@ -318,7 +317,7 @@ def encodePassword(plaintext, scheme, other=None, config=None):
318
317
319
318
320
319
def generatePassword (length = 12 ):
321
- chars = string .ascii_letters + string .digits
320
+ chars = string .ascii_letters + string .digits
322
321
password = [random_ .choice (chars ) for x in range (length - 1 )]
323
322
# make sure there is at least one digit
324
323
digitidx = random_ .randbelow (length )
@@ -426,9 +425,12 @@ def needs_migration(self, config):
426
425
"""
427
426
if self .scheme in self .deprecated_schemes :
428
427
return True
429
- rounds , salt , raw_salt , digest = pbkdf2_unpack (self .password )
428
+
429
+ rounds , _salt , _raw_salt , _digest = pbkdf2_unpack (self .password )
430
+
430
431
if rounds < 1000 :
431
432
return True
433
+
432
434
if (self .scheme == "PBKDF2" ):
433
435
new_rounds = config .PASSWORD_PBKDF2_DEFAULT_ROUNDS
434
436
if ("pytest" in sys .modules and
@@ -474,10 +476,11 @@ def __str__(self):
474
476
475
477
476
478
def test_missing_crypt (config = None ):
477
- p = encodePassword ('sekrit' , 'crypt' ) # noqa: F841 - test only
479
+ _p = encodePassword ('sekrit' , 'crypt' , config = config )
478
480
479
481
480
482
def test (config = None ):
483
+ # ruff: noqa: S101 SIM300 - asserts are ok
481
484
# SHA
482
485
p = Password ('sekrit' , config = config )
483
486
assert Password (encrypted = str (p )) == 'sekrit'
@@ -488,7 +491,7 @@ def test(config=None):
488
491
assert 'not sekrit' != p
489
492
490
493
# MD5
491
- p = Password ('sekrit' , 'MD5' , config = config )
494
+ p = Password ('sekrit' , 'MD5' , config = config )
492
495
assert Password (encrypted = str (p )) == 'sekrit'
493
496
assert 'sekrit' == Password (encrypted = str (p ))
494
497
assert p == 'sekrit'
@@ -498,7 +501,7 @@ def test(config=None):
498
501
499
502
# crypt
500
503
if crypt : # not available on Windows
501
- p = Password ('sekrit' , 'crypt' , config = config )
504
+ p = Password ('sekrit' , 'crypt' , config = config )
502
505
assert Password (encrypted = str (p )) == 'sekrit'
503
506
assert 'sekrit' == Password (encrypted = str (p ))
504
507
assert p == 'sekrit'
@@ -507,7 +510,7 @@ def test(config=None):
507
510
assert 'not sekrit' != p
508
511
509
512
# SSHA
510
- p = Password ('sekrit' , 'SSHA' , config = config )
513
+ p = Password ('sekrit' , 'SSHA' , config = config )
511
514
assert Password (encrypted = str (p )) == 'sekrit'
512
515
assert 'sekrit' == Password (encrypted = str (p ))
513
516
assert p == 'sekrit'
0 commit comments