summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--changelogs/fragments/75015-ca-path-bundle.yml3
-rw-r--r--lib/ansible/module_utils/urls.py28
-rw-r--r--test/integration/targets/uri/tasks/main.yml19
3 files changed, 42 insertions, 8 deletions
diff --git a/changelogs/fragments/75015-ca-path-bundle.yml b/changelogs/fragments/75015-ca-path-bundle.yml
new file mode 100644
index 0000000000..574f5aa96b
--- /dev/null
+++ b/changelogs/fragments/75015-ca-path-bundle.yml
@@ -0,0 +1,3 @@
+bugfixes:
+- urls - Allow ``ca_path`` to point to a bundle containing multiple PEM certs
+ (https://github.com/ansible/ansible/issues/75015)
diff --git a/lib/ansible/module_utils/urls.py b/lib/ansible/module_utils/urls.py
index 5ba945931d..c6b194d680 100644
--- a/lib/ansible/module_utils/urls.py
+++ b/lib/ansible/module_utils/urls.py
@@ -475,6 +475,11 @@ zKPZsZ2miVGclicJHzm5q080b1p/sZtuKIEZk6vZqEg=
-----END CERTIFICATE-----
"""
+b_PEM_CERT_RE = re.compile(
+ br'^-----BEGIN CERTIFICATE-----\n.+?-----END CERTIFICATE-----$',
+ flags=re.M | re.S
+)
+
#
# Exceptions
#
@@ -745,6 +750,11 @@ def generic_urlparse(parts):
return generic_parts
+def extract_pem_certs(b_data):
+ for match in b_PEM_CERT_RE.finditer(b_data):
+ yield match.group(0)
+
+
class RequestWithMethod(urllib_request.Request):
'''
Workaround for using DELETE/PUT/etc with urllib2
@@ -918,11 +928,12 @@ class SSLValidationHandler(urllib_request.BaseHandler):
paths_checked = [self.ca_path]
with open(to_bytes(self.ca_path, errors='surrogate_or_strict'), 'rb') as f:
if HAS_SSLCONTEXT:
- cadata.extend(
- ssl.PEM_cert_to_DER_cert(
- to_native(f.read(), errors='surrogate_or_strict')
+ for b_pem in extract_pem_certs(f.read()):
+ cadata.extend(
+ ssl.PEM_cert_to_DER_cert(
+ to_native(b_pem, errors='surrogate_or_strict')
+ )
)
- )
return self.ca_path, cadata, paths_checked
if not HAS_SSLCONTEXT:
@@ -981,11 +992,12 @@ class SSLValidationHandler(urllib_request.BaseHandler):
b_cert = cert_file.read()
if HAS_SSLCONTEXT:
try:
- cadata.extend(
- ssl.PEM_cert_to_DER_cert(
- to_native(b_cert, errors='surrogate_or_strict')
+ for b_pem in extract_pem_certs(b_cert):
+ cadata.extend(
+ ssl.PEM_cert_to_DER_cert(
+ to_native(b_pem, errors='surrogate_or_strict')
+ )
)
- )
except Exception:
continue
else:
diff --git a/test/integration/targets/uri/tasks/main.yml b/test/integration/targets/uri/tasks/main.yml
index 700e7f1017..a91c425db7 100644
--- a/test/integration/targets/uri/tasks/main.yml
+++ b/test/integration/targets/uri/tasks/main.yml
@@ -173,6 +173,25 @@
- result is failed
- "'certificate verify failed' in result.msg"
+- name: Locate ca-bundle
+ stat:
+ path: '{{ item }}'
+ loop:
+ - /etc/ssl/certs/ca-bundle.crt
+ - /etc/ssl/certs/ca-certificates.crt
+ - /var/lib/ca-certificates/ca-bundle.pem
+ - /usr/local/share/certs/ca-root-nss.crt
+ - '{{ macos_cafile.stdout_lines|default(["/_i_dont_exist_ca.pem"])|first }}'
+ - /etc/ssl/cert.pem
+ register: ca_bundle_candidates
+
+- name: Test that ca_path can be a full bundle
+ uri:
+ url: "https://{{ httpbin_host }}/get"
+ ca_path: '{{ ca_bundle }}'
+ vars:
+ ca_bundle: '{{ ca_bundle_candidates.results|selectattr("stat.exists")|map(attribute="item")|first }}'
+
- name: test redirect without follow_redirects
uri:
url: 'https://{{ httpbin_host }}/redirect/2'