From 0e4fe7a52bdfbc613a454358481b5bb64d04dac4 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Tue, 12 Nov 2019 02:34:35 +0100 Subject: [PATCH] ACMEAccount.get_request check status code value lower boundary (#63140) (#64071) * check status code value lower boundary Any HTTP code below 200 cannot be considered a success, should be handled like a failure instead. This is particularly true for below zero status codes. Fixes #63139 * provide changelog fragment * ensure connection errors are handled in Acme module * add fetch_url check to ACME.send_signed_request * remove module.fail_json * move _assert_fetch_url_success out of ACMEAccount * fix ansible-lint errors * use simplified syntax status checking (cherry picked from commit 0d905a0496f4554a9de57cbd3ee90e30d6249b34) --- .../63140-acme-fix-fetch-url-status-codes.yaml | 2 ++ lib/ansible/module_utils/acme.py | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/63140-acme-fix-fetch-url-status-codes.yaml diff --git a/changelogs/fragments/63140-acme-fix-fetch-url-status-codes.yaml b/changelogs/fragments/63140-acme-fix-fetch-url-status-codes.yaml new file mode 100644 index 00000000000..7c7c86ff8b3 --- /dev/null +++ b/changelogs/fragments/63140-acme-fix-fetch-url-status-codes.yaml @@ -0,0 +1,2 @@ +bugfixes: +- "ACME modules: make sure some connection errors are handled properly" diff --git a/lib/ansible/module_utils/acme.py b/lib/ansible/module_utils/acme.py index 38e2af68e97..aae2b9fdc7e 100644 --- a/lib/ansible/module_utils/acme.py +++ b/lib/ansible/module_utils/acme.py @@ -426,6 +426,16 @@ def _sign_request_cryptography(module, payload64, protected64, key_data): } +def _assert_fetch_url_success(response, info, allow_redirect=False, allow_client_error=True, allow_server_error=True): + if info['status'] < 0: + raise ModuleFailException(msg="Failure downloading %s, %s" % (info['url'], info['msg'])) + + if (300 <= info['status'] < 400 and not allow_redirect) or \ + (400 <= info['status'] < 500 and not allow_client_error) or \ + (info['status'] >= 500 and not allow_server_error): + raise ModuleFailException("ACME request failed: CODE: {0} MGS: {1} RESULT: {2}".format(info['status'], info['msg'], response)) + + class ACMEDirectory(object): ''' The ACME server directory. Gives access to the available resources, @@ -586,6 +596,7 @@ class ACMEAccount(object): 'Content-Type': 'application/jose+json', } resp, info = fetch_url(self.module, url, data=data, headers=headers, method='POST') + _assert_fetch_url_success(resp, info) result = {} try: content = resp.read() @@ -634,6 +645,8 @@ class ACMEAccount(object): # Perform unauthenticated GET resp, info = fetch_url(self.module, uri, method='GET', headers=headers) + _assert_fetch_url_success(resp, info) + try: content = resp.read() except AttributeError: @@ -653,7 +666,7 @@ class ACMEAccount(object): else: result = content - if fail_on_error and info['status'] >= 400: + if fail_on_error and (info['status'] < 200 or info['status'] >= 400): raise ModuleFailException("ACME request failed: CODE: {0} RESULT: {1}".format(info['status'], result)) return result, info