1 |
commit: eee983b6a6b8cf09256d37f46ab28117f317a3ee |
2 |
Author: Matthew Thode <prometheanfire <AT> gentoo <DOT> org> |
3 |
AuthorDate: Thu Jun 1 23:55:00 2017 +0000 |
4 |
Commit: Matt Thode <prometheanfire <AT> gentoo <DOT> org> |
5 |
CommitDate: Thu Jun 1 23:55:31 2017 +0000 |
6 |
URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=eee983b6 |
7 |
|
8 |
app-admin/ansible: 2.3.1.0 bup |
9 |
|
10 |
Package-Manager: Portage-2.3.5, Repoman-2.3.2 |
11 |
|
12 |
app-admin/ansible/Manifest | 1 + |
13 |
app-admin/ansible/ansible-2.3.1.0.ebuild | 60 ++ |
14 |
.../files/ansible-2.3.1.0-pycryptodome.patch | 905 +++++++++++++++++++++ |
15 |
3 files changed, 966 insertions(+) |
16 |
|
17 |
diff --git a/app-admin/ansible/Manifest b/app-admin/ansible/Manifest |
18 |
index f65d26d2619..fb28f16016d 100644 |
19 |
--- a/app-admin/ansible/Manifest |
20 |
+++ b/app-admin/ansible/Manifest |
21 |
@@ -1,2 +1,3 @@ |
22 |
DIST ansible-2.3.0.0-pycryptodome.patch 32449 SHA256 a87d712305160ef8a559bf9e27d7fe4361889f45da5ba501c4a9ae8c6c58e504 SHA512 f52611275262d772b2e44b858c59590ab18ed29c22899c0d8b47f3a21c71aebff9aab1a2284bdf44fbc47b63c3836851db1c065bafe0b6883bb582a98cf4d0a4 WHIRLPOOL bd344c2507eb8576a114e5618d182b90443a92d4cd57f27310eb495dbba123853503c64c69338a02ce680b615862c819985913f2860e3dde670ef929dcd5761f |
23 |
DIST ansible-2.3.0.0.tar.gz 4251730 SHA256 299f3907cd566a20e163942fa82b6afc86ef89c2726ba503b90c1a651e82a458 SHA512 88ac28befefd7a70c36d8c33bc1aba1b0a5ffdea4bddd0b9e6c5488c70057662812208c221e47721c5a194fc30282a33490f196a719d9eb6d9b1e7dcfd1ff941 WHIRLPOOL a6a622f17476c07e3446a7b09631027797ade04f7d1571e0eafccc2736390deabfcdd36fa1e849d209eb7ab5f1e3e86f2b6e7dd3032db1743665165c1dc710ba |
24 |
+DIST ansible-2.3.1.0.tar.gz 4263357 SHA256 cd4b8f53720fcd0c351156b840fdd15ecfbec22c951b5406ec503de49d40b9f5 SHA512 7b4b33c56a15c41d756f095944d7a0dbf894557350879430df21061b717b9574aae624a276bf7e1a13d043b718aeaccac1ce510a3cb085983311ddf06fa832bc WHIRLPOOL 5552ff64e8cac722a705bd1e72465c8bfe583a1c5efc587ca141b34eaa35d2af0ea2e1084a072ecb7dbb28d59d7f56e47c4c73f9e3e0f7f2451ef4e7134ad1af |
25 |
|
26 |
diff --git a/app-admin/ansible/ansible-2.3.1.0.ebuild b/app-admin/ansible/ansible-2.3.1.0.ebuild |
27 |
new file mode 100644 |
28 |
index 00000000000..1e73cf04d35 |
29 |
--- /dev/null |
30 |
+++ b/app-admin/ansible/ansible-2.3.1.0.ebuild |
31 |
@@ -0,0 +1,60 @@ |
32 |
+# Copyright 1999-2017 Gentoo Foundation |
33 |
+# Distributed under the terms of the GNU General Public License v2 |
34 |
+ |
35 |
+EAPI=6 |
36 |
+ |
37 |
+PYTHON_COMPAT=( python2_7 ) |
38 |
+ |
39 |
+inherit distutils-r1 eutils versionator |
40 |
+ |
41 |
+DESCRIPTION="Model-driven deployment, config management, and command execution framework" |
42 |
+HOMEPAGE="http://ansible.com/" |
43 |
+SRC_URI="http://releases.ansible.com/${PN}/${P}.tar.gz" |
44 |
+ |
45 |
+LICENSE="GPL-3" |
46 |
+SLOT="0" |
47 |
+KEYWORDS="~amd64 ~x86 ~x64-macos" |
48 |
+IUSE="test" |
49 |
+ |
50 |
+RDEPEND=" |
51 |
+ dev-python/paramiko[${PYTHON_USEDEP}] |
52 |
+ dev-python/jinja[${PYTHON_USEDEP}] |
53 |
+ dev-python/pyyaml[${PYTHON_USEDEP}] |
54 |
+ dev-python/setuptools[${PYTHON_USEDEP}] |
55 |
+ || ( |
56 |
+ dev-python/pycryptodome[${PYTHON_USEDEP}] |
57 |
+ >=dev-python/pycrypto-2.6[${PYTHON_USEDEP}] |
58 |
+ ) |
59 |
+ dev-python/httplib2[${PYTHON_USEDEP}] |
60 |
+ dev-python/six[${PYTHON_USEDEP}] |
61 |
+ net-misc/sshpass |
62 |
+ virtual/ssh |
63 |
+" |
64 |
+DEPEND=" |
65 |
+ dev-python/setuptools[${PYTHON_USEDEP}] |
66 |
+ >=dev-python/packaging-16.6[${PYTHON_USEDEP}] |
67 |
+ test? ( |
68 |
+ ${RDEPEND} |
69 |
+ dev-python/nose[${PYTHON_USEDEP}] |
70 |
+ >=dev-python/mock-1.0.1[${PYTHON_USEDEP}] |
71 |
+ <dev-python/mock-1.1[${PYTHON_USEDEP}] |
72 |
+ dev-python/passlib[${PYTHON_USEDEP}] |
73 |
+ dev-python/coverage[${PYTHON_USEDEP}] |
74 |
+ dev-python/unittest2[${PYTHON_USEDEP}] |
75 |
+ dev-vcs/git |
76 |
+ )" |
77 |
+ |
78 |
+# not included in release tarball |
79 |
+RESTRICT="test" |
80 |
+ |
81 |
+PATCHES=( "${FILESDIR}/${P}-pycryptodome.patch" ) |
82 |
+ |
83 |
+python_test() { |
84 |
+ nosetests -d -w test/units -v --with-coverage --cover-package=ansible --cover-branches || die |
85 |
+} |
86 |
+ |
87 |
+python_install_all() { |
88 |
+ distutils-r1_python_install_all |
89 |
+ |
90 |
+ doman docs/man/man1/*.1 |
91 |
+} |
92 |
|
93 |
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 |
94 |
new file mode 100644 |
95 |
index 00000000000..71799dec1ab |
96 |
--- /dev/null |
97 |
+++ b/app-admin/ansible/files/ansible-2.3.1.0-pycryptodome.patch |
98 |
@@ -0,0 +1,905 @@ |
99 |
+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 |
100 |
+--- ansible-2.3.0.0.ORIG/lib/ansible/executor/process/worker.py 2017-05-23 14:23:12.313595450 +0100 |
101 |
++++ ansible-2.3.0.0/lib/ansible/executor/process/worker.py 2017-05-23 14:24:22.116598926 +0100 |
102 |
+@@ -26,14 +26,6 @@ |
103 |
+ |
104 |
+ from jinja2.exceptions import TemplateNotFound |
105 |
+ |
106 |
+-# TODO: not needed if we use the cryptography library with its default RNG |
107 |
+-# engine |
108 |
+-HAS_ATFORK=True |
109 |
+-try: |
110 |
+- from Crypto.Random import atfork |
111 |
+-except ImportError: |
112 |
+- HAS_ATFORK=False |
113 |
+- |
114 |
+ from ansible.errors import AnsibleConnectionFailure |
115 |
+ from ansible.executor.task_executor import TaskExecutor |
116 |
+ from ansible.executor.task_result import TaskResult |
117 |
+@@ -95,9 +87,6 @@ |
118 |
+ #pr = cProfile.Profile() |
119 |
+ #pr.enable() |
120 |
+ |
121 |
+- if HAS_ATFORK: |
122 |
+- atfork() |
123 |
+- |
124 |
+ try: |
125 |
+ # execute the task and build a TaskResult from the result |
126 |
+ display.debug("running TaskExecutor() for %s/%s" % (self._host, self._task)) |
127 |
+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 |
128 |
+--- ansible-2.3.0.0.ORIG/lib/ansible/modules/cloud/amazon/ec2_win_password.py 2017-05-23 14:23:12.299595449 +0100 |
129 |
++++ ansible-2.3.0.0/lib/ansible/modules/cloud/amazon/ec2_win_password.py 2017-05-23 14:29:51.003615305 +0100 |
130 |
+@@ -93,9 +93,10 @@ |
131 |
+ ''' |
132 |
+ |
133 |
+ from base64 import b64decode |
134 |
+-from Crypto.Cipher import PKCS1_v1_5 |
135 |
+-from Crypto.PublicKey import RSA |
136 |
+ import datetime |
137 |
++from cryptography.hazmat.backends import default_backend |
138 |
++from cryptography.hazmat.primitives.asymmetric.padding import PKCS1v15 |
139 |
++from cryptography.hazmat.primitives.serialization import load_pem_private_key |
140 |
+ |
141 |
+ try: |
142 |
+ import boto.ec2 |
143 |
+@@ -103,6 +104,9 @@ |
144 |
+ except ImportError: |
145 |
+ HAS_BOTO = False |
146 |
+ |
147 |
++BACKEND = default_backend() |
148 |
++ |
149 |
++ |
150 |
+ def main(): |
151 |
+ argument_spec = ec2_argument_spec() |
152 |
+ argument_spec.update(dict( |
153 |
+@@ -151,15 +155,12 @@ |
154 |
+ else: |
155 |
+ try: |
156 |
+ with f: |
157 |
+- key = RSA.importKey(f.read(), key_passphrase) |
158 |
+- except (ValueError, IndexError, TypeError) as e: |
159 |
++ key = load_pem_private_key(f.read(), key_passphrase, BACKEND) |
160 |
++ except (ValueError, TypeError) as e: |
161 |
+ module.fail_json(msg = "unable to parse key file") |
162 |
+ |
163 |
+- cipher = PKCS1_v1_5.new(key) |
164 |
+- sentinel = 'password decryption failed!!!' |
165 |
+- |
166 |
+ try: |
167 |
+- decrypted = cipher.decrypt(decoded, sentinel) |
168 |
++ decrypted = key.decrypt(decoded, PKCS1v15()) |
169 |
+ except ValueError as e: |
170 |
+ decrypted = None |
171 |
+ |
172 |
+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 |
173 |
+--- ansible-2.3.0.0.ORIG/lib/ansible/parsing/vault/__init__.py 2017-05-23 14:23:12.311595449 +0100 |
174 |
++++ ansible-2.3.0.0/lib/ansible/parsing/vault/__init__.py 2017-05-23 14:31:23.267619901 +0100 |
175 |
+@@ -25,7 +25,6 @@ |
176 |
+ import sys |
177 |
+ import tempfile |
178 |
+ import random |
179 |
+-from io import BytesIO |
180 |
+ from subprocess import call |
181 |
+ from hashlib import sha256 |
182 |
+ from binascii import hexlify |
183 |
+@@ -35,32 +34,14 @@ |
184 |
+ # Note: Only used for loading obsolete VaultAES files. All files are written |
185 |
+ # using the newer VaultAES256 which does not require md5 |
186 |
+ |
187 |
+-try: |
188 |
+- from Crypto.Hash import SHA256, HMAC |
189 |
+- HAS_HASH = True |
190 |
+-except ImportError: |
191 |
+- HAS_HASH = False |
192 |
+- |
193 |
+-# Counter import fails for 2.0.1, requires >= 2.6.1 from pip |
194 |
+-try: |
195 |
+- from Crypto.Util import Counter |
196 |
+- HAS_COUNTER = True |
197 |
+-except ImportError: |
198 |
+- HAS_COUNTER = False |
199 |
+- |
200 |
+-# KDF import fails for 2.0.1, requires >= 2.6.1 from pip |
201 |
+-try: |
202 |
+- from Crypto.Protocol.KDF import PBKDF2 |
203 |
+- HAS_PBKDF2 = True |
204 |
+-except ImportError: |
205 |
+- HAS_PBKDF2 = False |
206 |
+- |
207 |
+-# AES IMPORTS |
208 |
+-try: |
209 |
+- from Crypto.Cipher import AES as AES |
210 |
+- HAS_AES = True |
211 |
+-except ImportError: |
212 |
+- HAS_AES = False |
213 |
++from cryptography.exceptions import InvalidSignature |
214 |
++from cryptography.hazmat.backends import default_backend |
215 |
++from cryptography.hazmat.primitives import hashes, padding |
216 |
++from cryptography.hazmat.primitives.hmac import HMAC |
217 |
++from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC |
218 |
++from cryptography.hazmat.primitives.ciphers import ( |
219 |
++ Cipher as C_Cipher, algorithms, modes |
220 |
++) |
221 |
+ |
222 |
+ from ansible.compat.six import PY3, binary_type |
223 |
+ from ansible.compat.six.moves import zip |
224 |
+@@ -73,26 +54,8 @@ |
225 |
+ from ansible.utils.display import Display |
226 |
+ display = Display() |
227 |
+ |
228 |
+-# OpenSSL pbkdf2_hmac |
229 |
+-HAS_PBKDF2HMAC = False |
230 |
+-try: |
231 |
+- from cryptography.hazmat.primitives.hashes import SHA256 as c_SHA256 |
232 |
+- from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC |
233 |
+- from cryptography.hazmat.backends import default_backend |
234 |
+- HAS_PBKDF2HMAC = True |
235 |
+-except ImportError: |
236 |
+- pass |
237 |
+-except Exception as e: |
238 |
+- display.vvvv("Optional dependency 'cryptography' raised an exception, falling back to 'Crypto'.") |
239 |
+- import traceback |
240 |
+- display.vvvv("Traceback from import of cryptography was {0}".format(traceback.format_exc())) |
241 |
+- |
242 |
+-HAS_ANY_PBKDF2HMAC = HAS_PBKDF2 or HAS_PBKDF2HMAC |
243 |
+- |
244 |
+- |
245 |
+-CRYPTO_UPGRADE = "ansible-vault requires a newer version of pycrypto than the one installed on your platform." \ |
246 |
+- " You may fix this with OS-specific commands such as: yum install python-devel; rpm -e --nodeps python-crypto; pip install pycrypto" |
247 |
+ |
248 |
++BACKEND = default_backend() |
249 |
+ b_HEADER = b'$ANSIBLE_VAULT' |
250 |
+ CIPHER_WHITELIST = frozenset((u'AES', u'AES256')) |
251 |
+ CIPHER_WRITE_WHITELIST = frozenset((u'AES256',)) |
252 |
+@@ -100,12 +63,6 @@ |
253 |
+ # (used in VaultFile header) to a cipher class |
254 |
+ |
255 |
+ |
256 |
+-def check_prereqs(): |
257 |
+- |
258 |
+- if not HAS_AES or not HAS_COUNTER or not HAS_ANY_PBKDF2HMAC or not HAS_HASH: |
259 |
+- raise AnsibleError(CRYPTO_UPGRADE) |
260 |
+- |
261 |
+- |
262 |
+ class AnsibleVaultError(AnsibleError): |
263 |
+ pass |
264 |
+ |
265 |
+@@ -410,8 +367,6 @@ |
266 |
+ |
267 |
+ def encrypt_file(self, filename, output_file=None): |
268 |
+ |
269 |
+- check_prereqs() |
270 |
+- |
271 |
+ # A file to be encrypted into a vaultfile could be any encoding |
272 |
+ # so treat the contents as a byte string. |
273 |
+ |
274 |
+@@ -424,8 +379,6 @@ |
275 |
+ |
276 |
+ def decrypt_file(self, filename, output_file=None): |
277 |
+ |
278 |
+- check_prereqs() |
279 |
+- |
280 |
+ # follow the symlink |
281 |
+ filename = os.path.realpath(filename) |
282 |
+ |
283 |
+@@ -440,8 +393,6 @@ |
284 |
+ def create_file(self, filename): |
285 |
+ """ create a new encrypted file """ |
286 |
+ |
287 |
+- check_prereqs() |
288 |
+- |
289 |
+ # FIXME: If we can raise an error here, we can probably just make it |
290 |
+ # behave like edit instead. |
291 |
+ if os.path.isfile(filename): |
292 |
+@@ -451,8 +402,6 @@ |
293 |
+ |
294 |
+ def edit_file(self, filename): |
295 |
+ |
296 |
+- check_prereqs() |
297 |
+- |
298 |
+ # follow the symlink |
299 |
+ filename = os.path.realpath(filename) |
300 |
+ |
301 |
+@@ -471,7 +420,6 @@ |
302 |
+ |
303 |
+ def plaintext(self, filename): |
304 |
+ |
305 |
+- check_prereqs() |
306 |
+ ciphertext = self.read_data(filename) |
307 |
+ |
308 |
+ try: |
309 |
+@@ -483,8 +431,6 @@ |
310 |
+ |
311 |
+ def rekey_file(self, filename, b_new_password): |
312 |
+ |
313 |
+- check_prereqs() |
314 |
+- |
315 |
+ # follow the symlink |
316 |
+ filename = os.path.realpath(filename) |
317 |
+ |
318 |
+@@ -581,10 +527,6 @@ |
319 |
+ |
320 |
+ # Note: strings in this class should be byte strings by default. |
321 |
+ |
322 |
+- def __init__(self): |
323 |
+- if not HAS_AES: |
324 |
+- raise AnsibleError(CRYPTO_UPGRADE) |
325 |
+- |
326 |
+ def _aes_derive_key_and_iv(self, b_password, b_salt, key_length, iv_length): |
327 |
+ |
328 |
+ """ Create a key and an initialization vector """ |
329 |
+@@ -620,41 +562,22 @@ |
330 |
+ ' switch to the newer VaultAES256 format', version='2.3') |
331 |
+ # http://stackoverflow.com/a/14989032 |
332 |
+ |
333 |
+- b_ciphertext = unhexlify(b_vaulttext) |
334 |
+- |
335 |
+- in_file = BytesIO(b_ciphertext) |
336 |
+- in_file.seek(0) |
337 |
+- out_file = BytesIO() |
338 |
++ b_vaultdata = unhexlify(b_vaulttext) |
339 |
++ b_tmpsalt = b_vaultdata[:16] |
340 |
++ b_ciphertext = b_vaultdata[16:] |
341 |
+ |
342 |
+- bs = AES.block_size |
343 |
+- b_tmpsalt = in_file.read(bs) |
344 |
++ bs = algorithms.AES.block_size // 8 |
345 |
+ b_salt = b_tmpsalt[len(b'Salted__'):] |
346 |
+ b_key, b_iv = self._aes_derive_key_and_iv(b_password, b_salt, key_length, bs) |
347 |
+- cipher = AES.new(b_key, AES.MODE_CBC, b_iv) |
348 |
+- b_next_chunk = b'' |
349 |
+- finished = False |
350 |
+- |
351 |
+- while not finished: |
352 |
+- b_chunk, b_next_chunk = b_next_chunk, cipher.decrypt(in_file.read(1024 * bs)) |
353 |
+- if len(b_next_chunk) == 0: |
354 |
+- if PY3: |
355 |
+- padding_length = b_chunk[-1] |
356 |
+- else: |
357 |
+- padding_length = ord(b_chunk[-1]) |
358 |
++ cipher = C_Cipher(algorithms.AES(b_key), modes.CBC(b_iv), BACKEND).decryptor() |
359 |
++ unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder() |
360 |
+ |
361 |
+- b_chunk = b_chunk[:-padding_length] |
362 |
+- finished = True |
363 |
+- |
364 |
+- out_file.write(b_chunk) |
365 |
+- out_file.flush() |
366 |
+- |
367 |
+- # reset the stream pointer to the beginning |
368 |
+- out_file.seek(0) |
369 |
+- b_out_data = out_file.read() |
370 |
+- out_file.close() |
371 |
++ b_plaintext = unpadder.update( |
372 |
++ cipher.update(b_ciphertext) + cipher.finalize() |
373 |
++ ) + unpadder.finalize() |
374 |
+ |
375 |
+ # split out sha and verify decryption |
376 |
+- b_split_data = b_out_data.split(b"\n", 1) |
377 |
++ b_split_data = b_plaintext.split(b"\n", 1) |
378 |
+ b_this_sha = b_split_data[0] |
379 |
+ b_plaintext = b_split_data[1] |
380 |
+ b_test_sha = to_bytes(sha256(b_plaintext).hexdigest()) |
381 |
+@@ -676,19 +599,16 @@ |
382 |
+ |
383 |
+ # Note: strings in this class should be byte strings by default. |
384 |
+ |
385 |
+- def __init__(self): |
386 |
+- |
387 |
+- check_prereqs() |
388 |
+- |
389 |
+ @staticmethod |
390 |
+ def _create_key(b_password, b_salt, keylength, ivlength): |
391 |
+- hash_function = SHA256 |
392 |
+- |
393 |
+- # make two keys and one iv |
394 |
+- pbkdf2_prf = lambda p, s: HMAC.new(p, s, hash_function).digest() |
395 |
++ kdf = PBKDF2HMAC( |
396 |
++ algorithm=hashes.SHA256(), |
397 |
++ length=2 * keylength + ivlength, |
398 |
++ salt=b_salt, |
399 |
++ iterations=10000, |
400 |
++ backend=BACKEND) |
401 |
++ b_derivedkey = kdf.derive(b_password) |
402 |
+ |
403 |
+- b_derivedkey = PBKDF2(b_password, b_salt, dkLen=(2 * keylength) + ivlength, |
404 |
+- count=10000, prf=pbkdf2_prf) |
405 |
+ return b_derivedkey |
406 |
+ |
407 |
+ @classmethod |
408 |
+@@ -696,55 +616,31 @@ |
409 |
+ # 16 for AES 128, 32 for AES256 |
410 |
+ keylength = 32 |
411 |
+ |
412 |
+- # match the size used for counter.new to avoid extra work |
413 |
+- ivlength = 16 |
414 |
++ # AES is a 128-bit block cipher, so IVs and counter nonces are 16 bytes |
415 |
++ ivlength = algorithms.AES.block_size // 8 |
416 |
+ |
417 |
+- if HAS_PBKDF2HMAC: |
418 |
+- backend = default_backend() |
419 |
+- kdf = PBKDF2HMAC( |
420 |
+- algorithm=c_SHA256(), |
421 |
+- length=2 * keylength + ivlength, |
422 |
+- salt=b_salt, |
423 |
+- iterations=10000, |
424 |
+- backend=backend) |
425 |
+- b_derivedkey = kdf.derive(b_password) |
426 |
+- else: |
427 |
+- b_derivedkey = cls._create_key(b_password, b_salt, keylength, ivlength) |
428 |
++ b_derivedkey = cls._create_key(b_password, b_salt, keylength, ivlength) |
429 |
+ |
430 |
+ b_key1 = b_derivedkey[:keylength] |
431 |
+ b_key2 = b_derivedkey[keylength:(keylength * 2)] |
432 |
+ b_iv = b_derivedkey[(keylength * 2):(keylength * 2) + ivlength] |
433 |
+ |
434 |
+- return b_key1, b_key2, hexlify(b_iv) |
435 |
++ return b_key1, b_key2, b_iv |
436 |
+ |
437 |
+ def encrypt(self, b_plaintext, b_password): |
438 |
+ b_salt = os.urandom(32) |
439 |
+ b_key1, b_key2, b_iv = self._gen_key_initctr(b_password, b_salt) |
440 |
+ |
441 |
+- # PKCS#7 PAD DATA http://tools.ietf.org/html/rfc5652#section-6.3 |
442 |
+- bs = AES.block_size |
443 |
+- padding_length = (bs - len(b_plaintext) % bs) or bs |
444 |
+- b_plaintext += to_bytes(padding_length * chr(padding_length), encoding='ascii', errors='strict') |
445 |
+- |
446 |
+- # COUNTER.new PARAMETERS |
447 |
+- # 1) nbits (integer) - Length of the counter, in bits. |
448 |
+- # 2) initial_value (integer) - initial value of the counter. "iv" from _gen_key_initctr |
449 |
+- |
450 |
+- ctr = Counter.new(128, initial_value=int(b_iv, 16)) |
451 |
+- |
452 |
+- # AES.new PARAMETERS |
453 |
+- # 1) AES key, must be either 16, 24, or 32 bytes long -- "key" from _gen_key_initctr |
454 |
+- # 2) MODE_CTR, is the recommended mode |
455 |
+- # 3) counter=<CounterObject> |
456 |
+- |
457 |
+- cipher = AES.new(b_key1, AES.MODE_CTR, counter=ctr) |
458 |
+- |
459 |
+- # ENCRYPT PADDED DATA |
460 |
+- b_ciphertext = cipher.encrypt(b_plaintext) |
461 |
++ cipher = C_Cipher(algorithms.AES(b_key1), modes.CTR(b_iv), BACKEND) |
462 |
++ encryptor = cipher.encryptor() |
463 |
++ padder = padding.PKCS7(algorithms.AES.block_size).padder() |
464 |
++ b_ciphertext = encryptor.update(padder.update(b_plaintext) + padder.finalize()) |
465 |
++ b_ciphertext += encryptor.finalize() |
466 |
+ |
467 |
+ # COMBINE SALT, DIGEST AND DATA |
468 |
+- hmac = HMAC.new(b_key2, b_ciphertext, SHA256) |
469 |
+- b_vaulttext = b'\n'.join([hexlify(b_salt), to_bytes(hmac.hexdigest()), hexlify(b_ciphertext)]) |
470 |
++ hmac = HMAC(b_key2, hashes.SHA256(), BACKEND) |
471 |
++ hmac.update(b_ciphertext) |
472 |
++ b_vaulttext = b'\n'.join([hexlify(b_salt), hexlify(hmac.finalize()), hexlify(b_ciphertext)]) |
473 |
+ b_vaulttext = hexlify(b_vaulttext) |
474 |
+ return b_vaulttext |
475 |
+ |
476 |
+@@ -757,48 +653,21 @@ |
477 |
+ b_key1, b_key2, b_iv = self._gen_key_initctr(b_password, b_salt) |
478 |
+ |
479 |
+ # EXIT EARLY IF DIGEST DOESN'T MATCH |
480 |
+- hmacDecrypt = HMAC.new(b_key2, b_ciphertext, SHA256) |
481 |
+- if not self._is_equal(b_cryptedHmac, to_bytes(hmacDecrypt.hexdigest())): |
482 |
++ hmac = HMAC(b_key2, hashes.SHA256(), BACKEND) |
483 |
++ hmac.update(b_ciphertext) |
484 |
++ try: |
485 |
++ hmac.verify(unhexlify(b_cryptedHmac)) |
486 |
++ except InvalidSignature: |
487 |
+ return None |
488 |
+- # SET THE COUNTER AND THE CIPHER |
489 |
+- ctr = Counter.new(128, initial_value=int(b_iv, 16)) |
490 |
+- cipher = AES.new(b_key1, AES.MODE_CTR, counter=ctr) |
491 |
+- |
492 |
+- # DECRYPT PADDED DATA |
493 |
+- b_plaintext = cipher.decrypt(b_ciphertext) |
494 |
+- |
495 |
+- # UNPAD DATA |
496 |
+- if PY3: |
497 |
+- padding_length = b_plaintext[-1] |
498 |
+- else: |
499 |
+- padding_length = ord(b_plaintext[-1]) |
500 |
+ |
501 |
+- b_plaintext = b_plaintext[:-padding_length] |
502 |
+- return b_plaintext |
503 |
++ cipher = C_Cipher(algorithms.AES(b_key1), modes.CTR(b_iv), BACKEND) |
504 |
++ decryptor = cipher.decryptor() |
505 |
++ unpadder = padding.PKCS7(128).unpadder() |
506 |
++ b_plaintext = unpadder.update( |
507 |
++ decryptor.update(b_ciphertext) + decryptor.finalize() |
508 |
++ ) + unpadder.finalize() |
509 |
+ |
510 |
+- @staticmethod |
511 |
+- def _is_equal(b_a, b_b): |
512 |
+- """ |
513 |
+- Comparing 2 byte arrrays in constant time |
514 |
+- to avoid timing attacks. |
515 |
+- |
516 |
+- It would be nice if there was a library for this but |
517 |
+- hey. |
518 |
+- """ |
519 |
+- if not (isinstance(b_a, binary_type) and isinstance(b_b, binary_type)): |
520 |
+- raise TypeError('_is_equal can only be used to compare two byte strings') |
521 |
+- |
522 |
+- # http://codahale.com/a-lesson-in-timing-attacks/ |
523 |
+- if len(b_a) != len(b_b): |
524 |
+- return False |
525 |
+- |
526 |
+- result = 0 |
527 |
+- for b_x, b_y in zip(b_a, b_b): |
528 |
+- if PY3: |
529 |
+- result |= b_x ^ b_y |
530 |
+- else: |
531 |
+- result |= ord(b_x) ^ ord(b_y) |
532 |
+- return result == 0 |
533 |
++ return b_plaintext |
534 |
+ |
535 |
+ |
536 |
+ # Keys could be made bytes later if the code that gets the data is more |
537 |
+diff -uNr ansible-2.3.0.0.ORIG/test/runner/requirements/integration.txt ansible-2.3.0.0/test/runner/requirements/integration.txt |
538 |
+--- ansible-2.3.0.0.ORIG/test/runner/requirements/integration.txt 2017-05-23 14:23:12.379595453 +0100 |
539 |
++++ ansible-2.3.0.0/test/runner/requirements/integration.txt 2017-05-23 14:24:22.118598926 +0100 |
540 |
+@@ -1,8 +1,8 @@ |
541 |
++cryptography |
542 |
+ jinja2 |
543 |
+ jmespath |
544 |
+ junit-xml |
545 |
+ ordereddict ; python_version < '2.7' |
546 |
+ paramiko |
547 |
+ passlib |
548 |
+-pycrypto |
549 |
+ pyyaml |
550 |
+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 |
551 |
+--- ansible-2.3.0.0.ORIG/test/runner/requirements/network-integration.txt 2017-05-23 14:23:12.379595453 +0100 |
552 |
++++ ansible-2.3.0.0/test/runner/requirements/network-integration.txt 2017-05-23 14:24:22.119598926 +0100 |
553 |
+@@ -1,5 +1,5 @@ |
554 |
++cryptography |
555 |
+ jinja2 |
556 |
+ junit-xml |
557 |
+ paramiko |
558 |
+-pycrypto |
559 |
+ pyyaml |
560 |
+diff -uNr ansible-2.3.0.0.ORIG/test/runner/requirements/sanity.txt ansible-2.3.0.0/test/runner/requirements/sanity.txt |
561 |
+--- ansible-2.3.0.0.ORIG/test/runner/requirements/sanity.txt 2017-05-23 14:23:12.379595453 +0100 |
562 |
++++ ansible-2.3.0.0/test/runner/requirements/sanity.txt 2017-05-23 14:26:01.910603896 +0100 |
563 |
+@@ -1,5 +1,7 @@ |
564 |
++cryptography |
565 |
+ jinja2 |
566 |
+ mock |
567 |
++paramiko |
568 |
+ pep8 |
569 |
+ pylint |
570 |
+ pytest |
571 |
+diff -uNr ansible-2.3.0.0.ORIG/test/runner/requirements/units.txt ansible-2.3.0.0/test/runner/requirements/units.txt |
572 |
+--- ansible-2.3.0.0.ORIG/test/runner/requirements/units.txt 2017-05-23 14:23:12.379595453 +0100 |
573 |
++++ ansible-2.3.0.0/test/runner/requirements/units.txt 2017-05-23 14:24:22.119598926 +0100 |
574 |
+@@ -1,10 +1,10 @@ |
575 |
+ boto |
576 |
+ boto3 |
577 |
++cryptography |
578 |
+ jinja2 |
579 |
+ mock |
580 |
+ nose |
581 |
+ passlib |
582 |
+-pycrypto |
583 |
+ pytest |
584 |
+ pytest-mock |
585 |
+ pytest-xdist |
586 |
+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 |
587 |
+--- ansible-2.3.0.0.ORIG/test/runner/requirements/windows-integration.txt 2017-05-23 14:23:12.379595453 +0100 |
588 |
++++ ansible-2.3.0.0/test/runner/requirements/windows-integration.txt 2017-05-23 14:24:22.119598926 +0100 |
589 |
+@@ -1,4 +1,6 @@ |
590 |
++cryptography |
591 |
+ jinja2 |
592 |
+ junit-xml |
593 |
++paramiko |
594 |
+ pywinrm |
595 |
+ pyyaml |
596 |
+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 |
597 |
+--- ansible-2.3.0.0.ORIG/test/units/parsing/vault/test_vault_editor.py 2017-05-23 14:23:12.324595450 +0100 |
598 |
++++ ansible-2.3.0.0/test/units/parsing/vault/test_vault_editor.py 2017-05-23 14:24:22.120598926 +0100 |
599 |
+@@ -22,7 +22,6 @@ |
600 |
+ |
601 |
+ import os |
602 |
+ import tempfile |
603 |
+-from nose.plugins.skip import SkipTest |
604 |
+ |
605 |
+ from ansible.compat.tests import unittest |
606 |
+ from ansible.compat.tests.mock import patch |
607 |
+@@ -32,27 +31,6 @@ |
608 |
+ from ansible.module_utils._text import to_bytes, to_text |
609 |
+ |
610 |
+ |
611 |
+-# Counter import fails for 2.0.1, requires >= 2.6.1 from pip |
612 |
+-try: |
613 |
+- from Crypto.Util import Counter |
614 |
+- HAS_COUNTER = True |
615 |
+-except ImportError: |
616 |
+- HAS_COUNTER = False |
617 |
+- |
618 |
+-# KDF import fails for 2.0.1, requires >= 2.6.1 from pip |
619 |
+-try: |
620 |
+- from Crypto.Protocol.KDF import PBKDF2 |
621 |
+- HAS_PBKDF2 = True |
622 |
+-except ImportError: |
623 |
+- HAS_PBKDF2 = False |
624 |
+- |
625 |
+-# AES IMPORTS |
626 |
+-try: |
627 |
+- from Crypto.Cipher import AES as AES |
628 |
+- HAS_AES = True |
629 |
+-except ImportError: |
630 |
+- HAS_AES = False |
631 |
+- |
632 |
+ v10_data = """$ANSIBLE_VAULT;1.0;AES |
633 |
+ 53616c7465645f5fd0026926a2d415a28a2622116273fbc90e377225c12a347e1daf4456d36a77f9 |
634 |
+ 9ad98d59f61d06a4b66718d855f16fb7bdfe54d1ec8aeaa4d06c2dc1fa630ae1846a029877f0eeb1 |
635 |
+@@ -423,9 +401,6 @@ |
636 |
+ |
637 |
+ def test_decrypt_1_0(self): |
638 |
+ # Skip testing decrypting 1.0 files if we don't have access to AES, KDF or Counter. |
639 |
+- if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2: |
640 |
+- raise SkipTest |
641 |
+- |
642 |
+ v10_file = tempfile.NamedTemporaryFile(delete=False) |
643 |
+ with v10_file as f: |
644 |
+ f.write(to_bytes(v10_data)) |
645 |
+@@ -451,9 +426,6 @@ |
646 |
+ assert fdata.strip() == "foo", "incorrect decryption of 1.0 file: %s" % fdata.strip() |
647 |
+ |
648 |
+ def test_decrypt_1_1(self): |
649 |
+- if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2: |
650 |
+- raise SkipTest |
651 |
+- |
652 |
+ v11_file = tempfile.NamedTemporaryFile(delete=False) |
653 |
+ with v11_file as f: |
654 |
+ f.write(to_bytes(v11_data)) |
655 |
+@@ -478,10 +450,6 @@ |
656 |
+ assert fdata.strip() == "foo", "incorrect decryption of 1.0 file: %s" % fdata.strip() |
657 |
+ |
658 |
+ def test_rekey_migration(self): |
659 |
+- # Skip testing rekeying files if we don't have access to AES, KDF or Counter. |
660 |
+- if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2: |
661 |
+- raise SkipTest |
662 |
+- |
663 |
+ v10_file = tempfile.NamedTemporaryFile(delete=False) |
664 |
+ with v10_file as f: |
665 |
+ f.write(to_bytes(v10_data)) |
666 |
+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 |
667 |
+--- ansible-2.3.0.0.ORIG/test/units/parsing/vault/test_vault.py 2017-05-23 14:23:12.324595450 +0100 |
668 |
++++ ansible-2.3.0.0/test/units/parsing/vault/test_vault.py 2017-05-23 14:24:22.120598926 +0100 |
669 |
+@@ -38,28 +38,6 @@ |
670 |
+ from ansible.module_utils._text import to_bytes, to_text |
671 |
+ |
672 |
+ |
673 |
+-# Counter import fails for 2.0.1, requires >= 2.6.1 from pip |
674 |
+-try: |
675 |
+- from Crypto.Util import Counter |
676 |
+- HAS_COUNTER = True |
677 |
+-except ImportError: |
678 |
+- HAS_COUNTER = False |
679 |
+- |
680 |
+-# KDF import fails for 2.0.1, requires >= 2.6.1 from pip |
681 |
+-try: |
682 |
+- from Crypto.Protocol.KDF import PBKDF2 |
683 |
+- HAS_PBKDF2 = True |
684 |
+-except ImportError: |
685 |
+- HAS_PBKDF2 = False |
686 |
+- |
687 |
+-# AES IMPORTS |
688 |
+-try: |
689 |
+- from Crypto.Cipher import AES as AES |
690 |
+- HAS_AES = True |
691 |
+-except ImportError: |
692 |
+- HAS_AES = False |
693 |
+- |
694 |
+- |
695 |
+ class TestVaultIsEncrypted(unittest.TestCase): |
696 |
+ def test_bytes_not_encrypted(self): |
697 |
+ b_data = b"foobar" |
698 |
+@@ -181,38 +159,6 @@ |
699 |
+ self.assertIsInstance(b_key, six.binary_type) |
700 |
+ self.assertEqual(b_key, b_key_2) |
701 |
+ |
702 |
+- def test_is_equal_is_equal(self): |
703 |
+- self.assertTrue(self.vault_cipher._is_equal(b'abcdefghijklmnopqrstuvwxyz', b'abcdefghijklmnopqrstuvwxyz')) |
704 |
+- |
705 |
+- def test_is_equal_unequal_length(self): |
706 |
+- self.assertFalse(self.vault_cipher._is_equal(b'abcdefghijklmnopqrstuvwxyz', b'abcdefghijklmnopqrstuvwx and sometimes y')) |
707 |
+- |
708 |
+- def test_is_equal_not_equal(self): |
709 |
+- self.assertFalse(self.vault_cipher._is_equal(b'abcdefghijklmnopqrstuvwxyz', b'AbcdefghijKlmnopQrstuvwxZ')) |
710 |
+- |
711 |
+- def test_is_equal_empty(self): |
712 |
+- self.assertTrue(self.vault_cipher._is_equal(b'', b'')) |
713 |
+- |
714 |
+- def test_is_equal_non_ascii_equal(self): |
715 |
+- utf8_data = to_bytes(u'私はガラスを食べられます。それは私を傷つけません。') |
716 |
+- self.assertTrue(self.vault_cipher._is_equal(utf8_data, utf8_data)) |
717 |
+- |
718 |
+- def test_is_equal_non_ascii_unequal(self): |
719 |
+- utf8_data = to_bytes(u'私はガラスを食べられます。それは私を傷つけません。') |
720 |
+- utf8_data2 = to_bytes(u'Pot să mănânc sticlă și ea nu mă rănește.') |
721 |
+- |
722 |
+- # Test for the len optimization path |
723 |
+- self.assertFalse(self.vault_cipher._is_equal(utf8_data, utf8_data2)) |
724 |
+- # Test for the slower, char by char comparison path |
725 |
+- self.assertFalse(self.vault_cipher._is_equal(utf8_data, utf8_data[:-1] + b'P')) |
726 |
+- |
727 |
+- def test_is_equal_non_bytes(self): |
728 |
+- """ Anything not a byte string should raise a TypeError """ |
729 |
+- self.assertRaises(TypeError, self.vault_cipher._is_equal, u"One fish", b"two fish") |
730 |
+- self.assertRaises(TypeError, self.vault_cipher._is_equal, b"One fish", u"two fish") |
731 |
+- self.assertRaises(TypeError, self.vault_cipher._is_equal, 1, b"red fish") |
732 |
+- self.assertRaises(TypeError, self.vault_cipher._is_equal, b"blue fish", 2) |
733 |
+- |
734 |
+ |
735 |
+ class TestVaultLib(unittest.TestCase): |
736 |
+ def setUp(self): |
737 |
+@@ -267,8 +213,6 @@ |
738 |
+ self.assertEqual(self.v.b_version, b"9.9", msg="version was not properly set") |
739 |
+ |
740 |
+ def test_encrypt_decrypt_aes(self): |
741 |
+- if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2: |
742 |
+- raise SkipTest |
743 |
+ self.v.cipher_name = u'AES' |
744 |
+ self.v.b_password = b'ansible' |
745 |
+ # AES encryption code has been removed, so this is old output for |
746 |
+@@ -282,8 +226,6 @@ |
747 |
+ self.assertEqual(b_plaintext, b"foobar", msg="decryption failed") |
748 |
+ |
749 |
+ def test_encrypt_decrypt_aes256(self): |
750 |
+- if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2: |
751 |
+- raise SkipTest |
752 |
+ self.v.cipher_name = u'AES256' |
753 |
+ plaintext = u"foobar" |
754 |
+ b_vaulttext = self.v.encrypt(plaintext) |
755 |
+@@ -292,8 +234,6 @@ |
756 |
+ self.assertEqual(b_plaintext, b"foobar", msg="decryption failed") |
757 |
+ |
758 |
+ def test_encrypt_decrypt_aes256_existing_vault(self): |
759 |
+- if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2: |
760 |
+- raise SkipTest |
761 |
+ self.v.cipher_name = u'AES256' |
762 |
+ b_orig_plaintext = b"Setec Astronomy" |
763 |
+ vaulttext = u'''$ANSIBLE_VAULT;1.1;AES256 |
764 |
+@@ -314,8 +254,6 @@ |
765 |
+ # FIXME This test isn't working quite yet. |
766 |
+ raise SkipTest |
767 |
+ |
768 |
+- if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2: |
769 |
+- raise SkipTest |
770 |
+ self.v.cipher_name = 'AES256' |
771 |
+ # plaintext = "Setec Astronomy" |
772 |
+ enc_data = '''$ANSIBLE_VAULT;1.1;AES256 |
773 |
+@@ -350,8 +288,6 @@ |
774 |
+ self.v.decrypt(b_invalid_ciphertext) |
775 |
+ |
776 |
+ def test_encrypt_encrypted(self): |
777 |
+- if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2: |
778 |
+- raise SkipTest |
779 |
+ self.v.cipher_name = u'AES' |
780 |
+ b_vaulttext = b"$ANSIBLE_VAULT;9.9;TEST\n%s" % hexlify(b"ansible") |
781 |
+ vaulttext = to_text(b_vaulttext, errors='strict') |
782 |
+@@ -359,8 +295,6 @@ |
783 |
+ self.assertRaises(errors.AnsibleError, self.v.encrypt, vaulttext) |
784 |
+ |
785 |
+ def test_decrypt_decrypted(self): |
786 |
+- if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2: |
787 |
+- raise SkipTest |
788 |
+ plaintext = u"ansible" |
789 |
+ self.assertRaises(errors.AnsibleError, self.v.decrypt, plaintext) |
790 |
+ |
791 |
+@@ -368,9 +302,6 @@ |
792 |
+ self.assertRaises(errors.AnsibleError, self.v.decrypt, b_plaintext) |
793 |
+ |
794 |
+ def test_cipher_not_set(self): |
795 |
+- # not setting the cipher should default to AES256 |
796 |
+- if not HAS_AES or not HAS_COUNTER or not HAS_PBKDF2: |
797 |
+- raise SkipTest |
798 |
+ plaintext = u"ansible" |
799 |
+ self.v.encrypt(plaintext) |
800 |
+ self.assertEquals(self.v.cipher_name, "AES256") |
801 |
+diff -uNr ansible-2.3.0.0.ORIG/test/utils/docker/centos6/Dockerfile ansible-2.3.0.0/test/utils/docker/centos6/Dockerfile |
802 |
+--- ansible-2.3.0.0.ORIG/test/utils/docker/centos6/Dockerfile 2017-05-23 14:23:12.321595450 +0100 |
803 |
++++ ansible-2.3.0.0/test/utils/docker/centos6/Dockerfile 2017-05-23 14:24:22.121598926 +0100 |
804 |
+@@ -9,6 +9,8 @@ |
805 |
+ file \ |
806 |
+ gcc \ |
807 |
+ git \ |
808 |
++ libffi \ |
809 |
++ libffi-devel \ |
810 |
+ make \ |
811 |
+ mercurial \ |
812 |
+ mysql \ |
813 |
+@@ -16,6 +18,7 @@ |
814 |
+ mysql-server \ |
815 |
+ openssh-clients \ |
816 |
+ openssh-server \ |
817 |
++ openssl-devel \ |
818 |
+ python-coverage \ |
819 |
+ python-devel \ |
820 |
+ python-httplib2 \ |
821 |
+@@ -40,8 +43,6 @@ |
822 |
+ && \ |
823 |
+ yum clean all |
824 |
+ |
825 |
+-RUN rpm -e --nodeps python-crypto && pip install --upgrade pycrypto |
826 |
+- |
827 |
+ RUN /bin/sed -i -e 's/^\(Defaults\s*requiretty\)/#--- \1/' /etc/sudoers |
828 |
+ RUN mkdir /etc/ansible/ |
829 |
+ RUN /bin/echo -e '[local]\nlocalhost ansible_connection=local' > /etc/ansible/hosts |
830 |
+diff -uNr ansible-2.3.0.0.ORIG/test/utils/docker/centos7/Dockerfile ansible-2.3.0.0/test/utils/docker/centos7/Dockerfile |
831 |
+--- ansible-2.3.0.0.ORIG/test/utils/docker/centos7/Dockerfile 2017-05-23 14:23:12.321595450 +0100 |
832 |
++++ ansible-2.3.0.0/test/utils/docker/centos7/Dockerfile 2017-05-23 14:24:22.121598926 +0100 |
833 |
+@@ -17,15 +17,20 @@ |
834 |
+ bzip2 \ |
835 |
+ dbus-python \ |
836 |
+ file \ |
837 |
++ gcc \ |
838 |
+ git \ |
839 |
+ iproute \ |
840 |
++ libffi \ |
841 |
++ libffi-devel \ |
842 |
+ make \ |
843 |
+ mariadb-server \ |
844 |
+ mercurial \ |
845 |
+ MySQL-python \ |
846 |
+ openssh-clients \ |
847 |
+ openssh-server \ |
848 |
++ openssl-devel \ |
849 |
+ python-coverage \ |
850 |
++ python-devel \ |
851 |
+ python-httplib2 \ |
852 |
+ python-jinja2 \ |
853 |
+ python-keyczar \ |
854 |
+diff -uNr ansible-2.3.0.0.ORIG/test/utils/docker/fedora24/Dockerfile ansible-2.3.0.0/test/utils/docker/fedora24/Dockerfile |
855 |
+--- ansible-2.3.0.0.ORIG/test/utils/docker/fedora24/Dockerfile 2017-05-23 14:23:12.321595450 +0100 |
856 |
++++ ansible-2.3.0.0/test/utils/docker/fedora24/Dockerfile 2017-05-23 14:24:22.121598926 +0100 |
857 |
+@@ -17,18 +17,23 @@ |
858 |
+ dbus-python \ |
859 |
+ file \ |
860 |
+ findutils \ |
861 |
++ gcc \ |
862 |
+ git \ |
863 |
+ glibc-locale-source \ |
864 |
+ iproute \ |
865 |
++ libffi \ |
866 |
++ libffi-devel \ |
867 |
+ make \ |
868 |
+ mariadb-server \ |
869 |
+ mercurial \ |
870 |
+ MySQL-python \ |
871 |
+ openssh-clients \ |
872 |
+ openssh-server \ |
873 |
++ openssl-devel \ |
874 |
+ procps \ |
875 |
+ python2-dnf \ |
876 |
+ python-coverage \ |
877 |
++ python-devel \ |
878 |
+ python-httplib2 \ |
879 |
+ python-jinja2 \ |
880 |
+ python-keyczar \ |
881 |
+diff -uNr ansible-2.3.0.0.ORIG/test/utils/docker/fedora25/Dockerfile ansible-2.3.0.0/test/utils/docker/fedora25/Dockerfile |
882 |
+--- ansible-2.3.0.0.ORIG/test/utils/docker/fedora25/Dockerfile 2017-05-23 14:23:12.321595450 +0100 |
883 |
++++ ansible-2.3.0.0/test/utils/docker/fedora25/Dockerfile 2017-05-23 14:24:22.121598926 +0100 |
884 |
+@@ -20,12 +20,15 @@ |
885 |
+ git \ |
886 |
+ glibc-locale-source \ |
887 |
+ iproute \ |
888 |
++ libffi \ |
889 |
++ libffi-devel \ |
890 |
+ make \ |
891 |
+ mariadb-server \ |
892 |
+ mercurial \ |
893 |
+ MySQL-python \ |
894 |
+ openssh-clients \ |
895 |
+ openssh-server \ |
896 |
++ openssl-devel \ |
897 |
+ procps \ |
898 |
+ python2-dnf \ |
899 |
+ python-coverage \ |
900 |
+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 |
901 |
+--- ansible-2.3.0.0.ORIG/test/utils/docker/opensuse42.1/Dockerfile 2017-05-23 14:23:12.321595450 +0100 |
902 |
++++ ansible-2.3.0.0/test/utils/docker/opensuse42.1/Dockerfile 2017-05-23 14:24:22.121598926 +0100 |
903 |
+@@ -21,6 +21,8 @@ |
904 |
+ openssh \ |
905 |
+ postgresql-server \ |
906 |
+ python-coverage \ |
907 |
++ python-cryptography \ |
908 |
++ python-devel \ |
909 |
+ python-httplib2 \ |
910 |
+ python-jinja2 \ |
911 |
+ python-keyczar \ |
912 |
+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 |
913 |
+--- ansible-2.3.0.0.ORIG/test/utils/docker/opensuse42.2/Dockerfile 2017-05-23 14:23:12.321595450 +0100 |
914 |
++++ ansible-2.3.0.0/test/utils/docker/opensuse42.2/Dockerfile 2017-05-23 14:24:22.122598926 +0100 |
915 |
+@@ -21,6 +21,7 @@ |
916 |
+ openssh \ |
917 |
+ postgresql-server \ |
918 |
+ python-coverage \ |
919 |
++ python-cryptography \ |
920 |
+ python-httplib2 \ |
921 |
+ python-jinja2 \ |
922 |
+ python-keyczar \ |
923 |
+diff -uNr ansible-2.3.0.0.ORIG/test/utils/docker/ubuntu1204/Dockerfile ansible-2.3.0.0/test/utils/docker/ubuntu1204/Dockerfile |
924 |
+--- ansible-2.3.0.0.ORIG/test/utils/docker/ubuntu1204/Dockerfile 2017-05-23 14:23:12.321595450 +0100 |
925 |
++++ ansible-2.3.0.0/test/utils/docker/ubuntu1204/Dockerfile 2017-05-23 14:24:22.122598926 +0100 |
926 |
+@@ -17,6 +17,8 @@ |
927 |
+ gawk \ |
928 |
+ gcc \ |
929 |
+ git \ |
930 |
++ libffi-dev \ |
931 |
++ libssl-dev \ |
932 |
+ libxml2-utils \ |
933 |
+ locales \ |
934 |
+ make \ |
935 |
+@@ -50,8 +52,6 @@ |
936 |
+ && \ |
937 |
+ apt-get clean |
938 |
+ |
939 |
+-RUN pip install --upgrade pycrypto |
940 |
+- |
941 |
+ # helpful things taken from the ubuntu-upstart Dockerfile: |
942 |
+ # https://github.com/tianon/dockerfiles/blob/4d24a12b54b75b3e0904d8a285900d88d3326361/sbin-init/ubuntu/upstart/14.04/Dockerfile |
943 |
+ ADD init-fake.conf /etc/init/fake-container-events.conf |
944 |
+diff -uNr ansible-2.3.0.0.ORIG/test/utils/docker/ubuntu1404/Dockerfile ansible-2.3.0.0/test/utils/docker/ubuntu1404/Dockerfile |
945 |
+--- ansible-2.3.0.0.ORIG/test/utils/docker/ubuntu1404/Dockerfile 2017-05-23 14:23:12.321595450 +0100 |
946 |
++++ ansible-2.3.0.0/test/utils/docker/ubuntu1404/Dockerfile 2017-05-23 14:24:22.122598926 +0100 |
947 |
+@@ -16,6 +16,8 @@ |
948 |
+ fakeroot \ |
949 |
+ gawk \ |
950 |
+ git \ |
951 |
++ libffi-dev \ |
952 |
++ libssl-dev \ |
953 |
+ libxml2-utils \ |
954 |
+ locales \ |
955 |
+ make \ |
956 |
+diff -uNr ansible-2.3.0.0.ORIG/test/utils/docker/ubuntu1604/Dockerfile ansible-2.3.0.0/test/utils/docker/ubuntu1604/Dockerfile |
957 |
+--- ansible-2.3.0.0.ORIG/test/utils/docker/ubuntu1604/Dockerfile 2017-05-23 14:23:12.321595450 +0100 |
958 |
++++ ansible-2.3.0.0/test/utils/docker/ubuntu1604/Dockerfile 2017-05-23 14:24:22.122598926 +0100 |
959 |
+@@ -17,6 +17,8 @@ |
960 |
+ gawk \ |
961 |
+ git \ |
962 |
+ iproute2 \ |
963 |
++ libffi-dev \ |
964 |
++ libssl-dev \ |
965 |
+ libxml2-utils \ |
966 |
+ locales \ |
967 |
+ lsb-release \ |
968 |
+diff -uNr ansible-2.3.0.0.ORIG/test/utils/docker/ubuntu1604py3/Dockerfile ansible-2.3.0.0/test/utils/docker/ubuntu1604py3/Dockerfile |
969 |
+--- ansible-2.3.0.0.ORIG/test/utils/docker/ubuntu1604py3/Dockerfile 2017-05-23 14:23:12.321595450 +0100 |
970 |
++++ ansible-2.3.0.0/test/utils/docker/ubuntu1604py3/Dockerfile 2017-05-23 14:24:22.122598926 +0100 |
971 |
+@@ -15,6 +15,8 @@ |
972 |
+ gawk \ |
973 |
+ git \ |
974 |
+ iproute2 \ |
975 |
++ libffi-dev \ |
976 |
++ libssl-dev \ |
977 |
+ libxml2-utils \ |
978 |
+ locales \ |
979 |
+ lsb-release \ |
980 |
+diff -uNr ansible-2.3.0.0.ORIG/test/utils/shippable/other.sh ansible-2.3.0.0/test/utils/shippable/other.sh |
981 |
+--- ansible-2.3.0.0.ORIG/test/utils/shippable/other.sh 2017-05-23 14:23:12.320595450 +0100 |
982 |
++++ ansible-2.3.0.0/test/utils/shippable/other.sh 2017-05-23 14:24:22.123598926 +0100 |
983 |
+@@ -12,6 +12,8 @@ |
984 |
+ retry.py apt-get install -qq \ |
985 |
+ shellcheck \ |
986 |
+ python2.4 \ |
987 |
++ libssl-dev \ |
988 |
++ libffi-dev \ |
989 |
+ |
990 |
+ ln -sf x86_64-linux-gnu-gcc-4.9 /usr/bin/x86_64-linux-gnu-gcc |
991 |
+ |
992 |
+diff -uNr ansible-2.3.0.0.ORIG/test/utils/tox/requirements.txt ansible-2.3.0.0/test/utils/tox/requirements.txt |
993 |
+--- ansible-2.3.0.0.ORIG/test/utils/tox/requirements.txt 2017-05-23 14:23:12.321595450 +0100 |
994 |
++++ ansible-2.3.0.0/test/utils/tox/requirements.txt 2017-05-23 14:24:22.123598926 +0100 |
995 |
+@@ -11,7 +11,7 @@ |
996 |
+ redis |
997 |
+ python-memcached |
998 |
+ python-systemd |
999 |
+-pycrypto |
1000 |
++cryptography |
1001 |
+ botocore |
1002 |
+ boto3 |
1003 |
+ pytest |