http-01 for manual plugin

This commit is contained in:
Jakub Warmuz 2015-10-28 20:42:44 +00:00
parent 5ef2507b0c
commit fd209eab66
No known key found for this signature in database
GPG key ID: 2A7BAD3A489B52EA
2 changed files with 17 additions and 17 deletions

View file

@ -27,7 +27,7 @@ class Authenticator(common.Plugin):
"""Manual Authenticator.
This plugin requires user's manual intervention in setting up a HTTP
server for solving SimpleHTTP challenges and thus does not need to be
server for solving http-01 challenges and thus does not need to be
run as a privileged process. Alternatively shows instructions on how
to use Python's built-in HTTP server.
@ -68,9 +68,9 @@ Are you OK with your IP being logged?
# anything recursively under the cwd
CMD_TEMPLATE = """\
mkdir -p {root}/public_html/{response.URI_ROOT_PATH}
mkdir -p {root}/public_html/{achall.URI_ROOT_PATH}
cd {root}/public_html
printf "%s" {validation} > {response.URI_ROOT_PATH}/{encoded_token}
printf "%s" {validation} > {achall.URI_ROOT_PATH}/{encoded_token}
# run only once per server:
$(command -v python2 || command -v python2.7 || command -v python2.6) -c \\
"import BaseHTTPServer, SimpleHTTPServer; \\
@ -95,14 +95,14 @@ s.serve_forever()" """
def more_info(self): # pylint: disable=missing-docstring,no-self-use
return ("This plugin requires user's manual intervention in setting "
"up an HTTP server for solving SimpleHTTP challenges and thus "
"up an HTTP server for solving http-01 challenges and thus "
"does not need to be run as a privileged process. "
"Alternatively shows instructions on how to use Python's "
"built-in HTTP server.")
def get_chall_pref(self, domain):
# pylint: disable=missing-docstring,no-self-use,unused-argument
return [challenges.SimpleHTTP]
return [challenges.HTTP01]
def perform(self, achalls): # pylint: disable=missing-docstring
responses = []
@ -130,16 +130,16 @@ s.serve_forever()" """
# same path for each challenge response would be easier for
# users, but will not work if multiple domains point at the
# same server: default command doesn't support virtual hosts
response, validation = achall.gen_response_and_validation(
tls=False) # SimpleHTTP TLS is dead: ietf-wg-acme/acme#7
response, validation = achall.response_and_validation()
port = (response.port if self.config.simple_http_port is None
else int(self.config.simple_http_port))
command = self.CMD_TEMPLATE.format(
root=self._root, achall=achall, response=response,
validation=pipes.quote(validation.json_dumps()),
# TODO(kuba): pipes still necessary?
validation=pipes.quote(validation),
encoded_token=achall.chall.encode("token"),
ct=response.CONTENT_TYPE, port=port)
ct=achall.CONTENT_TYPE, port=port)
if self.conf("test-mode"):
logger.debug("Test mode. Executing the manual command: %s", command)
# sh shipped with OS X does't support echo -n, but supports printf
@ -168,9 +168,9 @@ s.serve_forever()" """
raise errors.PluginError("Must agree to IP logging to proceed")
self._notify_and_wait(self.MESSAGE_TEMPLATE.format(
validation=validation.json_dumps(), response=response,
uri=response.uri(achall.domain, achall.challb.chall),
ct=response.CONTENT_TYPE, command=command))
validation=validation, response=response,
uri=achall.chall.uri(achall.domain),
ct=achall.CONTENT_TYPE, command=command))
if response.simple_verify(
achall.chall, achall.domain,

View file

@ -25,8 +25,8 @@ class AuthenticatorTest(unittest.TestCase):
self.config = mock.MagicMock(
simple_http_port=8080, manual_test_mode=False)
self.auth = Authenticator(config=self.config, name="manual")
self.achalls = [achallenges.SimpleHTTP(
challb=acme_util.SIMPLE_HTTP_P, domain="foo.com", account_key=KEY)]
self.achalls = [achallenges.KeyAuthorizationAnnotatedChallenge(
challb=acme_util.HTTP01_P, domain="foo.com", account_key=KEY)]
config_test_mode = mock.MagicMock(
simple_http_port=8080, manual_test_mode=True)
@ -45,13 +45,13 @@ class AuthenticatorTest(unittest.TestCase):
@mock.patch("letsencrypt.plugins.manual.zope.component.getUtility")
@mock.patch("letsencrypt.plugins.manual.sys.stdout")
@mock.patch("acme.challenges.SimpleHTTPResponse.simple_verify")
@mock.patch("acme.challenges.HTTP01Response.simple_verify")
@mock.patch("__builtin__.raw_input")
def test_perform(self, mock_raw_input, mock_verify, mock_stdout, mock_interaction):
mock_verify.return_value = True
mock_interaction().yesno.return_value = True
resp = challenges.SimpleHTTPResponse(tls=False)
resp = self.achalls[0].response(KEY)
self.assertEqual([resp], self.auth.perform(self.achalls))
self.assertEqual(1, mock_raw_input.call_count)
mock_verify.assert_called_with(
@ -89,7 +89,7 @@ class AuthenticatorTest(unittest.TestCase):
@mock.patch("letsencrypt.plugins.manual.socket.socket")
@mock.patch("letsencrypt.plugins.manual.time.sleep", autospec=True)
@mock.patch("acme.challenges.SimpleHTTPResponse.simple_verify",
@mock.patch("acme.challenges.HTTP01Response.simple_verify",
autospec=True)
@mock.patch("letsencrypt.plugins.manual.subprocess.Popen", autospec=True)
def test_perform_test_mode(self, mock_popen, mock_verify, mock_sleep,