##// END OF EJS Templates
Remove unnecessary check on password salt length.
Fernando Perez -
Show More
@@ -1,117 +1,117 b''
1 """
1 """
2 Password generation for the IPython notebook.
2 Password generation for the IPython notebook.
3 """
3 """
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Imports
5 # Imports
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 # Stdlib
7 # Stdlib
8 import getpass
8 import getpass
9 import hashlib
9 import hashlib
10 import random
10 import random
11
11
12 # Our own
12 # Our own
13 from IPython.core.error import UsageError
13 from IPython.core.error import UsageError
14 from IPython.testing.skipdoctest import skip_doctest
14 from IPython.testing.skipdoctest import skip_doctest
15
15
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17 # Globals
17 # Globals
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19
19
20 # Length of the salt in nr of hex chars, which implies salt_len * 4
20 # Length of the salt in nr of hex chars, which implies salt_len * 4
21 # bits of randomness.
21 # bits of randomness.
22 salt_len = 12
22 salt_len = 12
23
23
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 # Functions
25 # Functions
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27
27
28 @skip_doctest
28 @skip_doctest
29 def passwd(passphrase=None, algorithm='sha1'):
29 def passwd(passphrase=None, algorithm='sha1'):
30 """Generate hashed password and salt for use in notebook configuration.
30 """Generate hashed password and salt for use in notebook configuration.
31
31
32 In the notebook configuration, set `c.NotebookApp.password` to
32 In the notebook configuration, set `c.NotebookApp.password` to
33 the generated string.
33 the generated string.
34
34
35 Parameters
35 Parameters
36 ----------
36 ----------
37 passphrase : str
37 passphrase : str
38 Password to hash. If unspecified, the user is asked to input
38 Password to hash. If unspecified, the user is asked to input
39 and verify a password.
39 and verify a password.
40 algorithm : str
40 algorithm : str
41 Hashing algorithm to use (e.g, 'sha1' or any argument supported
41 Hashing algorithm to use (e.g, 'sha1' or any argument supported
42 by :func:`hashlib.new`).
42 by :func:`hashlib.new`).
43
43
44 Returns
44 Returns
45 -------
45 -------
46 hashed_passphrase : str
46 hashed_passphrase : str
47 Hashed password, in the format 'hash_algorithm:salt:passphrase_hash'.
47 Hashed password, in the format 'hash_algorithm:salt:passphrase_hash'.
48
48
49 Examples
49 Examples
50 --------
50 --------
51 In [1]: passwd('mypassword')
51 In [1]: passwd('mypassword')
52 Out[1]: 'sha1:7cf3:b7d6da294ea9592a9480c8f52e63cd42cfb9dd12'
52 Out[1]: 'sha1:7cf3:b7d6da294ea9592a9480c8f52e63cd42cfb9dd12'
53
53
54 """
54 """
55 if passphrase is None:
55 if passphrase is None:
56 for i in range(3):
56 for i in range(3):
57 p0 = getpass.getpass('Enter password: ')
57 p0 = getpass.getpass('Enter password: ')
58 p1 = getpass.getpass('Verify password: ')
58 p1 = getpass.getpass('Verify password: ')
59 if p0 == p1:
59 if p0 == p1:
60 passphrase = p0
60 passphrase = p0
61 break
61 break
62 else:
62 else:
63 print('Passwords do not match.')
63 print('Passwords do not match.')
64 else:
64 else:
65 raise UsageError('No matching passwords found. Giving up.')
65 raise UsageError('No matching passwords found. Giving up.')
66
66
67 h = hashlib.new(algorithm)
67 h = hashlib.new(algorithm)
68 salt = ('%0' + str(salt_len) + 'x') % random.getrandbits(4 * salt_len)
68 salt = ('%0' + str(salt_len) + 'x') % random.getrandbits(4 * salt_len)
69 h.update(passphrase + salt)
69 h.update(passphrase + salt)
70
70
71 return ':'.join((algorithm, salt, h.hexdigest()))
71 return ':'.join((algorithm, salt, h.hexdigest()))
72
72
73
73
74 def passwd_check(hashed_passphrase, passphrase):
74 def passwd_check(hashed_passphrase, passphrase):
75 """Verify that a given passphrase matches its hashed version.
75 """Verify that a given passphrase matches its hashed version.
76
76
77 Parameters
77 Parameters
78 ----------
78 ----------
79 hashed_passphrase : str
79 hashed_passphrase : str
80 Hashed password, in the format returned by `passwd`.
80 Hashed password, in the format returned by `passwd`.
81 passphrase : str
81 passphrase : str
82 Passphrase to validate.
82 Passphrase to validate.
83
83
84 Returns
84 Returns
85 -------
85 -------
86 valid : bool
86 valid : bool
87 True if the passphrase matches the hash.
87 True if the passphrase matches the hash.
88
88
89 Examples
89 Examples
90 --------
90 --------
91 In [1]: from IPython.lib.security import passwd_check
91 In [1]: from IPython.lib.security import passwd_check
92
92
93 In [2]: passwd_check('sha1:0e112c3ddfce:a68df677475c2b47b6e86d0467eec97ac5f4b85a',
93 In [2]: passwd_check('sha1:0e112c3ddfce:a68df677475c2b47b6e86d0467eec97ac5f4b85a',
94 ...: 'mypassword')
94 ...: 'mypassword')
95 Out[2]: True
95 Out[2]: True
96
96
97 In [3]: passwd_check('sha1:0e112c3ddfce:a68df677475c2b47b6e86d0467eec97ac5f4b85a',
97 In [3]: passwd_check('sha1:0e112c3ddfce:a68df677475c2b47b6e86d0467eec97ac5f4b85a',
98 ...: 'anotherpassword')
98 ...: 'anotherpassword')
99 Out[3]: False
99 Out[3]: False
100
100
101 """
101 """
102 try:
102 try:
103 algorithm, salt, pw_digest = hashed_passphrase.split(':', 2)
103 algorithm, salt, pw_digest = hashed_passphrase.split(':', 2)
104 except (ValueError, TypeError):
104 except (ValueError, TypeError):
105 return False
105 return False
106
106
107 try:
107 try:
108 h = hashlib.new(algorithm)
108 h = hashlib.new(algorithm)
109 except ValueError:
109 except ValueError:
110 return False
110 return False
111
111
112 if len(pw_digest) == 0 or len(salt) != salt_len:
112 if len(pw_digest) == 0:
113 return False
113 return False
114
114
115 h.update(passphrase + salt)
115 h.update(passphrase + salt)
116
116
117 return h.hexdigest() == pw_digest
117 return h.hexdigest() == pw_digest
General Comments 0
You need to be logged in to leave comments. Login now