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