def submit_domain_validation(client, regr, account, challenges_file, domain, log): # Get challenges for the domain. challg1 = get_challenges(client, regr, domain, challenges_file, log) challg = challg1.body if challg.status.name == "valid": # This is already valid. Return it immediately. return challg1 elif challg.status.name != "pending": raise ChallengesUnknownStatus() # Look for a challenge combination that we can fulfill. for combination in challg.combinations: if len(combination) == 1: chg = challg.challenges[combination[0]] if isinstance(chg.chall, acme.challenges.SimpleHTTP): if chg.status.name != "pending": # We can't submit twice. If this challenge is still pending # but the overall challg object is not valid, then I'm not # sure how to proceed. raise ChallengesUnknownStatus() # Submit the SimpleHTTP challenge, raising NeedToInstallFile if # the conditions are not yet met. chg = answer_challenge_simplehttp( domain, chg.chall, client, account, chg, log) # The ChallengeResource probably comes back still pending because # it doesn't go THAT fast. Give it a moment, then poll. time.sleep(1) challg1, resp = client.poll(challg1) if challg1.body.status.name == "valid": # It's valid now. That was fast. return challg1 # It's not valid. Tell the user they must want. retry_after = client.retry_after(resp, default=60) raise WaitABit(retry_after) raise NoChallengeMethodsSupported()
def submit_domain_validation(client, regr, account, challenges_file, domain, validation_method, log): # Get challenges for the domain. challg1, resp = get_challenges(client, regr, domain, challenges_file, log) challg = challg1.body # If this challenge was just issued, we may not have a resp object yet # but may still need to raise a WaitABit exception. if resp: wait_until = client.retry_after(resp, default=60) else: wait_until = datetime.datetime.now() + datetime.timedelta(seconds=15) # The authorization object as a whole has a status. if challg.status.name == "valid": # This is already valid. Return it immediately. log("The challenges for %s have been accepted." % domain) return challg1 elif challg.status.name == "invalid": # Challenge was rejected. The ACME server requested the # HTTP validation resource but got a 404, for instance. message = '; '.join(c.error.detail for c in challg.challenges if c.status.name == "invalid") log("The %s challenge for %s failed: %s." % (validation_method, domain, message)) raise ChallengeFailed(validation_method, domain, message, challg1.uri) elif challg.status.name not in ("pending", "processing"): # We can only respond to a challenge when its status is # pending. What do we do in the remaining case of "unknown" # status? ("revoked" is filtered out by get_challenges --- # we just request a new challenge in that case.) raise ChallengesUnknownStatus(challg.status.name) # Look for a challenge combination that we can fulfill. for combination in challg.combinations: if len(combination) == 1: chg = challg.challenges[combination[0]] if isinstance(chg.chall, acme.challenges.HTTP01) and isinstance( validation_method, HTTPValidation): # The particular challenge within the big authorization object also # has a status. I'm not sure what the rules are for when the # statuses can be different. if chg.status.name == "processing": # The challenge has been submitted and we must wait before proceeding, # which is the next step after the for loop. break elif chg.status.name == "valid": # Looks like we already answered this challenge correctly. # But the overall authorization object is not yet valid, # so instruct the user to wait? That's the next step after # the for loop. break elif chg.status.name != "pending": # We can only respond to a challenge when its status is # pending. What do we do in the remaining cases? # Other statuses are "unknown", "invalid" and "revoked". raise ChallengesUnknownStatus(chg.status.name) # Submit the HTTP validation challenge, raising NeedToInstallFile if # the conditions are not yet met. chg = answer_challenge_http(domain, chg.chall, validation_method, client, account, chg, log) # We found a challenge combination we can submit for, # and we submitted it. The ChallengeResource probably # comes back still pending because it doesn't go THAT # fast. The next step after the for loop is to wait. break else: # We were unable to handle any challenge combination. raise NoChallengeMethodsSupported( "No supported challenge methods were offered for %s." % domain) # On success, or in other cases, wait. raise WaitABit(wait_until)
def submit_domain_validation(client, regr, account, challenges_file, domain, validation_method, log): # Get challenges for the domain. challg1, resp = get_challenges(client, regr, domain, challenges_file, log) challg = challg1.body # If this challenge was just issued, we may not have a resp object yet # but may still need to raise a WaitABit exception. if resp: wait_until = client.retry_after(resp, default=60) else: wait_until = datetime.datetime.now() + datetime.timedelta(seconds=15) # The authorization object as a whole has a status. if challg.status.name == "valid": # This is already valid. Return it immediately. log("The challenges for %s have been accepted." % domain) return challg1 elif challg.status.name == "invalid": # Challenge was rejected. The ACME server requested the # HTTP validation resource but got a 404, for instance. message = '; '.join(c.error.detail for c in challg.challenges if c.status.name == "invalid") log("The %s challenge for %s failed: %s." % (validation_method, domain, message)) raise ChallengeFailed(validation_method, domain, message, challg1.uri) elif challg.status.name not in ("pending", "processing"): # We can only respond to a challenge when its status is # pending. What do we do in the remaining case of "unknown" # status? ("revoked" is filtered out by get_challenges --- # we just request a new challenge in that case.) raise ChallengesUnknownStatus(challg.status.name) # Look for a challenge combination that we can fulfill. for combination in challg.combinations: if len(combination) == 1: chg = challg.challenges[combination[0]] if isinstance(chg.chall, acme.challenges.HTTP01) and isinstance(validation_method, HTTPValidation): # The particular challenge within the big authorization object also # has a status. I'm not sure what the rules are for when the # statuses can be different. if chg.status.name == "processing": # The challenge has been submitted and we must wait before proceeding, # which is the next step after the for loop. break elif chg.status.name == "valid": # Looks like we already answered this challenge correctly. # But the overall authorization object is not yet valid, # so instruct the user to wait? That's the next step after # the for loop. break elif chg.status.name != "pending": # We can only respond to a challenge when its status is # pending. What do we do in the remaining cases? # Other statuses are "unknown", "invalid" and "revoked". raise ChallengesUnknownStatus(chg.status.name) # Submit the HTTP validation challenge, raising NeedToInstallFile if # the conditions are not yet met. chg = answer_challenge_http( domain, chg.chall, validation_method, client, account, chg, log) # We found a challenge combination we can submit for, # and we submitted it. The ChallengeResource probably # comes back still pending because it doesn't go THAT # fast. The next step after the for loop is to wait. break else: # We were unable to handle any challenge combination. raise NoChallengeMethodsSupported("No supported challenge methods were offered for %s." % domain) # On success, or in other cases, wait. raise WaitABit(wait_until)