mirror of
https://github.com/certbot/certbot.git
synced 2026-08-03 00:22:04 +02:00
Use DVSNI_Chall namedtuple
This commit is contained in:
@@ -949,12 +949,14 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||||||
|
|
||||||
`chall_dict` composed of:
|
`chall_dict` composed of:
|
||||||
|
|
||||||
list_sni_tuple:
|
`type`: `dvsni` (`str`)
|
||||||
List of tuples with form `(name, r, nonce)`, where
|
|
||||||
`name` (`str`), `r` (base64 `str`), `nonce` (hex `str`)
|
|
||||||
|
|
||||||
dvsni_key:
|
`dvsni_chall`:
|
||||||
DVSNI key (:class:`letsencrypt.client.client.Client.Key`)
|
List of DVSNI_Chall namedtuples
|
||||||
|
(:class:`letsencrypt.client.client.Client.DVSNI_Chall`)
|
||||||
|
where DVSNI_Chall tuples have the following fields
|
||||||
|
`domain` (`str`), `r_b64` (base64 `str`), `nonce` (hex `str`)
|
||||||
|
`key` (:class:`letsencrypt.client.client.Client.Key`)
|
||||||
|
|
||||||
:param dict chall_dict: dvsni challenge - see documentation
|
:param dict chall_dict: dvsni challenge - see documentation
|
||||||
|
|
||||||
@@ -964,18 +966,19 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
# Do weak validation that challenge is of expected type
|
# Do weak validation that challenge is of expected type
|
||||||
if not ("list_sni_tuple" in chall_dict and "dvsni_key" in chall_dict):
|
if "dvsni_chall" not in chall_dict:
|
||||||
logging.fatal("Incorrect parameter given to Apache DVSNI challenge")
|
logging.fatal("Incorrect parameter given to Apache DVSNI challenge")
|
||||||
logging.fatal("Chall dict: %s", chall_dict)
|
logging.fatal("Chall dict: %s", chall_dict)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
addresses = []
|
addresses = []
|
||||||
default_addr = "*:443"
|
default_addr = "*:443"
|
||||||
for tup in chall_dict["list_sni_tuple"]:
|
for chall in chall_dict["dvsni_chall"]:
|
||||||
vhost = self.choose_virtual_host(tup[0])
|
vhost = self.choose_virtual_host(chall.domain)
|
||||||
if vhost is None:
|
if vhost is None:
|
||||||
logging.error(
|
logging.error(
|
||||||
"No vhost exists with servername or alias of: %s", tup[0])
|
"No vhost exists with servername or alias of: %s",
|
||||||
|
chall.domain)
|
||||||
logging.error("No _default_:443 vhost exists")
|
logging.error("No _default_:443 vhost exists")
|
||||||
logging.error("Please specify servernames in the Apache config")
|
logging.error("Please specify servernames in the Apache config")
|
||||||
return None
|
return None
|
||||||
@@ -993,18 +996,16 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||||||
responses = []
|
responses = []
|
||||||
|
|
||||||
# Create all of the challenge certs
|
# Create all of the challenge certs
|
||||||
for tup in chall_dict["list_sni_tuple"]:
|
for chall in chall_dict["dvsni_chall"]:
|
||||||
cert_path = self.dvsni_get_cert_file(tup[2])
|
cert_path = self.dvsni_get_cert_file(chall.nonce)
|
||||||
self.register_file_creation(cert_path)
|
self.register_file_creation(cert_path)
|
||||||
s_b64 = challenge_util.dvsni_gen_cert(
|
s_b64 = challenge_util.dvsni_gen_cert(
|
||||||
cert_path, tup[0], tup[1], tup[2], chall_dict["dvsni_key"])
|
cert_path, chall.domain, chall.r_b64, chall.nonce, chall.key)
|
||||||
|
|
||||||
responses.append({"type": "dvsni", "s": s_b64})
|
responses.append({"type": "dvsni", "s": s_b64})
|
||||||
|
|
||||||
# Setup the configuration
|
# Setup the configuration
|
||||||
self.dvsni_mod_config(chall_dict["list_sni_tuple"],
|
self.dvsni_mod_config(chall_dict["dvsni_chall"], addresses)
|
||||||
chall_dict["dvsni_key"],
|
|
||||||
addresses)
|
|
||||||
|
|
||||||
# Save reversible changes and restart the server
|
# Save reversible changes and restart the server
|
||||||
self.save("SNI Challenge", True)
|
self.save("SNI Challenge", True)
|
||||||
@@ -1019,18 +1020,13 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||||||
self.restart()
|
self.restart()
|
||||||
|
|
||||||
# TODO: Variable names
|
# TODO: Variable names
|
||||||
def dvsni_mod_config(self, list_sni_tuple, dvsni_key,
|
def dvsni_mod_config(self, dvsni_chall, ll_addrs):
|
||||||
ll_addrs):
|
|
||||||
"""Modifies Apache config files to include challenge vhosts.
|
"""Modifies Apache config files to include challenge vhosts.
|
||||||
|
|
||||||
Result: Apache config includes virtual servers for issued challs
|
Result: Apache config includes virtual servers for issued challs
|
||||||
|
|
||||||
:param list list_sni_tuple: list of tuples with the form
|
:param list dvsni_chall: list of
|
||||||
`(addr, y, nonce)`, where `addr` is `str`, `y` is `bytearray`,
|
:class:`letsencrypt.client.client.Client.DVSNI_Chall`
|
||||||
and nonce is hex `str`
|
|
||||||
|
|
||||||
:param dvsni_key: DVSNI key
|
|
||||||
:type dvsni_key: :class:`letsencrypt.client.client.Client.Key`
|
|
||||||
|
|
||||||
:param list ll_addrs: list of list of
|
:param list ll_addrs: list of list of
|
||||||
:class:`letsencrypt.client.apache.obj.Addr` to apply
|
:class:`letsencrypt.client.apache.obj.Addr` to apply
|
||||||
@@ -1052,7 +1048,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||||||
config_text = "<IfModule mod_ssl.c>\n"
|
config_text = "<IfModule mod_ssl.c>\n"
|
||||||
for idx, lis in enumerate(ll_addrs):
|
for idx, lis in enumerate(ll_addrs):
|
||||||
config_text += self.get_config_text(
|
config_text += self.get_config_text(
|
||||||
list_sni_tuple[idx][2], lis, dvsni_key.file)
|
dvsni_chall[idx].nonce, lis, dvsni_chall[idx].key.file)
|
||||||
config_text += "</IfModule>\n"
|
config_text += "</IfModule>\n"
|
||||||
|
|
||||||
self.dvsni_conf_include_check(self.parser.loc["default"])
|
self.dvsni_conf_include_check(self.parser.loc["default"])
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ class Client(object):
|
|||||||
"""
|
"""
|
||||||
Key = collections.namedtuple("Key", "file pem")
|
Key = collections.namedtuple("Key", "file pem")
|
||||||
CSR = collections.namedtuple("CSR", "file data form")
|
CSR = collections.namedtuple("CSR", "file data form")
|
||||||
|
DVSNI_Chall = collections.namedtuple("DVSNI_Chall", "domain, r_b64, nonce, key")
|
||||||
|
|
||||||
def __init__(self, server, names, authkey, auth, installer):
|
def __init__(self, server, names, authkey, auth, installer):
|
||||||
"""Initialize a client."""
|
"""Initialize a client."""
|
||||||
@@ -419,8 +420,9 @@ class Client(object):
|
|||||||
if chall["type"] == "dvsni":
|
if chall["type"] == "dvsni":
|
||||||
logging.info(" DVSNI challenge for name %s.", name)
|
logging.info(" DVSNI challenge for name %s.", name)
|
||||||
sni_satisfies.append(index)
|
sni_satisfies.append(index)
|
||||||
sni_todo.append((str(name), str(chall["r"]),
|
sni_todo.append(Client.DVSNI_Chall(
|
||||||
str(chall["nonce"])))
|
str(name), str(chall["r"]),
|
||||||
|
str(chall["nonce"]), self.authkey))
|
||||||
|
|
||||||
elif chall["type"] == "recoveryToken":
|
elif chall["type"] == "recoveryToken":
|
||||||
logging.info("\tRecovery Token Challenge for name: %s.", name)
|
logging.info("\tRecovery Token Challenge for name: %s.", name)
|
||||||
@@ -438,8 +440,7 @@ class Client(object):
|
|||||||
# one "challenge object" is issued for all sni_challenges
|
# one "challenge object" is issued for all sni_challenges
|
||||||
challenge_objs.append({
|
challenge_objs.append({
|
||||||
"type": "dvsni",
|
"type": "dvsni",
|
||||||
"list_sni_tuple": sni_todo,
|
"dvsni_chall": sni_todo
|
||||||
"dvsni_key": self.authkey,
|
|
||||||
})
|
})
|
||||||
challenge_obj_indices.append(sni_satisfies)
|
challenge_obj_indices.append(sni_satisfies)
|
||||||
logging.debug(sni_todo)
|
logging.debug(sni_todo)
|
||||||
@@ -447,11 +448,17 @@ class Client(object):
|
|||||||
return challenge_objs, challenge_obj_indices
|
return challenge_objs, challenge_obj_indices
|
||||||
|
|
||||||
|
|
||||||
def validate_key_csr(privkey, csr, names):
|
def validate_key_csr(privkey, csr):
|
||||||
"""Validate CSR and key files.
|
"""Validate CSR and key files.
|
||||||
|
|
||||||
Verifies that the client key and csr arguments are valid and
|
Verifies that the client key and csr arguments are valid and correspond to
|
||||||
correspond to one another.
|
one another. This does not currently check the names in the CSR.
|
||||||
|
|
||||||
|
:param privkey: Key associated with CSR
|
||||||
|
:type privkey: :class:`letsencrypt.client.client.Client.Key`
|
||||||
|
|
||||||
|
:param csr: CSR
|
||||||
|
:type csr: :class:`letsencrypt.client.client.Client.CSR`
|
||||||
|
|
||||||
:raises LetsEncryptClientError: if validation fails
|
:raises LetsEncryptClientError: if validation fails
|
||||||
|
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ def main():
|
|||||||
acme = client.Client(server, domains, privkey, auth, installer)
|
acme = client.Client(server, domains, privkey, auth, installer)
|
||||||
|
|
||||||
# Validate the key and csr
|
# Validate the key and csr
|
||||||
client.validate_key_csr(privkey, csr, domains)
|
client.validate_key_csr(privkey, csr)
|
||||||
|
|
||||||
cert_file, chain_file = acme.obtain_certificate(csr)
|
cert_file, chain_file = acme.obtain_certificate(csr)
|
||||||
vhost = acme.deploy_certificate(privkey, cert_file, chain_file)
|
vhost = acme.deploy_certificate(privkey, cert_file, chain_file)
|
||||||
|
|||||||
Reference in New Issue
Block a user