We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Log when simple-verify fails
Half #1409. When we fail to self verify a challenge, we should log the problem and continue instead of exiting.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `letsencrypt/plugins/manual.py`
Content:
```
1 """Manual plugin."""
2 import os
3 import logging
4 import pipes
5 import shutil
6 import signal
7 import socket
8 import subprocess
9 import sys
10 import tempfile
11 import time
12 
13 import zope.component
14 import zope.interface
15 
16 from acme import challenges
17 
18 from letsencrypt import errors
19 from letsencrypt import interfaces
20 from letsencrypt.plugins import common
21 
22 
23 logger = logging.getLogger(__name__)
24 
25 
26 class Authenticator(common.Plugin):
27     """Manual Authenticator.
28 
29     This plugin requires user's manual intervention in setting up a HTTP
30     server for solving http-01 challenges and thus does not need to be
31     run as a privileged process. Alternatively shows instructions on how
32     to use Python's built-in HTTP server.
33 
34     .. todo:: Support for `~.challenges.TLSSNI01`.
35 
36     """
37     zope.interface.implements(interfaces.IAuthenticator)
38     zope.interface.classProvides(interfaces.IPluginFactory)
39     hidden = True
40 
41     description = "Manually configure an HTTP server"
42 
43     MESSAGE_TEMPLATE = """\
44 Make sure your web server displays the following content at
45 {uri} before continuing:
46 
47 {validation}
48 
49 Content-Type header MUST be set to {ct}.
50 
51 If you don't have HTTP server configured, you can run the following
52 command on the target server (as root):
53 
54 {command}
55 """
56 
57     # a disclaimer about your current IP being transmitted to Let's Encrypt's servers.
58     IP_DISCLAIMER = """\
59 NOTE: The IP of this machine will be publicly logged as having requested this certificate. \
60 If you're running letsencrypt in manual mode on a machine that is not your server, \
61 please ensure you're okay with that.
62 
63 Are you OK with your IP being logged?
64 """
65 
66     # "cd /tmp/letsencrypt" makes sure user doesn't serve /root,
67     # separate "public_html" ensures that cert.pem/key.pem are not
68     # served and makes it more obvious that Python command will serve
69     # anything recursively under the cwd
70 
71     CMD_TEMPLATE = """\
72 mkdir -p {root}/public_html/{achall.URI_ROOT_PATH}
73 cd {root}/public_html
74 printf "%s" {validation} > {achall.URI_ROOT_PATH}/{encoded_token}
75 # run only once per server:
76 $(command -v python2 || command -v python2.7 || command -v python2.6) -c \\
77 "import BaseHTTPServer, SimpleHTTPServer; \\
78 SimpleHTTPServer.SimpleHTTPRequestHandler.extensions_map = {{'': '{ct}'}}; \\
79 s = BaseHTTPServer.HTTPServer(('', {port}), SimpleHTTPServer.SimpleHTTPRequestHandler); \\
80 s.serve_forever()" """
81     """Command template."""
82 
83     def __init__(self, *args, **kwargs):
84         super(Authenticator, self).__init__(*args, **kwargs)
85         self._root = (tempfile.mkdtemp() if self.conf("test-mode")
86                       else "/tmp/letsencrypt")
87         self._httpd = None
88 
89     @classmethod
90     def add_parser_arguments(cls, add):
91         add("test-mode", action="store_true",
92             help="Test mode. Executes the manual command in subprocess.")
93 
94     def prepare(self):  # pylint: disable=missing-docstring,no-self-use
95         pass  # pragma: no cover
96 
97     def more_info(self):  # pylint: disable=missing-docstring,no-self-use
98         return ("This plugin requires user's manual intervention in setting "
99                 "up an HTTP server for solving http-01 challenges and thus "
100                 "does not need to be run as a privileged process. "
101                 "Alternatively shows instructions on how to use Python's "
102                 "built-in HTTP server.")
103 
104     def get_chall_pref(self, domain):
105         # pylint: disable=missing-docstring,no-self-use,unused-argument
106         return [challenges.HTTP01]
107 
108     def perform(self, achalls):  # pylint: disable=missing-docstring
109         responses = []
110         # TODO: group achalls by the same socket.gethostbyname(_ex)
111         # and prompt only once per server (one "echo -n" per domain)
112         for achall in achalls:
113             responses.append(self._perform_single(achall))
114         return responses
115 
116     @classmethod
117     def _test_mode_busy_wait(cls, port):
118         while True:
119             time.sleep(1)
120             sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
121             try:
122                 sock.connect(("localhost", port))
123             except socket.error:  # pragma: no cover
124                 pass
125             else:
126                 break
127             finally:
128                 sock.close()
129 
130     def _perform_single(self, achall):
131         # same path for each challenge response would be easier for
132         # users, but will not work if multiple domains point at the
133         # same server: default command doesn't support virtual hosts
134         response, validation = achall.response_and_validation()
135 
136         port = (response.port if self.config.http01_port is None
137                 else int(self.config.http01_port))
138         command = self.CMD_TEMPLATE.format(
139             root=self._root, achall=achall, response=response,
140             # TODO(kuba): pipes still necessary?
141             validation=pipes.quote(validation),
142             encoded_token=achall.chall.encode("token"),
143             ct=achall.CONTENT_TYPE, port=port)
144         if self.conf("test-mode"):
145             logger.debug("Test mode. Executing the manual command: %s", command)
146             # sh shipped with OS X does't support echo -n, but supports printf
147             try:
148                 self._httpd = subprocess.Popen(
149                     command,
150                     # don't care about setting stdout and stderr,
151                     # we're in test mode anyway
152                     shell=True,
153                     executable=None,
154                     # "preexec_fn" is UNIX specific, but so is "command"
155                     preexec_fn=os.setsid)
156             except OSError as error:  # ValueError should not happen!
157                 logger.debug(
158                     "Couldn't execute manual command: %s", error, exc_info=True)
159                 return False
160             logger.debug("Manual command running as PID %s.", self._httpd.pid)
161             # give it some time to bootstrap, before we try to verify
162             # (cert generation in case of simpleHttpS might take time)
163             self._test_mode_busy_wait(port)
164             if self._httpd.poll() is not None:
165                 raise errors.Error("Couldn't execute manual command")
166         else:
167             if not zope.component.getUtility(interfaces.IDisplay).yesno(
168                     self.IP_DISCLAIMER, "Yes", "No"):
169                 raise errors.PluginError("Must agree to IP logging to proceed")
170 
171             self._notify_and_wait(self.MESSAGE_TEMPLATE.format(
172                 validation=validation, response=response,
173                 uri=achall.chall.uri(achall.domain),
174                 ct=achall.CONTENT_TYPE, command=command))
175 
176         if response.simple_verify(
177                 achall.chall, achall.domain,
178                 achall.account_key.public_key(), self.config.http01_port):
179             return response
180         else:
181             logger.error(
182                 "Self-verify of challenge failed, authorization abandoned.")
183             if self.conf("test-mode") and self._httpd.poll() is not None:
184                 # simply verify cause command failure...
185                 return False
186             return None
187 
188     def _notify_and_wait(self, message):  # pylint: disable=no-self-use
189         # TODO: IDisplay wraps messages, breaking the command
190         #answer = zope.component.getUtility(interfaces.IDisplay).notification(
191         #    message=message, height=25, pause=True)
192         sys.stdout.write(message)
193         raw_input("Press ENTER to continue")
194 
195     def cleanup(self, achalls):
196         # pylint: disable=missing-docstring,no-self-use,unused-argument
197         if self.conf("test-mode"):
198             assert self._httpd is not None, (
199                 "cleanup() must be called after perform()")
200             if self._httpd.poll() is None:
201                 logger.debug("Terminating manual command process")
202                 os.killpg(self._httpd.pid, signal.SIGTERM)
203             else:
204                 logger.debug("Manual command process already terminated "
205                              "with %s code", self._httpd.returncode)
206             shutil.rmtree(self._root)
207
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/letsencrypt/plugins/manual.py b/letsencrypt/plugins/manual.py
--- a/letsencrypt/plugins/manual.py
+++ b/letsencrypt/plugins/manual.py
@@ -173,17 +173,12 @@
                 uri=achall.chall.uri(achall.domain),
                 ct=achall.CONTENT_TYPE, command=command))
 
-        if response.simple_verify(
+        if not response.simple_verify(
                 achall.chall, achall.domain,
                 achall.account_key.public_key(), self.config.http01_port):
-            return response
-        else:
-            logger.error(
-                "Self-verify of challenge failed, authorization abandoned.")
-            if self.conf("test-mode") and self._httpd.poll() is not None:
-                # simply verify cause command failure...
-                return False
-            return None
+            logger.warning("Self-verify of challenge failed.")
+
+        return response
 
     def _notify_and_wait(self, message):  # pylint: disable=no-self-use
         # TODO: IDisplay wraps messages, breaking the command

{"golden_diff": "diff --git a/letsencrypt/plugins/manual.py b/letsencrypt/plugins/manual.py\n--- a/letsencrypt/plugins/manual.py\n+++ b/letsencrypt/plugins/manual.py\n@@ -173,17 +173,12 @@\n                 uri=achall.chall.uri(achall.domain),\n                 ct=achall.CONTENT_TYPE, command=command))\n \n-        if response.simple_verify(\n+        if not response.simple_verify(\n                 achall.chall, achall.domain,\n                 achall.account_key.public_key(), self.config.http01_port):\n-            return response\n-        else:\n-            logger.error(\n-                \"Self-verify of challenge failed, authorization abandoned.\")\n-            if self.conf(\"test-mode\") and self._httpd.poll() is not None:\n-                # simply verify cause command failure...\n-                return False\n-            return None\n+            logger.warning(\"Self-verify of challenge failed.\")\n+\n+        return response\n \n     def _notify_and_wait(self, message):  # pylint: disable=no-self-use\n         # TODO: IDisplay wraps messages, breaking the command\n", "issue": "Log when simple-verify fails\nHalf #1409. When we fail to self verify a challenge, we should log the problem and continue instead of exiting.\n\n", "before_files": [{"content": "\"\"\"Manual plugin.\"\"\"\nimport os\nimport logging\nimport pipes\nimport shutil\nimport signal\nimport socket\nimport subprocess\nimport sys\nimport tempfile\nimport time\n\nimport zope.component\nimport zope.interface\n\nfrom acme import challenges\n\nfrom letsencrypt import errors\nfrom letsencrypt import interfaces\nfrom letsencrypt.plugins import common\n\n\nlogger = logging.getLogger(__name__)\n\n\nclass Authenticator(common.Plugin):\n    \"\"\"Manual Authenticator.\n\n    This plugin requires user's manual intervention in setting up a HTTP\n    server for solving http-01 challenges and thus does not need to be\n    run as a privileged process. Alternatively shows instructions on how\n    to use Python's built-in HTTP server.\n\n    .. todo:: Support for `~.challenges.TLSSNI01`.\n\n    \"\"\"\n    zope.interface.implements(interfaces.IAuthenticator)\n    zope.interface.classProvides(interfaces.IPluginFactory)\n    hidden = True\n\n    description = \"Manually configure an HTTP server\"\n\n    MESSAGE_TEMPLATE = \"\"\"\\\nMake sure your web server displays the following content at\n{uri} before continuing:\n\n{validation}\n\nContent-Type header MUST be set to {ct}.\n\nIf you don't have HTTP server configured, you can run the following\ncommand on the target server (as root):\n\n{command}\n\"\"\"\n\n    # a disclaimer about your current IP being transmitted to Let's Encrypt's servers.\n    IP_DISCLAIMER = \"\"\"\\\nNOTE: The IP of this machine will be publicly logged as having requested this certificate. \\\nIf you're running letsencrypt in manual mode on a machine that is not your server, \\\nplease ensure you're okay with that.\n\nAre you OK with your IP being logged?\n\"\"\"\n\n    # \"cd /tmp/letsencrypt\" makes sure user doesn't serve /root,\n    # separate \"public_html\" ensures that cert.pem/key.pem are not\n    # served and makes it more obvious that Python command will serve\n    # anything recursively under the cwd\n\n    CMD_TEMPLATE = \"\"\"\\\nmkdir -p {root}/public_html/{achall.URI_ROOT_PATH}\ncd {root}/public_html\nprintf \"%s\" {validation} > {achall.URI_ROOT_PATH}/{encoded_token}\n# run only once per server:\n$(command -v python2 || command -v python2.7 || command -v python2.6) -c \\\\\n\"import BaseHTTPServer, SimpleHTTPServer; \\\\\nSimpleHTTPServer.SimpleHTTPRequestHandler.extensions_map = {{'': '{ct}'}}; \\\\\ns = BaseHTTPServer.HTTPServer(('', {port}), SimpleHTTPServer.SimpleHTTPRequestHandler); \\\\\ns.serve_forever()\" \"\"\"\n    \"\"\"Command template.\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        super(Authenticator, self).__init__(*args, **kwargs)\n        self._root = (tempfile.mkdtemp() if self.conf(\"test-mode\")\n                      else \"/tmp/letsencrypt\")\n        self._httpd = None\n\n    @classmethod\n    def add_parser_arguments(cls, add):\n        add(\"test-mode\", action=\"store_true\",\n            help=\"Test mode. Executes the manual command in subprocess.\")\n\n    def prepare(self):  # pylint: disable=missing-docstring,no-self-use\n        pass  # pragma: no cover\n\n    def more_info(self):  # pylint: disable=missing-docstring,no-self-use\n        return (\"This plugin requires user's manual intervention in setting \"\n                \"up an HTTP server for solving http-01 challenges and thus \"\n                \"does not need to be run as a privileged process. \"\n                \"Alternatively shows instructions on how to use Python's \"\n                \"built-in HTTP server.\")\n\n    def get_chall_pref(self, domain):\n        # pylint: disable=missing-docstring,no-self-use,unused-argument\n        return [challenges.HTTP01]\n\n    def perform(self, achalls):  # pylint: disable=missing-docstring\n        responses = []\n        # TODO: group achalls by the same socket.gethostbyname(_ex)\n        # and prompt only once per server (one \"echo -n\" per domain)\n        for achall in achalls:\n            responses.append(self._perform_single(achall))\n        return responses\n\n    @classmethod\n    def _test_mode_busy_wait(cls, port):\n        while True:\n            time.sleep(1)\n            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n            try:\n                sock.connect((\"localhost\", port))\n            except socket.error:  # pragma: no cover\n                pass\n            else:\n                break\n            finally:\n                sock.close()\n\n    def _perform_single(self, achall):\n        # same path for each challenge response would be easier for\n        # users, but will not work if multiple domains point at the\n        # same server: default command doesn't support virtual hosts\n        response, validation = achall.response_and_validation()\n\n        port = (response.port if self.config.http01_port is None\n                else int(self.config.http01_port))\n        command = self.CMD_TEMPLATE.format(\n            root=self._root, achall=achall, response=response,\n            # TODO(kuba): pipes still necessary?\n            validation=pipes.quote(validation),\n            encoded_token=achall.chall.encode(\"token\"),\n            ct=achall.CONTENT_TYPE, port=port)\n        if self.conf(\"test-mode\"):\n            logger.debug(\"Test mode. Executing the manual command: %s\", command)\n            # sh shipped with OS X does't support echo -n, but supports printf\n            try:\n                self._httpd = subprocess.Popen(\n                    command,\n                    # don't care about setting stdout and stderr,\n                    # we're in test mode anyway\n                    shell=True,\n                    executable=None,\n                    # \"preexec_fn\" is UNIX specific, but so is \"command\"\n                    preexec_fn=os.setsid)\n            except OSError as error:  # ValueError should not happen!\n                logger.debug(\n                    \"Couldn't execute manual command: %s\", error, exc_info=True)\n                return False\n            logger.debug(\"Manual command running as PID %s.\", self._httpd.pid)\n            # give it some time to bootstrap, before we try to verify\n            # (cert generation in case of simpleHttpS might take time)\n            self._test_mode_busy_wait(port)\n            if self._httpd.poll() is not None:\n                raise errors.Error(\"Couldn't execute manual command\")\n        else:\n            if not zope.component.getUtility(interfaces.IDisplay).yesno(\n                    self.IP_DISCLAIMER, \"Yes\", \"No\"):\n                raise errors.PluginError(\"Must agree to IP logging to proceed\")\n\n            self._notify_and_wait(self.MESSAGE_TEMPLATE.format(\n                validation=validation, response=response,\n                uri=achall.chall.uri(achall.domain),\n                ct=achall.CONTENT_TYPE, command=command))\n\n        if response.simple_verify(\n                achall.chall, achall.domain,\n                achall.account_key.public_key(), self.config.http01_port):\n            return response\n        else:\n            logger.error(\n                \"Self-verify of challenge failed, authorization abandoned.\")\n            if self.conf(\"test-mode\") and self._httpd.poll() is not None:\n                # simply verify cause command failure...\n                return False\n            return None\n\n    def _notify_and_wait(self, message):  # pylint: disable=no-self-use\n        # TODO: IDisplay wraps messages, breaking the command\n        #answer = zope.component.getUtility(interfaces.IDisplay).notification(\n        #    message=message, height=25, pause=True)\n        sys.stdout.write(message)\n        raw_input(\"Press ENTER to continue\")\n\n    def cleanup(self, achalls):\n        # pylint: disable=missing-docstring,no-self-use,unused-argument\n        if self.conf(\"test-mode\"):\n            assert self._httpd is not None, (\n                \"cleanup() must be called after perform()\")\n            if self._httpd.poll() is None:\n                logger.debug(\"Terminating manual command process\")\n                os.killpg(self._httpd.pid, signal.SIGTERM)\n            else:\n                logger.debug(\"Manual command process already terminated \"\n                             \"with %s code\", self._httpd.returncode)\n            shutil.rmtree(self._root)\n", "path": "letsencrypt/plugins/manual.py"}], "after_files": [{"content": "\"\"\"Manual plugin.\"\"\"\nimport os\nimport logging\nimport pipes\nimport shutil\nimport signal\nimport socket\nimport subprocess\nimport sys\nimport tempfile\nimport time\n\nimport zope.component\nimport zope.interface\n\nfrom acme import challenges\n\nfrom letsencrypt import errors\nfrom letsencrypt import interfaces\nfrom letsencrypt.plugins import common\n\n\nlogger = logging.getLogger(__name__)\n\n\nclass Authenticator(common.Plugin):\n    \"\"\"Manual Authenticator.\n\n    This plugin requires user's manual intervention in setting up a HTTP\n    server for solving http-01 challenges and thus does not need to be\n    run as a privileged process. Alternatively shows instructions on how\n    to use Python's built-in HTTP server.\n\n    .. todo:: Support for `~.challenges.TLSSNI01`.\n\n    \"\"\"\n    zope.interface.implements(interfaces.IAuthenticator)\n    zope.interface.classProvides(interfaces.IPluginFactory)\n    hidden = True\n\n    description = \"Manually configure an HTTP server\"\n\n    MESSAGE_TEMPLATE = \"\"\"\\\nMake sure your web server displays the following content at\n{uri} before continuing:\n\n{validation}\n\nContent-Type header MUST be set to {ct}.\n\nIf you don't have HTTP server configured, you can run the following\ncommand on the target server (as root):\n\n{command}\n\"\"\"\n\n    # a disclaimer about your current IP being transmitted to Let's Encrypt's servers.\n    IP_DISCLAIMER = \"\"\"\\\nNOTE: The IP of this machine will be publicly logged as having requested this certificate. \\\nIf you're running letsencrypt in manual mode on a machine that is not your server, \\\nplease ensure you're okay with that.\n\nAre you OK with your IP being logged?\n\"\"\"\n\n    # \"cd /tmp/letsencrypt\" makes sure user doesn't serve /root,\n    # separate \"public_html\" ensures that cert.pem/key.pem are not\n    # served and makes it more obvious that Python command will serve\n    # anything recursively under the cwd\n\n    CMD_TEMPLATE = \"\"\"\\\nmkdir -p {root}/public_html/{achall.URI_ROOT_PATH}\ncd {root}/public_html\nprintf \"%s\" {validation} > {achall.URI_ROOT_PATH}/{encoded_token}\n# run only once per server:\n$(command -v python2 || command -v python2.7 || command -v python2.6) -c \\\\\n\"import BaseHTTPServer, SimpleHTTPServer; \\\\\nSimpleHTTPServer.SimpleHTTPRequestHandler.extensions_map = {{'': '{ct}'}}; \\\\\ns = BaseHTTPServer.HTTPServer(('', {port}), SimpleHTTPServer.SimpleHTTPRequestHandler); \\\\\ns.serve_forever()\" \"\"\"\n    \"\"\"Command template.\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        super(Authenticator, self).__init__(*args, **kwargs)\n        self._root = (tempfile.mkdtemp() if self.conf(\"test-mode\")\n                      else \"/tmp/letsencrypt\")\n        self._httpd = None\n\n    @classmethod\n    def add_parser_arguments(cls, add):\n        add(\"test-mode\", action=\"store_true\",\n            help=\"Test mode. Executes the manual command in subprocess.\")\n\n    def prepare(self):  # pylint: disable=missing-docstring,no-self-use\n        pass  # pragma: no cover\n\n    def more_info(self):  # pylint: disable=missing-docstring,no-self-use\n        return (\"This plugin requires user's manual intervention in setting \"\n                \"up an HTTP server for solving http-01 challenges and thus \"\n                \"does not need to be run as a privileged process. \"\n                \"Alternatively shows instructions on how to use Python's \"\n                \"built-in HTTP server.\")\n\n    def get_chall_pref(self, domain):\n        # pylint: disable=missing-docstring,no-self-use,unused-argument\n        return [challenges.HTTP01]\n\n    def perform(self, achalls):  # pylint: disable=missing-docstring\n        responses = []\n        # TODO: group achalls by the same socket.gethostbyname(_ex)\n        # and prompt only once per server (one \"echo -n\" per domain)\n        for achall in achalls:\n            responses.append(self._perform_single(achall))\n        return responses\n\n    @classmethod\n    def _test_mode_busy_wait(cls, port):\n        while True:\n            time.sleep(1)\n            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n            try:\n                sock.connect((\"localhost\", port))\n            except socket.error:  # pragma: no cover\n                pass\n            else:\n                break\n            finally:\n                sock.close()\n\n    def _perform_single(self, achall):\n        # same path for each challenge response would be easier for\n        # users, but will not work if multiple domains point at the\n        # same server: default command doesn't support virtual hosts\n        response, validation = achall.response_and_validation()\n\n        port = (response.port if self.config.http01_port is None\n                else int(self.config.http01_port))\n        command = self.CMD_TEMPLATE.format(\n            root=self._root, achall=achall, response=response,\n            # TODO(kuba): pipes still necessary?\n            validation=pipes.quote(validation),\n            encoded_token=achall.chall.encode(\"token\"),\n            ct=achall.CONTENT_TYPE, port=port)\n        if self.conf(\"test-mode\"):\n            logger.debug(\"Test mode. Executing the manual command: %s\", command)\n            # sh shipped with OS X does't support echo -n, but supports printf\n            try:\n                self._httpd = subprocess.Popen(\n                    command,\n                    # don't care about setting stdout and stderr,\n                    # we're in test mode anyway\n                    shell=True,\n                    executable=None,\n                    # \"preexec_fn\" is UNIX specific, but so is \"command\"\n                    preexec_fn=os.setsid)\n            except OSError as error:  # ValueError should not happen!\n                logger.debug(\n                    \"Couldn't execute manual command: %s\", error, exc_info=True)\n                return False\n            logger.debug(\"Manual command running as PID %s.\", self._httpd.pid)\n            # give it some time to bootstrap, before we try to verify\n            # (cert generation in case of simpleHttpS might take time)\n            self._test_mode_busy_wait(port)\n            if self._httpd.poll() is not None:\n                raise errors.Error(\"Couldn't execute manual command\")\n        else:\n            if not zope.component.getUtility(interfaces.IDisplay).yesno(\n                    self.IP_DISCLAIMER, \"Yes\", \"No\"):\n                raise errors.PluginError(\"Must agree to IP logging to proceed\")\n\n            self._notify_and_wait(self.MESSAGE_TEMPLATE.format(\n                validation=validation, response=response,\n                uri=achall.chall.uri(achall.domain),\n                ct=achall.CONTENT_TYPE, command=command))\n\n        if not response.simple_verify(\n                achall.chall, achall.domain,\n                achall.account_key.public_key(), self.config.http01_port):\n            logger.warning(\"Self-verify of challenge failed.\")\n\n        return response\n\n    def _notify_and_wait(self, message):  # pylint: disable=no-self-use\n        # TODO: IDisplay wraps messages, breaking the command\n        #answer = zope.component.getUtility(interfaces.IDisplay).notification(\n        #    message=message, height=25, pause=True)\n        sys.stdout.write(message)\n        raw_input(\"Press ENTER to continue\")\n\n    def cleanup(self, achalls):\n        # pylint: disable=missing-docstring,no-self-use,unused-argument\n        if self.conf(\"test-mode\"):\n            assert self._httpd is not None, (\n                \"cleanup() must be called after perform()\")\n            if self._httpd.poll() is None:\n                logger.debug(\"Terminating manual command process\")\n                os.killpg(self._httpd.pid, signal.SIGTERM)\n            else:\n                logger.debug(\"Manual command process already terminated \"\n                             \"with %s code\", self._httpd.returncode)\n            shutil.rmtree(self._root)\n", "path": "letsencrypt/plugins/manual.py"}]}