summaryrefslogtreecommitdiff
path: root/lib/ansible/parsing
diff options
context:
space:
mode:
authorAdrian Likins <alikins@redhat.com>2018-03-27 14:12:21 -0400
committerGitHub <noreply@github.com>2018-03-27 14:12:21 -0400
commit6e737c8cb66df1500dba1c74369314dd8f65867c (patch)
tree7c7505da5a4d0831c5dd4ddde29631cb95955db6 /lib/ansible/parsing
parentcbe2915ba5236030ba560ba870b97f57e09bebe7 (diff)
downloadansible-6e737c8cb66df1500dba1c74369314dd8f65867c.tar.gz
Fix 'New Vault password' on vault 'edit' (#35923)
* Fix 'New Vault password' on vault 'edit' ffe0ddea96bbe8ac27af816e58667c212e74688e 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
Diffstat (limited to 'lib/ansible/parsing')
-rw-r--r--lib/ansible/parsing/vault/__init__.py32
1 files changed, 14 insertions, 18 deletions
diff --git a/lib/ansible/parsing/vault/__init__.py b/lib/ansible/parsing/vault/__init__.py
index cca3164763..7a68166d13 100644
--- a/lib/ansible/parsing/vault/__init__.py
+++ b/lib/ansible/parsing/vault/__init__.py
@@ -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)))