Fix 'vault rekey' with vault secret env var

if ANSIBLE_VAULT_PASSWORD_FILE is set, 'ansible-vault rekey myvault.yml'
will fail to prompt for the new vault password file, and will use
None.

Fix is to split out 'ask_vault_passwords' into 'ask_vault_passwords'
and 'ask_new_vault_passwords' to make the logic simpler. And then
make sure new_vault_pass is always set for 'rekey', and if not, then
call ask_new_vault_passwords() to set it.

ask_vault_passwords() would return values for vault_pass and new
vault_pass, and vault cli previously would not prompt for new_vault_pass
if there was a vault_pass set via a vault password file.

Fixes #18247
pull/18286/head
Adrian Likins 8 years ago committed by Brian Coca
parent 557f46658c
commit 309f54b709

@ -161,16 +161,26 @@ class CLI(with_metaclass(ABCMeta, object)):
display.display(u"No config file found; using defaults") display.display(u"No config file found; using defaults")
@staticmethod @staticmethod
def ask_vault_passwords(ask_new_vault_pass=False, rekey=False): def ask_vault_passwords():
''' prompt for vault password and/or password change ''' ''' prompt for vault password and/or password change '''
vault_pass = None vault_pass = None
new_vault_pass = None
try: try:
if rekey or not ask_new_vault_pass:
vault_pass = getpass.getpass(prompt="Vault password: ") vault_pass = getpass.getpass(prompt="Vault password: ")
if ask_new_vault_pass: except EOFError:
pass
# enforce no newline chars at the end of passwords
if vault_pass:
vault_pass = to_bytes(vault_pass, errors='strict', nonstring='simplerepr').strip()
return vault_pass
@staticmethod
def ask_new_vault_passwords():
new_vault_pass = None
try:
new_vault_pass = getpass.getpass(prompt="New Vault password: ") new_vault_pass = getpass.getpass(prompt="New Vault password: ")
new_vault_pass2 = getpass.getpass(prompt="Confirm New Vault password: ") new_vault_pass2 = getpass.getpass(prompt="Confirm New Vault password: ")
if new_vault_pass != new_vault_pass2: if new_vault_pass != new_vault_pass2:
@ -178,16 +188,10 @@ class CLI(with_metaclass(ABCMeta, object)):
except EOFError: except EOFError:
pass pass
# enforce no newline chars at the end of passwords
if vault_pass:
vault_pass = to_bytes(vault_pass, errors='strict', nonstring='simplerepr').strip()
if new_vault_pass: if new_vault_pass:
new_vault_pass = to_bytes(new_vault_pass, errors='strict', nonstring='simplerepr').strip() new_vault_pass = to_bytes(new_vault_pass, errors='strict', nonstring='simplerepr').strip()
if ask_new_vault_pass and not rekey: return new_vault_pass
vault_pass = new_vault_pass
return vault_pass, new_vault_pass
def ask_passwords(self): def ask_passwords(self):
''' prompt for connection and become passwords if needed ''' ''' prompt for connection and become passwords if needed '''

@ -118,7 +118,7 @@ class AdHocCLI(CLI):
vault_pass = CLI.read_vault_password_file(self.options.vault_password_file, loader=loader) vault_pass = CLI.read_vault_password_file(self.options.vault_password_file, loader=loader)
loader.set_vault_password(vault_pass) loader.set_vault_password(vault_pass)
elif self.options.ask_vault_pass: elif self.options.ask_vault_pass:
vault_pass = self.ask_vault_passwords()[0] vault_pass = self.ask_vault_passwords()
loader.set_vault_password(vault_pass) loader.set_vault_password(vault_pass)
variable_manager = VariableManager() variable_manager = VariableManager()

@ -116,7 +116,7 @@ class PlaybookCLI(CLI):
vault_pass = CLI.read_vault_password_file(self.options.vault_password_file, loader=loader) vault_pass = CLI.read_vault_password_file(self.options.vault_password_file, loader=loader)
loader.set_vault_password(vault_pass) loader.set_vault_password(vault_pass)
elif self.options.ask_vault_pass: elif self.options.ask_vault_pass:
vault_pass = self.ask_vault_passwords()[0] vault_pass = self.ask_vault_passwords()
loader.set_vault_password(vault_pass) loader.set_vault_password(vault_pass)
# create the variable manager, which will be shared throughout # create the variable manager, which will be shared throughout

@ -101,21 +101,23 @@ class VaultCLI(CLI):
if self.options.vault_password_file: if self.options.vault_password_file:
# read vault_pass from a file # read vault_pass from a file
self.vault_pass = CLI.read_vault_password_file(self.options.vault_password_file, loader) self.vault_pass = CLI.read_vault_password_file(self.options.vault_password_file, loader)
else:
newpass = False
rekey = False
if not self.options.new_vault_password_file:
newpass = (self.action in ['create', 'rekey', 'encrypt'])
rekey = (self.action == 'rekey')
self.vault_pass, self.new_vault_pass = self.ask_vault_passwords(ask_new_vault_pass=newpass, rekey=rekey)
if self.options.new_vault_password_file: if self.options.new_vault_password_file:
# for rekey only # for rekey only
self.new_vault_pass = CLI.read_vault_password_file(self.options.new_vault_password_file, loader) self.new_vault_pass = CLI.read_vault_password_file(self.options.new_vault_password_file, loader)
if not self.vault_pass or self.options.ask_vault_pass:
self.vault_pass = self.ask_vault_passwords()
if not self.vault_pass: if not self.vault_pass:
raise AnsibleOptionsError("A password is required to use Ansible's Vault") raise AnsibleOptionsError("A password is required to use Ansible's Vault")
if self.action == 'rekey':
if not self.new_vault_pass:
self.new_vault_pass = self.ask_new_vault_passwords()
if not self.new_vault_pass:
raise AnsibleOptionsError("A password is required to rekey Ansible's Vault")
self.editor = VaultEditor(self.vault_pass) self.editor = VaultEditor(self.vault_pass)
self.execute() self.execute()

@ -486,6 +486,10 @@ class VaultEditor:
except AnsibleError as e: except AnsibleError as e:
raise AnsibleError("%s for %s" % (to_bytes(e),to_bytes(filename))) raise AnsibleError("%s for %s" % (to_bytes(e),to_bytes(filename)))
# This is more or less an assert, see #18247
if new_password is None:
raise AnsibleError('The value for the new_password to rekey %s with is not valid' % filename)
new_vault = VaultLib(new_password) new_vault = VaultLib(new_password)
new_ciphertext = new_vault.encrypt(plaintext) new_ciphertext = new_vault.encrypt(plaintext)

Loading…
Cancel
Save