|
|
|
@ -130,7 +130,7 @@ class VaultLib:
|
|
|
|
|
b_data = to_bytes(data, errors='strict', encoding='utf-8')
|
|
|
|
|
|
|
|
|
|
if self.is_encrypted(b_data):
|
|
|
|
|
raise AnsibleError("data is already encrypted")
|
|
|
|
|
raise AnsibleError("input is already encrypted")
|
|
|
|
|
|
|
|
|
|
if not self.cipher_name or self.cipher_name not in CIPHER_WRITE_WHITELIST:
|
|
|
|
|
self.cipher_name = u"AES256"
|
|
|
|
@ -162,7 +162,7 @@ class VaultLib:
|
|
|
|
|
raise AnsibleError("A vault password must be specified to decrypt data")
|
|
|
|
|
|
|
|
|
|
if not self.is_encrypted(b_data):
|
|
|
|
|
raise AnsibleError("data is not encrypted")
|
|
|
|
|
raise AnsibleError("input is not encrypted")
|
|
|
|
|
|
|
|
|
|
# clean out header
|
|
|
|
|
b_data = self._split_header(b_data)
|
|
|
|
@ -258,97 +258,82 @@ class VaultEditor:
|
|
|
|
|
# and restore umask
|
|
|
|
|
os.umask(old_umask)
|
|
|
|
|
|
|
|
|
|
def create_file(self, filename):
|
|
|
|
|
""" create a new encrypted file """
|
|
|
|
|
def encrypt_file(self, filename):
|
|
|
|
|
|
|
|
|
|
check_prereqs()
|
|
|
|
|
|
|
|
|
|
if os.path.isfile(filename):
|
|
|
|
|
raise AnsibleError("%s exists, please use 'edit' instead" % filename)
|
|
|
|
|
|
|
|
|
|
# Let the user specify contents and save file
|
|
|
|
|
self._edit_file_helper(filename)
|
|
|
|
|
plaintext = self.read_data(filename)
|
|
|
|
|
ciphertext = self.vault.encrypt(plaintext)
|
|
|
|
|
self.write_data(ciphertext, filename)
|
|
|
|
|
|
|
|
|
|
def decrypt_file(self, filename):
|
|
|
|
|
|
|
|
|
|
check_prereqs()
|
|
|
|
|
|
|
|
|
|
if not os.path.isfile(filename):
|
|
|
|
|
raise AnsibleError("%s does not exist" % filename)
|
|
|
|
|
ciphertext = self.read_data(filename)
|
|
|
|
|
plaintext = self.vault.decrypt(ciphertext)
|
|
|
|
|
self.write_data(plaintext, filename)
|
|
|
|
|
|
|
|
|
|
tmpdata = self.read_data(filename)
|
|
|
|
|
if self.vault.is_encrypted(tmpdata):
|
|
|
|
|
dec_data = self.vault.decrypt(tmpdata)
|
|
|
|
|
if dec_data is None:
|
|
|
|
|
raise AnsibleError("Decryption failed")
|
|
|
|
|
else:
|
|
|
|
|
self.write_data(dec_data, filename)
|
|
|
|
|
else:
|
|
|
|
|
raise AnsibleError("%s is not encrypted" % filename)
|
|
|
|
|
def create_file(self, filename):
|
|
|
|
|
""" create a new encrypted file """
|
|
|
|
|
|
|
|
|
|
check_prereqs()
|
|
|
|
|
|
|
|
|
|
# FIXME: If we can raise an error here, we can probably just make it
|
|
|
|
|
# behave like edit instead.
|
|
|
|
|
if os.path.isfile(filename):
|
|
|
|
|
raise AnsibleError("%s exists, please use 'edit' instead" % filename)
|
|
|
|
|
|
|
|
|
|
self._edit_file_helper(filename)
|
|
|
|
|
|
|
|
|
|
def edit_file(self, filename):
|
|
|
|
|
|
|
|
|
|
check_prereqs()
|
|
|
|
|
|
|
|
|
|
# decrypt to tmpfile
|
|
|
|
|
tmpdata = self.read_data(filename)
|
|
|
|
|
dec_data = self.vault.decrypt(tmpdata)
|
|
|
|
|
ciphertext = self.read_data(filename)
|
|
|
|
|
plaintext = self.vault.decrypt(ciphertext)
|
|
|
|
|
|
|
|
|
|
# let the user edit the data and save
|
|
|
|
|
if self.vault.cipher_name not in CIPHER_WRITE_WHITELIST:
|
|
|
|
|
# we want to get rid of files encrypted with the AES cipher
|
|
|
|
|
self._edit_file_helper(filename, existing_data=dec_data, force_save=True)
|
|
|
|
|
self._edit_file_helper(filename, existing_data=plaintext, force_save=True)
|
|
|
|
|
else:
|
|
|
|
|
self._edit_file_helper(filename, existing_data=dec_data, force_save=False)
|
|
|
|
|
self._edit_file_helper(filename, existing_data=plaintext, force_save=False)
|
|
|
|
|
|
|
|
|
|
def view_file(self, filename):
|
|
|
|
|
|
|
|
|
|
check_prereqs()
|
|
|
|
|
|
|
|
|
|
# decrypt to tmpfile
|
|
|
|
|
tmpdata = self.read_data(filename)
|
|
|
|
|
dec_data = self.vault.decrypt(tmpdata)
|
|
|
|
|
# FIXME: Why write this to a temporary file at all? It would be safer
|
|
|
|
|
# to feed it to the PAGER on stdin.
|
|
|
|
|
_, tmp_path = tempfile.mkstemp()
|
|
|
|
|
self.write_data(dec_data, tmp_path)
|
|
|
|
|
ciphertext = self.read_data(filename)
|
|
|
|
|
plaintext = self.vault.decrypt(ciphertext)
|
|
|
|
|
self.write_data(plaintext, tmp_path)
|
|
|
|
|
|
|
|
|
|
# drop the user into pager on the tmp file
|
|
|
|
|
call(self._pager_shell_command(tmp_path))
|
|
|
|
|
os.remove(tmp_path)
|
|
|
|
|
|
|
|
|
|
def encrypt_file(self, filename):
|
|
|
|
|
|
|
|
|
|
check_prereqs()
|
|
|
|
|
|
|
|
|
|
if not os.path.isfile(filename):
|
|
|
|
|
raise AnsibleError("%s does not exist" % filename)
|
|
|
|
|
|
|
|
|
|
tmpdata = self.read_data(filename)
|
|
|
|
|
if not self.vault.is_encrypted(tmpdata):
|
|
|
|
|
enc_data = self.vault.encrypt(tmpdata)
|
|
|
|
|
self.write_data(enc_data, filename)
|
|
|
|
|
else:
|
|
|
|
|
raise AnsibleError("%s is already encrypted" % filename)
|
|
|
|
|
|
|
|
|
|
def rekey_file(self, filename, new_password):
|
|
|
|
|
|
|
|
|
|
check_prereqs()
|
|
|
|
|
|
|
|
|
|
# decrypt
|
|
|
|
|
tmpdata = self.read_data(filename)
|
|
|
|
|
dec_data = self.vault.decrypt(tmpdata)
|
|
|
|
|
ciphertext = self.read_data(filename)
|
|
|
|
|
plaintext = self.vault.decrypt(ciphertext)
|
|
|
|
|
|
|
|
|
|
# create new vault
|
|
|
|
|
new_vault = VaultLib(new_password)
|
|
|
|
|
|
|
|
|
|
# re-encrypt data and re-write file
|
|
|
|
|
enc_data = new_vault.encrypt(dec_data)
|
|
|
|
|
self.write_data(enc_data, filename)
|
|
|
|
|
new_ciphertext = new_vault.encrypt(plaintext)
|
|
|
|
|
self.write_data(new_ciphertext, filename)
|
|
|
|
|
|
|
|
|
|
def read_data(self, filename):
|
|
|
|
|
f = open(filename, "rb")
|
|
|
|
|
tmpdata = f.read()
|
|
|
|
|
f.close()
|
|
|
|
|
return tmpdata
|
|
|
|
|
try:
|
|
|
|
|
f = open(filename, "rb")
|
|
|
|
|
data = f.read()
|
|
|
|
|
f.close()
|
|
|
|
|
except Exception as e:
|
|
|
|
|
raise AnsibleError(str(e))
|
|
|
|
|
|
|
|
|
|
return data
|
|
|
|
|
|
|
|
|
|
def write_data(self, data, filename):
|
|
|
|
|
if os.path.isfile(filename):
|
|
|
|
|