mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-05-02 23:31:25 -07:00
Better handling of malformed vault data envelope (#32515)
* Better handling of malformed vault data envelope If an embedded vaulted variable ('!vault' in yaml) had an invalid format, it would eventually cause an error for seemingly unrelated reasons. "Invalid" meaning not valid hexlify (extra chars, non-hex chars, etc). For ex, if a host_vars file had invalid vault format variables, on py2, it would cause an error like: 'ansible.vars.hostvars.HostVars object' has no attribute u'broken.example.com' Depending on where the invalid vault is, it could also cause "VARIABLE IS NOT DEFINED!". The behavior can also change if ansible-playbook is py2 or py3. Root cause is errors from binascii.unhexlify() not being handled consistently. Fix is to add a AnsibleVaultFormatError exception and raise it on any unhexlify() errors and to handle it properly elsewhere. Add a _unhexlify() that try/excepts around a binascii.unhexlify() and raises an AnsibleVaultFormatError on invalid vault data. This is so the same exception type is always raised for this case. Previous it was different between py2 and py3. binascii.unhexlify() raises a binascii.Error if the hexlified blobs in a vault data blob are invalid. On py2, binascii.Error is a subclass of Exception. On py3, binascii.Error is a subclass of TypeError When decrypting content of vault encrypted variables, if a binascii.Error is raised it propagates up to playbook.base.Base.post_validate(). post_validate() handles exceptions for TypeErrors but not for base Exception subclasses (like py2 binascii.Error). * Add a display.warning on vault format errors * Unit tests for _unhexlify, parse_vaulttext* * Add intg test cases for invalid vault formats Fixes #28038
This commit is contained in:
parent
e7941b0d4e
commit
9c58827410
13 changed files with 220 additions and 24 deletions
|
@ -41,6 +41,62 @@ from units.mock.loader import DictDataLoader
|
|||
from units.mock.vault_helper import TextVaultSecret
|
||||
|
||||
|
||||
class TestUnhexlify(unittest.TestCase):
|
||||
def test(self):
|
||||
b_plain_data = b'some text to hexlify'
|
||||
b_data = hexlify(b_plain_data)
|
||||
res = vault._unhexlify(b_data)
|
||||
self.assertEquals(res, b_plain_data)
|
||||
|
||||
def test_odd_length(self):
|
||||
b_data = b'123456789abcdefghijklmnopqrstuvwxyz'
|
||||
|
||||
self.assertRaisesRegexp(vault.AnsibleVaultFormatError,
|
||||
'.*Vault format unhexlify error.*',
|
||||
vault._unhexlify,
|
||||
b_data)
|
||||
|
||||
def test_nonhex(self):
|
||||
b_data = b'6z36316566653264333665333637623064303639353237620a636366633565663263336335656532'
|
||||
|
||||
self.assertRaisesRegexp(vault.AnsibleVaultFormatError,
|
||||
'.*Vault format unhexlify error.*Non-hexadecimal digit found',
|
||||
vault._unhexlify,
|
||||
b_data)
|
||||
|
||||
|
||||
class TestParseVaulttext(unittest.TestCase):
|
||||
def test(self):
|
||||
vaulttext_envelope = u'''$ANSIBLE_VAULT;1.1;AES256
|
||||
33363965326261303234626463623963633531343539616138316433353830356566396130353436
|
||||
3562643163366231316662386565383735653432386435610a306664636137376132643732393835
|
||||
63383038383730306639353234326630666539346233376330303938323639306661313032396437
|
||||
6233623062366136310a633866373936313238333730653739323461656662303864663666653563
|
||||
3138'''
|
||||
|
||||
b_vaulttext_envelope = to_bytes(vaulttext_envelope, errors='strict', encoding='utf-8')
|
||||
b_vaulttext, b_version, cipher_name, vault_id = vault.parse_vaulttext_envelope(b_vaulttext_envelope)
|
||||
res = vault.parse_vaulttext(b_vaulttext)
|
||||
self.assertIsInstance(res[0], bytes)
|
||||
self.assertIsInstance(res[1], bytes)
|
||||
self.assertIsInstance(res[2], bytes)
|
||||
|
||||
def test_non_hex(self):
|
||||
vaulttext_envelope = u'''$ANSIBLE_VAULT;1.1;AES256
|
||||
3336396J326261303234626463623963633531343539616138316433353830356566396130353436
|
||||
3562643163366231316662386565383735653432386435610a306664636137376132643732393835
|
||||
63383038383730306639353234326630666539346233376330303938323639306661313032396437
|
||||
6233623062366136310a633866373936313238333730653739323461656662303864663666653563
|
||||
3138'''
|
||||
|
||||
b_vaulttext_envelope = to_bytes(vaulttext_envelope, errors='strict', encoding='utf-8')
|
||||
b_vaulttext, b_version, cipher_name, vault_id = vault.parse_vaulttext_envelope(b_vaulttext_envelope)
|
||||
self.assertRaisesRegexp(vault.AnsibleVaultFormatError,
|
||||
'.*Vault format unhexlify error.*Non-hexadecimal digit found',
|
||||
vault.parse_vaulttext,
|
||||
b_vaulttext_envelope)
|
||||
|
||||
|
||||
class TestVaultSecret(unittest.TestCase):
|
||||
def test(self):
|
||||
secret = vault.VaultSecret()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue