comparison roundup/password.py @ 5378:35ea9b1efc14

Python 3 preparation: "raise" syntax. Changing "raise Exception, value" to "raise Exception(value)". Tool-assisted patch. Particular cases to check carefully are the one place in frontends/ZRoundup/ZRoundup.py where a string exception needed to be fixed, and the one in roundup/cgi/client.py involving raising an exception with a traceback (requires three-argument form of raise in Python 2, which as I understand it requires exec() to avoid a Python 3 syntax error).
author Joseph Myers <jsm@polyomino.org.uk>
date Tue, 24 Jul 2018 21:39:58 +0000
parents 91954be46a66
children a391a071d045
comparison
equal deleted inserted replaced
5377:12fe83f90f0d 5378:35ea9b1efc14
111 salt = salt.encode("utf-8") 111 salt = salt.encode("utf-8")
112 if keylen > 40: 112 if keylen > 40:
113 #NOTE: pbkdf2 allows up to (2**31-1)*20 bytes, 113 #NOTE: pbkdf2 allows up to (2**31-1)*20 bytes,
114 # but m2crypto has issues on some platforms above 40, 114 # but m2crypto has issues on some platforms above 40,
115 # and such sizes aren't needed for a password hash anyways... 115 # and such sizes aren't needed for a password hash anyways...
116 raise ValueError, "key length too large" 116 raise ValueError("key length too large")
117 if rounds < 1: 117 if rounds < 1:
118 raise ValueError, "rounds must be positive number" 118 raise ValueError("rounds must be positive number")
119 return _pbkdf2(password, salt, rounds, keylen) 119 return _pbkdf2(password, salt, rounds, keylen)
120 120
121 class PasswordValueError(ValueError): 121 class PasswordValueError(ValueError):
122 """ The password value is not valid """ 122 """ The password value is not valid """
123 pass 123 pass
129 if isinstance(pbkdf2, unicode): 129 if isinstance(pbkdf2, unicode):
130 pbkdf2 = pbkdf2.encode("ascii") 130 pbkdf2 = pbkdf2.encode("ascii")
131 try: 131 try:
132 rounds, salt, digest = pbkdf2.split("$") 132 rounds, salt, digest = pbkdf2.split("$")
133 except ValueError: 133 except ValueError:
134 raise PasswordValueError, "invalid PBKDF2 hash (wrong number of separators)" 134 raise PasswordValueError("invalid PBKDF2 hash (wrong number of separators)")
135 if rounds.startswith("0"): 135 if rounds.startswith("0"):
136 raise PasswordValueError, "invalid PBKDF2 hash (zero-padded rounds)" 136 raise PasswordValueError("invalid PBKDF2 hash (zero-padded rounds)")
137 try: 137 try:
138 rounds = int(rounds) 138 rounds = int(rounds)
139 except ValueError: 139 except ValueError:
140 raise PasswordValueError, "invalid PBKDF2 hash (invalid rounds)" 140 raise PasswordValueError("invalid PBKDF2 hash (invalid rounds)")
141 raw_salt = h64decode(salt) 141 raw_salt = h64decode(salt)
142 return rounds, salt, raw_salt, digest 142 return rounds, salt, raw_salt, digest
143 143
144 def encodePassword(plaintext, scheme, other=None, config=None): 144 def encodePassword(plaintext, scheme, other=None, config=None):
145 """Encrypt the plaintext password. 145 """Encrypt the plaintext password.
155 if config: 155 if config:
156 rounds = config.PASSWORD_PBKDF2_DEFAULT_ROUNDS 156 rounds = config.PASSWORD_PBKDF2_DEFAULT_ROUNDS
157 else: 157 else:
158 rounds = 10000 158 rounds = 10000
159 if rounds < 1000: 159 if rounds < 1000:
160 raise PasswordValueError, "invalid PBKDF2 hash (rounds too low)" 160 raise PasswordValueError("invalid PBKDF2 hash (rounds too low)")
161 raw_digest = pbkdf2(plaintext, raw_salt, rounds, 20) 161 raw_digest = pbkdf2(plaintext, raw_salt, rounds, 20)
162 return "%d$%s$%s" % (rounds, salt, h64encode(raw_digest)) 162 return "%d$%s$%s" % (rounds, salt, h64encode(raw_digest))
163 elif scheme == 'SSHA': 163 elif scheme == 'SSHA':
164 if other: 164 if other:
165 raw_other = b64decode(other) 165 raw_other = b64decode(other)
182 salt = random.choice(saltchars) + random.choice(saltchars) 182 salt = random.choice(saltchars) + random.choice(saltchars)
183 s = crypt.crypt(plaintext, salt) 183 s = crypt.crypt(plaintext, salt)
184 elif scheme == 'plaintext': 184 elif scheme == 'plaintext':
185 s = plaintext 185 s = plaintext
186 else: 186 else:
187 raise PasswordValueError, 'Unknown encryption scheme %r'%scheme 187 raise PasswordValueError('Unknown encryption scheme %r'%scheme)
188 return s 188 return s
189 189
190 def generatePassword(length=12): 190 def generatePassword(length=12):
191 chars = string.letters+string.digits 191 chars = string.letters+string.digits
192 password = [random.choice(chars) for x in range(length)] 192 password = [random.choice(chars) for x in range(length)]
231 return cmp(self.scheme, other.scheme) 231 return cmp(self.scheme, other.scheme)
232 return cmp(self.password, other.password) 232 return cmp(self.password, other.password)
233 233
234 # assume password is plaintext 234 # assume password is plaintext
235 if self.password is None: 235 if self.password is None:
236 raise ValueError, 'Password not set' 236 raise ValueError('Password not set')
237 return cmp(self.password, encodePassword(other, self.scheme, 237 return cmp(self.password, encodePassword(other, self.scheme,
238 self.password or None)) 238 self.password or None))
239 239
240 class Password(JournalPassword): 240 class Password(JournalPassword):
241 """The class encapsulates a Password property type value in the database. 241 """The class encapsulates a Password property type value in the database.
299 self.plaintext = None 299 self.plaintext = None
300 else: 300 else:
301 # currently plaintext - encrypt 301 # currently plaintext - encrypt
302 self.setPassword(encrypted, scheme, config=config) 302 self.setPassword(encrypted, scheme, config=config)
303 if strict and self.scheme not in self.known_schemes: 303 if strict and self.scheme not in self.known_schemes:
304 raise PasswordValueError, "Unknown encryption scheme: %r" % (self.scheme,) 304 raise PasswordValueError("Unknown encryption scheme: %r" % (self.scheme,))
305 305
306 def setPassword(self, plaintext, scheme=None, config=None): 306 def setPassword(self, plaintext, scheme=None, config=None):
307 """Sets encrypts plaintext.""" 307 """Sets encrypts plaintext."""
308 if scheme is None: 308 if scheme is None:
309 scheme = self.default_scheme 309 scheme = self.default_scheme
312 self.plaintext = plaintext 312 self.plaintext = plaintext
313 313
314 def __str__(self): 314 def __str__(self):
315 """Stringify the encrypted password for database storage.""" 315 """Stringify the encrypted password for database storage."""
316 if self.password is None: 316 if self.password is None:
317 raise ValueError, 'Password not set' 317 raise ValueError('Password not set')
318 return '{%s}%s'%(self.scheme, self.password) 318 return '{%s}%s'%(self.scheme, self.password)
319 319
320 def test(): 320 def test():
321 # SHA 321 # SHA
322 p = Password('sekrit') 322 p = Password('sekrit')

Roundup Issue Tracker: http://roundup-tracker.org/