mirror of
https://github.com/certbot/certbot.git
synced 2026-06-03 22:08:07 -04:00
- Lint fixes
- Add test for multiple TXT records returned - Add extra parameter in DNS01.validation to select hexdigit vs. bas64 encoded validation
This commit is contained in:
parent
55ca1b484f
commit
ffc2b1ee78
2 changed files with 40 additions and 19 deletions
|
|
@ -242,17 +242,15 @@ class DNS01Response(KeyAuthorizationChallengeResponse):
|
|||
logger.debug("Verification of key authorization in response failed")
|
||||
return False
|
||||
|
||||
validation_name = chall.validation_domain_name(domain)
|
||||
validation_domain_name = chall.validation_domain_name(domain)
|
||||
validation = chall.validation(account_public_key)
|
||||
logger.debug("Verifying %s at %s...", chall.typ, validation_name)
|
||||
txt_records = []
|
||||
logger.debug("Verifying %s at %s...", chall.typ, validation_domain_name)
|
||||
try:
|
||||
dns_response = dns.resolver.query(validation_name, 'TXT')
|
||||
for rdata in dns_response:
|
||||
for txt_record in rdata.strings:
|
||||
txt_records.append(txt_record)
|
||||
dns_response = dns.resolver.query(validation_domain_name, 'TXT')
|
||||
txt_records = sum([rdata.strings for rdata in dns_response], [])
|
||||
except dns.exception.DNSException as error:
|
||||
logger.error("Unable to resolve %s: %s", validation_name, error)
|
||||
logger.error("Unable to resolve %s: %s", validation_domain_name,
|
||||
error)
|
||||
return False
|
||||
|
||||
for txt_record in txt_records:
|
||||
|
|
@ -273,7 +271,8 @@ class DNS01(KeyAuthorizationChallenge):
|
|||
LABEL = "_acme-challenge"
|
||||
"""Label clients prepend to the domain name being validated."""
|
||||
|
||||
def validation(self, account_key, **unused_kwargs):
|
||||
# FIXME: Remove extra parameter once #2052 is integrated
|
||||
def validation(self, account_key, dns01_hexdigit_response=True, **unused_kwargs):
|
||||
"""Generate validation.
|
||||
|
||||
:param JWK account_key:
|
||||
|
|
@ -281,9 +280,9 @@ class DNS01(KeyAuthorizationChallenge):
|
|||
|
||||
"""
|
||||
key_authorization = self.key_authorization(account_key)
|
||||
# FIXME Once boulder response according to the spec this needs to be fixed
|
||||
# return base64.b64encode(hashlib.sha256(key_authorization).digest())
|
||||
return hashlib.sha256(key_authorization).hexdigest()
|
||||
if dns01_hexdigit_response:
|
||||
return hashlib.sha256(key_authorization).hexdigest()
|
||||
return base64.urlsafe_b64encode(hashlib.sha256(key_authorization).digest())
|
||||
|
||||
def validation_domain_name(self, name):
|
||||
"""Domain name for TXT validation record.
|
||||
|
|
|
|||
|
|
@ -93,10 +93,15 @@ class DNS01ResponseTest(unittest.TestCase):
|
|||
self.chall = DNS01(token=(b'x' * 16))
|
||||
self.response = self.chall.response(KEY)
|
||||
|
||||
# This takes advantage of the fact that an answer object mostly behaves like
|
||||
# an RRset
|
||||
def create_txt_response(self, name, txt_record):
|
||||
return dns.rrset.from_text(name, 60, "IN", "TXT", txt_record)
|
||||
def create_txt_response(self, name, txt_records):
|
||||
"""
|
||||
Returns an RRSet containing the 'txt_records' as the result of a DNS
|
||||
query for 'name'.
|
||||
|
||||
This takes advantage of the fact that an Answer object mostly behaves
|
||||
like an RRset.
|
||||
"""
|
||||
return dns.rrset.from_text_list(name, 60, "IN", "TXT", txt_records)
|
||||
|
||||
def test_to_partial_json(self):
|
||||
self.assertEqual(self.jmsg, self.msg.to_partial_json())
|
||||
|
|
@ -118,7 +123,17 @@ class DNS01ResponseTest(unittest.TestCase):
|
|||
def test_simple_verify_good_validation(self, mock_dns):
|
||||
mock_dns.return_value = self.create_txt_response(
|
||||
self.chall.validation_domain_name("local"),
|
||||
self.chall.validation(KEY.public_key()))
|
||||
[self.chall.validation(KEY.public_key())])
|
||||
self.assertTrue(self.response.simple_verify(
|
||||
self.chall, "local", KEY.public_key()))
|
||||
mock_dns.assert_called_once_with(
|
||||
self.chall.validation_domain_name("local"), "TXT")
|
||||
|
||||
@mock.patch("acme.challenges.dns.resolver.query")
|
||||
def test_simple_verify_good_validation_multiple_txts(self, mock_dns):
|
||||
mock_dns.return_value = self.create_txt_response(
|
||||
self.chall.validation_domain_name("local"),
|
||||
["!", self.chall.validation(KEY.public_key())])
|
||||
self.assertTrue(self.response.simple_verify(
|
||||
self.chall, "local", KEY.public_key()))
|
||||
mock_dns.assert_called_once_with(
|
||||
|
|
@ -127,7 +142,7 @@ class DNS01ResponseTest(unittest.TestCase):
|
|||
@mock.patch("acme.challenges.dns.resolver.query")
|
||||
def test_simple_verify_bad_validation(self, mock_dns):
|
||||
mock_dns.return_value = self.create_txt_response(
|
||||
self.chall.validation_domain_name("local"), "!")
|
||||
self.chall.validation_domain_name("local"), ["!"])
|
||||
self.assertFalse(self.response.simple_verify(
|
||||
self.chall, "local", KEY.public_key()))
|
||||
|
||||
|
|
@ -153,10 +168,17 @@ class DNS01Test(unittest.TestCase):
|
|||
self.assertEqual('_acme-challenge.www.example.com',
|
||||
self.msg.validation_domain_name('www.example.com'))
|
||||
|
||||
# FIXME: Remove extra parameter once #2052 is integrated
|
||||
def test_validation(self):
|
||||
self.assertEqual(
|
||||
"rAa7iIg4K2y63fvUhCfy8dP1Xl7wEhmQq0oChTcE3Zk=",
|
||||
self.msg.validation(KEY, dns01_hexdigit_response=False))
|
||||
|
||||
# FIXME: Remove this once #2052 is integrated
|
||||
def test_validation_for_server_with_hexdigit_response(self):
|
||||
self.assertEqual(
|
||||
"ac06bb8888382b6cbaddfbd48427f2f1d3f55e5ef0121990ab4a02853704dd99",
|
||||
self.msg.validation(KEY))
|
||||
self.msg.validation(KEY, dns01_hexdigit_response=True))
|
||||
|
||||
def test_to_partial_json(self):
|
||||
self.assertEqual(self.jmsg, self.msg.to_partial_json())
|
||||
|
|
|
|||
Loading…
Reference in a new issue