Example #1
0
def restore(path, password_file=None):
    """
    Retrieves a file from the atk vault and restores it to its original
    location, re-encrypting it if it has changed.

    :param path: path to original file
    """
    vault = VaultLib(get_vault_password(password_file))
    atk_path = os.path.join(ATK_VAULT, path)

    # Load stored data
    with open(os.path.join(atk_path, 'encrypted'), 'rb') as f:
        old_data = f.read()
    with open(os.path.join(atk_path, 'hash'), 'rb') as f:
        old_hash = f.read()

    # Load new data
    with open(path, 'rb') as f:
        new_data = f.read()
        new_hash = hashlib.sha1(new_data).hexdigest()

    # Determine whether to re-encrypt
    if old_hash != new_hash:
        new_data = vault.encrypt(new_data)
    else:
        new_data = old_data

    # Update file
    with open(path, 'wb') as f:
        f.write(new_data)

    # Clean atk vault
    os.remove(os.path.join(atk_path, 'encrypted'))
    os.remove(os.path.join(atk_path, 'hash'))
Example #2
0
def backup(path, password_file=None):
    """
    Replaces the contents of a file with its decrypted counterpart, storing the
    original encrypted version and a hash of the file contents for later
    retrieval.
    """
    vault = VaultLib(get_vault_password(password_file))
    with open(path, 'r') as f:
        encrypted_data = f.read()

        # Normally we'd just try and catch the exception, but the
        # exception raised here is not very specific (just
        # `AnsibleError`), so this feels safer to avoid suppressing
        # other things that might go wrong.
        if vault.is_encrypted(encrypted_data):
            decrypted_data = vault.decrypt(encrypted_data)

            # Create atk vault files
            atk_path = os.path.join(ATK_VAULT, path)
            mkdir_p(atk_path)
            # ... encrypted
            with open(os.path.join(atk_path, 'encrypted'), 'wb') as f:
                f.write(encrypted_data)
            # ... hash
            with open(os.path.join(atk_path, 'hash'), 'wb') as f:
                f.write(hashlib.sha1(decrypted_data).hexdigest())

            # Replace encrypted file with decrypted one
            with open(path, 'wb') as f:
                f.write(decrypted_data)
Example #3
0
def restore(path, password_file=None):
    """
    Retrieves a file from the atk vault and restores it to its original
    location, re-encrypting it if it has changed.

    :param path: path to original file
    """
    vault = VaultLib(get_vault_password(password_file))
    atk_path = os.path.join(ATK_VAULT, path)

    # Load stored data
    with open(os.path.join(atk_path, 'encrypted'), 'rb') as f:
        old_data = f.read()
    with open(os.path.join(atk_path, 'hash'), 'rb') as f:
        old_hash = f.read()

    # Load new data
    with open(path, 'rb') as f:
        new_data = f.read()
        new_hash = hashlib.sha1(new_data).hexdigest()

    # Determine whether to re-encrypt
    if old_hash != new_hash:
        new_data = vault.encrypt(new_data)
    else:
        new_data = old_data

    # Update file
    with open(path, 'wb') as f:
        f.write(new_data)

    # Clean atk vault
    os.remove(os.path.join(atk_path, 'encrypted'))
    os.remove(os.path.join(atk_path, 'hash'))
Example #4
0
def backup(path, password_file=None):
    """
    Replaces the contents of a file with its decrypted counterpart, storing the
    original encrypted version and a hash of the file contents for later
    retrieval.
    """
    vault = VaultLib(get_vault_password(password_file))
    with open(path, 'r') as f:
        encrypted_data = f.read()

        # Normally we'd just try and catch the exception, but the
        # exception raised here is not very specific (just
        # `AnsibleError`), so this feels safer to avoid suppressing
        # other things that might go wrong.
        if vault.is_encrypted(encrypted_data):
            decrypted_data = vault.decrypt(encrypted_data)

            # Create atk vault files
            atk_path = os.path.join(ATK_VAULT, path)
            mkdir_p(atk_path)
            # ... encrypted
            with open(os.path.join(atk_path, 'encrypted'), 'wb') as f:
                f.write(encrypted_data)
            # ... hash
            with open(os.path.join(atk_path, 'hash'), 'wb') as f:
                f.write(hashlib.sha1(decrypted_data).hexdigest())

            # Replace encrypted file with decrypted one
            with open(path, 'wb') as f:
                f.write(decrypted_data)
Example #5
0
 def test_split_header(self):
     v = VaultLib('ansible')
     data = "$ANSIBLE_VAULT;9.9;TEST\nansible" 
     rdata = v._split_header(data)        
     lines = rdata.split('\n')
     assert lines[0] == "ansible"
     assert v.cipher_name == 'TEST', "cipher name was not set"
     assert v.version == "9.9"
Example #6
0
 def test_split_header(self):
     v = VaultLib('ansible')
     data = "$ANSIBLE_VAULT;9.9;TEST\nansible" 
     rdata = v._split_header(data)        
     lines = rdata.split('\n')
     assert lines[0] == "ansible"
     assert v.cipher_name == 'TEST', "cipher name was not set"
     assert v.version == "9.9"
Example #7
0
 def test_remove_header(self):
     v = VaultLib('ansible')
     data = "$ANSIBLE_VAULT;9.9;TEST\n%s" % hexlify("ansible")
     rdata = v._split_headers_and_get_unhexified_data(data)
     lines = rdata.split('\n')
     assert lines[0] == "ansible"
     assert v.cipher_name == 'TEST', "cipher name was not set"
     assert v.version == "9.9"
Example #8
0
 def test_encyrpt_decrypt(self):
     if not HAS_AES:
         raise SkipTest
     v = VaultLib('ansible')
     v.cipher_name = 'AES'
     enc_data = v.encrypt("foobar")
     dec_data = v.decrypt(enc_data)
     assert enc_data != "foobar", "encryption failed"
     assert dec_data == "foobar", "decryption failed"
Example #9
0
 def test_encrypt_decrypt_aes256(self):
     if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2:
         raise SkipTest
     v = VaultLib('ansible')
     v.cipher_name = 'AES256'
     enc_data = v.encrypt("foobar")
     dec_data = v.decrypt(enc_data)
     assert enc_data != "foobar", "encryption failed"
     assert dec_data == "foobar", "decryption failed"           
Example #10
0
 def test_encrypt_decrypt_aes256(self):
     if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2:
         raise SkipTest
     v = VaultLib('ansible')
     v.cipher_name = 'AES256'
     enc_data = v.encrypt("foobar")
     dec_data = v.decrypt(enc_data)
     assert enc_data != "foobar", "encryption failed"
     assert dec_data == "foobar", "decryption failed"           
Example #11
0
 def test_decrypt_decrypted(self):
     if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2:
         raise SkipTest
     v = VaultLib('ansible')
     data = "ansible"
     error_hit = False
     try:
         dec_data = v.decrypt(data)
     except errors.AnsibleError, e:
         error_hit = True
Example #12
0
 def test_cipher_not_set(self):
     if not HAS_AES:
         raise SkipTest
     v = VaultLib('ansible')
     data = "ansible"
     error_hit = False
     try:
         enc_data = v.encrypt(data)
     except errors.AnsibleError, e:
         error_hit = True
Example #13
0
 def test_decrypt_decrypted(self):
     if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2:
         raise SkipTest
     v = VaultLib('ansible')
     data = "ansible"
     error_hit = False
     try:
         dec_data = v.decrypt(data)
     except errors.AnsibleError, e:
         error_hit = True
Example #14
0
 def test_encrypt_decrypt_aes(self):
     if self._is_fips():
         raise SkipTest('MD5 not available on FIPS enabled systems')
     if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2:
         raise SkipTest
     v = VaultLib('ansible')
     v.cipher_name = 'AES'
     enc_data = v.encrypt("foobar")
     dec_data = v.decrypt(enc_data)
     assert enc_data != "foobar", "encryption failed"
     assert dec_data == "foobar", "decryption failed"
Example #15
0
 def test_encrypt_decrypt_aes(self):
     if self._is_fips():
         raise SkipTest('MD5 not available on FIPS enabled systems')
     if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2:
         raise SkipTest
     v = VaultLib('ansible')
     v.cipher_name = 'AES'
     enc_data = v.encrypt("foobar")
     dec_data = v.decrypt(enc_data)
     assert enc_data != "foobar", "encryption failed"
     assert dec_data == "foobar", "decryption failed"
Example #16
0
 def test_cipher_not_set(self):
     # not setting the cipher should default to AES256
     if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2:
         raise SkipTest
     v = VaultLib('ansible')
     data = "ansible"
     error_hit = False
     try:
         enc_data = v.encrypt(data)
     except errors.AnsibleError, e:
         error_hit = True
Example #17
0
 def test_encrypt_encrypted(self):
     if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2:
         raise SkipTest
     v = VaultLib('ansible')
     v.cipher_name = 'AES'
     data = "$ANSIBLE_VAULT;9.9;TEST\n%s" % hexlify("ansible")
     error_hit = False
     try:
         enc_data = v.encrypt(data)
     except errors.AnsibleError, e:
         error_hit = True
Example #18
0
 def test_encrypt_encrypted(self):
     if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2:
         raise SkipTest
     v = VaultLib('ansible')
     v.cipher_name = 'AES'
     data = "$ANSIBLE_VAULT;9.9;TEST\n%s" % hexlify("ansible")
     error_hit = False
     try:
         enc_data = v.encrypt(data)
     except errors.AnsibleError, e:
         error_hit = True
Example #19
0
 def test_cipher_not_set(self):
     # not setting the cipher should default to AES256
     if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2:
         raise SkipTest
     v = VaultLib('ansible')
     data = "ansible"
     error_hit = False
     try:
         enc_data = v.encrypt(data)
     except errors.AnsibleError, e:
         error_hit = True
Example #20
0
 def test_add_header(self):
     v = VaultLib('ansible')
     v.cipher_name = "TEST"
     sensitive_data = "ansible"
     data = v._add_header(sensitive_data)
     lines = data.split('\n')
     assert len(lines) > 1, "failed to properly add header"
     header = lines[0]
     assert header.endswith(';TEST'), "header does end with cipher name"
     header_parts = header.split(';')
     assert len(header_parts) == 3, "header has the wrong number of parts"        
     assert header_parts[0] == '$ANSIBLE_VAULT', "header does not start with $ANSIBLE_VAULT"
     assert header_parts[1] == v.version, "header version is incorrect"
     assert header_parts[2] == 'TEST', "header does end with cipher name"
Example #21
0
 def test_add_header(self):
     v = VaultLib('ansible')
     v.cipher_name = "TEST"
     sensitive_data = "ansible"
     data = v._add_header(sensitive_data)
     lines = data.split('\n')
     assert len(lines) > 1, "failed to properly add header"
     header = lines[0]
     assert header.endswith(';TEST'), "header does end with cipher name"
     header_parts = header.split(';')
     assert len(header_parts) == 3, "header has the wrong number of parts"        
     assert header_parts[0] == '$ANSIBLE_VAULT', "header does not start with $ANSIBLE_VAULT"
     assert header_parts[1] == v.version, "header version is incorrect"
     assert header_parts[2] == 'TEST', "header does end with cipher name"
Example #22
0
 def test_methods_exist(self):
     v = VaultLib('ansible')
     slots = ['is_encrypted',
              'encrypt',
              'decrypt',
              '_add_header',
              '_split_header',]
     for slot in slots:         
         assert hasattr(v, slot), "VaultLib is missing the %s method" % slot
Example #23
0
 def test_add_header(self):
     v = VaultLib('ansible')
     v.cipher_name = "TEST"
     sensitive_data = "ansible"
     sensitive_hex = hexlify(sensitive_data)
     data = v._add_headers_and_hexify_encrypted_data(sensitive_data)
     open("/tmp/awx.log", "a").write("data: %s\n" % data)
     lines = data.split('\n')
     assert len(lines) > 1, "failed to properly add header"
     header = lines[0]
     assert header.endswith(';TEST'), "header does end with cipher name"
     header_parts = header.split(';')
     assert len(header_parts) == 3, "header has the wrong number of parts"
     assert header_parts[
         0] == '$ANSIBLE_VAULT', "header does not start with $ANSIBLE_VAULT"
     assert header_parts[1] == v.version, "header version is incorrect"
     assert header_parts[2] == 'TEST', "header does end with cipher name"
     assert lines[1] == sensitive_hex
Example #24
0
class Vault(object):
    '''R/W an ansible-vault yaml file'''
    def __init__(self, password):
        self.password = password
        self.vault = VaultLib(password)

    def load(self, stream):
        '''read vault steam and return python object'''
        return yaml.load(self.vault.decrypt(stream))

    def dump(self, data, stream=None):
        '''encrypt data and print stdout or write to stream'''
        yaml_text = yaml.dump(data,
                              default_flow_style=False,
                              allow_unicode=True)
        encrypted = self.vault.encrypt(yaml_text)
        if stream:
            stream.write(encrypted)
        else:
            return encrypted
Example #25
0
class Vault(object):
    '''R/W an ansible-vault yaml file'''

    def __init__(self, password):
        self.password = password
        self.vault = VaultLib(password)

    def load(self, stream):
        '''read vault steam and return python object'''
        return yaml.load(self.vault.decrypt(stream))

    def dump(self, data, stream=None):
        '''encrypt data and print stdout or write to stream'''
        yaml_text = yaml.dump(
            data,
            default_flow_style=False,
            allow_unicode=True)
        encrypted = self.vault.encrypt(yaml_text)
        if stream:
            stream.write(encrypted)
        else:
            return encrypted
Example #26
0
def decrypt_diff(diff_part, password_file=None):
    """
    Diff part is a string in the format:

        diff --git a/group_vars/foo b/group_vars/foo
        index c09080b..0d803bb 100644
        --- a/group_vars/foo
        +++ b/group_vars/foo
        @@ -1,32 +1,33 @@
         $ANSIBLE_VAULT;1.1;AES256
        -61316662363730313230626432303662316330323064373866616436623565613033396539366263
        -383632656663356364656531653039333965
        +30393563383639396563623339383936613866326332383162306532653239636166633162323236
        +62376161626137626133

    Returns a tuple of decrypted old contents and decrypted new contents.
    """
    vault = VaultLib(get_vault_password(password_file))
    old_contents, new_contents = get_contents(diff_part)
    if vault.is_encrypted(old_contents):
        old_contents = vault.decrypt(old_contents)
    if vault.is_encrypted(new_contents):
        new_contents = vault.decrypt(new_contents)
    return old_contents, new_contents
Example #27
0
        # A register for if we executed a module.
        # Used to cut down on command calls when not recursive.
        module_executed = False

        # Tell _execute_module to delete the file if there is one file.
        delete_remote_tmp = (len(source_files) == 1)

        # If this is a recursive action create a tmp_path that we can share as the _exec_module create is too late.
        if not delete_remote_tmp:
            if "-tmp-" not in tmp_path:
                tmp_path = self.runner._make_tmp_path(conn)

        # expand any user home dir specifier
        dest = self.runner._remote_expand_user(conn, dest, tmp_path)

        vault = VaultLib(password=self.runner.vault_pass)

        for source_full, source_rel in source_files:
            
            vault_temp_file = None
            data = None

            try:
                data = open(source_full).read()
            except IOError:
                raise errors.AnsibleError("file could not read: %s" % source_full)

            if vault.is_encrypted(data):
                # if the file is encrypted and no password was specified,
                # the decrypt call would throw an error, but we check first
                # since the decrypt function doesn't know the file name
Example #28
0
 def __init__(self, password):
     self.password = password
     self.vault = VaultLib(password)
Example #29
0
 def test_is_encrypted(self):
     v = VaultLib(None)
     assert not v.is_encrypted("foobar"), "encryption check on plaintext failed"
     data = "$ANSIBLE_VAULT;9.9;TEST\n%s" % hexlify("ansible")
     assert v.is_encrypted(data), "encryption check on headered text failed"
#!/usr/bin/python
from ansible.utils.vault import VaultLib
import fileinput
from sys import argv


data = open(argv[2], 'rb').read()

vl = VaultLib(argv[1])

decrypted_data = vl.decrypt(data)
print(decrypted_data)
Example #31
0
#!/usr/bin/env python
from __future__ import print_function

import os

from kazoo.client import KazooClient

try:
    from ansible.utils.vault import VaultLib
except ImportError:
    # Ansible 2.0 has changed the vault location
    from ansible.parsing.vault import VaultLib

os.system("docker-compose up -d zk")
vault = VaultLib(open(os.path.expanduser("~/.vault-password.nestor")).read().strip())
DEFAULT_HOSTS = os.environ.get("ZK_HOST", "localhost:2181")

zk = KazooClient(hosts=DEFAULT_HOSTS)
zk.start()
dir = 'config'
path = '/nestor/config'
for root, dirs, files in os.walk(dir):
    outroot = root.replace(dir, "").strip("/")
    outroot = os.path.join(path, outroot)
    for name in files:
        inpath = os.path.join(root, name)
        outpath = os.path.join(outroot, name)
        zk.ensure_path(outpath)
        with open(inpath) as f:
            data = f.read()
            if data.startswith("$ANSIBLE_VAULT"):
Example #32
0
 def test_is_encrypted(self):
     v = VaultLib(None)
     assert not v.is_encrypted("foobar"), "encryption check on plaintext failed"
     data = "$ANSIBLE_VAULT;9.9;TEST\n%s" % hexlify("ansible")
     assert v.is_encrypted(data), "encryption check on headered text failed"
Example #33
0
        # make sure the password functions for the cipher
        error_hit = False
        try:        
            ve.rekey_file('ansible2')
        except errors.AnsibleError, e:
            error_hit = True

        # verify decrypted content
        f = open(filename, "rb")
        fdata = f.read()
        f.close()

        shutil.rmtree(dirpath)
        assert error_hit == False, "error rekeying 1.0 file to 1.1"            

        # ensure filedata can be decrypted, is 1.1 and is AES256
        vl = VaultLib("ansible2")
        dec_data = None
        error_hit = False
        try:
            dec_data = vl.decrypt(fdata)
        except errors.AnsibleError, e:
            error_hit = True

        assert vl.cipher_name == "AES256", "wrong cipher name set after rekey: %s" % vl.cipher_name
        assert error_hit == False, "error decrypting migrated 1.0 file"            
        assert dec_data.strip() == "foo", "incorrect decryption of rekeyed/migrated file: %s" % dec_data


Example #34
0
 def __init__(self, password):
     self.password = password
     self.vault = VaultLib(password)