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