diff options
author | Adrian Likins <alikins@redhat.com> | 2018-03-27 14:12:21 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-27 14:12:21 -0400 |
commit | 6e737c8cb66df1500dba1c74369314dd8f65867c (patch) | |
tree | 7c7505da5a4d0831c5dd4ddde29631cb95955db6 /lib/ansible/parsing | |
parent | cbe2915ba5236030ba560ba870b97f57e09bebe7 (diff) | |
download | ansible-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__.py | 32 |
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))) |