1
0
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:
James Kasten
2014-11-20 12:23:44 -08:00
parent d57dd9faee
commit bf393f78ab
4 changed files with 74 additions and 39 deletions

View File

@@ -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]"]

View File

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

View File

@@ -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):
"""

View File

@@ -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