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