From 155adb16319236d1d891556717b34ad0db4a1879 Mon Sep 17 00:00:00 2001
From: Felix Fontein <felix@fontein.de>
Date: Thu, 8 Mar 2018 15:11:20 +0100
Subject: [PATCH] Using correct content type (as per version 10 of ACME draft).
 (#37165)

* Using correct content type (as per version 10 of ACME draft).

* Another incompatibility with ACME v2: body must be {} and not contain v1 data (Pebble fails otherwise).

* Fixing bug: self.args in a subclass of Exception is apparently always a tuple.
---
 .../modules/web_infrastructure/letsencrypt.py | 23 +++++++++++--------
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/lib/ansible/modules/web_infrastructure/letsencrypt.py b/lib/ansible/modules/web_infrastructure/letsencrypt.py
index 8205e09e5fb..e70c03dc14f 100644
--- a/lib/ansible/modules/web_infrastructure/letsencrypt.py
+++ b/lib/ansible/modules/web_infrastructure/letsencrypt.py
@@ -361,10 +361,10 @@ class ModuleFailException(Exception):
     def __init__(self, msg, **args):
         super(ModuleFailException, self).__init__(self, msg)
         self.msg = msg
-        self.args = args
+        self.module_fail_args = args
 
     def do_fail(self, module):
-        module.fail_json(msg=self.msg, **self.args)
+        module.fail_json(msg=self.msg, other=self.module_fail_args)
 
 
 def _lowercase_fetch_url(*args, **kwargs):
@@ -675,7 +675,7 @@ class ACMEAccount(object):
         '''
         Sends a JWS signed HTTP POST request to the ACME server and returns
         the response as dictionary
-        https://tools.ietf.org/html/draft-ietf-acme-acme-09#section-6.2
+        https://tools.ietf.org/html/draft-ietf-acme-acme-10#section-6.2
         '''
         failed_tries = 0
         while True:
@@ -719,7 +719,10 @@ class ACMEAccount(object):
                 data["header"] = self.jws_header
             data = self.module.jsonify(data)
 
-            resp, info = fetch_url(self.module, url, data=data, method='POST')
+            headers = {
+                'Content-Type': 'application/jose+json',
+            }
+            resp, info = fetch_url(self.module, url, data=data, headers=headers, method='POST')
             result = {}
             try:
                 content = resp.read()
@@ -979,13 +982,13 @@ class ACMEClient(object):
                 continue
 
             uri = challenge['uri'] if self.version == 1 else challenge['url']
-            token = re.sub(r"[^A-Za-z0-9_\-]", "_", challenge['token'])
-            keyauthorization = self.account.get_keyauthorization(token)
 
-            challenge_response = {
-                "resource": "challenge",
-                "keyAuthorization": keyauthorization,
-            }
+            challenge_response = {}
+            if self.version == 1:
+                token = re.sub(r"[^A-Za-z0-9_\-]", "_", challenge['token'])
+                keyauthorization = self.account.get_keyauthorization(token)
+                challenge_response["resource"] = "challenge"
+                challenge_response["keyAuthorization"] = keyauthorization
             result, info = self.account.send_signed_request(uri, challenge_response)
             if info['status'] not in [200, 202]:
                 raise ModuleFailException("Error validating challenge: CODE: {0} RESULT: {1}".format(info['status'], result))