mirror of
https://github.com/certbot/certbot.git
synced 2026-01-23 07:20:55 +03:00
Changed client to use new form of challenges
This commit is contained in:
@@ -55,5 +55,8 @@ CHALLENGE_PREFERENCES = ["dvsni", "recoveryToken"]
|
||||
# Mutually Exclusive Challenges - only solve 1
|
||||
EXCLUSIVE_CHALLENGES = [set(["dvsni", "simpleHttps"])]
|
||||
|
||||
# These are challenges that must be solved by a Configurator object
|
||||
CONFIG_CHALLENGES = {"dvsni", "simpleHttps"}
|
||||
|
||||
# Rewrite rule arguments used for redirections to https vhost
|
||||
REWRITE_HTTPS_ARGS = ["^.*$", "https://%{SERVER_NAME}%{REQUEST_URI}", "[L,R=permanent]"]
|
||||
|
||||
@@ -411,3 +411,11 @@ class AugeasConfigurator(Configurator):
|
||||
Restart or refresh the server content
|
||||
"""
|
||||
raise Exception("Error: augeas Configurator class")
|
||||
|
||||
def perform(self, challenge):
|
||||
""" Perform the challenge """
|
||||
raise Exception("Error: augeas Configurator class")
|
||||
|
||||
def cleanup(self):
|
||||
""" Clean up any challenge configurations """
|
||||
raise Exception("Error: augeas Configurator class")
|
||||
|
||||
@@ -15,8 +15,8 @@ from letsencrypt.client import logger, display
|
||||
from letsencrypt.client import le_util, crypto_util
|
||||
from letsencrypt.client.CONFIG import RSA_KEY_SIZE, CERT_PATH
|
||||
from letsencrypt.client.CONFIG import CHAIN_PATH, SERVER_ROOT, KEY_DIR, CERT_DIR
|
||||
from letsencrypt.client.CONFIG import CERT_KEY_BACKUP
|
||||
from letsencrypt.client.CONFIG import CHALLENGE_PREFERENCES, EXCLUSIVE_CHALLENGES
|
||||
from letsencrypt.client.CONFIG import CERT_KEY_BACKUP, EXCLUSIVE_CHALLENGES
|
||||
from letsencrypt.client.CONFIG import CHALLENGE_PREFERENCES, CONFIG_CHALLENGES
|
||||
# it's weird to point to chocolate servers via raw IPv6 addresses, and such
|
||||
# addresses can be %SCARY in some contexts, so out of paranoia let's disable
|
||||
# them by default
|
||||
@@ -309,7 +309,11 @@ class Client(object):
|
||||
def cleanup_challenges(self, challenge_objs):
|
||||
logger.info("Cleaning up challenges...")
|
||||
for c in challenge_objs:
|
||||
c.cleanup()
|
||||
if c["type"] in CONFIG_CHALLENGES:
|
||||
self.config.cleanup()
|
||||
else:
|
||||
#Handle other cleanup if needed
|
||||
pass
|
||||
|
||||
def is_expected_msg(self, msg_dict, expected, delay=3, rounds = 20):
|
||||
for i in range(rounds):
|
||||
@@ -369,17 +373,20 @@ class Client(object):
|
||||
challenge_objs, indicies = self.challenge_factory(
|
||||
self.names[0], c["challenges"], path)
|
||||
|
||||
responses = ["null"] * len(c["challenges"])
|
||||
|
||||
responses = [None] * len(c["challenges"])
|
||||
# Perform challenges
|
||||
for i, c_obj in challenge_objs:
|
||||
response = "null"
|
||||
if c_obj["type"] in CONFIG_CHALLENGES:
|
||||
response = self.config.perform(c_obj)
|
||||
else:
|
||||
# Handle RecoveryToken type challenges
|
||||
pass
|
||||
|
||||
# Perform challenges and populate responses
|
||||
for i, c_obj in enumerate(challenge_objs):
|
||||
if not c_obj.perform():
|
||||
logger.fatal("Challenge Failed")
|
||||
sys.exit(1)
|
||||
for index in indicies[i]:
|
||||
responses[index] = c_obj.generate_response()
|
||||
|
||||
responses[index] = response
|
||||
|
||||
logger.info("Configured Apache for challenges; " +
|
||||
"waiting for verification...")
|
||||
|
||||
@@ -389,7 +396,7 @@ class Client(object):
|
||||
"""
|
||||
Generate a plan to get authority over the identity
|
||||
TODO: Make sure that the challenges are feasible...
|
||||
TODO Example: Do you have the recovery key?
|
||||
Example: Do you have the recovery key?
|
||||
"""
|
||||
|
||||
if combos:
|
||||
@@ -546,7 +553,7 @@ class Client(object):
|
||||
elif challenges[c]["type"] == "recoveryToken":
|
||||
logger.info("\tRecovery Token Challenge for name: %s." % name)
|
||||
challenge_objs_indicies.append(c)
|
||||
challenge_objs.append(RecoveryToken())
|
||||
challenge_objs.append({type:"recoveryToken"})
|
||||
|
||||
else:
|
||||
logger.fatal("Challenge not currently supported")
|
||||
@@ -555,8 +562,8 @@ class Client(object):
|
||||
if sni_todo:
|
||||
# SNI_Challenge can satisfy many sni challenges at once so only
|
||||
# one "challenge object" is issued for all sni_challenges
|
||||
challenge_objs.append(SNI_Challenge(
|
||||
sni_todo, os.path.abspath(self.key_file), self.config))
|
||||
challenge_objs.append({"type":"dvsni", "listSNITuple":snitodo
|
||||
"dvsni_key":os.path.abspath(self.key_file)})
|
||||
challenge_obj_indicies.append(sni_satisfies)
|
||||
logger.debug(sni_todo)
|
||||
|
||||
@@ -622,33 +629,36 @@ class Client(object):
|
||||
|
||||
return selection
|
||||
|
||||
def get_cas(self):
|
||||
DV_choices = []
|
||||
OV_choices = []
|
||||
EV_choices = []
|
||||
choices = []
|
||||
try:
|
||||
with open("/etc/letsencrypt/.ca_offerings") as f:
|
||||
for line in f:
|
||||
choice = line.split(";", 1)
|
||||
if 'DV' in choice[0]:
|
||||
DV_choices.append(choice)
|
||||
elif 'OV' in choice[0]:
|
||||
OV_choices.append(choice)
|
||||
else:
|
||||
EV_choices.append(choice)
|
||||
# Legacy Code: Although I would like to see a free and open marketplace
|
||||
# in the future. The Let's Encrypt Client will not have this feature at
|
||||
# launch
|
||||
# def get_cas(self):
|
||||
# DV_choices = []
|
||||
# OV_choices = []
|
||||
# EV_choices = []
|
||||
# choices = []
|
||||
# try:
|
||||
# with open("/etc/letsencrypt/.ca_offerings") as f:
|
||||
# for line in f:
|
||||
# choice = line.split(";", 1)
|
||||
# if 'DV' in choice[0]:
|
||||
# DV_choices.append(choice)
|
||||
# elif 'OV' in choice[0]:
|
||||
# OV_choices.append(choice)
|
||||
# else:
|
||||
# EV_choices.append(choice)
|
||||
|
||||
# random.shuffle(DV_choices)
|
||||
# random.shuffle(OV_choices)
|
||||
# random.shuffle(EV_choices)
|
||||
choices = DV_choices + OV_choices + EV_choices
|
||||
choices = [(l[0], l[1]) for l in choices]
|
||||
# # random.shuffle(DV_choices)
|
||||
# # random.shuffle(OV_choices)
|
||||
# # random.shuffle(EV_choices)
|
||||
# choices = DV_choices + OV_choices + EV_choices
|
||||
# choices = [(l[0], l[1]) for l in choices]
|
||||
|
||||
except IOError as e:
|
||||
logger.fatal("Unable to find .ca_offerings file")
|
||||
sys.exit(1)
|
||||
# except IOError as e:
|
||||
# logger.fatal("Unable to find .ca_offerings file")
|
||||
# sys.exit(1)
|
||||
|
||||
return choices
|
||||
# return choices
|
||||
|
||||
def get_all_names(self):
|
||||
"""
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Note: abc requires python 2.6 so we may remove this before
|
||||
# launch. This should help in the creation of other configurators while
|
||||
# we develop though
|
||||
|
||||
import abc
|
||||
|
||||
class Configurator(object):
|
||||
@@ -115,3 +119,13 @@ class Configurator(object):
|
||||
Restart or refresh the server content
|
||||
"""
|
||||
return
|
||||
|
||||
@abc.abstractmethod
|
||||
def perform(self, chall_type, tup):
|
||||
""" Perform the given challenge"""
|
||||
return
|
||||
|
||||
@abc.abstractmethod
|
||||
def cleanup(self):
|
||||
""" Cleanup configuration changes from challenge """
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user