mirror of
https://github.com/ansible/ansible.git
synced 2026-08-03 08:03:05 +02:00
use passlib default if password_hash option isn't set (#75043)
* add changelog fragment * password_hash|length == 120 * mention the new default bcrypt format in the porting guide
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
minor_changes:
|
||||
- password_hash uses passlib default if option isn't set
|
||||
@@ -103,7 +103,7 @@ Plugins
|
||||
|
||||
* ``unique`` filter with Jinja2 < 2.10 is case-sensitive and now raise coherently an error if ``case_sensitive=False`` instead of when ``case_sensitive=True``.
|
||||
* Set theory filters (``intersect``, ``difference``, ``symmetric_difference`` and ``union``) are now case-sensitive. Explicitly use ``case_sensitive=False`` to keep previous behavior. Note: with Jinja2 < 2.10, the filters were already case-sensitive by default.
|
||||
|
||||
* ``password_hash``` now uses ``passlib`` defaults when an option is unspecified, e.g. ``bcrypt_sha256`` now default to the "2b" format and if the "2a" format is required it must be specified.
|
||||
|
||||
Porting custom scripts
|
||||
======================
|
||||
|
||||
@@ -78,9 +78,9 @@ class BaseHash(object):
|
||||
algo = namedtuple('algo', ['crypt_id', 'salt_size', 'implicit_rounds', 'salt_exact', 'implicit_ident'])
|
||||
algorithms = {
|
||||
'md5_crypt': algo(crypt_id='1', salt_size=8, implicit_rounds=None, salt_exact=False, implicit_ident=None),
|
||||
'bcrypt': algo(crypt_id='2a', salt_size=22, implicit_rounds=None, salt_exact=True, implicit_ident='2a'),
|
||||
'sha256_crypt': algo(crypt_id='5', salt_size=16, implicit_rounds=5000, salt_exact=False, implicit_ident=None),
|
||||
'sha512_crypt': algo(crypt_id='6', salt_size=16, implicit_rounds=5000, salt_exact=False, implicit_ident=None),
|
||||
'bcrypt': algo(crypt_id='2b', salt_size=22, implicit_rounds=12, salt_exact=True, implicit_ident='2b'),
|
||||
'sha256_crypt': algo(crypt_id='5', salt_size=16, implicit_rounds=535000, salt_exact=False, implicit_ident=None),
|
||||
'sha512_crypt': algo(crypt_id='6', salt_size=16, implicit_rounds=656000, salt_exact=False, implicit_ident=None),
|
||||
}
|
||||
|
||||
def __init__(self, algorithm):
|
||||
|
||||
@@ -449,7 +449,7 @@
|
||||
- name: Verify password_hash
|
||||
assert:
|
||||
that:
|
||||
- "'what in the WORLD is up?'|password_hash|length == 106"
|
||||
- "'what in the WORLD is up?'|password_hash|length == 120 or 'what in the WORLD is up?'|password_hash|length == 106"
|
||||
# This throws a vastly different error on py2 vs py3, so we just check
|
||||
# that it's a failure, not a substring of the exception.
|
||||
- password_hash_1 is failed
|
||||
|
||||
@@ -40,11 +40,11 @@ def assert_hash(expected, secret, algorithm, **settings):
|
||||
@pytest.mark.skipif(sys.platform.startswith('darwin'), reason='macOS requires passlib')
|
||||
def test_encrypt_with_rounds_no_passlib():
|
||||
with passlib_off():
|
||||
assert_hash("$5$12345678$uAZsE3BenI2G.nA8DpTl.9Dc8JiqacI53pEqRr5ppT7",
|
||||
assert_hash("$5$rounds=5000$12345678$uAZsE3BenI2G.nA8DpTl.9Dc8JiqacI53pEqRr5ppT7",
|
||||
secret="123", algorithm="sha256_crypt", salt="12345678", rounds=5000)
|
||||
assert_hash("$5$rounds=10000$12345678$JBinliYMFEcBeAXKZnLjenhgEhTmJBvZn3aR8l70Oy/",
|
||||
secret="123", algorithm="sha256_crypt", salt="12345678", rounds=10000)
|
||||
assert_hash("$6$12345678$LcV9LQiaPekQxZ.OfkMADjFdSO2k9zfbDQrHPVcYjSLqSdjLYpsgqviYvTEP/R41yPmhH3CCeEDqVhW1VHr3L.",
|
||||
assert_hash("$6$rounds=5000$12345678$LcV9LQiaPekQxZ.OfkMADjFdSO2k9zfbDQrHPVcYjSLqSdjLYpsgqviYvTEP/R41yPmhH3CCeEDqVhW1VHr3L.",
|
||||
secret="123", algorithm="sha512_crypt", salt="12345678", rounds=5000)
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ def test_encrypt_with_ident():
|
||||
secret="123", algorithm="bcrypt", salt='1234567890123456789012', ident='2a')
|
||||
assert_hash("$2b$12$123456789012345678901ugbM1PeTfRQ0t6dCJu5lQA8hwrZOYgDu",
|
||||
secret="123", algorithm="bcrypt", salt='1234567890123456789012', ident='2b')
|
||||
assert_hash("$2a$12$123456789012345678901ugbM1PeTfRQ0t6dCJu5lQA8hwrZOYgDu",
|
||||
assert_hash("$2b$12$123456789012345678901ugbM1PeTfRQ0t6dCJu5lQA8hwrZOYgDu",
|
||||
secret="123", algorithm="bcrypt", salt='1234567890123456789012')
|
||||
# negative test: sha256_crypt does not take ident as parameter so ignore it
|
||||
assert_hash("$5$12345678$uAZsE3BenI2G.nA8DpTl.9Dc8JiqacI53pEqRr5ppT7",
|
||||
@@ -94,9 +94,9 @@ def test_encrypt_default_rounds_no_passlib():
|
||||
def test_encrypt_default_rounds():
|
||||
assert_hash("$1$12345678$tRy4cXc3kmcfRZVj4iFXr/",
|
||||
secret="123", algorithm="md5_crypt", salt="12345678")
|
||||
assert_hash("$5$12345678$uAZsE3BenI2G.nA8DpTl.9Dc8JiqacI53pEqRr5ppT7",
|
||||
assert_hash("$5$rounds=535000$12345678$uy3TurUPaY71aioJi58HvUY8jkbhSQU8HepbyaNngv.",
|
||||
secret="123", algorithm="sha256_crypt", salt="12345678")
|
||||
assert_hash("$6$12345678$LcV9LQiaPekQxZ.OfkMADjFdSO2k9zfbDQrHPVcYjSLqSdjLYpsgqviYvTEP/R41yPmhH3CCeEDqVhW1VHr3L.",
|
||||
assert_hash("$6$rounds=656000$12345678$InMy49UwxyCh2pGJU1NpOhVSElDDzKeyuC6n6E9O34BCUGVNYADnI.rcA3m.Vro9BiZpYmjEoNhpREqQcbvQ80",
|
||||
secret="123", algorithm="sha512_crypt", salt="12345678")
|
||||
|
||||
assert encrypt.PasslibHash("md5_crypt").hash("123")
|
||||
@@ -118,8 +118,8 @@ def test_password_hash_filter_passlib():
|
||||
with pytest.raises(AnsibleFilterError):
|
||||
get_encrypted_password("123", "sha257", salt="12345678")
|
||||
|
||||
# Uses 5000 rounds by default for sha256 matching crypt behaviour
|
||||
assert get_encrypted_password("123", "sha256", salt="12345678") == "$5$12345678$uAZsE3BenI2G.nA8DpTl.9Dc8JiqacI53pEqRr5ppT7"
|
||||
# Uses passlib default rounds value for sha256 matching crypt behaviour
|
||||
assert get_encrypted_password("123", "sha256", salt="12345678") == "$5$rounds=535000$12345678$uy3TurUPaY71aioJi58HvUY8jkbhSQU8HepbyaNngv."
|
||||
assert get_encrypted_password("123", "sha256", salt="12345678", rounds=5000) == "$5$12345678$uAZsE3BenI2G.nA8DpTl.9Dc8JiqacI53pEqRr5ppT7"
|
||||
|
||||
assert (get_encrypted_password("123", "sha256", salt="12345678", rounds=10000) ==
|
||||
@@ -154,8 +154,8 @@ def test_do_encrypt_passlib():
|
||||
with pytest.raises(AnsibleError):
|
||||
encrypt.do_encrypt("123", "sha257_crypt", salt="12345678")
|
||||
|
||||
# Uses 5000 rounds by default for sha256 matching crypt behaviour.
|
||||
assert encrypt.do_encrypt("123", "sha256_crypt", salt="12345678") == "$5$12345678$uAZsE3BenI2G.nA8DpTl.9Dc8JiqacI53pEqRr5ppT7"
|
||||
# Uses passlib default rounds value for sha256 matching crypt behaviour.
|
||||
assert encrypt.do_encrypt("123", "sha256_crypt", salt="12345678") == "$5$rounds=535000$12345678$uy3TurUPaY71aioJi58HvUY8jkbhSQU8HepbyaNngv."
|
||||
|
||||
assert encrypt.do_encrypt("123", "md5_crypt", salt="12345678") == "$1$12345678$tRy4cXc3kmcfRZVj4iFXr/"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user