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)
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)
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
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)
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)
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)
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
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)
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,
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)
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",