annotate roundup/password.py @ 5414:3fa026621f69

Python 3 preparation: comparisons. Python 3 no longer has the cmp function, or cmp= arguments to sorting functions / methods (key= must be used instead), and requires rich comparison methods such as __lt__ to be defined instead of using __cmp__. All of the comparison mechanisms supported in Python 3 are also supported in Python 2. This patch makes the corresponding changes in Roundup to use key functions and rich comparison methods. In the case of the JournalPassword and Permission classes, only __eq__ and __ne__ are defined as I don't see ordered comparisons as useful there (and for Permission, the old __cmp__ function didn't try to provide a valid ordering). In the case of the Date class, I kept the __cmp__ method and implemented the others in terms of it, to avoid excess repetitiveness in duplicating implementation code for all six rich comparison methods. In roundup/admin.py, help_commands_html used operator.attrgetter to produce the second argument of sorted() - which would be reasonable for a key function, but the second argument is the cmp function in Python 2, not a key function (and the key function must be a named argument not a positional argument in Python 3). That function appears to be completely unused, so I expect that code never worked. This patch adds the missing key= to that sorted() call, but it would also be reasonable to remove the unused function completely instead.
author Joseph Myers <jsm@polyomino.org.uk>
date Wed, 25 Jul 2018 00:39:37 +0000
parents a391a071d045
children 2d6a92c3e212
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
270
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1 #
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2 # Copyright (c) 2001 Bizar Software Pty Ltd (http://www.bizarsoftware.com.au/)
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
3 # This module is free software, and you may redistribute it and/or modify
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
4 # under the same terms as Python, so long as this copyright message and
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
5 # disclaimer are retained in their original form.
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
6 #
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
7 # IN NO EVENT SHALL BIZAR SOFTWARE PTY LTD BE LIABLE TO ANY PARTY FOR
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
8 # DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
9 # OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
10 # POSSIBILITY OF SUCH DAMAGE.
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
11 #
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
12 # BIZAR SOFTWARE PTY LTD SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
13 # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
14 # FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS"
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
15 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
16 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
3434
1f860b50fa5f encodePassword: don't trim the salt string...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2277
diff changeset
17 #
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 1905
diff changeset
18 """Password handling (encoding, decoding).
406
bdc2ea127ae9 Added module docstrings to all modules.
Jürgen Hermann <jhermann@users.sourceforge.net>
parents: 302
diff changeset
19 """
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 1905
diff changeset
20 __docformat__ = 'restructuredtext'
270
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
21
5356
91954be46a66 A real fix for the problem where:
John Rouillard <rouilj@ieee.org>
parents: 5350
diff changeset
22 import re, string, random
5053
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
23 import os
4480
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
24 from base64 import b64encode, b64decode
4982
9ba03348f923 Remove roundup/anypy/hashlib_.py
John Kristensen <john@jerrykan.com>
parents: 4760
diff changeset
25 from hashlib import md5, sha1
9ba03348f923 Remove roundup/anypy/hashlib_.py
John Kristensen <john@jerrykan.com>
parents: 4760
diff changeset
26
1229
5c581b120738 added "crypt" password encoding...
Richard Jones <richard@users.sourceforge.net>
parents: 1090
diff changeset
27 try:
1231
c0a40d7ec47c fix typo
Gordon B. McMillan <gmcm@users.sourceforge.net>
parents: 1229
diff changeset
28 import crypt
4089
eddb82d0964c Add compatibility package to allow us to deal with Python versions 2.3..2.6.
Richard Jones <richard@users.sourceforge.net>
parents: 3439
diff changeset
29 except ImportError:
1229
5c581b120738 added "crypt" password encoding...
Richard Jones <richard@users.sourceforge.net>
parents: 1090
diff changeset
30 crypt = None
270
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
31
4480
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
32 _bempty = ""
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
33 _bjoin = _bempty.join
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
34
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
35 def getrandbytes(count):
5391
a391a071d045 Python 3 preparation: use range() instead of xrange().
Joseph Myers <jsm@polyomino.org.uk>
parents: 5378
diff changeset
36 return _bjoin(chr(random.randint(0,255)) for i in range(count))
4480
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
37
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
38 #NOTE: PBKDF2 hash is using this variant of base64 to minimize encoding size,
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
39 # and have charset that's compatible w/ unix crypt variants
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
40 def h64encode(data):
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
41 """encode using variant of base64"""
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
42 return b64encode(data, "./").strip("=\n")
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
43
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
44 def h64decode(data):
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
45 """decode using variant of base64"""
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
46 off = len(data) % 4
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
47 if off == 0:
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
48 return b64decode(data, "./")
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
49 elif off == 1:
4683
2f66d44616ad windows: Fix failing password tests due to missing crypt module
anatoly techtonik <techtonik@gmail.com>
parents: 4570
diff changeset
50 raise ValueError("Invalid base64 input")
4480
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
51 elif off == 2:
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
52 return b64decode(data + "==", "./")
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
53 else:
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
54 return b64decode(data + "=", "./")
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
55
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
56 try:
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
57 from M2Crypto.EVP import pbkdf2 as _pbkdf2
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
58 except ImportError:
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
59 #no m2crypto - make our own pbkdf2 function
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
60 from struct import pack
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
61 from hmac import HMAC
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
62
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
63 def xor_bytes(left, right):
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
64 "perform bitwise-xor of two byte-strings"
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
65 return _bjoin(chr(ord(l) ^ ord(r)) for l, r in zip(left, right))
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
66
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
67 def _pbkdf2(password, salt, rounds, keylen):
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
68 digest_size = 20 # sha1 generates 20-byte blocks
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
69 total_blocks = int((keylen+digest_size-1)/digest_size)
4982
9ba03348f923 Remove roundup/anypy/hashlib_.py
John Kristensen <john@jerrykan.com>
parents: 4760
diff changeset
70 hmac_template = HMAC(password, None, sha1)
4480
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
71 out = _bempty
5391
a391a071d045 Python 3 preparation: use range() instead of xrange().
Joseph Myers <jsm@polyomino.org.uk>
parents: 5378
diff changeset
72 for i in range(1, total_blocks+1):
4480
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
73 hmac = hmac_template.copy()
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
74 hmac.update(salt + pack(">L",i))
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
75 block = tmp = hmac.digest()
5391
a391a071d045 Python 3 preparation: use range() instead of xrange().
Joseph Myers <jsm@polyomino.org.uk>
parents: 5378
diff changeset
76 for j in range(rounds-1):
4480
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
77 hmac = hmac_template.copy()
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
78 hmac.update(tmp)
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
79 tmp = hmac.digest()
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
80 #TODO: need to speed up this call
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
81 block = xor_bytes(block, tmp)
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
82 out += block
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
83 return out[:keylen]
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
84
5053
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
85 def ssha(password, salt):
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
86 ''' Make ssha digest from password and salt.
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
87 Based on code of Roberto Aguilar <roberto@baremetal.io>
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
88 https://gist.github.com/rca/7217540
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
89 '''
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
90 shaval = sha1(password)
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
91 shaval.update( salt )
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
92 ssha_digest = b64encode( '{}{}'.format(shaval.digest(), salt) ).strip()
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
93 return ssha_digest
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
94
4480
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
95 def pbkdf2(password, salt, rounds, keylen):
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
96 """pkcs#5 password-based key derivation v2.0
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
97
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
98 :arg password: passphrase to use to generate key (if unicode, converted to utf-8)
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
99 :arg salt: salt string to use when generating key (if unicode, converted to utf-8)
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
100 :param rounds: number of rounds to use to generate key
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
101 :arg keylen: number of bytes to generate
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
102
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
103 If M2Crypto is present, uses it's implementation as backend.
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
104
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
105 :returns:
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
106 raw bytes of generated key
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
107 """
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
108 if isinstance(password, unicode):
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
109 password = password.encode("utf-8")
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
110 if isinstance(salt, unicode):
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
111 salt = salt.encode("utf-8")
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
112 if keylen > 40:
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
113 #NOTE: pbkdf2 allows up to (2**31-1)*20 bytes,
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
114 # but m2crypto has issues on some platforms above 40,
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
115 # and such sizes aren't needed for a password hash anyways...
5378
35ea9b1efc14 Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5356
diff changeset
116 raise ValueError("key length too large")
4480
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
117 if rounds < 1:
5378
35ea9b1efc14 Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5356
diff changeset
118 raise ValueError("rounds must be positive number")
4480
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
119 return _pbkdf2(password, salt, rounds, keylen)
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
120
1905
dc43e339e607 Centralised conversion of user-input data to hyperdb values
Richard Jones <richard@users.sourceforge.net>
parents: 1583
diff changeset
121 class PasswordValueError(ValueError):
4089
eddb82d0964c Add compatibility package to allow us to deal with Python versions 2.3..2.6.
Richard Jones <richard@users.sourceforge.net>
parents: 3439
diff changeset
122 """ The password value is not valid """
1905
dc43e339e607 Centralised conversion of user-input data to hyperdb values
Richard Jones <richard@users.sourceforge.net>
parents: 1583
diff changeset
123 pass
dc43e339e607 Centralised conversion of user-input data to hyperdb values
Richard Jones <richard@users.sourceforge.net>
parents: 1583
diff changeset
124
4484
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
125 def pbkdf2_unpack(pbkdf2):
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
126 """ unpack pbkdf2 encrypted password into parts,
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
127 assume it has format "{rounds}${salt}${digest}
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
128 """
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
129 if isinstance(pbkdf2, unicode):
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
130 pbkdf2 = pbkdf2.encode("ascii")
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
131 try:
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
132 rounds, salt, digest = pbkdf2.split("$")
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
133 except ValueError:
5378
35ea9b1efc14 Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5356
diff changeset
134 raise PasswordValueError("invalid PBKDF2 hash (wrong number of separators)")
4484
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
135 if rounds.startswith("0"):
5378
35ea9b1efc14 Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5356
diff changeset
136 raise PasswordValueError("invalid PBKDF2 hash (zero-padded rounds)")
4484
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
137 try:
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
138 rounds = int(rounds)
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
139 except ValueError:
5378
35ea9b1efc14 Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5356
diff changeset
140 raise PasswordValueError("invalid PBKDF2 hash (invalid rounds)")
4484
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
141 raw_salt = h64decode(salt)
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
142 return rounds, salt, raw_salt, digest
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
143
4486
693c75d56ebe Add new config-option 'password_pbkdf2_default_rounds'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4485
diff changeset
144 def encodePassword(plaintext, scheme, other=None, config=None):
4089
eddb82d0964c Add compatibility package to allow us to deal with Python versions 2.3..2.6.
Richard Jones <richard@users.sourceforge.net>
parents: 3439
diff changeset
145 """Encrypt the plaintext password.
eddb82d0964c Add compatibility package to allow us to deal with Python versions 2.3..2.6.
Richard Jones <richard@users.sourceforge.net>
parents: 3439
diff changeset
146 """
1343
2e557762ee87 fixed handling of missing password [SF#655632]
Richard Jones <richard@users.sourceforge.net>
parents: 1231
diff changeset
147 if plaintext is None:
2e557762ee87 fixed handling of missing password [SF#655632]
Richard Jones <richard@users.sourceforge.net>
parents: 1231
diff changeset
148 plaintext = ""
4480
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
149 if scheme == "PBKDF2":
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
150 if other:
4484
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
151 rounds, salt, raw_salt, digest = pbkdf2_unpack(other)
4480
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
152 else:
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
153 raw_salt = getrandbytes(20)
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
154 salt = h64encode(raw_salt)
4486
693c75d56ebe Add new config-option 'password_pbkdf2_default_rounds'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4485
diff changeset
155 if config:
693c75d56ebe Add new config-option 'password_pbkdf2_default_rounds'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4485
diff changeset
156 rounds = config.PASSWORD_PBKDF2_DEFAULT_ROUNDS
693c75d56ebe Add new config-option 'password_pbkdf2_default_rounds'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4485
diff changeset
157 else:
693c75d56ebe Add new config-option 'password_pbkdf2_default_rounds'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4485
diff changeset
158 rounds = 10000
4480
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
159 if rounds < 1000:
5378
35ea9b1efc14 Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5356
diff changeset
160 raise PasswordValueError("invalid PBKDF2 hash (rounds too low)")
4480
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
161 raw_digest = pbkdf2(plaintext, raw_salt, rounds, 20)
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
162 return "%d$%s$%s" % (rounds, salt, h64encode(raw_digest))
5053
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
163 elif scheme == 'SSHA':
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
164 if other:
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
165 raw_other = b64decode(other)
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
166 salt = raw_other[20:]
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
167 else:
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
168 #new password
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
169 # variable salt length
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
170 salt_len = random.randrange(36, 52)
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
171 salt = os.urandom(salt_len)
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
172 s = ssha(plaintext, salt)
4480
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
173 elif scheme == 'SHA':
4089
eddb82d0964c Add compatibility package to allow us to deal with Python versions 2.3..2.6.
Richard Jones <richard@users.sourceforge.net>
parents: 3439
diff changeset
174 s = sha1(plaintext).hexdigest()
2277
c9e52addda42 added MD5 scheme for password hiding
Richard Jones <richard@users.sourceforge.net>
parents: 2098
diff changeset
175 elif scheme == 'MD5':
4089
eddb82d0964c Add compatibility package to allow us to deal with Python versions 2.3..2.6.
Richard Jones <richard@users.sourceforge.net>
parents: 3439
diff changeset
176 s = md5(plaintext).hexdigest()
1229
5c581b120738 added "crypt" password encoding...
Richard Jones <richard@users.sourceforge.net>
parents: 1090
diff changeset
177 elif scheme == 'crypt' and crypt is not None:
5c581b120738 added "crypt" password encoding...
Richard Jones <richard@users.sourceforge.net>
parents: 1090
diff changeset
178 if other is not None:
3434
1f860b50fa5f encodePassword: don't trim the salt string...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2277
diff changeset
179 salt = other
1229
5c581b120738 added "crypt" password encoding...
Richard Jones <richard@users.sourceforge.net>
parents: 1090
diff changeset
180 else:
5c581b120738 added "crypt" password encoding...
Richard Jones <richard@users.sourceforge.net>
parents: 1090
diff changeset
181 saltchars = './0123456789'+string.letters
5c581b120738 added "crypt" password encoding...
Richard Jones <richard@users.sourceforge.net>
parents: 1090
diff changeset
182 salt = random.choice(saltchars) + random.choice(saltchars)
5c581b120738 added "crypt" password encoding...
Richard Jones <richard@users.sourceforge.net>
parents: 1090
diff changeset
183 s = crypt.crypt(plaintext, salt)
270
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
184 elif scheme == 'plaintext':
1229
5c581b120738 added "crypt" password encoding...
Richard Jones <richard@users.sourceforge.net>
parents: 1090
diff changeset
185 s = plaintext
270
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
186 else:
5378
35ea9b1efc14 Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5356
diff changeset
187 raise PasswordValueError('Unknown encryption scheme %r'%scheme)
270
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
188 return s
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
189
4760
efdce3d32698 Increase generated password length to 12 symbols.
anatoly techtonik <techtonik@gmail.com>
parents: 4683
diff changeset
190 def generatePassword(length=12):
1583
caae7d8934dc set new email rego user password to random string
Richard Jones <richard@users.sourceforge.net>
parents: 1343
diff changeset
191 chars = string.letters+string.digits
4760
efdce3d32698 Increase generated password length to 12 symbols.
anatoly techtonik <techtonik@gmail.com>
parents: 4683
diff changeset
192 password = [random.choice(chars) for x in range(length)]
efdce3d32698 Increase generated password length to 12 symbols.
anatoly techtonik <techtonik@gmail.com>
parents: 4683
diff changeset
193 # make sure there is at least one digit
efdce3d32698 Increase generated password length to 12 symbols.
anatoly techtonik <techtonik@gmail.com>
parents: 4683
diff changeset
194 password[0] = random.choice(string.digits)
efdce3d32698 Increase generated password length to 12 symbols.
anatoly techtonik <techtonik@gmail.com>
parents: 4683
diff changeset
195 random.shuffle(password)
efdce3d32698 Increase generated password length to 12 symbols.
anatoly techtonik <techtonik@gmail.com>
parents: 4683
diff changeset
196 return ''.join(password)
1583
caae7d8934dc set new email rego user password to random string
Richard Jones <richard@users.sourceforge.net>
parents: 1343
diff changeset
197
4483
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
198 class JournalPassword:
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
199 """ Password dummy instance intended for journal operation.
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
200 We do not store passwords in the journal any longer. The dummy
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
201 version only reads the encryption scheme from the given
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
202 encrypted password.
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
203 """
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
204 default_scheme = 'PBKDF2' # new encryptions use this scheme
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
205 pwre = re.compile(r'{(\w+)}(.+)')
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
206
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
207 def __init__ (self, encrypted=''):
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
208 if isinstance(encrypted, self.__class__):
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
209 self.scheme = encrypted.scheme or self.default_scheme
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
210 else:
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
211 m = self.pwre.match(encrypted)
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
212 if m:
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
213 self.scheme = m.group(1)
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
214 else:
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
215 self.scheme = self.default_scheme
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
216 self.password = ''
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
217
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
218 def dummystr(self):
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
219 """ return dummy string to store in journal
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
220 - reports scheme, but nothing else
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
221 """
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
222 return "{%s}*encrypted*" % (self.scheme,)
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
223
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
224 __str__ = dummystr
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
225
5414
3fa026621f69 Python 3 preparation: comparisons.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5391
diff changeset
226 def __eq__(self, other):
4483
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
227 """Compare this password against another password."""
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
228 # check to see if we're comparing instances
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
229 if isinstance(other, self.__class__):
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
230 if self.scheme != other.scheme:
5414
3fa026621f69 Python 3 preparation: comparisons.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5391
diff changeset
231 return False
3fa026621f69 Python 3 preparation: comparisons.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5391
diff changeset
232 return self.password == other.password
4483
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
233
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
234 # assume password is plaintext
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
235 if self.password is None:
5378
35ea9b1efc14 Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5356
diff changeset
236 raise ValueError('Password not set')
5414
3fa026621f69 Python 3 preparation: comparisons.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5391
diff changeset
237 return self.password == encodePassword(other, self.scheme,
3fa026621f69 Python 3 preparation: comparisons.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5391
diff changeset
238 self.password or None)
3fa026621f69 Python 3 preparation: comparisons.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5391
diff changeset
239
3fa026621f69 Python 3 preparation: comparisons.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5391
diff changeset
240 def __ne__(self, other):
3fa026621f69 Python 3 preparation: comparisons.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5391
diff changeset
241 return not self.__eq__(other)
4483
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
242
22bc0426e348 Second patch from issue2550688 -- with some changes:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4480
diff changeset
243 class Password(JournalPassword):
4089
eddb82d0964c Add compatibility package to allow us to deal with Python versions 2.3..2.6.
Richard Jones <richard@users.sourceforge.net>
parents: 3439
diff changeset
244 """The class encapsulates a Password property type value in the database.
270
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
245
2277
c9e52addda42 added MD5 scheme for password hiding
Richard Jones <richard@users.sourceforge.net>
parents: 2098
diff changeset
246 The encoding of the password is one if None, 'SHA', 'MD5' or 'plaintext'.
c9e52addda42 added MD5 scheme for password hiding
Richard Jones <richard@users.sourceforge.net>
parents: 2098
diff changeset
247 The encodePassword function is used to actually encode the password from
270
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
248 plaintext. The None encoding is used in legacy databases where no
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
249 encoding scheme is identified.
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
250
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
251 The scheme is stored with the encoded data in the database:
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
252 {scheme}data
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
253
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
254 Example usage:
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
255 >>> p = Password('sekrit')
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
256 >>> p == 'sekrit'
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
257 1
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
258 >>> p != 'not sekrit'
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
259 1
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
260 >>> 'sekrit' == p
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
261 1
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
262 >>> 'not sekrit' != p
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
263 1
4089
eddb82d0964c Add compatibility package to allow us to deal with Python versions 2.3..2.6.
Richard Jones <richard@users.sourceforge.net>
parents: 3439
diff changeset
264 """
4480
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
265 #TODO: code to migrate from old password schemes.
270
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
266
4485
95aace124a8e use idea from Eli Collins to use a list of deprecated password encoding schemes
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4484
diff changeset
267 deprecated_schemes = ["SHA", "MD5", "crypt", "plaintext"]
5053
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
268 known_schemes = ["PBKDF2", "SSHA"] + deprecated_schemes
270
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
269
4486
693c75d56ebe Add new config-option 'password_pbkdf2_default_rounds'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4485
diff changeset
270 def __init__(self, plaintext=None, scheme=None, encrypted=None, strict=False, config=None):
4089
eddb82d0964c Add compatibility package to allow us to deal with Python versions 2.3..2.6.
Richard Jones <richard@users.sourceforge.net>
parents: 3439
diff changeset
271 """Call setPassword if plaintext is not None."""
1229
5c581b120738 added "crypt" password encoding...
Richard Jones <richard@users.sourceforge.net>
parents: 1090
diff changeset
272 if scheme is None:
5c581b120738 added "crypt" password encoding...
Richard Jones <richard@users.sourceforge.net>
parents: 1090
diff changeset
273 scheme = self.default_scheme
270
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
274 if plaintext is not None:
4486
693c75d56ebe Add new config-option 'password_pbkdf2_default_rounds'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4485
diff changeset
275 self.setPassword (plaintext, scheme, config=config)
2098
18addf2a8596 Implemented proper datatypes in mysql and postgresql backends...
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
276 elif encrypted is not None:
4486
693c75d56ebe Add new config-option 'password_pbkdf2_default_rounds'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4485
diff changeset
277 self.unpack(encrypted, scheme, strict=strict, config=config)
270
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
278 else:
3439
822a2719b81b keep plaintext password in Password object property (rfe [SF#1379447])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3434
diff changeset
279 self.scheme = self.default_scheme
270
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
280 self.password = None
3439
822a2719b81b keep plaintext password in Password object property (rfe [SF#1379447])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3434
diff changeset
281 self.plaintext = None
270
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
282
4484
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
283 def needs_migration(self):
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
284 """ Password has insecure scheme or other insecure parameters
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
285 and needs migration to new password scheme
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
286 """
4485
95aace124a8e use idea from Eli Collins to use a list of deprecated password encoding schemes
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4484
diff changeset
287 if self.scheme in self.deprecated_schemes:
4484
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
288 return True
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
289 rounds, salt, raw_salt, digest = pbkdf2_unpack(self.password)
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
290 if rounds < 1000:
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
291 return True
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
292 return False
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4483
diff changeset
293
4486
693c75d56ebe Add new config-option 'password_pbkdf2_default_rounds'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4485
diff changeset
294 def unpack(self, encrypted, scheme=None, strict=False, config=None):
4089
eddb82d0964c Add compatibility package to allow us to deal with Python versions 2.3..2.6.
Richard Jones <richard@users.sourceforge.net>
parents: 3439
diff changeset
295 """Set the password info from the scheme:<encryted info> string
270
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
296 (the inverse of __str__)
4089
eddb82d0964c Add compatibility package to allow us to deal with Python versions 2.3..2.6.
Richard Jones <richard@users.sourceforge.net>
parents: 3439
diff changeset
297 """
270
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
298 m = self.pwre.match(encrypted)
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
299 if m:
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
300 self.scheme = m.group(1)
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
301 self.password = m.group(2)
3439
822a2719b81b keep plaintext password in Password object property (rfe [SF#1379447])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3434
diff changeset
302 self.plaintext = None
270
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
303 else:
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
304 # currently plaintext - encrypt
4486
693c75d56ebe Add new config-option 'password_pbkdf2_default_rounds'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4485
diff changeset
305 self.setPassword(encrypted, scheme, config=config)
4480
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
306 if strict and self.scheme not in self.known_schemes:
5378
35ea9b1efc14 Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5356
diff changeset
307 raise PasswordValueError("Unknown encryption scheme: %r" % (self.scheme,))
270
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
308
4486
693c75d56ebe Add new config-option 'password_pbkdf2_default_rounds'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4485
diff changeset
309 def setPassword(self, plaintext, scheme=None, config=None):
4089
eddb82d0964c Add compatibility package to allow us to deal with Python versions 2.3..2.6.
Richard Jones <richard@users.sourceforge.net>
parents: 3439
diff changeset
310 """Sets encrypts plaintext."""
1229
5c581b120738 added "crypt" password encoding...
Richard Jones <richard@users.sourceforge.net>
parents: 1090
diff changeset
311 if scheme is None:
5c581b120738 added "crypt" password encoding...
Richard Jones <richard@users.sourceforge.net>
parents: 1090
diff changeset
312 scheme = self.default_scheme
3439
822a2719b81b keep plaintext password in Password object property (rfe [SF#1379447])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3434
diff changeset
313 self.scheme = scheme
4486
693c75d56ebe Add new config-option 'password_pbkdf2_default_rounds'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4485
diff changeset
314 self.password = encodePassword(plaintext, scheme, config=config)
3439
822a2719b81b keep plaintext password in Password object property (rfe [SF#1379447])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3434
diff changeset
315 self.plaintext = plaintext
270
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
316
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
317 def __str__(self):
4089
eddb82d0964c Add compatibility package to allow us to deal with Python versions 2.3..2.6.
Richard Jones <richard@users.sourceforge.net>
parents: 3439
diff changeset
318 """Stringify the encrypted password for database storage."""
270
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
319 if self.password is None:
5378
35ea9b1efc14 Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5356
diff changeset
320 raise ValueError('Password not set')
270
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
321 return '{%s}%s'%(self.scheme, self.password)
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
322
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
323 def test():
1229
5c581b120738 added "crypt" password encoding...
Richard Jones <richard@users.sourceforge.net>
parents: 1090
diff changeset
324 # SHA
270
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
325 p = Password('sekrit')
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
326 assert p == 'sekrit'
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
327 assert p != 'not sekrit'
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
328 assert 'sekrit' == p
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
329 assert 'not sekrit' != p
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
330
2277
c9e52addda42 added MD5 scheme for password hiding
Richard Jones <richard@users.sourceforge.net>
parents: 2098
diff changeset
331 # MD5
c9e52addda42 added MD5 scheme for password hiding
Richard Jones <richard@users.sourceforge.net>
parents: 2098
diff changeset
332 p = Password('sekrit', 'MD5')
c9e52addda42 added MD5 scheme for password hiding
Richard Jones <richard@users.sourceforge.net>
parents: 2098
diff changeset
333 assert p == 'sekrit'
c9e52addda42 added MD5 scheme for password hiding
Richard Jones <richard@users.sourceforge.net>
parents: 2098
diff changeset
334 assert p != 'not sekrit'
c9e52addda42 added MD5 scheme for password hiding
Richard Jones <richard@users.sourceforge.net>
parents: 2098
diff changeset
335 assert 'sekrit' == p
c9e52addda42 added MD5 scheme for password hiding
Richard Jones <richard@users.sourceforge.net>
parents: 2098
diff changeset
336 assert 'not sekrit' != p
c9e52addda42 added MD5 scheme for password hiding
Richard Jones <richard@users.sourceforge.net>
parents: 2098
diff changeset
337
1229
5c581b120738 added "crypt" password encoding...
Richard Jones <richard@users.sourceforge.net>
parents: 1090
diff changeset
338 # crypt
4683
2f66d44616ad windows: Fix failing password tests due to missing crypt module
anatoly techtonik <techtonik@gmail.com>
parents: 4570
diff changeset
339 if crypt: # not available on Windows
2f66d44616ad windows: Fix failing password tests due to missing crypt module
anatoly techtonik <techtonik@gmail.com>
parents: 4570
diff changeset
340 p = Password('sekrit', 'crypt')
2f66d44616ad windows: Fix failing password tests due to missing crypt module
anatoly techtonik <techtonik@gmail.com>
parents: 4570
diff changeset
341 assert p == 'sekrit'
2f66d44616ad windows: Fix failing password tests due to missing crypt module
anatoly techtonik <techtonik@gmail.com>
parents: 4570
diff changeset
342 assert p != 'not sekrit'
2f66d44616ad windows: Fix failing password tests due to missing crypt module
anatoly techtonik <techtonik@gmail.com>
parents: 4570
diff changeset
343 assert 'sekrit' == p
2f66d44616ad windows: Fix failing password tests due to missing crypt module
anatoly techtonik <techtonik@gmail.com>
parents: 4570
diff changeset
344 assert 'not sekrit' != p
1229
5c581b120738 added "crypt" password encoding...
Richard Jones <richard@users.sourceforge.net>
parents: 1090
diff changeset
345
5053
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
346 # SSHA
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
347 p = Password('sekrit', 'SSHA')
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
348 assert p == 'sekrit'
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
349 assert p != 'not sekrit'
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
350 assert 'sekrit' == p
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
351 assert 'not sekrit' != p
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4982
diff changeset
352
4480
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
353 # PBKDF2 - low level function
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
354 from binascii import unhexlify
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
355 k = pbkdf2("password", "ATHENA.MIT.EDUraeburn", 1200, 32)
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
356 assert k == unhexlify("5c08eb61fdf71e4e4ec3cf6ba1f5512ba7e52ddbc5e5142f708a31e2e62b1e13")
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
357
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
358 # PBKDF2 - hash function
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
359 h = "5000$7BvbBq.EZzz/O0HuwX3iP.nAG3s$g3oPnFFaga2BJaX5PoPRljl4XIE"
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
360 assert encodePassword("sekrit", "PBKDF2", h) == h
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
361
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
362 # PBKDF2 - high level integration
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
363 p = Password('sekrit', 'PBKDF2')
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
364 assert p == 'sekrit'
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
365 assert p != 'not sekrit'
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
366 assert 'sekrit' == p
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
367 assert 'not sekrit' != p
1613754d2646 Fix first part of Password handling security issue2550688
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4089
diff changeset
368
270
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
369 if __name__ == '__main__':
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
370 test()
a4241ddd22d7 Added the Password property type.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
371
3434
1f860b50fa5f encodePassword: don't trim the salt string...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2277
diff changeset
372 # vim: set filetype=python sts=4 sw=4 et si :

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