mirror of
https://github.com/certbot/certbot.git
synced 2026-01-23 07:20:55 +03:00
Adjust achallanges to be used with ChallengeBody
This commit is contained in:
@@ -1,17 +1,20 @@
|
||||
"""Client annotated ACME challenges.
|
||||
|
||||
Please use names such as ``achall`` to distiguish from variables "of type"
|
||||
:class:`letsencrypt.acme.challenges.Challenge` (denoted by ``chall``)::
|
||||
:class:`letsencrypt.acme.challenges.Challenge` (denoted by ``chall``)
|
||||
and :class:`.ChallengeBody` (denoted by ``challb``)::
|
||||
|
||||
from letsencrypt.acme import challenges
|
||||
from letsencrypt.acme import messages2
|
||||
from letsencrypt.client import achallenges
|
||||
|
||||
chall = challenges.DNS(token='foo')
|
||||
achall = achallenges.DNS(chall=chall, domain='example.com')
|
||||
challb = messages2.ChallengeBody(chall=chall)
|
||||
achall = achallenges.DNS(chall=challb, domain='example.com')
|
||||
|
||||
Note, that all annotated challenges act as a proxy objects::
|
||||
|
||||
achall.token == chall.token
|
||||
achall.token == challb.token
|
||||
|
||||
"""
|
||||
from letsencrypt.acme import challenges
|
||||
@@ -29,19 +32,19 @@ class AnnotatedChallenge(jose_util.ImmutableMap):
|
||||
Wraps around server provided challenge and annotates with data
|
||||
useful for the client.
|
||||
|
||||
:ivar chall: Wrapped `~.ChallengeBody` (or just `~.challenges.Challenge`).
|
||||
:ivar challb: Wrapped `~.ChallengeBody`.
|
||||
|
||||
"""
|
||||
__slots__ = ('chall',)
|
||||
__slots__ = ('challb',)
|
||||
acme_type = NotImplemented
|
||||
|
||||
def __getattr__(self, name):
|
||||
return getattr(self.chall, name)
|
||||
return getattr(self.challb, name)
|
||||
|
||||
|
||||
class DVSNI(AnnotatedChallenge):
|
||||
"""Client annotated "dvsni" ACME challenge."""
|
||||
__slots__ = ('chall', 'domain', 'key')
|
||||
__slots__ = ('challb', 'domain', 'key')
|
||||
acme_type = challenges.DVSNI
|
||||
|
||||
def gen_cert_and_response(self, s=None): # pylint: disable=invalid-name
|
||||
@@ -55,35 +58,35 @@ class DVSNI(AnnotatedChallenge):
|
||||
"""
|
||||
response = challenges.DVSNIResponse(s=s)
|
||||
cert_pem = crypto_util.make_ss_cert(self.key.pem, [
|
||||
self.nonce_domain, self.domain, response.z_domain(self.chall)])
|
||||
self.nonce_domain, self.domain, response.z_domain(self.challb)])
|
||||
return cert_pem, response
|
||||
|
||||
|
||||
class SimpleHTTPS(AnnotatedChallenge):
|
||||
"""Client annotated "simpleHttps" ACME challenge."""
|
||||
__slots__ = ('chall', 'domain', 'key')
|
||||
__slots__ = ('challb', 'domain', 'key')
|
||||
acme_type = challenges.SimpleHTTPS
|
||||
|
||||
|
||||
class DNS(AnnotatedChallenge):
|
||||
"""Client annotated "dns" ACME challenge."""
|
||||
__slots__ = ('chall', 'domain')
|
||||
__slots__ = ('challb', 'domain')
|
||||
acme_type = challenges.DNS
|
||||
|
||||
|
||||
class RecoveryContact(AnnotatedChallenge):
|
||||
"""Client annotated "recoveryContact" ACME challenge."""
|
||||
__slots__ = ('chall', 'domain')
|
||||
__slots__ = ('challb', 'domain')
|
||||
acme_type = challenges.RecoveryContact
|
||||
|
||||
|
||||
class RecoveryToken(AnnotatedChallenge):
|
||||
"""Client annotated "recoveryToken" ACME challenge."""
|
||||
__slots__ = ('chall', 'domain')
|
||||
__slots__ = ('challb', 'domain')
|
||||
acme_type = challenges.RecoveryToken
|
||||
|
||||
|
||||
class ProofOfPossession(AnnotatedChallenge):
|
||||
"""Client annotated "proofOfPossession" ACME challenge."""
|
||||
__slots__ = ('chall', 'domain')
|
||||
__slots__ = ('challb', 'domain')
|
||||
acme_type = challenges.ProofOfPossession
|
||||
|
||||
@@ -138,7 +138,7 @@ class AuthHandler(object): # pylint: disable=too-many-instance-attributes
|
||||
for achall, resp in itertools.izip(achalls, resps):
|
||||
# Don't send challenges for None and False authenticator responses
|
||||
if resp:
|
||||
challr = self.network.answer_challenge(achall.chall, resp)
|
||||
challr = self.network.answer_challenge(achall.challb, resp)
|
||||
if achall.domain in chall_update:
|
||||
chall_update[achall.domain].append(achall)
|
||||
else:
|
||||
@@ -267,31 +267,32 @@ class AuthHandler(object): # pylint: disable=too-many-instance-attributes
|
||||
cont_chall = set()
|
||||
|
||||
for index in path:
|
||||
chall = self.authzr[domain].body.challenges[index]
|
||||
challb = self.authzr[domain].body.challenges[index]
|
||||
chall = challb.chall
|
||||
|
||||
if isinstance(chall, challenges.DVSNI):
|
||||
logging.info(" DVSNI challenge for %s.", domain)
|
||||
achall = achallenges.DVSNI(
|
||||
chall=chall, domain=domain, key=self.authkey)
|
||||
challb=challb, domain=domain, key=self.authkey)
|
||||
elif isinstance(chall, challenges.SimpleHTTPS):
|
||||
logging.info(" SimpleHTTPS challenge for %s.", domain)
|
||||
achall = achallenges.SimpleHTTPS(
|
||||
chall=chall, domain=domain, key=self.authkey)
|
||||
challb=challb, domain=domain, key=self.authkey)
|
||||
elif isinstance(chall, challenges.DNS):
|
||||
logging.info(" DNS challenge for %s.", domain)
|
||||
achall = achallenges.DNS(chall=chall, domain=domain)
|
||||
achall = achallenges.DNS(challb=challb, domain=domain)
|
||||
|
||||
elif isinstance(chall, challenges.RecoveryToken):
|
||||
logging.info(" Recovery Token Challenge for %s.", domain)
|
||||
achall = achallenges.RecoveryToken(chall=chall, domain=domain)
|
||||
achall = achallenges.RecoveryToken(challb=challb, domain=domain)
|
||||
elif isinstance(chall, challenges.RecoveryContact):
|
||||
logging.info(" Recovery Contact Challenge for %s.", domain)
|
||||
achall = achallenges.RecoveryContact(
|
||||
chall=chall, domain=domain)
|
||||
challb=challb, domain=domain)
|
||||
elif isinstance(chall, challenges.ProofOfPossession):
|
||||
logging.info(" Proof-of-Possession Challenge for %s", domain)
|
||||
achall = achallenges.ProofOfPossession(
|
||||
chall=chall, domain=domain)
|
||||
challb=challb, domain=domain)
|
||||
|
||||
else:
|
||||
raise errors.LetsEncryptClientError(
|
||||
@@ -306,15 +307,15 @@ class AuthHandler(object): # pylint: disable=too-many-instance-attributes
|
||||
return dv_chall, cont_chall
|
||||
|
||||
|
||||
def gen_challenge_path(challs, preferences, combinations):
|
||||
def gen_challenge_path(challbs, preferences, combinations):
|
||||
"""Generate a plan to get authority over the identity.
|
||||
|
||||
.. todo:: This can be possibly be rewritten to use resolved_combinations.
|
||||
|
||||
:param tuple challs: A tuple of challenges
|
||||
(:class:`letsencrypt.acme.challenges.Challenge`) from
|
||||
:class:`letsencrypt.acme.messages.Challenge` server message to
|
||||
be fulfilled by the client in order to prove possession of the
|
||||
:param tuple challbs: A tuple of challenges
|
||||
(:class:`letsencrypt.acme.messages2.Challenge`) from
|
||||
:class:`letsencrypt.acme.messages2.AuthorizationResource` to be
|
||||
fulfilled by the client in order to prove possession of the
|
||||
identifier.
|
||||
|
||||
:param list preferences: List of challenge preferences for domain
|
||||
@@ -333,12 +334,12 @@ def gen_challenge_path(challs, preferences, combinations):
|
||||
|
||||
"""
|
||||
if combinations:
|
||||
return _find_smart_path(challs, preferences, combinations)
|
||||
return _find_smart_path(challbs, preferences, combinations)
|
||||
else:
|
||||
return _find_dumb_path(challs, preferences)
|
||||
return _find_dumb_path(challbs, preferences)
|
||||
|
||||
|
||||
def _find_smart_path(challs, preferences, combinations):
|
||||
def _find_smart_path(challbs, preferences, combinations):
|
||||
"""Find challenge path with server hints.
|
||||
|
||||
Can be called if combinations is included. Function uses a simple
|
||||
@@ -360,8 +361,8 @@ def _find_smart_path(challs, preferences, combinations):
|
||||
combo_total = 0
|
||||
for combo in combinations:
|
||||
for challenge_index in combo:
|
||||
combo_total += chall_cost.get(challs[
|
||||
challenge_index].__class__, max_cost)
|
||||
combo_total += chall_cost.get(challbs[
|
||||
challenge_index].chall.__class__, max_cost)
|
||||
|
||||
if combo_total < best_combo_cost:
|
||||
best_combo = combo
|
||||
@@ -378,7 +379,7 @@ def _find_smart_path(challs, preferences, combinations):
|
||||
return best_combo
|
||||
|
||||
|
||||
def _find_dumb_path(challs, preferences):
|
||||
def _find_dumb_path(challbs, preferences):
|
||||
"""Find challenge path without server hints.
|
||||
|
||||
Should be called if the combinations hint is not included by the
|
||||
@@ -391,11 +392,11 @@ def _find_dumb_path(challs, preferences):
|
||||
path = []
|
||||
satisfied = set()
|
||||
for pref_c in preferences:
|
||||
for i, offered_chall in enumerate(challs):
|
||||
if (isinstance(offered_chall, pref_c) and
|
||||
is_preferred(offered_chall, satisfied)):
|
||||
for i, offered_challb in enumerate(challbs):
|
||||
if (isinstance(offered_challb.chall, pref_c) and
|
||||
is_preferred(offered_challb, satisfied)):
|
||||
path.append(i)
|
||||
satisfied.add(offered_chall)
|
||||
satisfied.add(offered_challb)
|
||||
return path
|
||||
|
||||
|
||||
@@ -415,11 +416,12 @@ def mutually_exclusive(obj1, obj2, groups, different=False):
|
||||
return True
|
||||
|
||||
|
||||
def is_preferred(offered_chall, satisfied,
|
||||
def is_preferred(offered_challb, satisfied,
|
||||
exclusive_groups=constants.EXCLUSIVE_CHALLENGES):
|
||||
"""Return whether or not the challenge is preferred in path."""
|
||||
for chall in satisfied:
|
||||
for challb in satisfied:
|
||||
if not mutually_exclusive(
|
||||
offered_chall, chall, exclusive_groups, different=True):
|
||||
offered_challb.chall, challb.chall, exclusive_groups,
|
||||
different=True):
|
||||
return False
|
||||
return True
|
||||
|
||||
Reference in New Issue
Block a user