##// END OF EJS Templates
Merge pull request #1627 from minrk/msgspec...
Merge pull request #1627 from minrk/msgspec Test the Message Spec and add our zmq subpackage to the test suite. It uses Traitlets to perform validation of keys. Checks right now are not very strict, as (almost) any key is allowed to be None, as long as it is defined. This is because I simply do not know which keys are allowed to be None, and this is not discussed in the specification. If no keys are allowed to be None, we violate that all over the place. Parametric tests are used, so every key validation counts as a test (147!). Message spec doc was found to misrepresent code in a few points, and some changes were made: * spec had error keys as `exc_name/value`, but we are actually using `ename/value` (docs updated to match code) * payloads were inaccurate - list of dicts, rather than single dict, and transformed_output is a payload, not top-level in exec-reply (docs update to match code). * in oinfo_request, detail_level was in message spec, but not actually implemented (code updated to match docs). History messages are not yet tested, but I think I get at least elementary coverage of everything else in the doc.

File last commit:

r5343:9a89486e
r6567:232fa81a merge
Show More
security.py
118 lines | 3.4 KiB | text/x-python | PythonLexer
Stefan van der Walt
Add hashed passphrase generation and verification.
r5320 """
Password generation for the IPython notebook.
"""
Fernando Perez
Fix failing doctests and post correct example of passwd() usage.
r5337 #-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
# Stdlib
import getpass
Stefan van der Walt
Add hashed passphrase generation and verification.
r5320 import hashlib
import random
Fernando Perez
Fix failing doctests and post correct example of passwd() usage.
r5337 # Our own
Stefan van der Walt
Throw UsageError instead of ValueError.
r5335 from IPython.core.error import UsageError
Fernando Perez
Fix failing doctests and post correct example of passwd() usage.
r5337 from IPython.testing.skipdoctest import skip_doctest
Thomas Kluyver
Fix password hashing for Python 3...
r5343 from IPython.utils.py3compat import cast_bytes, str_to_bytes
Fernando Perez
Fix failing doctests and post correct example of passwd() usage.
r5337
#-----------------------------------------------------------------------------
# Globals
#-----------------------------------------------------------------------------
Stefan van der Walt
Throw UsageError instead of ValueError.
r5335
Stefan van der Walt
Use a global variable to adjust the number of bits used to generate the salt.
r5332 # Length of the salt in nr of hex chars, which implies salt_len * 4
# bits of randomness.
salt_len = 12
Fernando Perez
Fix failing doctests and post correct example of passwd() usage.
r5337 #-----------------------------------------------------------------------------
# Functions
#-----------------------------------------------------------------------------
@skip_doctest
Stefan van der Walt
Try to get password from user three times.
r5334 def passwd(passphrase=None, algorithm='sha1'):
Stefan van der Walt
Add hashed passphrase generation and verification.
r5320 """Generate hashed password and salt for use in notebook configuration.
Stefan van der Walt
In passwd, mention which variable in the notebook config to update.
r5322 In the notebook configuration, set `c.NotebookApp.password` to
the generated string.
Stefan van der Walt
Add hashed passphrase generation and verification.
r5320 Parameters
----------
passphrase : str
Stefan van der Walt
If no password is given, ask for one on the prompt.
r5333 Password to hash. If unspecified, the user is asked to input
and verify a password.
Stefan van der Walt
Allow any hashing algorithm.
r5328 algorithm : str
Stefan van der Walt
Update docstring to refer to hashlib.
r5331 Hashing algorithm to use (e.g, 'sha1' or any argument supported
by :func:`hashlib.new`).
Stefan van der Walt
Add hashed passphrase generation and verification.
r5320
Returns
-------
hashed_passphrase : str
Hashed password, in the format 'hash_algorithm:salt:passphrase_hash'.
Examples
--------
In [1]: passwd('mypassword')
Out[1]: 'sha1:7cf3:b7d6da294ea9592a9480c8f52e63cd42cfb9dd12'
"""
Stefan van der Walt
Try to get password from user three times.
r5334 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.')
Stefan van der Walt
If no password is given, ask for one on the prompt.
r5333 else:
Stefan van der Walt
Throw UsageError instead of ValueError.
r5335 raise UsageError('No matching passwords found. Giving up.')
Stefan van der Walt
If no password is given, ask for one on the prompt.
r5333
Stefan van der Walt
Add hashed passphrase generation and verification.
r5320 h = hashlib.new(algorithm)
Stefan van der Walt
Use a global variable to adjust the number of bits used to generate the salt.
r5332 salt = ('%0' + str(salt_len) + 'x') % random.getrandbits(4 * salt_len)
Thomas Kluyver
Fix password hashing for Python 3...
r5343 h.update(cast_bytes(passphrase, 'utf-8') + str_to_bytes(salt, 'ascii'))
Stefan van der Walt
Add hashed passphrase generation and verification.
r5320
return ':'.join((algorithm, salt, h.hexdigest()))
Fernando Perez
Fix failing doctests and post correct example of passwd() usage.
r5337
Stefan van der Walt
Add hashed passphrase generation and verification.
r5320 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
--------
In [1]: from IPython.lib.security import passwd_check
Fernando Perez
Fix failing doctests and post correct example of passwd() usage.
r5337 In [2]: passwd_check('sha1:0e112c3ddfce:a68df677475c2b47b6e86d0467eec97ac5f4b85a',
Stefan van der Walt
Add hashed passphrase generation and verification.
r5320 ...: 'mypassword')
Out[2]: True
Fernando Perez
Fix failing doctests and post correct example of passwd() usage.
r5337 In [3]: passwd_check('sha1:0e112c3ddfce:a68df677475c2b47b6e86d0467eec97ac5f4b85a',
Stefan van der Walt
Add hashed passphrase generation and verification.
r5320 ...: 'anotherpassword')
Out[3]: False
"""
try:
algorithm, salt, pw_digest = hashed_passphrase.split(':', 2)
except (ValueError, TypeError):
return False
Stefan van der Walt
Allow any hashing algorithm.
r5328 try:
h = hashlib.new(algorithm)
except ValueError:
return False
Fernando Perez
Remove unnecessary check on password salt length.
r5338 if len(pw_digest) == 0:
Stefan van der Walt
Add hashed passphrase generation and verification.
r5320 return False
Thomas Kluyver
Fix password hashing for Python 3...
r5343 h.update(cast_bytes(passphrase, 'utf-8') + str_to_bytes(salt, 'ascii'))
Stefan van der Walt
Add hashed passphrase generation and verification.
r5320
return h.hexdigest() == pw_digest