public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] repo/gentoo:master commit in: app-admin/ansible/, app-admin/ansible/files/
@ 2017-06-12 19:20 Matt Thode
  0 siblings, 0 replies; 2+ messages in thread
From: Matt Thode @ 2017-06-12 19:20 UTC (permalink / raw
  To: gentoo-commits

commit:     3e9a1c0cab7d8f00665226863e8877028390e3dc
Author:     Matthew Thode <prometheanfire <AT> gentoo <DOT> org>
AuthorDate: Mon Jun 12 19:19:09 2017 +0000
Commit:     Matt Thode <prometheanfire <AT> gentoo <DOT> org>
CommitDate: Mon Jun 12 19:20:05 2017 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=3e9a1c0c

app-admin/ansible: fixing bug 620536

Package-Manager: Portage-2.3.5, Repoman-2.3.2

 app-admin/ansible/Manifest                         |   1 +
 app-admin/ansible/ansible-2.3.1.0.ebuild           |   5 +-
 app-admin/ansible/files/CVE-2017-7481.patch        | 135 ---
 app-admin/ansible/files/README.gentoo              |   8 -
 .../files/ansible-2.3.1.0-pycryptodome.patch       | 905 ---------------------
 app-admin/ansible/files/ansible.env                |   2 -
 6 files changed, 4 insertions(+), 1052 deletions(-)

diff --git a/app-admin/ansible/Manifest b/app-admin/ansible/Manifest
index bcc9f9164ee..f3d963b87e1 100644
--- a/app-admin/ansible/Manifest
+++ b/app-admin/ansible/Manifest
@@ -1 +1,2 @@
+DIST ansible-2.3.1.0-pycryptodome.patch 32463 SHA256 fe464db648783871618ef26b9b1d8ffa7c090a558caed30857953eec65ef6a65 SHA512 0ed750d5d27378b942808a7db9be968cfe281a2985d40a13476763572b5aa95a4e336eda9b91b4fda4e20320214d7dabc38a69c18baf404696cb4bdb70c395cf WHIRLPOOL 9b2f754a31926c54bed9416d273d9e6b790b7652721c0f7de2abc8ccb25354925b64fbf98a02ab42f89fe9bc58c495bec54e12f8a541599b1d409914af6628af
 DIST ansible-2.3.1.0.tar.gz 4263357 SHA256 cd4b8f53720fcd0c351156b840fdd15ecfbec22c951b5406ec503de49d40b9f5 SHA512 7b4b33c56a15c41d756f095944d7a0dbf894557350879430df21061b717b9574aae624a276bf7e1a13d043b718aeaccac1ce510a3cb085983311ddf06fa832bc WHIRLPOOL 5552ff64e8cac722a705bd1e72465c8bfe583a1c5efc587ca141b34eaa35d2af0ea2e1084a072ecb7dbb28d59d7f56e47c4c73f9e3e0f7f2451ef4e7134ad1af

diff --git a/app-admin/ansible/ansible-2.3.1.0.ebuild b/app-admin/ansible/ansible-2.3.1.0.ebuild
index 79f0274da90..29e02f9a2cf 100644
--- a/app-admin/ansible/ansible-2.3.1.0.ebuild
+++ b/app-admin/ansible/ansible-2.3.1.0.ebuild
@@ -9,7 +9,8 @@ inherit distutils-r1 eutils versionator
 
 DESCRIPTION="Model-driven deployment, config management, and command execution framework"
 HOMEPAGE="http://ansible.com/"
-SRC_URI="http://releases.ansible.com/${PN}/${P}.tar.gz"
+SRC_URI="http://releases.ansible.com/${PN}/${P}.tar.gz
+	https://dev.gentoo.org/~prometheanfire/dist/ansible/ansible-2.3.1.0-pycryptodome.patch"
 
 LICENSE="GPL-3"
 SLOT="0"
@@ -47,7 +48,7 @@ DEPEND="
 # not included in release tarball
 RESTRICT="test"
 
-PATCHES=( "${FILESDIR}/${P}-pycryptodome.patch" )
+PATCHES=( "${DISTDIR}/${P}-pycryptodome.patch" )
 
 python_test() {
 	nosetests -d -w test/units -v --with-coverage --cover-package=ansible --cover-branches || die

diff --git a/app-admin/ansible/files/CVE-2017-7481.patch b/app-admin/ansible/files/CVE-2017-7481.patch
deleted file mode 100644
index 135fdc27478..00000000000
--- a/app-admin/ansible/files/CVE-2017-7481.patch
+++ /dev/null
@@ -1,135 +0,0 @@
-From ed56f51f185a1ffd7ea57130d260098686fcc7c2 Mon Sep 17 00:00:00 2001
-From: James Cammarata <jimi@sngx.net>
-Date: Mon, 8 May 2017 10:37:10 -0500
-Subject: [PATCH] Fixing security issue with lookup returns not tainting the
- jinja2 environment
-
-CVE-2017-7481
-
-Lookup returns wrap the result in unsafe, however when used through the
-standard templar engine, this does not result in the jinja2 environment being
-marked as unsafe as a whole. This means the lookup result looses the unsafe
-protection and may become simple unicode strings, which can result in bad
-things being re-templated.
-
-This also adds a global lookup param and cfg options for lookups to allow
-unsafe returns, so users can force the previous (insecure) behavior.
----
- docs/docsite/rst/intro_configuration.rst | 14 ++++++++++++++
- examples/ansible.cfg                     |  8 +++++++-
- lib/ansible/constants.py                 |  1 +
- lib/ansible/template/__init__.py         | 11 +++++++++--
- 4 files changed, 31 insertions(+), 3 deletions(-)
-
-diff --git a/docs/docsite/rst/intro_configuration.rst b/docs/docsite/rst/intro_configuration.rst
-index 3647e22..259e107 100644
---- a/docs/docsite/rst/intro_configuration.rst
-+++ b/docs/docsite/rst/intro_configuration.rst
-@@ -86,6 +86,20 @@ different locations::
- Most users will not need to use this feature.  See :doc:`dev_guide/developing_plugins` for more details.
- 
- 
-+.. _allow_unsafe_lookups:
-+
-+allow_unsafe_lookups
-+====================
-+
-+.. versionadded:: 2.2.3, 2.3.1
-+
-+When enabled, this option allows lookup plugins (whether used in variables as `{{lookup('foo')}}` or as a loop as `with_foo`) to return data that is **not** marked "unsafe". By default, such data is marked as unsafe to prevent the templating engine from evaluating any jinja2 templating language, as this could represent a security risk.
-+
-+This option is provided to allow for backwards-compatibility, however users should first consider adding `allow_unsafe=True` to any lookups which may be expected to contain data which may be run through the templating engine later. For example::
-+
-+    {{lookup('pipe', '/path/to/some/command', allow_unsafe=True)}}
-+
-+
- .. _allow_world_readable_tmpfiles:
- 
- allow_world_readable_tmpfiles
-diff --git a/examples/ansible.cfg b/examples/ansible.cfg
-index e283064..77ba5d2 100644
---- a/examples/ansible.cfg
-+++ b/examples/ansible.cfg
-@@ -282,7 +282,7 @@
- # Controls showing custom stats at the end, off by default
- #show_custom_stats = True
- 
--# Controlls which files to ignore when using a directory as inventory with
-+# Controls which files to ignore when using a directory as inventory with
- # possibly multiple sources (both static and dynamic)
- #inventory_ignore_extensions = ~, .orig, .bak, .ini, .cfg, .retry, .pyc, .pyo
- 
-@@ -294,6 +294,12 @@
- # Setting to True keeps them under the ansible_facts namespace, the default is False
- #restrict_facts_namespace: True
- 
-+# When enabled, this option allows lookups (via variables like {{lookup('foo')}} or when used as
-+# a loop with `with_foo`) to return data that is not marked "unsafe". This means the data may contain
-+# jinja2 templating language which will be run through the templating engine.
-+# ENABLING THIS COULD BE A SECURITY RISK
-+#allow_unsafe_lookups = False
-+
- [privilege_escalation]
- #become=True
- #become_method=sudo
-diff --git a/lib/ansible/constants.py b/lib/ansible/constants.py
-index da45037..40d1038 100644
---- a/lib/ansible/constants.py
-+++ b/lib/ansible/constants.py
-@@ -236,6 +236,7 @@ def load_config_file():
-                                        ["~", ".orig", ".bak", ".ini", ".cfg", ".retry", ".pyc", ".pyo"], value_type='list')
- DEFAULT_VAR_COMPRESSION_LEVEL = get_config(p, DEFAULTS, 'var_compression_level', 'ANSIBLE_VAR_COMPRESSION_LEVEL', 0, value_type='integer')
- DEFAULT_INTERNAL_POLL_INTERVAL = get_config(p, DEFAULTS, 'internal_poll_interval', None, 0.001, value_type='float')
-+DEFAULT_ALLOW_UNSAFE_LOOKUPS = get_config(p, DEFAULTS, 'allow_unsafe_lookups', None, False, value_type='boolean')
- ERROR_ON_MISSING_HANDLER  = get_config(p, DEFAULTS, 'error_on_missing_handler', 'ANSIBLE_ERROR_ON_MISSING_HANDLER', True, value_type='boolean')
- SHOW_CUSTOM_STATS = get_config(p, DEFAULTS, 'show_custom_stats', 'ANSIBLE_SHOW_CUSTOM_STATS', False, value_type='boolean')
- NAMESPACE_FACTS = get_config(p, DEFAULTS, 'restrict_facts_namespace', 'ANSIBLE_RESTRICT_FACTS', False, value_type='boolean')
-diff --git a/lib/ansible/template/__init__.py b/lib/ansible/template/__init__.py
-index 5d551d7..49de8aa 100644
---- a/lib/ansible/template/__init__.py
-+++ b/lib/ansible/template/__init__.py
-@@ -252,6 +252,9 @@ def __init__(self, loader, shared_loader_obj=None, variables=dict()):
-             loader=FileSystemLoader(self._basedir),
-         )
- 
-+        # the current rendering context under which the templar class is working
-+        self.cur_context = None
-+
-         self.SINGLE_VAR = re.compile(r"^%s\s*(\w*)\s*%s$" % (self.environment.variable_start_string, self.environment.variable_end_string))
- 
-         self._clean_regex   = re.compile(r'(?:%s|%s|%s|%s)' % (
-@@ -574,6 +577,7 @@ def _lookup(self, name, *args, **kwargs):
- 
-         if instance is not None:
-             wantlist = kwargs.pop('wantlist', False)
-+            allow_unsafe = kwargs.pop('allow_unsafe', C.DEFAULT_ALLOW_UNSAFE_LOOKUPS)
- 
-             from ansible.utils.listify import listify_lookup_plugin_terms
-             loop_terms = listify_lookup_plugin_terms(terms=args, templar=self, loader=self._loader, fail_on_undefined=True, convert_bare=False)
-@@ -510,7 +510,7 @@
-                     raise AnsibleError("An unhandled exception occurred while running the lookup plugin '%s'. Error was a %s, original message: %s" % (name, type(e), e))
-                 ran = None
- 
--            if ran:
-+            if ran and not allow_unsafe:
-                 from ansible.vars.unsafe_proxy import UnsafeProxy, wrap_var
-                 if wantlist:
-                     ran = wrap_var(ran)
-@@ -600,6 +605,8 @@ def _lookup(self, name, *args, **kwargs):
-                         else:
-                             ran = wrap_var(ran)
- 
-+                if self.cur_context:
-+                    self.cur_context.unsafe = True
-             return ran
-         else:
-             raise AnsibleError("lookup plugin (%s) not found" % name)
-@@ -656,7 +663,7 @@ def do_template(self, data, preserve_trailing_newlines=True, escape_backslashes=
- 
-             jvars = AnsibleJ2Vars(self, t.globals)
- 
--            new_context = t.new_context(jvars, shared=True)
-+            self.cur_context = new_context = t.new_context(jvars, shared=True)
-             rf = t.root_render_func(new_context)
- 
-             try:

diff --git a/app-admin/ansible/files/README.gentoo b/app-admin/ansible/files/README.gentoo
deleted file mode 100644
index 828e13cddeb..00000000000
--- a/app-admin/ansible/files/README.gentoo
+++ /dev/null
@@ -1,8 +0,0 @@
-You can define parameters through shell variables OR use config files
-Examples of config files installed in /usr/share/ansible/examples
-You have to create ansible hosts file!
-More info on http://docs.ansible.com/intro_getting_started.html
-
-Some optional dependencies, you might want to install:
-dev-python/keyczar - needed to support accelerated mode
-dev-python/paramiko - alternative SSH backend"

diff --git a/app-admin/ansible/files/ansible-2.3.1.0-pycryptodome.patch b/app-admin/ansible/files/ansible-2.3.1.0-pycryptodome.patch
deleted file mode 100644
index 71799dec1ab..00000000000
--- a/app-admin/ansible/files/ansible-2.3.1.0-pycryptodome.patch
+++ /dev/null
@@ -1,905 +0,0 @@
-diff -uNr ansible-2.3.0.0.ORIG/lib/ansible/executor/process/worker.py ansible-2.3.0.0/lib/ansible/executor/process/worker.py
---- ansible-2.3.0.0.ORIG/lib/ansible/executor/process/worker.py	2017-05-23 14:23:12.313595450 +0100
-+++ ansible-2.3.0.0/lib/ansible/executor/process/worker.py	2017-05-23 14:24:22.116598926 +0100
-@@ -26,14 +26,6 @@
- 
- from jinja2.exceptions import TemplateNotFound
- 
--# TODO: not needed if we use the cryptography library with its default RNG
--# engine
--HAS_ATFORK=True
--try:
--    from Crypto.Random import atfork
--except ImportError:
--    HAS_ATFORK=False
--
- from ansible.errors import AnsibleConnectionFailure
- from ansible.executor.task_executor import TaskExecutor
- from ansible.executor.task_result import TaskResult
-@@ -95,9 +87,6 @@
-         #pr = cProfile.Profile()
-         #pr.enable()
- 
--        if HAS_ATFORK:
--            atfork()
--
-         try:
-             # execute the task and build a TaskResult from the result
-             display.debug("running TaskExecutor() for %s/%s" % (self._host, self._task))
-diff -uNr ansible-2.3.0.0.ORIG/lib/ansible/modules/cloud/amazon/ec2_win_password.py ansible-2.3.0.0/lib/ansible/modules/cloud/amazon/ec2_win_password.py
---- ansible-2.3.0.0.ORIG/lib/ansible/modules/cloud/amazon/ec2_win_password.py	2017-05-23 14:23:12.299595449 +0100
-+++ ansible-2.3.0.0/lib/ansible/modules/cloud/amazon/ec2_win_password.py	2017-05-23 14:29:51.003615305 +0100
-@@ -93,9 +93,10 @@
- '''
- 
- from base64 import b64decode
--from Crypto.Cipher import PKCS1_v1_5
--from Crypto.PublicKey import RSA
- import datetime
-+from cryptography.hazmat.backends import default_backend
-+from cryptography.hazmat.primitives.asymmetric.padding import PKCS1v15
-+from cryptography.hazmat.primitives.serialization import load_pem_private_key
- 
- try:
-     import boto.ec2
-@@ -103,6 +104,9 @@
- except ImportError:
-     HAS_BOTO = False
- 
-+BACKEND = default_backend()
-+
-+
- def main():
-     argument_spec = ec2_argument_spec()
-     argument_spec.update(dict(
-@@ -151,15 +155,12 @@
-     else:
-         try:
-             with f:
--                key = RSA.importKey(f.read(), key_passphrase)
--        except (ValueError, IndexError, TypeError) as e:
-+                key = load_pem_private_key(f.read(), key_passphrase, BACKEND)
-+        except (ValueError, TypeError) as e:
-             module.fail_json(msg = "unable to parse key file")
- 
--    cipher = PKCS1_v1_5.new(key)
--    sentinel = 'password decryption failed!!!'
--
-     try:
--        decrypted = cipher.decrypt(decoded, sentinel)
-+	decrypted = key.decrypt(decoded, PKCS1v15())
-     except ValueError as e:
-         decrypted = None
- 
-diff -uNr ansible-2.3.0.0.ORIG/lib/ansible/parsing/vault/__init__.py ansible-2.3.0.0/lib/ansible/parsing/vault/__init__.py
---- ansible-2.3.0.0.ORIG/lib/ansible/parsing/vault/__init__.py	2017-05-23 14:23:12.311595449 +0100
-+++ ansible-2.3.0.0/lib/ansible/parsing/vault/__init__.py	2017-05-23 14:31:23.267619901 +0100
-@@ -25,7 +25,6 @@
- import sys
- import tempfile
- import random
--from io import BytesIO
- from subprocess import call
- from hashlib import sha256
- from binascii import hexlify
-@@ -35,32 +34,14 @@
- # Note: Only used for loading obsolete VaultAES files.  All files are written
- # using the newer VaultAES256 which does not require md5
- 
--try:
--    from Crypto.Hash import SHA256, HMAC
--    HAS_HASH = True
--except ImportError:
--    HAS_HASH = False
--
--# Counter import fails for 2.0.1, requires >= 2.6.1 from pip
--try:
--    from Crypto.Util import Counter
--    HAS_COUNTER = True
--except ImportError:
--    HAS_COUNTER = False
--
--# KDF import fails for 2.0.1, requires >= 2.6.1 from pip
--try:
--    from Crypto.Protocol.KDF import PBKDF2
--    HAS_PBKDF2 = True
--except ImportError:
--    HAS_PBKDF2 = False
--
--# AES IMPORTS
--try:
--    from Crypto.Cipher import AES as AES
--    HAS_AES = True
--except ImportError:
--    HAS_AES = False
-+from cryptography.exceptions import InvalidSignature
-+from cryptography.hazmat.backends import default_backend
-+from cryptography.hazmat.primitives import hashes, padding
-+from cryptography.hazmat.primitives.hmac import HMAC
-+from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
-+from cryptography.hazmat.primitives.ciphers import (
-+    Cipher as C_Cipher, algorithms, modes
-+)
- 
- from ansible.compat.six import PY3, binary_type
- from ansible.compat.six.moves import zip
-@@ -73,26 +54,8 @@
-     from ansible.utils.display import Display
-     display = Display()
- 
--# OpenSSL pbkdf2_hmac
--HAS_PBKDF2HMAC = False
--try:
--    from cryptography.hazmat.primitives.hashes import SHA256 as c_SHA256
--    from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
--    from cryptography.hazmat.backends import default_backend
--    HAS_PBKDF2HMAC = True
--except ImportError:
--    pass
--except Exception as e:
--    display.vvvv("Optional dependency 'cryptography' raised an exception, falling back to 'Crypto'.")
--    import traceback
--    display.vvvv("Traceback from import of cryptography was {0}".format(traceback.format_exc()))
--
--HAS_ANY_PBKDF2HMAC = HAS_PBKDF2 or HAS_PBKDF2HMAC
--
--
--CRYPTO_UPGRADE = "ansible-vault requires a newer version of pycrypto than the one installed on your platform." \
--    " You may fix this with OS-specific commands such as: yum install python-devel; rpm -e --nodeps python-crypto; pip install pycrypto"
- 
-+BACKEND = default_backend()
- b_HEADER = b'$ANSIBLE_VAULT'
- CIPHER_WHITELIST = frozenset((u'AES', u'AES256'))
- CIPHER_WRITE_WHITELIST = frozenset((u'AES256',))
-@@ -100,12 +63,6 @@
- # (used in VaultFile header) to a cipher class
- 
- 
--def check_prereqs():
--
--    if not HAS_AES or not HAS_COUNTER or not HAS_ANY_PBKDF2HMAC or not HAS_HASH:
--        raise AnsibleError(CRYPTO_UPGRADE)
--
--
- class AnsibleVaultError(AnsibleError):
-     pass
- 
-@@ -410,8 +367,6 @@
- 
-     def encrypt_file(self, filename, output_file=None):
- 
--        check_prereqs()
--
-         # A file to be encrypted into a vaultfile could be any encoding
-         # so treat the contents as a byte string.
- 
-@@ -424,8 +379,6 @@
- 
-     def decrypt_file(self, filename, output_file=None):
- 
--        check_prereqs()
--
-         # follow the symlink
-         filename = os.path.realpath(filename)
- 
-@@ -440,8 +393,6 @@
-     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):
-@@ -451,8 +402,6 @@
- 
-     def edit_file(self, filename):
- 
--        check_prereqs()
--
-         # follow the symlink
-         filename = os.path.realpath(filename)
- 
-@@ -471,7 +420,6 @@
- 
-     def plaintext(self, filename):
- 
--        check_prereqs()
-         ciphertext = self.read_data(filename)
- 
-         try:
-@@ -483,8 +431,6 @@
- 
-     def rekey_file(self, filename, b_new_password):
- 
--        check_prereqs()
--
-         # follow the symlink
-         filename = os.path.realpath(filename)
- 
-@@ -581,10 +527,6 @@
- 
-     # Note: strings in this class should be byte strings by default.
- 
--    def __init__(self):
--        if not HAS_AES:
--            raise AnsibleError(CRYPTO_UPGRADE)
--
-     def _aes_derive_key_and_iv(self, b_password, b_salt, key_length, iv_length):
- 
-         """ Create a key and an initialization vector """
-@@ -620,41 +562,22 @@
-                 ' switch to the newer VaultAES256 format', version='2.3')
-         # http://stackoverflow.com/a/14989032
- 
--        b_ciphertext = unhexlify(b_vaulttext)
--
--        in_file = BytesIO(b_ciphertext)
--        in_file.seek(0)
--        out_file = BytesIO()
-+        b_vaultdata = unhexlify(b_vaulttext)
-+        b_tmpsalt = b_vaultdata[:16]
-+        b_ciphertext = b_vaultdata[16:]
- 
--        bs = AES.block_size
--        b_tmpsalt = in_file.read(bs)
-+        bs = algorithms.AES.block_size // 8
-         b_salt = b_tmpsalt[len(b'Salted__'):]
-         b_key, b_iv = self._aes_derive_key_and_iv(b_password, b_salt, key_length, bs)
--        cipher = AES.new(b_key, AES.MODE_CBC, b_iv)
--        b_next_chunk = b''
--        finished = False
--
--        while not finished:
--            b_chunk, b_next_chunk = b_next_chunk, cipher.decrypt(in_file.read(1024 * bs))
--            if len(b_next_chunk) == 0:
--                if PY3:
--                    padding_length = b_chunk[-1]
--                else:
--                    padding_length = ord(b_chunk[-1])
-+        cipher = C_Cipher(algorithms.AES(b_key), modes.CBC(b_iv), BACKEND).decryptor()
-+        unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()
- 
--                b_chunk = b_chunk[:-padding_length]
--                finished = True
--
--            out_file.write(b_chunk)
--            out_file.flush()
--
--        # reset the stream pointer to the beginning
--        out_file.seek(0)
--        b_out_data = out_file.read()
--        out_file.close()
-+        b_plaintext = unpadder.update(
-+            cipher.update(b_ciphertext) + cipher.finalize()
-+        ) + unpadder.finalize()
- 
-         # split out sha and verify decryption
--        b_split_data = b_out_data.split(b"\n", 1)
-+        b_split_data = b_plaintext.split(b"\n", 1)
-         b_this_sha = b_split_data[0]
-         b_plaintext = b_split_data[1]
-         b_test_sha = to_bytes(sha256(b_plaintext).hexdigest())
-@@ -676,19 +599,16 @@
- 
-     # Note: strings in this class should be byte strings by default.
- 
--    def __init__(self):
--
--        check_prereqs()
--
-     @staticmethod
-     def _create_key(b_password, b_salt, keylength, ivlength):
--        hash_function = SHA256
--
--        # make two keys and one iv
--        pbkdf2_prf = lambda p, s: HMAC.new(p, s, hash_function).digest()
-+        kdf = PBKDF2HMAC(
-+            algorithm=hashes.SHA256(),
-+            length=2 * keylength + ivlength,
-+            salt=b_salt,
-+            iterations=10000,
-+            backend=BACKEND)
-+        b_derivedkey = kdf.derive(b_password)
- 
--        b_derivedkey = PBKDF2(b_password, b_salt, dkLen=(2 * keylength) + ivlength,
--                            count=10000, prf=pbkdf2_prf)
-         return b_derivedkey
- 
-     @classmethod
-@@ -696,55 +616,31 @@
-         # 16 for AES 128, 32 for AES256
-         keylength = 32
- 
--        # match the size used for counter.new to avoid extra work
--        ivlength = 16
-+        # AES is a 128-bit block cipher, so IVs and counter nonces are 16 bytes
-+        ivlength = algorithms.AES.block_size // 8
- 
--        if HAS_PBKDF2HMAC:
--            backend = default_backend()
--            kdf = PBKDF2HMAC(
--                algorithm=c_SHA256(),
--                length=2 * keylength + ivlength,
--                salt=b_salt,
--                iterations=10000,
--                backend=backend)
--            b_derivedkey = kdf.derive(b_password)
--        else:
--            b_derivedkey = cls._create_key(b_password, b_salt, keylength, ivlength)
-+        b_derivedkey = cls._create_key(b_password, b_salt, keylength, ivlength)
- 
-         b_key1 = b_derivedkey[:keylength]
-         b_key2 = b_derivedkey[keylength:(keylength * 2)]
-         b_iv = b_derivedkey[(keylength * 2):(keylength * 2) + ivlength]
- 
--        return b_key1, b_key2, hexlify(b_iv)
-+        return b_key1, b_key2, b_iv
- 
-     def encrypt(self, b_plaintext, b_password):
-         b_salt = os.urandom(32)
-         b_key1, b_key2, b_iv = self._gen_key_initctr(b_password, b_salt)
- 
--        # PKCS#7 PAD DATA http://tools.ietf.org/html/rfc5652#section-6.3
--        bs = AES.block_size
--        padding_length = (bs - len(b_plaintext) % bs) or bs
--        b_plaintext += to_bytes(padding_length * chr(padding_length), encoding='ascii', errors='strict')
--
--        # COUNTER.new PARAMETERS
--        # 1) nbits (integer) - Length of the counter, in bits.
--        # 2) initial_value (integer) - initial value of the counter. "iv" from _gen_key_initctr
--
--        ctr = Counter.new(128, initial_value=int(b_iv, 16))
--
--        # AES.new PARAMETERS
--        # 1) AES key, must be either 16, 24, or 32 bytes long -- "key" from _gen_key_initctr
--        # 2) MODE_CTR, is the recommended mode
--        # 3) counter=<CounterObject>
--
--        cipher = AES.new(b_key1, AES.MODE_CTR, counter=ctr)
--
--        # ENCRYPT PADDED DATA
--        b_ciphertext = cipher.encrypt(b_plaintext)
-+        cipher = C_Cipher(algorithms.AES(b_key1), modes.CTR(b_iv), BACKEND)
-+        encryptor = cipher.encryptor()
-+        padder = padding.PKCS7(algorithms.AES.block_size).padder()
-+        b_ciphertext = encryptor.update(padder.update(b_plaintext) + padder.finalize())
-+        b_ciphertext += encryptor.finalize()
- 
-         # COMBINE SALT, DIGEST AND DATA
--        hmac = HMAC.new(b_key2, b_ciphertext, SHA256)
--        b_vaulttext = b'\n'.join([hexlify(b_salt), to_bytes(hmac.hexdigest()), hexlify(b_ciphertext)])
-+        hmac = HMAC(b_key2, hashes.SHA256(), BACKEND)
-+        hmac.update(b_ciphertext)
-+        b_vaulttext = b'\n'.join([hexlify(b_salt), hexlify(hmac.finalize()), hexlify(b_ciphertext)])
-         b_vaulttext = hexlify(b_vaulttext)
-         return b_vaulttext
- 
-@@ -757,48 +653,21 @@
-         b_key1, b_key2, b_iv = self._gen_key_initctr(b_password, b_salt)
- 
-         # EXIT EARLY IF DIGEST DOESN'T MATCH
--        hmacDecrypt = HMAC.new(b_key2, b_ciphertext, SHA256)
--        if not self._is_equal(b_cryptedHmac, to_bytes(hmacDecrypt.hexdigest())):
-+        hmac = HMAC(b_key2, hashes.SHA256(), BACKEND)
-+        hmac.update(b_ciphertext)
-+        try:
-+            hmac.verify(unhexlify(b_cryptedHmac))
-+        except InvalidSignature:
-             return None
--        # SET THE COUNTER AND THE CIPHER
--        ctr = Counter.new(128, initial_value=int(b_iv, 16))
--        cipher = AES.new(b_key1, AES.MODE_CTR, counter=ctr)
--
--        # DECRYPT PADDED DATA
--        b_plaintext = cipher.decrypt(b_ciphertext)
--
--        # UNPAD DATA
--        if PY3:
--            padding_length = b_plaintext[-1]
--        else:
--            padding_length = ord(b_plaintext[-1])
- 
--        b_plaintext = b_plaintext[:-padding_length]
--        return b_plaintext
-+        cipher = C_Cipher(algorithms.AES(b_key1), modes.CTR(b_iv), BACKEND)
-+        decryptor = cipher.decryptor()
-+        unpadder = padding.PKCS7(128).unpadder()
-+        b_plaintext = unpadder.update(
-+            decryptor.update(b_ciphertext) + decryptor.finalize()
-+        ) + unpadder.finalize()
- 
--    @staticmethod
--    def _is_equal(b_a, b_b):
--        """
--        Comparing 2 byte arrrays in constant time
--        to avoid timing attacks.
--
--        It would be nice if there was a library for this but
--        hey.
--        """
--        if not (isinstance(b_a, binary_type) and isinstance(b_b, binary_type)):
--            raise TypeError('_is_equal can only be used to compare two byte strings')
--
--        # http://codahale.com/a-lesson-in-timing-attacks/
--        if len(b_a) != len(b_b):
--            return False
--
--        result = 0
--        for b_x, b_y in zip(b_a, b_b):
--            if PY3:
--                result |= b_x ^ b_y
--            else:
--                result |= ord(b_x) ^ ord(b_y)
--        return result == 0
-+        return b_plaintext
- 
- 
- # Keys could be made bytes later if the code that gets the data is more
-diff -uNr ansible-2.3.0.0.ORIG/test/runner/requirements/integration.txt ansible-2.3.0.0/test/runner/requirements/integration.txt
---- ansible-2.3.0.0.ORIG/test/runner/requirements/integration.txt	2017-05-23 14:23:12.379595453 +0100
-+++ ansible-2.3.0.0/test/runner/requirements/integration.txt	2017-05-23 14:24:22.118598926 +0100
-@@ -1,8 +1,8 @@
-+cryptography
- jinja2
- jmespath
- junit-xml
- ordereddict ; python_version < '2.7'
- paramiko
- passlib
--pycrypto
- pyyaml
-diff -uNr ansible-2.3.0.0.ORIG/test/runner/requirements/network-integration.txt ansible-2.3.0.0/test/runner/requirements/network-integration.txt
---- ansible-2.3.0.0.ORIG/test/runner/requirements/network-integration.txt	2017-05-23 14:23:12.379595453 +0100
-+++ ansible-2.3.0.0/test/runner/requirements/network-integration.txt	2017-05-23 14:24:22.119598926 +0100
-@@ -1,5 +1,5 @@
-+cryptography
- jinja2
- junit-xml
- paramiko
--pycrypto
- pyyaml
-diff -uNr ansible-2.3.0.0.ORIG/test/runner/requirements/sanity.txt ansible-2.3.0.0/test/runner/requirements/sanity.txt
---- ansible-2.3.0.0.ORIG/test/runner/requirements/sanity.txt	2017-05-23 14:23:12.379595453 +0100
-+++ ansible-2.3.0.0/test/runner/requirements/sanity.txt	2017-05-23 14:26:01.910603896 +0100
-@@ -1,5 +1,7 @@
-+cryptography
- jinja2
- mock
-+paramiko
- pep8
- pylint
- pytest
-diff -uNr ansible-2.3.0.0.ORIG/test/runner/requirements/units.txt ansible-2.3.0.0/test/runner/requirements/units.txt
---- ansible-2.3.0.0.ORIG/test/runner/requirements/units.txt	2017-05-23 14:23:12.379595453 +0100
-+++ ansible-2.3.0.0/test/runner/requirements/units.txt	2017-05-23 14:24:22.119598926 +0100
-@@ -1,10 +1,10 @@
- boto
- boto3
-+cryptography
- jinja2
- mock
- nose
- passlib
--pycrypto
- pytest
- pytest-mock
- pytest-xdist
-diff -uNr ansible-2.3.0.0.ORIG/test/runner/requirements/windows-integration.txt ansible-2.3.0.0/test/runner/requirements/windows-integration.txt
---- ansible-2.3.0.0.ORIG/test/runner/requirements/windows-integration.txt	2017-05-23 14:23:12.379595453 +0100
-+++ ansible-2.3.0.0/test/runner/requirements/windows-integration.txt	2017-05-23 14:24:22.119598926 +0100
-@@ -1,4 +1,6 @@
-+cryptography
- jinja2
- junit-xml
-+paramiko
- pywinrm
- pyyaml
-diff -uNr ansible-2.3.0.0.ORIG/test/units/parsing/vault/test_vault_editor.py ansible-2.3.0.0/test/units/parsing/vault/test_vault_editor.py
---- ansible-2.3.0.0.ORIG/test/units/parsing/vault/test_vault_editor.py	2017-05-23 14:23:12.324595450 +0100
-+++ ansible-2.3.0.0/test/units/parsing/vault/test_vault_editor.py	2017-05-23 14:24:22.120598926 +0100
-@@ -22,7 +22,6 @@
- 
- import os
- import tempfile
--from nose.plugins.skip import SkipTest
- 
- from ansible.compat.tests import unittest
- from ansible.compat.tests.mock import patch
-@@ -32,27 +31,6 @@
- from ansible.module_utils._text import to_bytes, to_text
- 
- 
--# Counter import fails for 2.0.1, requires >= 2.6.1 from pip
--try:
--    from Crypto.Util import Counter
--    HAS_COUNTER = True
--except ImportError:
--    HAS_COUNTER = False
--
--# KDF import fails for 2.0.1, requires >= 2.6.1 from pip
--try:
--    from Crypto.Protocol.KDF import PBKDF2
--    HAS_PBKDF2 = True
--except ImportError:
--    HAS_PBKDF2 = False
--
--# AES IMPORTS
--try:
--    from Crypto.Cipher import AES as AES
--    HAS_AES = True
--except ImportError:
--    HAS_AES = False
--
- v10_data = """$ANSIBLE_VAULT;1.0;AES
- 53616c7465645f5fd0026926a2d415a28a2622116273fbc90e377225c12a347e1daf4456d36a77f9
- 9ad98d59f61d06a4b66718d855f16fb7bdfe54d1ec8aeaa4d06c2dc1fa630ae1846a029877f0eeb1
-@@ -423,9 +401,6 @@
- 
-     def test_decrypt_1_0(self):
-         # Skip testing decrypting 1.0 files if we don't have access to AES, KDF or Counter.
--        if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2:
--            raise SkipTest
--
-         v10_file = tempfile.NamedTemporaryFile(delete=False)
-         with v10_file as f:
-             f.write(to_bytes(v10_data))
-@@ -451,9 +426,6 @@
-         assert fdata.strip() == "foo", "incorrect decryption of 1.0 file: %s" % fdata.strip()
- 
-     def test_decrypt_1_1(self):
--        if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2:
--            raise SkipTest
--
-         v11_file = tempfile.NamedTemporaryFile(delete=False)
-         with v11_file as f:
-             f.write(to_bytes(v11_data))
-@@ -478,10 +450,6 @@
-         assert fdata.strip() == "foo", "incorrect decryption of 1.0 file: %s" % fdata.strip()
- 
-     def test_rekey_migration(self):
--        # Skip testing rekeying files if we don't have access to AES, KDF or Counter.
--        if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2:
--            raise SkipTest
--
-         v10_file = tempfile.NamedTemporaryFile(delete=False)
-         with v10_file as f:
-             f.write(to_bytes(v10_data))
-diff -uNr ansible-2.3.0.0.ORIG/test/units/parsing/vault/test_vault.py ansible-2.3.0.0/test/units/parsing/vault/test_vault.py
---- ansible-2.3.0.0.ORIG/test/units/parsing/vault/test_vault.py	2017-05-23 14:23:12.324595450 +0100
-+++ ansible-2.3.0.0/test/units/parsing/vault/test_vault.py	2017-05-23 14:24:22.120598926 +0100
-@@ -38,28 +38,6 @@
- from ansible.module_utils._text import to_bytes, to_text
- 
- 
--# Counter import fails for 2.0.1, requires >= 2.6.1 from pip
--try:
--    from Crypto.Util import Counter
--    HAS_COUNTER = True
--except ImportError:
--    HAS_COUNTER = False
--
--# KDF import fails for 2.0.1, requires >= 2.6.1 from pip
--try:
--    from Crypto.Protocol.KDF import PBKDF2
--    HAS_PBKDF2 = True
--except ImportError:
--    HAS_PBKDF2 = False
--
--# AES IMPORTS
--try:
--    from Crypto.Cipher import AES as AES
--    HAS_AES = True
--except ImportError:
--    HAS_AES = False
--
--
- class TestVaultIsEncrypted(unittest.TestCase):
-     def test_bytes_not_encrypted(self):
-         b_data = b"foobar"
-@@ -181,38 +159,6 @@
-         self.assertIsInstance(b_key, six.binary_type)
-         self.assertEqual(b_key, b_key_2)
- 
--    def test_is_equal_is_equal(self):
--        self.assertTrue(self.vault_cipher._is_equal(b'abcdefghijklmnopqrstuvwxyz', b'abcdefghijklmnopqrstuvwxyz'))
--
--    def test_is_equal_unequal_length(self):
--        self.assertFalse(self.vault_cipher._is_equal(b'abcdefghijklmnopqrstuvwxyz', b'abcdefghijklmnopqrstuvwx and sometimes y'))
--
--    def test_is_equal_not_equal(self):
--        self.assertFalse(self.vault_cipher._is_equal(b'abcdefghijklmnopqrstuvwxyz', b'AbcdefghijKlmnopQrstuvwxZ'))
--
--    def test_is_equal_empty(self):
--        self.assertTrue(self.vault_cipher._is_equal(b'', b''))
--
--    def test_is_equal_non_ascii_equal(self):
--        utf8_data = to_bytes(u'私はガラスを食べられます。それは私を傷つけません。')
--        self.assertTrue(self.vault_cipher._is_equal(utf8_data, utf8_data))
--
--    def test_is_equal_non_ascii_unequal(self):
--        utf8_data = to_bytes(u'私はガラスを食べられます。それは私を傷つけません。')
--        utf8_data2 = to_bytes(u'Pot să mănânc sticlă și ea nu mă rănește.')
--
--        # Test for the len optimization path
--        self.assertFalse(self.vault_cipher._is_equal(utf8_data, utf8_data2))
--        # Test for the slower, char by char comparison path
--        self.assertFalse(self.vault_cipher._is_equal(utf8_data, utf8_data[:-1] + b'P'))
--
--    def test_is_equal_non_bytes(self):
--        """ Anything not a byte string should raise a TypeError """
--        self.assertRaises(TypeError, self.vault_cipher._is_equal, u"One fish", b"two fish")
--        self.assertRaises(TypeError, self.vault_cipher._is_equal, b"One fish", u"two fish")
--        self.assertRaises(TypeError, self.vault_cipher._is_equal, 1, b"red fish")
--        self.assertRaises(TypeError, self.vault_cipher._is_equal, b"blue fish", 2)
--
- 
- class TestVaultLib(unittest.TestCase):
-     def setUp(self):
-@@ -267,8 +213,6 @@
-         self.assertEqual(self.v.b_version, b"9.9", msg="version was not properly set")
- 
-     def test_encrypt_decrypt_aes(self):
--        if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2:
--            raise SkipTest
-         self.v.cipher_name = u'AES'
-         self.v.b_password = b'ansible'
-         # AES encryption code has been removed, so this is old output for
-@@ -282,8 +226,6 @@
-         self.assertEqual(b_plaintext, b"foobar", msg="decryption failed")
- 
-     def test_encrypt_decrypt_aes256(self):
--        if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2:
--            raise SkipTest
-         self.v.cipher_name = u'AES256'
-         plaintext = u"foobar"
-         b_vaulttext = self.v.encrypt(plaintext)
-@@ -292,8 +234,6 @@
-         self.assertEqual(b_plaintext, b"foobar", msg="decryption failed")
- 
-     def test_encrypt_decrypt_aes256_existing_vault(self):
--        if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2:
--            raise SkipTest
-         self.v.cipher_name = u'AES256'
-         b_orig_plaintext = b"Setec Astronomy"
-         vaulttext = u'''$ANSIBLE_VAULT;1.1;AES256
-@@ -314,8 +254,6 @@
-         # FIXME This test isn't working quite yet.
-         raise SkipTest
- 
--        if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2:
--            raise SkipTest
-         self.v.cipher_name = 'AES256'
-         # plaintext = "Setec Astronomy"
-         enc_data = '''$ANSIBLE_VAULT;1.1;AES256
-@@ -350,8 +288,6 @@
-         self.v.decrypt(b_invalid_ciphertext)
- 
-     def test_encrypt_encrypted(self):
--        if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2:
--            raise SkipTest
-         self.v.cipher_name = u'AES'
-         b_vaulttext = b"$ANSIBLE_VAULT;9.9;TEST\n%s" % hexlify(b"ansible")
-         vaulttext = to_text(b_vaulttext, errors='strict')
-@@ -359,8 +295,6 @@
-         self.assertRaises(errors.AnsibleError, self.v.encrypt, vaulttext)
- 
-     def test_decrypt_decrypted(self):
--        if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2:
--            raise SkipTest
-         plaintext = u"ansible"
-         self.assertRaises(errors.AnsibleError, self.v.decrypt, plaintext)
- 
-@@ -368,9 +302,6 @@
-         self.assertRaises(errors.AnsibleError, self.v.decrypt, b_plaintext)
- 
-     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
-         plaintext = u"ansible"
-         self.v.encrypt(plaintext)
-         self.assertEquals(self.v.cipher_name, "AES256")
-diff -uNr ansible-2.3.0.0.ORIG/test/utils/docker/centos6/Dockerfile ansible-2.3.0.0/test/utils/docker/centos6/Dockerfile
---- ansible-2.3.0.0.ORIG/test/utils/docker/centos6/Dockerfile	2017-05-23 14:23:12.321595450 +0100
-+++ ansible-2.3.0.0/test/utils/docker/centos6/Dockerfile	2017-05-23 14:24:22.121598926 +0100
-@@ -9,6 +9,8 @@
-     file \
-     gcc \
-     git \
-+    libffi \
-+    libffi-devel \
-     make \
-     mercurial \
-     mysql \
-@@ -16,6 +18,7 @@
-     mysql-server \
-     openssh-clients \
-     openssh-server \
-+    openssl-devel \
-     python-coverage \
-     python-devel \
-     python-httplib2 \
-@@ -40,8 +43,6 @@
-     && \
-     yum clean all
- 
--RUN rpm -e --nodeps python-crypto && pip install --upgrade pycrypto
--
- RUN /bin/sed -i -e 's/^\(Defaults\s*requiretty\)/#--- \1/'  /etc/sudoers
- RUN mkdir /etc/ansible/
- RUN /bin/echo -e '[local]\nlocalhost ansible_connection=local' > /etc/ansible/hosts
-diff -uNr ansible-2.3.0.0.ORIG/test/utils/docker/centos7/Dockerfile ansible-2.3.0.0/test/utils/docker/centos7/Dockerfile
---- ansible-2.3.0.0.ORIG/test/utils/docker/centos7/Dockerfile	2017-05-23 14:23:12.321595450 +0100
-+++ ansible-2.3.0.0/test/utils/docker/centos7/Dockerfile	2017-05-23 14:24:22.121598926 +0100
-@@ -17,15 +17,20 @@
-     bzip2 \
-     dbus-python \
-     file \
-+    gcc \
-     git \
-     iproute \
-+    libffi \
-+    libffi-devel \
-     make \
-     mariadb-server \
-     mercurial \
-     MySQL-python \
-     openssh-clients \
-     openssh-server \
-+    openssl-devel \
-     python-coverage \
-+    python-devel \
-     python-httplib2 \
-     python-jinja2 \
-     python-keyczar \
-diff -uNr ansible-2.3.0.0.ORIG/test/utils/docker/fedora24/Dockerfile ansible-2.3.0.0/test/utils/docker/fedora24/Dockerfile
---- ansible-2.3.0.0.ORIG/test/utils/docker/fedora24/Dockerfile	2017-05-23 14:23:12.321595450 +0100
-+++ ansible-2.3.0.0/test/utils/docker/fedora24/Dockerfile	2017-05-23 14:24:22.121598926 +0100
-@@ -17,18 +17,23 @@
-     dbus-python \
-     file \
-     findutils \
-+    gcc \
-     git \
-     glibc-locale-source \
-     iproute \
-+    libffi \
-+    libffi-devel \
-     make \
-     mariadb-server \
-     mercurial \
-     MySQL-python \
-     openssh-clients \
-     openssh-server \
-+    openssl-devel \
-     procps \
-     python2-dnf \
-     python-coverage \
-+    python-devel \
-     python-httplib2 \
-     python-jinja2 \
-     python-keyczar \
-diff -uNr ansible-2.3.0.0.ORIG/test/utils/docker/fedora25/Dockerfile ansible-2.3.0.0/test/utils/docker/fedora25/Dockerfile
---- ansible-2.3.0.0.ORIG/test/utils/docker/fedora25/Dockerfile	2017-05-23 14:23:12.321595450 +0100
-+++ ansible-2.3.0.0/test/utils/docker/fedora25/Dockerfile	2017-05-23 14:24:22.121598926 +0100
-@@ -20,12 +20,15 @@
-     git \
-     glibc-locale-source \
-     iproute \
-+    libffi \
-+    libffi-devel \
-     make \
-     mariadb-server \
-     mercurial \
-     MySQL-python \
-     openssh-clients \
-     openssh-server \
-+    openssl-devel \
-     procps \
-     python2-dnf \
-     python-coverage \
-diff -uNr ansible-2.3.0.0.ORIG/test/utils/docker/opensuse42.1/Dockerfile ansible-2.3.0.0/test/utils/docker/opensuse42.1/Dockerfile
---- ansible-2.3.0.0.ORIG/test/utils/docker/opensuse42.1/Dockerfile	2017-05-23 14:23:12.321595450 +0100
-+++ ansible-2.3.0.0/test/utils/docker/opensuse42.1/Dockerfile	2017-05-23 14:24:22.121598926 +0100
-@@ -21,6 +21,8 @@
-     openssh \
-     postgresql-server \
-     python-coverage \
-+    python-cryptography \
-+    python-devel \
-     python-httplib2 \
-     python-jinja2 \
-     python-keyczar \
-diff -uNr ansible-2.3.0.0.ORIG/test/utils/docker/opensuse42.2/Dockerfile ansible-2.3.0.0/test/utils/docker/opensuse42.2/Dockerfile
---- ansible-2.3.0.0.ORIG/test/utils/docker/opensuse42.2/Dockerfile	2017-05-23 14:23:12.321595450 +0100
-+++ ansible-2.3.0.0/test/utils/docker/opensuse42.2/Dockerfile	2017-05-23 14:24:22.122598926 +0100
-@@ -21,6 +21,7 @@
-     openssh \
-     postgresql-server \
-     python-coverage \
-+    python-cryptography \
-     python-httplib2 \
-     python-jinja2 \
-     python-keyczar \
-diff -uNr ansible-2.3.0.0.ORIG/test/utils/docker/ubuntu1204/Dockerfile ansible-2.3.0.0/test/utils/docker/ubuntu1204/Dockerfile
---- ansible-2.3.0.0.ORIG/test/utils/docker/ubuntu1204/Dockerfile	2017-05-23 14:23:12.321595450 +0100
-+++ ansible-2.3.0.0/test/utils/docker/ubuntu1204/Dockerfile	2017-05-23 14:24:22.122598926 +0100
-@@ -17,6 +17,8 @@
-     gawk \
-     gcc \
-     git \
-+    libffi-dev \
-+    libssl-dev \
-     libxml2-utils \
-     locales \
-     make \
-@@ -50,8 +52,6 @@
-     && \
-     apt-get clean
- 
--RUN pip install --upgrade pycrypto
--
- # helpful things taken from the ubuntu-upstart Dockerfile:
- # https://github.com/tianon/dockerfiles/blob/4d24a12b54b75b3e0904d8a285900d88d3326361/sbin-init/ubuntu/upstart/14.04/Dockerfile
- ADD init-fake.conf /etc/init/fake-container-events.conf
-diff -uNr ansible-2.3.0.0.ORIG/test/utils/docker/ubuntu1404/Dockerfile ansible-2.3.0.0/test/utils/docker/ubuntu1404/Dockerfile
---- ansible-2.3.0.0.ORIG/test/utils/docker/ubuntu1404/Dockerfile	2017-05-23 14:23:12.321595450 +0100
-+++ ansible-2.3.0.0/test/utils/docker/ubuntu1404/Dockerfile	2017-05-23 14:24:22.122598926 +0100
-@@ -16,6 +16,8 @@
-     fakeroot \
-     gawk \
-     git \
-+    libffi-dev \
-+    libssl-dev \
-     libxml2-utils \
-     locales \
-     make \
-diff -uNr ansible-2.3.0.0.ORIG/test/utils/docker/ubuntu1604/Dockerfile ansible-2.3.0.0/test/utils/docker/ubuntu1604/Dockerfile
---- ansible-2.3.0.0.ORIG/test/utils/docker/ubuntu1604/Dockerfile	2017-05-23 14:23:12.321595450 +0100
-+++ ansible-2.3.0.0/test/utils/docker/ubuntu1604/Dockerfile	2017-05-23 14:24:22.122598926 +0100
-@@ -17,6 +17,8 @@
-     gawk \
-     git \
-     iproute2 \
-+    libffi-dev \
-+    libssl-dev \
-     libxml2-utils \
-     locales \
-     lsb-release \
-diff -uNr ansible-2.3.0.0.ORIG/test/utils/docker/ubuntu1604py3/Dockerfile ansible-2.3.0.0/test/utils/docker/ubuntu1604py3/Dockerfile
---- ansible-2.3.0.0.ORIG/test/utils/docker/ubuntu1604py3/Dockerfile	2017-05-23 14:23:12.321595450 +0100
-+++ ansible-2.3.0.0/test/utils/docker/ubuntu1604py3/Dockerfile	2017-05-23 14:24:22.122598926 +0100
-@@ -15,6 +15,8 @@
-     gawk \
-     git \
-     iproute2 \
-+    libffi-dev \
-+    libssl-dev \
-     libxml2-utils \
-     locales \
-     lsb-release \
-diff -uNr ansible-2.3.0.0.ORIG/test/utils/shippable/other.sh ansible-2.3.0.0/test/utils/shippable/other.sh
---- ansible-2.3.0.0.ORIG/test/utils/shippable/other.sh	2017-05-23 14:23:12.320595450 +0100
-+++ ansible-2.3.0.0/test/utils/shippable/other.sh	2017-05-23 14:24:22.123598926 +0100
-@@ -12,6 +12,8 @@
- retry.py apt-get install -qq \
-     shellcheck \
-     python2.4 \
-+    libssl-dev \
-+    libffi-dev \
- 
- ln -sf x86_64-linux-gnu-gcc-4.9 /usr/bin/x86_64-linux-gnu-gcc
- 
-diff -uNr ansible-2.3.0.0.ORIG/test/utils/tox/requirements.txt ansible-2.3.0.0/test/utils/tox/requirements.txt
---- ansible-2.3.0.0.ORIG/test/utils/tox/requirements.txt	2017-05-23 14:23:12.321595450 +0100
-+++ ansible-2.3.0.0/test/utils/tox/requirements.txt	2017-05-23 14:24:22.123598926 +0100
-@@ -11,7 +11,7 @@
- redis
- python-memcached
- python-systemd
--pycrypto
-+cryptography
- botocore
- boto3
- pytest

diff --git a/app-admin/ansible/files/ansible.env b/app-admin/ansible/files/ansible.env
deleted file mode 100644
index 9df5a2ab5a9..00000000000
--- a/app-admin/ansible/files/ansible.env
+++ /dev/null
@@ -1,2 +0,0 @@
-# Use ssh transport by default. Comment it out if you want to use paramiko
-ANSIBLE_TRANSPORT="ssh"


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [gentoo-commits] repo/gentoo:master commit in: app-admin/ansible/, app-admin/ansible/files/
@ 2020-10-16  2:58 Matthew Thode
  0 siblings, 0 replies; 2+ messages in thread
From: Matthew Thode @ 2020-10-16  2:58 UTC (permalink / raw
  To: gentoo-commits

commit:     7d23da514953be1ad0fd02a9aab9e5a24ca3449d
Author:     Matthew Thode <prometheanfire <AT> gentoo <DOT> org>
AuthorDate: Fri Oct 16 02:57:56 2020 +0000
Commit:     Matthew Thode <prometheanfire <AT> gentoo <DOT> org>
CommitDate: Fri Oct 16 02:58:10 2020 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=7d23da51

app-admin/ansible: Fix CVE

Bug: https://bugs.gentoo.org/749369
Package-Manager: Portage-3.0.8, Repoman-3.0.1
Signed-off-by: Matthew Thode <prometheanfire <AT> gentoo.org>

 app-admin/ansible/ansible-2.10.0-r2.ebuild         | 82 ++++++++++++++++++++++
 .../files/ansible-2.10.0-CVE-2020-25635-6.patch    | 54 ++++++++++++++
 2 files changed, 136 insertions(+)

diff --git a/app-admin/ansible/ansible-2.10.0-r2.ebuild b/app-admin/ansible/ansible-2.10.0-r2.ebuild
new file mode 100644
index 00000000000..2086aad0672
--- /dev/null
+++ b/app-admin/ansible/ansible-2.10.0-r2.ebuild
@@ -0,0 +1,82 @@
+# Copyright 1999-2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+PYTHON_COMPAT=( python3_{6..8} )
+DISTUTILS_USE_SETUPTOOLS=bdepend
+
+inherit distutils-r1 eutils
+
+DESCRIPTION="Model-driven deployment, config management, and command execution framework"
+HOMEPAGE="https://ansible.com/"
+
+if [[ ${PV} == 9999 ]]; then
+	inherit git-r3
+	EGIT_REPO_URI="https://github.com/ansible/ansible.git"
+	EGIT_BRANCH="devel"
+	KEYWORDS=""
+else
+	SRC_URI="mirror://pypi/${PN:0:1}/${PN}/${P}.tar.gz"
+	KEYWORDS="~amd64 ~arm ~arm64 ~ppc64 ~x86 ~x64-macos"
+fi
+
+LICENSE="GPL-3"
+SLOT="0"
+IUSE="doc test"
+RESTRICT="test"
+
+RDEPEND="
+	dev-python/paramiko[${PYTHON_USEDEP}]
+	dev-python/jinja[${PYTHON_USEDEP}]
+	dev-python/pyyaml[${PYTHON_USEDEP}]
+	dev-python/cryptography[${PYTHON_USEDEP}]
+	dev-python/httplib2[${PYTHON_USEDEP}]
+	dev-python/six[${PYTHON_USEDEP}]
+	dev-python/netaddr[${PYTHON_USEDEP}]
+	dev-python/pexpect[${PYTHON_USEDEP}]
+	net-misc/sshpass
+	virtual/ssh
+	app-admin/ansible-base
+"
+DEPEND="
+	>=dev-python/packaging-16.6[${PYTHON_USEDEP}]
+	app-admin/ansible-base
+	doc? (
+		dev-python/sphinx[${PYTHON_USEDEP}]
+		dev-python/sphinx-notfound-page[${PYTHON_USEDEP}]
+		>=dev-python/pygments-2.4.0[${PYTHON_USEDEP}]
+	)
+	test? (
+		${RDEPEND}
+		dev-python/nose[${PYTHON_USEDEP}]
+		>=dev-python/mock-1.0.1[${PYTHON_USEDEP}]
+		dev-python/passlib[${PYTHON_USEDEP}]
+		dev-python/coverage[${PYTHON_USEDEP}]
+		dev-python/unittest2[${PYTHON_USEDEP}]
+		dev-vcs/git
+	)"
+
+PATCHES=( "${FILESDIR}/ansible-2.10.0-CVE-2020-25635-6.patch" )
+
+python_compile() {
+	export ANSIBLE_SKIP_CONFLICT_CHECK=1
+	distutils-r1_python_compile
+}
+
+python_compile_all() {
+	if use doc; then
+		cd docs/docsite || die
+		export CPUS=4
+		emake -f Makefile.sphinx html
+	fi
+}
+
+python_test() {
+	nosetests -d -w test/units -v --with-coverage --cover-package=ansible --cover-branches || die
+}
+
+python_install_all() {
+	use doc && local HTML_DOCS=( docs/docsite/_build/html/. )
+	distutils-r1_python_install_all
+}

diff --git a/app-admin/ansible/files/ansible-2.10.0-CVE-2020-25635-6.patch b/app-admin/ansible/files/ansible-2.10.0-CVE-2020-25635-6.patch
new file mode 100644
index 00000000000..df88be4264f
--- /dev/null
+++ b/app-admin/ansible/files/ansible-2.10.0-CVE-2020-25635-6.patch
@@ -0,0 +1,54 @@
+From 921bd53103c2b543e95c9e6b863702db3ff54d0c Mon Sep 17 00:00:00 2001
+From: Jill R <4121322+jillr@users.noreply.github.com>
+Date: Fri, 2 Oct 2020 11:37:37 -0700
+Subject: [PATCH] aws_ssm: Namespace S3 buckets and delete transferred files
+ (#237)
+
+Files transferred to instances via the SSM connection plugin should use
+folders within the bucket that are namespaced per-host, to prevent collisions.
+Files should also be deleted from buckets when they are no longer required.
+
+Fixes: #221
+Fixes: #222
+
+Based on work by abeluck
+
+changelog
+---
+ ansible_collections/community/aws/changelogs/fragments/221_222_ssm_bucket_operations.yaml | 2 ++
+ ansible_collections/community/aws/plugins/connection/aws_ssm.py                           | 6 +++++-
+ 2 files changed, 7 insertions(+), 1 deletion(-)
+ create mode 100644 ansible_collections/community/aws/changelogs/fragments/221_222_ssm_bucket_operations.yaml
+
+diff --git a/ansible_collections/community/aws/changelogs/fragments/221_222_ssm_bucket_operations.yaml b/ansible_collections/community/aws/changelogs/fragments/221_222_ssm_bucket_operations.yaml
+new file mode 100644
+index 00000000..247d5e36
+--- /dev/null
++++ b/ansible_collections/community/aws/changelogs/fragments/221_222_ssm_bucket_operations.yaml
+@@ -0,0 +1,2 @@
++bugfixes:
++  - aws_ssm connection plugin - namespace file uploads to S3 into unique folders per host, to prevent name collisions. Also deletes files from S3 to ensure temp files are not left behind. (https://github.com/ansible-collections/community.aws/issues/221, https://github.com/ansible-collections/community.aws/issues/222)
+diff --git a/ansible_collections/community/aws/plugins/connection/aws_ssm.py b/ansible_collections/community/aws/plugins/connection/aws_ssm.py
+index 7f7d6926..94289eee 100644
+--- a/ansible_collections/community/aws/plugins/connection/aws_ssm.py
++++ b/ansible_collections/community/aws/plugins/connection/aws_ssm.py
+@@ -522,7 +522,8 @@ def _get_boto_client(self, service, region_name=None):
+     def _file_transport_command(self, in_path, out_path, ssm_action):
+         ''' transfer a file from using an intermediate S3 bucket '''
+ 
+-        s3_path = out_path.replace('\\', '/')
++        path_unescaped = "{0}/{1}".format(self.instance_id, out_path)
++        s3_path = path_unescaped.replace('\\', '/')
+         bucket_url = 's3://%s/%s' % (self.get_option('bucket_name'), s3_path)
+ 
+         if self.is_windows:
+@@ -546,6 +547,9 @@ def _file_transport_command(self, in_path, out_path, ssm_action):
+                 client.upload_fileobj(data, self.get_option('bucket_name'), s3_path)
+             (returncode, stdout, stderr) = self.exec_command(get_command, in_data=None, sudoable=False)
+ 
++        # Remove the files from the bucket after they've been transferred
++        client.delete_object(Bucket=self.get_option('bucket_name'), Key=s3_path)
++
+         # Check the return code
+         if returncode == 0:
+             return (returncode, stdout, stderr)


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-10-16  2:58 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-06-12 19:20 [gentoo-commits] repo/gentoo:master commit in: app-admin/ansible/, app-admin/ansible/files/ Matt Thode
  -- strict thread matches above, loose matches on Subject: below --
2020-10-16  2:58 Matthew Thode

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox