Exemple #1
0
    def test_create_file(self, mock_editor_shell_command):
        def sc_side_effect(filename):
            return ['touch', filename]

        mock_editor_shell_command.side_effect = sc_side_effect

        tmp_file = tempfile.NamedTemporaryFile()
        os.unlink(tmp_file.name)

        _secrets = self._secrets('ansible')
        ve = self._vault_editor(_secrets)
        ve.create_file(tmp_file.name, vault.match_encrypt_secret(_secrets)[1])

        self.assertTrue(os.path.exists(tmp_file.name))
    def test_create_file(self, mock_editor_shell_command):

        def sc_side_effect(filename):
            return ['touch', filename]
        mock_editor_shell_command.side_effect = sc_side_effect

        tmp_file = tempfile.NamedTemporaryFile()
        os.unlink(tmp_file.name)

        _secrets = self._secrets('ansible')
        ve = self._vault_editor(_secrets)
        ve.create_file(tmp_file.name, vault.match_encrypt_secret(_secrets)[1])

        self.assertTrue(os.path.exists(tmp_file.name))
Exemple #3
0
    def test_wrong_password(self):
        plaintext = u"Ansible"
        bob_password = "******"

        bobs_secret = TextVaultSecret(bob_password)
        bobs_secrets = [('default', bobs_secret)]

        bobs_vault = vault.VaultLib(bobs_secrets)

        ciphertext = bobs_vault.encrypt(plaintext, vault.match_encrypt_secret(bobs_secrets)[1])

        try:
            self.vault.decrypt(ciphertext)
        except Exception as e:
            self.assertIsInstance(e, errors.AnsibleError)
            self.assertEqual(e.message, 'Decryption failed (no vault secrets were found that could decrypt)')
Exemple #4
0
    def test_wrong_password(self):
        plaintext = u"Ansible"
        bob_password = "******"

        bobs_secret = TextVaultSecret(bob_password)
        bobs_secrets = [('default', bobs_secret)]

        bobs_vault = vault.VaultLib(bobs_secrets)

        ciphertext = bobs_vault.encrypt(plaintext, vault.match_encrypt_secret(bobs_secrets)[1])

        try:
            self.vault.decrypt(ciphertext)
        except Exception as e:
            self.assertIsInstance(e, errors.AnsibleError)
            self.assertEqual(e.message, 'Decryption failed (no vault secrets would found that could decrypt)')
Exemple #5
0
    def test_rekey_file(self):
        self._test_dir = self._create_test_dir()

        src_file_contents = to_bytes("some info in a file\nyup.")
        src_file_path = self._create_file(self._test_dir, 'src_file', content=src_file_contents)

        ve = self._vault_editor()
        ve.encrypt_file(src_file_path, self.vault_secret)

        # FIXME: update to just set self._secrets or just a new vault secret id
        new_password = '******'
        new_vault_secret = TextVaultSecret(new_password)
        new_vault_secrets = [('default', new_vault_secret)]
        ve.rekey_file(src_file_path, vault.match_encrypt_secret(new_vault_secrets)[1])

        # FIXME: can just update self._secrets here
        new_ve = vault.VaultEditor(VaultLib(new_vault_secrets))
        self._assert_file_is_encrypted(new_ve, src_file_path, src_file_contents)
    def test_rekey_file(self):
        self._test_dir = self._create_test_dir()

        src_file_contents = to_bytes("some info in a file\nyup.")
        src_file_path = self._create_file(self._test_dir, 'src_file', content=src_file_contents)

        ve = self._vault_editor()
        ve.encrypt_file(src_file_path, self.vault_secret)

        # FIXME: update to just set self._secrets or just a new vault secret id
        new_password = '******'
        new_vault_secret = TextVaultSecret(new_password)
        new_vault_secrets = [('default', new_vault_secret)]
        ve.rekey_file(src_file_path, vault.match_encrypt_secret(new_vault_secrets)[1])

        # FIXME: can just update self._secrets here
        new_ve = vault.VaultEditor(VaultLib(new_vault_secrets))
        self._assert_file_is_encrypted(new_ve, src_file_path, src_file_contents)
Exemple #7
0
    def run(self):
        loader = DataLoader()
        vault_ids = self.options.vault_ids
        default_vault_ids = C.DEFAULT_VAULT_IDENTITY_LIST
        vault_ids = default_vault_ids + vault_ids
        encrypt_vault_id = None
        vault_secrets = self.setup_vault_secrets(loader,
                                                 vault_ids=vault_ids,
                                                 vault_password_files=self.options.vault_password_files,
                                                 vault_pass=self.options.vault_pass)
        encrypt_secret = match_encrypt_secret(vault_secrets,
                                              encrypt_vault_id=encrypt_vault_id)

        self.encrypt_vault_id = encrypt_secret[0]
        self.encrypt_secret = encrypt_secret[1]
        loader.set_vault_secrets(vault_secrets)
        vault = VaultLib(vault_secrets)
        self.editor = VaultEditor(vault)
Exemple #8
0
    def run(self):
        super().run()
        self.loader = DataLoader()

        vault_ids = C.DEFAULT_VAULT_IDENTITY_LIST + list(
            context.CLIARGS['vault_ids'])
        vault_secrets = self.setup_vault_secrets(
            self.loader,
            vault_ids=vault_ids,
            vault_password_files=list(context.CLIARGS['vault_password_files']),
            ask_vault_pass=context.CLIARGS['ask_vault_pass'])

        if not vault_secrets:
            raise AnsibleOptionsError(
                "A vault password is required to use ansible-vault")

        encrypt_vault_id = context.CLIARGS.get(
            'encrypt_vault_id') or C.DEFAULT_VAULT_ENCRYPT_IDENTITY
        if len(vault_secrets) > 1 and not encrypt_vault_id:
            raise AnsibleOptionsError(
                "Use '--encrypt-vault-id id' to choose one of the following vault ids to use for encryption: %s"
                % ','.join([x[0] for x in vault_secrets]))

        encrypt_secret = match_encrypt_secret(
            vault_secrets, encrypt_vault_id=encrypt_vault_id)

        self.encrypt_vault_id = encrypt_secret[0]
        self.encrypt_secret = encrypt_secret[1]

        self.loader.set_vault_secrets(vault_secrets)

        self.vault = VaultLib(vault_secrets)

        if len(context.CLIARGS['args']) != 1:
            raise AnsibleOptionsError(
                "Exactly one inventory file must be specified")

        self.file = os.path.expanduser(context.CLIARGS['args'][0])

        old_umask = os.umask(0o077)

        self.execute()

        os.umask(old_umask)
Exemple #9
0
    def test_rekey_migration(self):
        v10_file = tempfile.NamedTemporaryFile(delete=False)
        with v10_file as f:
            f.write(to_bytes(v10_data))

        ve = self._vault_editor(self._secrets("ansible"))

        # make sure the password functions for the cipher
        error_hit = False
        new_secrets = self._secrets("ansible2")
        try:
            ve.rekey_file(v10_file.name,
                          vault.match_encrypt_secret(new_secrets)[1])
        except errors.AnsibleError:
            raise
            error_hit = True

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

        assert error_hit is False, "error rekeying 1.0 file to 1.1"

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

        os.unlink(v10_file.name)

        self.assertIn(b'AES256', fdata,
                      'AES256 was not found in vault file %s' % to_text(fdata))
        assert error_hit is False, "error decrypting migrated 1.0 file"
        assert dec_data.strip(
        ) == b"foo", "incorrect decryption of rekeyed/migrated file: %s" % dec_data
    def test_rekey_migration(self):
        v10_file = tempfile.NamedTemporaryFile(delete=False)
        with v10_file as f:
            f.write(to_bytes(v10_data))

        ve = self._vault_editor(self._secrets("ansible"))

        # make sure the password functions for the cipher
        error_hit = False
        new_secrets = self._secrets("ansible2")
        try:
            ve.rekey_file(v10_file.name, vault.match_encrypt_secret(new_secrets)[1])
        except errors.AnsibleError:
            error_hit = True

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

        assert error_hit is False, "error rekeying 1.0 file to 1.1"

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

        os.unlink(v10_file.name)

        self.assertIn(b'AES256', fdata, 'AES256 was not found in vault file %s' % to_text(fdata))
        assert error_hit is False, "error decrypting migrated 1.0 file"
        assert dec_data.strip() == b"foo", "incorrect decryption of rekeyed/migrated file: %s" % dec_data
Exemple #11
0
    def run(self):
        super(VaultCLI, self).run()
        loader = DataLoader()

        # set default restrictive umask
        old_umask = os.umask(0o077)

        vault_ids = list(context.CLIARGS['vault_ids'])

        # there are 3 types of actions, those that just 'read' (decrypt, view) and only
        # need to ask for a password once, and those that 'write' (create, encrypt) that
        # ask for a new password and confirm it, and 'read/write (rekey) that asks for the
        # old password, then asks for a new one and confirms it.

        default_vault_ids = C.DEFAULT_VAULT_IDENTITY_LIST
        vault_ids = default_vault_ids + vault_ids

        action = context.CLIARGS['action']

        # TODO: instead of prompting for these before, we could let VaultEditor
        #       call a callback when it needs it.
        if action in ['decrypt', 'view', 'rekey', 'edit']:
            vault_secrets = self.setup_vault_secrets(loader, vault_ids=vault_ids,
                                                     vault_password_files=list(context.CLIARGS['vault_password_files']),
                                                     ask_vault_pass=context.CLIARGS['ask_vault_pass'])
            if not vault_secrets:
                raise AnsibleOptionsError("A vault password is required to use Ansible's Vault")

        if action in ['encrypt', 'encrypt_string', 'create']:

            encrypt_vault_id = None
            # no --encrypt-vault-id context.CLIARGS['encrypt_vault_id'] for 'edit'
            if action not in ['edit']:
                encrypt_vault_id = context.CLIARGS['encrypt_vault_id'] or C.DEFAULT_VAULT_ENCRYPT_IDENTITY

            vault_secrets = None
            vault_secrets = \
                self.setup_vault_secrets(loader,
                                         vault_ids=vault_ids,
                                         vault_password_files=list(context.CLIARGS['vault_password_files']),
                                         ask_vault_pass=context.CLIARGS['ask_vault_pass'],
                                         create_new_password=True)

            if len(vault_secrets) > 1 and not encrypt_vault_id:
                raise AnsibleOptionsError("The vault-ids %s are available to encrypt. Specify the vault-id to encrypt with --encrypt-vault-id" %
                                          ','.join([x[0] for x in vault_secrets]))

            if not vault_secrets:
                raise AnsibleOptionsError("A vault password is required to use Ansible's Vault")

            encrypt_secret = match_encrypt_secret(vault_secrets,
                                                  encrypt_vault_id=encrypt_vault_id)

            # only one secret for encrypt for now, use the first vault_id and use its first secret
            # TODO: exception if more than one?
            self.encrypt_vault_id = encrypt_secret[0]
            self.encrypt_secret = encrypt_secret[1]

        if action in ['rekey']:
            encrypt_vault_id = context.CLIARGS['encrypt_vault_id'] or C.DEFAULT_VAULT_ENCRYPT_IDENTITY
            # print('encrypt_vault_id: %s' % encrypt_vault_id)
            # print('default_encrypt_vault_id: %s' % default_encrypt_vault_id)

            # new_vault_ids should only ever be one item, from
            # load the default vault ids if we are using encrypt-vault-id
            new_vault_ids = []
            if encrypt_vault_id:
                new_vault_ids = default_vault_ids
            if context.CLIARGS['new_vault_id']:
                new_vault_ids.append(context.CLIARGS['new_vault_id'])

            new_vault_password_files = []
            if context.CLIARGS['new_vault_password_file']:
                new_vault_password_files.append(context.CLIARGS['new_vault_password_file'])

            new_vault_secrets = \
                self.setup_vault_secrets(loader,
                                         vault_ids=new_vault_ids,
                                         vault_password_files=new_vault_password_files,
                                         ask_vault_pass=context.CLIARGS['ask_vault_pass'],
                                         create_new_password=True)

            if not new_vault_secrets:
                raise AnsibleOptionsError("A new vault password is required to use Ansible's Vault rekey")

            # There is only one new_vault_id currently and one new_vault_secret, or we
            # use the id specified in --encrypt-vault-id
            new_encrypt_secret = match_encrypt_secret(new_vault_secrets,
                                                      encrypt_vault_id=encrypt_vault_id)

            self.new_encrypt_vault_id = new_encrypt_secret[0]
            self.new_encrypt_secret = new_encrypt_secret[1]

        loader.set_vault_secrets(vault_secrets)

        # FIXME: do we need to create VaultEditor here? its not reused
        vault = VaultLib(vault_secrets)
        self.editor = VaultEditor(vault)

        context.CLIARGS['func']()

        # and restore umask
        os.umask(old_umask)
Exemple #12
0
    def run(self):
        super(VaultCLI, self).run()
        loader = DataLoader()

        # set default restrictive umask
        old_umask = os.umask(0o077)

        vault_ids = self.options.vault_ids

        # there are 3 types of actions, those that just 'read' (decrypt, view) and only
        # need to ask for a password once, and those that 'write' (create, encrypt) that
        # ask for a new password and confirm it, and 'read/write (rekey) that asks for the
        # old password, then asks for a new one and confirms it.

        default_vault_ids = C.DEFAULT_VAULT_IDENTITY_LIST
        vault_ids = default_vault_ids + vault_ids

        # TODO: instead of prompting for these before, we could let VaultEditor
        #       call a callback when it needs it.
        if self.action in ['decrypt', 'view', 'rekey', 'edit']:
            vault_secrets = self.setup_vault_secrets(loader,
                                                     vault_ids=vault_ids,
                                                     vault_password_files=self.options.vault_password_files,
                                                     ask_vault_pass=self.options.ask_vault_pass)
            if not vault_secrets:
                raise AnsibleOptionsError("A vault password is required to use Ansible's Vault")

        if self.action in ['encrypt', 'encrypt_string', 'create']:
            if len(vault_ids) > 1:
                raise AnsibleOptionsError("Only one --vault-id can be used for encryption")

            vault_secrets = None
            vault_secrets = \
                self.setup_vault_secrets(loader,
                                         vault_ids=vault_ids,
                                         vault_password_files=self.options.vault_password_files,
                                         ask_vault_pass=self.options.ask_vault_pass,
                                         create_new_password=True)
            if not vault_secrets:
                raise AnsibleOptionsError("A vault password is required to use Ansible's Vault")

            encrypt_secret = match_encrypt_secret(vault_secrets)
            # only one secret for encrypt for now, use the first vault_id and use its first secret
            # self.encrypt_vault_id = list(vault_secrets.keys())[0]
            # self.encrypt_secret = vault_secrets[self.encrypt_vault_id][0]
            self.encrypt_vault_id = encrypt_secret[0]
            self.encrypt_secret = encrypt_secret[1]

        if self.action in ['rekey']:
            new_vault_ids = []
            if self.options.new_vault_id:
                new_vault_ids.append(self.options.new_vault_id)

            new_vault_secrets = \
                self.setup_vault_secrets(loader,
                                         vault_ids=new_vault_ids,
                                         vault_password_files=self.options.new_vault_password_files,
                                         ask_vault_pass=self.options.ask_vault_pass,
                                         create_new_password=True)

            if not new_vault_secrets:
                raise AnsibleOptionsError("A new vault password is required to use Ansible's Vault rekey")

            # There is only one new_vault_id currently and one new_vault_secret
            new_encrypt_secret = match_encrypt_secret(new_vault_secrets)

            self.new_encrypt_vault_id = new_encrypt_secret[0]
            self.new_encrypt_secret = new_encrypt_secret[1]

        loader.set_vault_secrets(vault_secrets)

        # FIXME: do we need to create VaultEditor here? its not reused
        vault = VaultLib(vault_secrets)
        self.editor = VaultEditor(vault)

        self.execute()

        # and restore umask
        os.umask(old_umask)
Exemple #13
0
 def _from_plaintext(self, seq):
     id_secret = vault.match_encrypt_secret(self.good_vault_secrets)
     return objects.AnsibleVaultEncryptedUnicode.from_plaintext(
         seq, vault=self.vault, secret=id_secret[1])
Exemple #14
0
    def run(self):
        super(VaultCLI, self).run()
        loader = DataLoader()

        # set default restrictive umask
        old_umask = os.umask(0o077)

        vault_ids = self.options.vault_ids

        # there are 3 types of actions, those that just 'read' (decrypt, view) and only
        # need to ask for a password once, and those that 'write' (create, encrypt) that
        # ask for a new password and confirm it, and 'read/write (rekey) that asks for the
        # old password, then asks for a new one and confirms it.

        default_vault_ids = C.DEFAULT_VAULT_IDENTITY_LIST
        vault_ids = default_vault_ids + vault_ids

        # TODO: instead of prompting for these before, we could let VaultEditor
        #       call a callback when it needs it.
        if self.action in ['decrypt', 'view', 'rekey', 'edit']:
            vault_secrets = self.setup_vault_secrets(loader,
                                                     vault_ids=vault_ids,
                                                     vault_password_files=self.options.vault_password_files,
                                                     ask_vault_pass=self.options.ask_vault_pass)
            if not vault_secrets:
                raise AnsibleOptionsError("A vault password is required to use Ansible's Vault")

        if self.action in ['encrypt', 'encrypt_string', 'create']:
            if len(vault_ids) > 1:
                raise AnsibleOptionsError("Only one --vault-id can be used for encryption")

            vault_secrets = None
            vault_secrets = \
                self.setup_vault_secrets(loader,
                                         vault_ids=vault_ids,
                                         vault_password_files=self.options.vault_password_files,
                                         ask_vault_pass=self.options.ask_vault_pass,
                                         create_new_password=True)

            if len(vault_secrets) > 1:
                raise AnsibleOptionsError("Only one --vault-id can be used for encryption. This includes passwords from configuration and cli.")

            if not vault_secrets:
                raise AnsibleOptionsError("A vault password is required to use Ansible's Vault")

            encrypt_secret = match_encrypt_secret(vault_secrets)
            # only one secret for encrypt for now, use the first vault_id and use its first secret
            # self.encrypt_vault_id = list(vault_secrets.keys())[0]
            # self.encrypt_secret = vault_secrets[self.encrypt_vault_id][0]
            self.encrypt_vault_id = encrypt_secret[0]
            self.encrypt_secret = encrypt_secret[1]

        if self.action in ['rekey']:
            new_vault_ids = []
            if self.options.new_vault_id:
                new_vault_ids.append(self.options.new_vault_id)

            new_vault_secrets = \
                self.setup_vault_secrets(loader,
                                         vault_ids=new_vault_ids,
                                         vault_password_files=self.options.new_vault_password_files,
                                         ask_vault_pass=self.options.ask_vault_pass,
                                         create_new_password=True)

            if not new_vault_secrets:
                raise AnsibleOptionsError("A new vault password is required to use Ansible's Vault rekey")

            # There is only one new_vault_id currently and one new_vault_secret
            new_encrypt_secret = match_encrypt_secret(new_vault_secrets)

            self.new_encrypt_vault_id = new_encrypt_secret[0]
            self.new_encrypt_secret = new_encrypt_secret[1]

        loader.set_vault_secrets(vault_secrets)

        # FIXME: do we need to create VaultEditor here? its not reused
        vault = VaultLib(vault_secrets)
        self.editor = VaultEditor(vault)

        self.execute()

        # and restore umask
        os.umask(old_umask)
Exemple #15
0
 def vault_secret(self):
     return vault.match_encrypt_secret(self.vault_secrets)[1]
Exemple #16
0
    def run(self):
        super(VaultCLI, self).run()
        loader = DataLoader()

        # set default restrictive umask
        old_umask = os.umask(0o077)

        vault_ids = self.options.vault_ids

        # there are 3 types of actions, those that just 'read' (decrypt, view) and only
        # need to ask for a password once, and those that 'write' (create, encrypt) that
        # ask for a new password and confirm it, and 'read/write (rekey) that asks for the
        # old password, then asks for a new one and confirms it.

        default_vault_ids = C.DEFAULT_VAULT_IDENTITY_LIST
        vault_ids = default_vault_ids + vault_ids

        # TODO: instead of prompting for these before, we could let VaultEditor
        #       call a callback when it needs it.
        if self.action in ['decrypt', 'view', 'rekey', 'edit']:
            vault_secrets = self.setup_vault_secrets(loader,
                                                     vault_ids=vault_ids,
                                                     vault_password_files=self.options.vault_password_files,
                                                     ask_vault_pass=self.options.ask_vault_pass)
            if not vault_secrets:
                raise AnsibleOptionsError("A vault password is required to use Ansible's Vault")

        if self.action in ['encrypt', 'encrypt_string', 'create']:

            encrypt_vault_id = None
            # no --encrypt-vault-id self.options.encrypt_vault_id for 'edit'
            if self.action not in ['edit']:
                encrypt_vault_id = self.options.encrypt_vault_id or C.DEFAULT_VAULT_ENCRYPT_IDENTITY

            vault_secrets = None
            vault_secrets = \
                self.setup_vault_secrets(loader,
                                         vault_ids=vault_ids,
                                         vault_password_files=self.options.vault_password_files,
                                         ask_vault_pass=self.options.ask_vault_pass,
                                         create_new_password=True)

            if len(vault_secrets) > 1 and not encrypt_vault_id:
                raise AnsibleOptionsError("The vault-ids %s are available to encrypt. Specify the vault-id to encrypt with --encrypt-vault-id" %
                                          ','.join([x[0] for x in vault_secrets]))

            if not vault_secrets:
                raise AnsibleOptionsError("A vault password is required to use Ansible's Vault")

            encrypt_secret = match_encrypt_secret(vault_secrets,
                                                  encrypt_vault_id=encrypt_vault_id)

            # only one secret for encrypt for now, use the first vault_id and use its first secret
            # TODO: exception if more than one?
            self.encrypt_vault_id = encrypt_secret[0]
            self.encrypt_secret = encrypt_secret[1]

        if self.action in ['rekey']:
            encrypt_vault_id = self.options.encrypt_vault_id or C.DEFAULT_VAULT_ENCRYPT_IDENTITY
            # print('encrypt_vault_id: %s' % encrypt_vault_id)
            # print('default_encrypt_vault_id: %s' % default_encrypt_vault_id)

            # new_vault_ids should only ever be one item, from
            # load the default vault ids if we are using encrypt-vault-id
            new_vault_ids = []
            if encrypt_vault_id:
                new_vault_ids = default_vault_ids
            if self.options.new_vault_id:
                new_vault_ids.append(self.options.new_vault_id)

            new_vault_password_files = []
            if self.options.new_vault_password_file:
                new_vault_password_files.append(self.options.new_vault_password_file)

            new_vault_secrets = \
                self.setup_vault_secrets(loader,
                                         vault_ids=new_vault_ids,
                                         vault_password_files=new_vault_password_files,
                                         ask_vault_pass=self.options.ask_vault_pass,
                                         create_new_password=True)

            if not new_vault_secrets:
                raise AnsibleOptionsError("A new vault password is required to use Ansible's Vault rekey")

            # There is only one new_vault_id currently and one new_vault_secret, or we
            # use the id specified in --encrypt-vault-id
            new_encrypt_secret = match_encrypt_secret(new_vault_secrets,
                                                      encrypt_vault_id=encrypt_vault_id)

            self.new_encrypt_vault_id = new_encrypt_secret[0]
            self.new_encrypt_secret = new_encrypt_secret[1]

        loader.set_vault_secrets(vault_secrets)

        # FIXME: do we need to create VaultEditor here? its not reused
        vault = VaultLib(vault_secrets)
        self.editor = VaultEditor(vault)

        self.execute()

        # and restore umask
        os.umask(old_umask)
Exemple #17
0
 def vault_secret(self):
     return match_encrypt_secret(self.vault_secrets)[1]
Exemple #18
0
 def _from_plaintext(self, seq):
     id_secret = vault.match_encrypt_secret(self.good_vault_secrets)
     return objects.AnsibleVaultEncryptedUnicode.from_plaintext(seq, vault=self.vault, secret=id_secret[1])