Skip to content

Commit

Permalink
Remove tls-sni in compatibility tests (#6854)
Browse files Browse the repository at this point in the history
* Reconfigure compatibility tests to use http challenge

* Correct simple test

* Add a fake DNS resolution for HTTP simple_verify

* Debug

* More subtle approach: we monkey patch urllib3 to fake a dns resolution to the target IP, allowing every host header to be preserved.

* Private package

* Relaxed permissions on certbot temp working dir

* Move the fake DNS logic in compatibility test, to avoid degrading the acme coverage

* Fix lint

* Update certbot-compatibility-test/certbot_compatibility_test/configurators/common.py

Co-Authored-By: adferrand <adferrand@users.noreply.github.com>
  • Loading branch information
adferrand committed Mar 15, 2019
1 parent 5e64349 commit c2f2aa5
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 11 deletions.
Expand Up @@ -23,6 +23,9 @@ def add_parser_arguments(cls, parser):
def __init__(self, args):
"""Initializes the plugin with the given command line args"""
self._temp_dir = tempfile.mkdtemp()
# tempfile.mkdtemp() creates folders with too restrictive permissions to be accessible
# to an Apache worker, leading to HTTP challenge failures. Let's fix that.
os.chmod(self._temp_dir, 0o755)
self.le_config = util.create_le_config(self._temp_dir)
config_dir = util.extract_configs(args.configs, self._temp_dir)
self._configs = [
Expand Down
@@ -1,12 +1,14 @@
"""Tests Certbot plugins against different server configurations."""
import argparse
import contextlib
import filecmp
import logging
import os
import shutil
import tempfile
import time
import sys
from urllib3.util import connection

import OpenSSL

Expand Down Expand Up @@ -64,18 +66,19 @@ def test_authenticator(plugin, config, temp_dir):
"Plugin failed to complete %s for %s in %s",
type(achalls[i]), achalls[i].domain, config)
success = False
elif isinstance(responses[i], challenges.TLSSNI01Response):
verified = responses[i].simple_verify(achalls[i].chall,
achalls[i].domain,
util.JWK.public_key(),
host="127.0.0.1",
port=plugin.https_port)
elif isinstance(responses[i], challenges.HTTP01Response):
# We fake the DNS resolution to ensure that any domain is resolved
# to the local HTTP server setup for the compatibility tests
with _fake_dns_resolution("127.0.0.1"):
verified = responses[i].simple_verify(
achalls[i].chall, achalls[i].domain,
util.JWK.public_key(), port=plugin.http_port)
if verified:
logger.info(
"tls-sni-01 verification for %s succeeded", achalls[i].domain)
"http-01 verification for %s succeeded", achalls[i].domain)
else:
logger.error(
"**** tls-sni-01 verification for %s in %s failed",
"**** http-01 verification for %s in %s failed",
achalls[i].domain, config)
success = False

Expand All @@ -102,9 +105,9 @@ def _create_achalls(plugin):
for domain in names:
prefs = plugin.get_chall_pref(domain)
for chall_type in prefs:
if chall_type == challenges.TLSSNI01:
chall = challenges.TLSSNI01(
token=os.urandom(challenges.TLSSNI01.TOKEN_SIZE))
if chall_type == challenges.HTTP01:
chall = challenges.HTTP01(
token=os.urandom(challenges.HTTP01.TOKEN_SIZE))
challb = acme_util.chall_to_challb(
chall, messages.STATUS_PENDING)
achall = achallenges.KeyAuthorizationAnnotatedChallenge(
Expand Down Expand Up @@ -369,5 +372,21 @@ def main():
sys.exit(1)


@contextlib.contextmanager
def _fake_dns_resolution(resolved_ip):
"""Monkey patch urllib3 to make any hostname be resolved to the provided IP"""
_original_create_connection = connection.create_connection

def _patched_create_connection(address, *args, **kwargs):
_, port = address
return _original_create_connection((resolved_ip, port), *args, **kwargs)

try:
connection.create_connection = _patched_create_connection
yield
finally:
connection.create_connection = _original_create_connection


if __name__ == "__main__":
main()

0 comments on commit c2f2aa5

Please sign in to comment.