Пример #1
0
    def test_get_dns_challenges_mixed_valid(self, mock_len):
        assert mock_len

        from acme import challenges

        host = "example.com"
        c = challenges.DNS01()

        host2 = "www.example.com"
        c2 = challenges.DNS01()

        mock_authz = MagicMock()
        mock_authz.body = STATUS_VALID
        mock_authz.body.resolved_combinations = []
        mock_entry = Mock()
        mock_entry.chall = c
        mock_authz.body.resolved_combinations.append(mock_entry)

        mock_authz2 = MagicMock()
        mock_authz2.body = STATUS_PENDING
        mock_authz2.body.resolved_combinations = []
        mock_entry2 = Mock()
        mock_entry.chall = c2
        mock_authz.body.resolved_combinations.append(mock_entry2)

        # a pending status, mixed with valid
        result, hostname_still_validatd = yield self.acme.get_dns_challenges(
            host2, [mock_authz, mock_authz2])
        self.assertEqual(result, mock_entry)
        self.assertFalse(hostname_still_validatd)
Пример #2
0
    def test_create_certificate_missing_http_challenge(
            self,
            mock_authorization_service,
            mock_request_certificate,
            mock_destination_service,
            mock_plugin_manager_get,
            mock_acme,
    ):
        provider = plugin.ACMEHttpIssuerPlugin()
        mock_authority = Mock()
        mock_authority.options = '[{"name": "tokenDestination", "value": "mock-sftp-destination"}]'

        mock_order_resource = Mock()
        mock_order_resource.authorizations = [Mock()]
        mock_order_resource.authorizations[0].body.challenges = [Mock()]
        mock_order_resource.authorizations[0].body.challenges[0].chall = challenges.DNS01(
            token=b'\x0f\x1c\xbe#od\xd1\x9c\xa6j\\\xa4\r\xed\xe5\xbf0pz\xeaxnl)\xea[i\xbc\x95\x08\x96\x1f')

        mock_client = Mock()
        mock_client.new_order.return_value = mock_order_resource
        mock_acme.return_value = (mock_client, "")

        issuer_options = {
            "authority": mock_authority,
            "tokenDestination": "mock-sftp-destination",
            "common_name": "test.netflix.net",
        }
        csr = "123"
        mock_request_certificate.return_value = ("pem_certificate", "chain")
        with self.assertRaisesRegex(Exception, "HTTP-01 challenge was not offered"):
            provider.create_certificate(csr, issuer_options)
Пример #3
0
    def finalize_authorizations(self, acme_client, authorizations):
        for authz_record in authorizations:
            self.complete_dns_challenge(acme_client, authz_record)
        for authz_record in authorizations:
            dns_challenges = authz_record.dns_challenge
            for dns_challenge in dns_challenges:
                dns_providers = self.dns_providers_for_domain.get(
                    authz_record.target_domain)
                for dns_provider in dns_providers:
                    # Grab account number (For Route53)
                    dns_provider_plugin = self.get_dns_provider(
                        dns_provider.provider_type)
                    dns_provider_options = json.loads(dns_provider.credentials)
                    account_number = dns_provider_options.get("account_id")
                    host_to_validate, _ = self.strip_wildcard(
                        authz_record.target_domain)
                    host_to_validate = self.maybe_add_extension(
                        host_to_validate, dns_provider_options)
                    if not authz_record.cname_delegation:
                        host_to_validate = challenges.DNS01(
                        ).validation_domain_name(host_to_validate)
                    dns_provider_plugin.delete_txt_record(
                        authz_record.change_id,
                        account_number,
                        host_to_validate,
                        dns_challenge.validation(acme_client.client.net.key),
                    )

        return authorizations
Пример #4
0
    def test_start_dns_challenge(
        self, mock_find_dns_challenge, mock_len, mock_app, mock_acme
    ):
        assert mock_len
        mock_order = Mock()
        mock_app.logger.debug = Mock()
        mock_authz = Mock()
        mock_authz.body.resolved_combinations = []
        mock_entry = MagicMock()
        from acme import challenges

        c = challenges.DNS01()
        mock_entry.chall = TestAcme.test_complete_dns_challenge_fail
        mock_authz.body.resolved_combinations.append(mock_entry)
        mock_acme.request_domain_challenges = Mock(return_value=mock_authz)
        mock_dns_provider = Mock()
        mock_dns_provider.create_txt_record = Mock(return_value=1)

        values = [mock_entry]
        iterable = mock_find_dns_challenge.return_value
        iterator = iter(values)
        iterable.__iter__.return_value = iterator
        result = self.acme.start_dns_challenge(
            mock_acme, "accountid", "host", mock_dns_provider, mock_order, {}
        )
        self.assertEqual(type(result), plugin.AuthorizationRecord)
Пример #5
0
    def test_find_dns_challenge(self, mock_len):
        assert mock_len

        from acme import challenges
        c = challenges.DNS01()

        mock_authz = Mock()
        mock_authz.body.resolved_combinations = []
        mock_entry = Mock()
        mock_entry.chall = c
        mock_authz.body.resolved_combinations.append(mock_entry)
        result = yield plugin.find_dns_challenge(mock_authz)
        self.assertEqual(result, mock_entry)
Пример #6
0
    def test_get_dns_challenges(self, mock_len):
        assert mock_len

        from acme import challenges

        host = "example.com"
        c = challenges.DNS01()

        mock_authz = Mock()
        mock_authz.body.resolved_combinations = []
        mock_entry = Mock()
        mock_entry.chall = c
        mock_authz.body.resolved_combinations.append(mock_entry)
        result = yield self.acme.get_dns_challenges(host, mock_authz)
        self.assertEqual(result, mock_entry)
Пример #7
0
    def get_authorizations(self, acme_client, order, order_info):
        """ The list can be empty if all hostname validations are still valid"""
        authorizations = []

        for domain in order_info.domains:

            # If CNAME exists, set host to the target address
            target_domain = domain
            if current_app.config.get("ACME_ENABLE_DELEGATED_CNAME", False):
                cname_result, _ = self.strip_wildcard(domain)
                cname_result = challenges.DNS01().validation_domain_name(
                    cname_result)
                cname_result = self.get_cname(cname_result)
                if cname_result:
                    target_domain = cname_result
                    self.autodetect_dns_providers(target_domain)
                    metrics.send(
                        "get_authorizations_cname_delegation_for_domain",
                        "counter",
                        1,
                        metric_tags={"domain": domain})

            if not self.dns_providers_for_domain.get(target_domain):
                metrics.send("get_authorizations_no_dns_provider_for_domain",
                             "counter", 1)
                raise Exception("No DNS providers found for domain: {}".format(
                    target_domain))

            for dns_provider in self.dns_providers_for_domain[target_domain]:
                dns_provider_plugin = self.get_dns_provider(
                    dns_provider.provider_type)
                dns_provider_options = json.loads(dns_provider.credentials)
                account_number = dns_provider_options.get("account_id")
                authz_record = self.start_dns_challenge(
                    acme_client,
                    account_number,
                    domain,
                    target_domain,
                    dns_provider_plugin,
                    order,
                    dns_provider.options,
                )
                # it can be null, if hostname is still valid
                if authz_record:
                    authorizations.append(authz_record)
        return authorizations
Пример #8
0
    def test_get_dns_challenges_already_valid(self, mock_len):
        assert mock_len

        from acme import challenges

        host = "example.com"
        c = challenges.DNS01()

        mock_authz = MagicMock()
        mock_authz.body = STATUS_VALID
        mock_authz.body.resolved_combinations = []
        mock_entry = Mock()
        mock_entry.chall = c
        mock_authz.body.resolved_combinations.append(mock_entry)
        result, hostname_still_validatd = yield self.acme.get_dns_challenges(
            host, mock_authz)
        self.assertEqual(result, mock_entry)
        self.assertTrue(hostname_still_validatd)
Пример #9
0
from typing import Tuple

import josepy as jose

from acme import challenges
from acme import messages
from certbot._internal import auth_handler
from certbot.tests import util

JWK = jose.JWK.load(util.load_vector('rsa512_key.pem'))
KEY = util.load_rsa_private_key('rsa512_key.pem')

# Challenges
HTTP01 = challenges.HTTP01(
    token=b"evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ+PCt92wr+oA")
DNS01 = challenges.DNS01(token=b"17817c66b60ce2e4012dfad92657527a")
DNS01_2 = challenges.DNS01(token=b"cafecafecafecafecafecafe0feedbac")

CHALLENGES = [HTTP01, DNS01]


def gen_combos(challbs: Iterable[messages.ChallengeBody]) -> Tuple[Tuple[int], ...]:
    """Generate natural combinations for challbs."""
    # completing a single DV challenge satisfies the CA
    return tuple((i,) for i, _ in enumerate(challbs))


def chall_to_challb(chall: challenges.Challenge, status: messages.Status) -> messages.ChallengeBody:
    """Return ChallengeBody from Challenge."""
    kwargs = {
        "chall": chall,
Пример #10
0
def wildcard_request(cn, account):
    def dns_check_ns1():
        recieved_data_dup = []
        recieved_data = []

        ns1_resolver = dns.resolver.Resolver()
        #ns1_resolver.nameservers = ['130.193.8.82','2a03:b780::1:1']
        ns1_resolver.nameservers = ['173.245.58.51']

        for data in validation_data:
            domainname = data[1]
            #challenge = data[0]
            answers = ns1_resolver.query(domainname, 'txt')
            for rdata in answers:
                recieved_data_dup.append(
                    [str(rdata).replace('"', ''), domainname])

        #Deduplication of ns records (in case of more cnames)
        for i in recieved_data_dup:
            if i not in recieved_data:
                recieved_data.append(i)

        # print sorted(recieved_data)
        # print sorted(validation_data)
        if sorted(validation_data) == sorted(recieved_data):
            return True
        else:
            return False

    #Check if CN is valid domain
    domain_regex = re.compile(
        "^([a-zA-Z0-9]([\-a-zA-Z0-9]{0,61}[a-zA-Z0-9])?\.)*([a-zA-Z0-9]([\-a-zA-Z0-9]{0,61}[a-zA-Z0-9])+\.)([a-zA-Z0-9]+([\-a-zA-Z0-9]{0,61}[a-zA-Z])+)$"
    )
    if not domain_regex.match(cn):
        print 'First argument is not valid CN'
        sys.exit(1)

    #Check if registrar exists
    if account not in os.listdir(REG_DIRECTORY):
        print "This account does not exists, register it first with new_account.py"
        sys.exit(1)

    #Load files from disk
    with open(REG_DIRECTORY + "/" + account + "/private.key",
              "rb") as key_file:
        privkey = serialization.load_pem_private_key(key_file.read(),
                                                     password=None,
                                                     backend=default_backend())
    with open(REG_DIRECTORY + "/" + account + "/reguri.txt",
              "r") as reguri_file:
        reg_uri = reguri_file.read()

    #Compose regr
    key = jose.JWKRSA(key=privkey)
    regr = messages.RegistrationResource(
        body=messages.Registration(key=key.public_key()), uri=reg_uri)

    #Init ACME
    net = ClientNetwork(key)
    directory = net.get(DIRECTORY_URL).json()

    acme = client.ClientV2(directory, net)

    #Check if registration is valid
    if acme.query_registration(regr).body.status == u'valid':
        print "Registration valid"
    else:
        print "Registration invalid"
        sys.exit(1)

    #Generate private key for certificate
    pkey = OpenSSL.crypto.PKey()
    pkey.generate_key(OpenSSL.crypto.TYPE_RSA, BITS)

    #Serialize key for output
    pkey_printable = OpenSSL.crypto.dump_privatekey(
        OpenSSL.crypto.FILETYPE_PEM, pkey, cipher=None, passphrase=None)

    #Compose request for acme
    req = crypto_util.make_csr(
        OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, pkey),
        [cn, '*.' + cn])

    #begin order
    orderr = acme.new_order(req)

    validation_data = []

    for authr in orderr.authorizations:
        for chalr in authr.body.challenges:
            if type(chalr.chall) == type(challenges.DNS01()):
                validation_data.append([
                    str(chalr.chall.validation(key)),
                    chalr.chall.validation_domain_name(cn)
                ])
    #print validation_data
    #Now, call DNS writing function to apply challenges
    dns_apply(cn, validation_data)

    #Check if DNS is valid on our server
    sys.stdin.readline()  #DEBUG: wait for manual DNS input
    limiter = 2
    while not dns_check_ns1():
        if limiter != 0:
            print "DNS records are not correct, trying again in few seconds"
            limiter = limiter - 1
            time.sleep(5)
        else:
            print "DNS are not correct even after several tries. Aborting"
            sys.exit(1)

    for authr in orderr.authorizations:
        for chalr in authr.body.challenges:
            if type(chalr.chall) == type(challenges.DNS01()):
                try:
                    acme.answer_challenge(chalr, challenges.DNS01Response())
                except:
                    print chalr.chall.encode(
                        'token'
                    ) + " already answered (challenge failed, you have to generate new one)"

    #After filling DNS and waiting for propagation, finalize order
    try:
        res = acme.poll_and_finalize(orderr)
    finally:
        dns_remove(cn)
    #logging.info(res)

    cert = x509.load_pem_x509_certificate(str(res.fullchain_pem),
                                          default_backend())

    output_data = {
        'wildcard': {
            'cn': cn,
            'private_key': str(pkey_printable),
            'certificate': str(res.fullchain_pem),
            'expiration': cert.not_valid_after.strftime(
                "%x %X"
            )  #Locale-specific time+date representation. Edit to your need
        }
    }

    print json.dumps(output_data)
Пример #11
0
from acme import challenges
from acme import jose
from acme import messages

from certbot.tests import util


KEY = util.load_rsa_private_key('rsa512_key.pem')

# Challenges
HTTP01 = challenges.HTTP01(
    token=b"evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ+PCt92wr+oA")
TLSSNI01 = challenges.TLSSNI01(
    token=jose.b64decode(b"evaGxfADs6pSRb2LAv9IZf17Dt3juxGJyPCt92wrDoA"))
DNS01 = challenges.DNS01(token=b"17817c66b60ce2e4012dfad92657527a")

CHALLENGES = [HTTP01, TLSSNI01, DNS01]


def gen_combos(challbs):
    """Generate natural combinations for challbs."""
    # completing a single DV challenge satisfies the CA
    return tuple((i,) for i, _ in enumerate(challbs))


def chall_to_challb(chall, status):  # pylint: disable=redefined-outer-name
    """Return ChallengeBody from Challenge."""
    kwargs = {
        "chall": chall,
        "uri": chall.typ + "_uri",