mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-04-26 20:31:27 -07:00
Fix 'New Vault password' on vault 'edit' (#35923)
* Fix 'New Vault password' on vault 'edit'
ffe0ddea96
introduce a
change on 'ansible-vault edit' that tried to check
for --encrypt-vault-id in that mode. But '--encrypt-vault-id'
is not intended for 'edit' since the 'edit' should always
reuse the vault secret that was used to decrypt the text.
Change cli to not check for --encrypt-vault-id on 'edit'.
VaultLib.decrypt_and_get_vault_id() was change to return
the vault secret used to decrypt (in addition to vault_id
and the plaintext).
VaultEditor.edit_file() will now use 'vault_secret_used'
as returned from decrypt_and_get_vault_id() so that
an edited file always gets reencrypted with the same
secret, regardless of any vault id configuration or
cli options.
Fixes #35834
This commit is contained in:
parent
cbe2915ba5
commit
6e737c8cb6
4 changed files with 63 additions and 20 deletions
|
@ -657,7 +657,7 @@ class VaultLib:
|
|||
:returns: a byte string containing the decrypted data and the vault-id that was used
|
||||
|
||||
'''
|
||||
plaintext, vault_id = self.decrypt_and_get_vault_id(vaulttext, filename=filename)
|
||||
plaintext, vault_id, vault_secret = self.decrypt_and_get_vault_id(vaulttext, filename=filename)
|
||||
return plaintext
|
||||
|
||||
def decrypt_and_get_vault_id(self, vaulttext, filename=None):
|
||||
|
@ -668,7 +668,7 @@ class VaultLib:
|
|||
:kwarg filename: a filename that the data came from. This is only
|
||||
used to make better error messages in case the data cannot be
|
||||
decrypted.
|
||||
:returns: a byte string containing the decrypted data and the vault-id that was used
|
||||
:returns: a byte string containing the decrypted data and the vault-id vault-secret that was used
|
||||
|
||||
"""
|
||||
b_vaulttext = to_bytes(vaulttext, errors='strict', encoding='utf-8')
|
||||
|
@ -709,6 +709,7 @@ class VaultLib:
|
|||
|
||||
vault_id_matchers = []
|
||||
vault_id_used = None
|
||||
vault_secret_used = None
|
||||
|
||||
if vault_id:
|
||||
display.vvvvv('Found a vault_id (%s) in the vaulttext' % (vault_id))
|
||||
|
@ -737,6 +738,7 @@ class VaultLib:
|
|||
b_plaintext = this_cipher.decrypt(b_vaulttext, vault_secret)
|
||||
if b_plaintext is not None:
|
||||
vault_id_used = vault_secret_id
|
||||
vault_secret_used = vault_secret
|
||||
file_slug = ''
|
||||
if filename:
|
||||
file_slug = ' of "%s"' % filename
|
||||
|
@ -765,7 +767,7 @@ class VaultLib:
|
|||
msg += " on %s" % to_native(filename)
|
||||
raise AnsibleError(msg)
|
||||
|
||||
return b_plaintext, vault_id_used
|
||||
return b_plaintext, vault_id_used, vault_secret_used
|
||||
|
||||
|
||||
class VaultEditor:
|
||||
|
@ -931,7 +933,8 @@ class VaultEditor:
|
|||
self._edit_file_helper(filename, secret, vault_id=vault_id)
|
||||
|
||||
def edit_file(self, filename):
|
||||
|
||||
vault_id_used = None
|
||||
vault_secret_used = None
|
||||
# follow the symlink
|
||||
filename = self._real_path(filename)
|
||||
|
||||
|
@ -943,7 +946,7 @@ class VaultEditor:
|
|||
try:
|
||||
# vaulttext gets converted back to bytes, but alas
|
||||
# TODO: return the vault_id that worked?
|
||||
plaintext, vault_id_used = self.vault.decrypt_and_get_vault_id(vaulttext)
|
||||
plaintext, vault_id_used, vault_secret_used = self.vault.decrypt_and_get_vault_id(vaulttext)
|
||||
except AnsibleError as e:
|
||||
raise AnsibleError("%s for %s" % (to_bytes(e), to_bytes(filename)))
|
||||
|
||||
|
@ -956,21 +959,14 @@ class VaultEditor:
|
|||
# as when the edited file has no vault-id but is decrypted by non-default id in secrets
|
||||
# (vault_id=default, while a different vault-id decrypted)
|
||||
|
||||
# if we could decrypt, the vault_id should be in secrets or we use vault_id_used
|
||||
# though we could have multiple secrets for a given vault_id, pick the first one
|
||||
secrets = match_secrets(self.vault.secrets, [vault_id_used, vault_id])
|
||||
|
||||
if not secrets:
|
||||
raise AnsibleVaultError('Attempting to encrypt "%s" but no vault secrets were found for vault ids "%s" or "%s"' %
|
||||
(filename, vault_id, vault_id_used))
|
||||
|
||||
secret = secrets[0][1]
|
||||
|
||||
# Keep the same vault-id (and version) as in the header
|
||||
if cipher_name not in CIPHER_WRITE_WHITELIST:
|
||||
# we want to get rid of files encrypted with the AES cipher
|
||||
self._edit_file_helper(filename, secret, existing_data=plaintext, force_save=True, vault_id=vault_id)
|
||||
self._edit_file_helper(filename, vault_secret_used, existing_data=plaintext,
|
||||
force_save=True, vault_id=vault_id)
|
||||
else:
|
||||
self._edit_file_helper(filename, secret, existing_data=plaintext, force_save=False, vault_id=vault_id)
|
||||
self._edit_file_helper(filename, vault_secret_used, existing_data=plaintext,
|
||||
force_save=False, vault_id=vault_id)
|
||||
|
||||
def plaintext(self, filename):
|
||||
|
||||
|
@ -996,7 +992,7 @@ class VaultEditor:
|
|||
display.vvvvv('Rekeying file "%s" to with new vault-id "%s" and vault secret %s' %
|
||||
(filename, new_vault_id, new_vault_secret))
|
||||
try:
|
||||
plaintext, vault_id_used = self.vault.decrypt_and_get_vault_id(vaulttext)
|
||||
plaintext, vault_id_used, _dummy = self.vault.decrypt_and_get_vault_id(vaulttext)
|
||||
except AnsibleError as e:
|
||||
raise AnsibleError("%s for %s" % (to_bytes(e), to_bytes(filename)))
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue