mirror of
https://github.com/certbot/certbot.git
synced 2026-01-26 07:41:33 +03:00
Added apache/sni_challenge cleanup
This commit is contained in:
@@ -146,9 +146,9 @@ while r.challenge or r.proceed.IsInitialized():
|
||||
print r
|
||||
|
||||
# TODO: there should be an unperform_sni_cert_challenge() here.
|
||||
# TODO: there should be a deploy_cert() here.
|
||||
|
||||
if r.success.IsInitialized():
|
||||
sni_challenge.cleanup(sni_todo, config)
|
||||
cert_chain_abspath = None
|
||||
with open(cert_file, "w") as f:
|
||||
f.write(r.success.certificate)
|
||||
@@ -163,6 +163,7 @@ if r.success.IsInitialized():
|
||||
#cert_chain_abspath = os.path.abspath(chain_file)
|
||||
for host in vhost:
|
||||
config.deploy_cert(host, os.path.abspath(cert_file), os.path.abspath(key_file), cert_chain_abspath)
|
||||
sni_challenge.apache_restart()
|
||||
elif r.failure.IsInitialized():
|
||||
print "Server reported failure."
|
||||
sys.exit(1)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import augeas
|
||||
import subprocess
|
||||
import re
|
||||
import os
|
||||
|
||||
BASE_DIR = "/etc/apache2/"
|
||||
|
||||
@@ -32,6 +33,7 @@ class Configurator(object):
|
||||
self.httpd_files = []
|
||||
for m in self.aug.match("/augeas/load/Httpd/incl"):
|
||||
self.httpd_files.append(self.aug.get(m))
|
||||
self.mod_files = set()
|
||||
|
||||
# TODO: This function can be improved to ensure that the final directives
|
||||
# are being modified whether that be in the include files or in the
|
||||
@@ -83,12 +85,7 @@ class Configurator(object):
|
||||
if cert_chain is not None:
|
||||
self.aug.set(path["cert_chain"][0], cert_chain)
|
||||
|
||||
try:
|
||||
self.aug.save()
|
||||
except IOError:
|
||||
print "Unable to save config - Is the script running as root?"
|
||||
return False
|
||||
return True
|
||||
return self.save("Virtual Server - deploying certificate")
|
||||
|
||||
def choose_virtual_host(self, name):
|
||||
"""
|
||||
@@ -114,7 +111,7 @@ class Configurator(object):
|
||||
|
||||
|
||||
|
||||
def add_servernames(self, host):
|
||||
def __add_servernames(self, host):
|
||||
"""
|
||||
Helper function for get_virtual_hosts()
|
||||
"""
|
||||
@@ -141,7 +138,7 @@ class Configurator(object):
|
||||
vhs.append(VH(p, addrs))
|
||||
|
||||
for host in vhs:
|
||||
self.add_servernames(host)
|
||||
self.__add_servernames(host)
|
||||
|
||||
return vhs
|
||||
|
||||
@@ -175,8 +172,8 @@ class Configurator(object):
|
||||
|
||||
def add_name_vhost(self, addr):
|
||||
"""
|
||||
TODO: For final code... this function should check that ports.conf
|
||||
is included along the main path... it is by default
|
||||
Adds NameVirtualHost directive for given address
|
||||
Directive is added to ports.conf unless
|
||||
"""
|
||||
aug_file_path = "/files" + BASE_DIR + "ports.conf"
|
||||
self.add_dir_to_ifmodssl(aug_file_path, "NameVirtualHost", addr)
|
||||
@@ -185,8 +182,6 @@ class Configurator(object):
|
||||
print "ports.conf is not included in your Apache config... "
|
||||
print "Adding NameVirtualHost directive to httpd.conf"
|
||||
self.add_dir_to_ifmodssl("/files" + BASE_DIR + "httpd.conf", "NameVirtualHost", addr)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def add_dir_to_ifmodssl(self, aug_conf_path, directive, val):
|
||||
@@ -198,12 +193,6 @@ class Configurator(object):
|
||||
nvhPath = ifModPath + "directive[1]"
|
||||
self.aug.set(nvhPath, directive)
|
||||
self.aug.set(nvhPath + "/arg", val)
|
||||
try:
|
||||
self.aug.save()
|
||||
except IOError:
|
||||
print "Unable to save file - Is the script running as root?"
|
||||
return False
|
||||
return True
|
||||
|
||||
def make_server_sni_ready(self, vhost):
|
||||
"""
|
||||
@@ -250,9 +239,9 @@ class Configurator(object):
|
||||
|
||||
def add_dir(self, aug_conf_path, directive, arg):
|
||||
self.aug.set(aug_conf_path + "/directive[last() + 1]", directive)
|
||||
self.aug.set(aug_conf_path + "/directive[last()]", arg)
|
||||
self.aug.set(aug_conf_path + "/directive[last()]/arg", arg)
|
||||
|
||||
def find_directive(self, directive, arg, start="/files"+BASE_DIR+"apache2.conf"):
|
||||
def find_directive(self, directive, arg=None, start="/files"+BASE_DIR+"apache2.conf"):
|
||||
"""
|
||||
Recursively searches through config files to find directives
|
||||
TODO: arg should probably be a list
|
||||
@@ -381,11 +370,37 @@ class Configurator(object):
|
||||
self.aug.add_transform("Httpd.lns", self.httpd_files)
|
||||
self.aug.load()
|
||||
|
||||
def save(self, mod_conf="Augeas Configuration", reversible=False):
|
||||
try:
|
||||
self.aug.save()
|
||||
if reversible:
|
||||
# Retrieve list of modified files
|
||||
save_paths = self.aug.match("/augeas/events/saved")
|
||||
for path in save_paths:
|
||||
# Strip off /files
|
||||
filename = self.aug.get(path)[6:]
|
||||
if filename in self.mod_files:
|
||||
# Output a warning... hopefully this can be avoided so more
|
||||
# complex code doesn't have to be written
|
||||
print "Reversible file has been overwritten -", filename
|
||||
else:
|
||||
self.mod_files.add(filename)
|
||||
return True
|
||||
except IOError:
|
||||
print "Unable to save file - ", mod_conf
|
||||
print "Is the script running as root?"
|
||||
return False
|
||||
|
||||
def revert_config(self):
|
||||
"""
|
||||
This function should reload the users original configuration files
|
||||
"""
|
||||
return False
|
||||
for f in self.mod_files:
|
||||
print "reverting", f
|
||||
os.rename(f + ".augsave", f)
|
||||
self.aug.load()
|
||||
self.mod_files.clear()
|
||||
|
||||
|
||||
def recurmatch(aug, path):
|
||||
if path:
|
||||
@@ -411,13 +426,9 @@ def main():
|
||||
for v in config.vhosts:
|
||||
for a in v.addrs:
|
||||
print "Address:",a, "- Is name vhost?", config.is_name_vhost(a)
|
||||
|
||||
#print config.make_server_sni_ready("example.com:443")
|
||||
setHost = set()
|
||||
setHost.add(config.choose_virtual_host("example.com"))
|
||||
setHost.add(config.choose_virtual_host("example2.com"))
|
||||
for s in setHost:
|
||||
print s.path
|
||||
|
||||
config.parse_file("/etc/apache2/ports_test.conf")
|
||||
|
||||
|
||||
#for m in config.aug.match("/augeas/load/Httpd/incl"):
|
||||
# print m, config.aug.get(m)
|
||||
|
||||
@@ -12,7 +12,8 @@ import augeas
|
||||
import configurator
|
||||
#import dns.resolver
|
||||
|
||||
CHOC_DIR = "/home/ubuntu/chocolate/client-webserver/"
|
||||
#CHOC_DIR = "/home/ubuntu/chocolate/client-webserver/"
|
||||
CHOC_DIR = "/home/james/Documents/apache_choc/"
|
||||
CHOC_CERT_CONF = "choc_cert_extensions.cnf"
|
||||
OPTIONS_SSL_CONF = CHOC_DIR + "options-ssl.conf"
|
||||
APACHE_CHALLENGE_CONF = CHOC_DIR + "choc_sni_cert_challenge.conf"
|
||||
@@ -38,7 +39,6 @@ def findApacheConfigFile():
|
||||
|
||||
result: returns file path if present
|
||||
"""
|
||||
|
||||
# This needs to be fixed to account for multiple httpd.conf files
|
||||
try:
|
||||
p = subprocess.check_output(["sudo", "find", "/etc", "-name", "httpd.conf"], stderr=open("/dev/null"))
|
||||
@@ -143,10 +143,8 @@ def generateExtension(key, y):
|
||||
|
||||
rsaPrivKey = M2Crypto.RSA.load_key(key)
|
||||
r = rsaPrivKey.private_decrypt(y, M2Crypto.RSA.pkcs1_oaep_padding)
|
||||
#print r
|
||||
|
||||
s = Random.get_random_bytes(S_SIZE)
|
||||
#s = "0xDEADBEEF"
|
||||
extHMAC = hmac.new(r, str(s), hashlib.sha256)
|
||||
return byteToHex(s) + extHMAC.hexdigest()
|
||||
|
||||
@@ -195,6 +193,28 @@ def apache_restart():
|
||||
"""
|
||||
subprocess.call(["sudo", "/etc/init.d/apache2", "reload"])
|
||||
|
||||
def cleanup(listSNITuple, configurator):
|
||||
"""
|
||||
Remove all temporary changes necessary to perform the challenge
|
||||
|
||||
configurator: Configurator object
|
||||
listSNITuple: The initial challenge tuple
|
||||
|
||||
result: Apache server is restored to the pre-challenge state
|
||||
"""
|
||||
configurator.revert_config()
|
||||
apache_restart()
|
||||
remove_files(listSNITuple)
|
||||
|
||||
|
||||
def remove_files(listSNITuple):
|
||||
"""
|
||||
Removes all of the temporary SNI files
|
||||
"""
|
||||
for tup in listSNITuple:
|
||||
remove(getChocCertFile(tup[2]))
|
||||
remove(APACHE_CHALLENGE_CONF)
|
||||
|
||||
#main call
|
||||
def perform_sni_cert_challenge(listSNITuple, csr, key, configurator):
|
||||
"""
|
||||
@@ -207,6 +227,9 @@ def perform_sni_cert_challenge(listSNITuple, csr, key, configurator):
|
||||
key: string - File path to key
|
||||
configurator: Configurator obj
|
||||
"""
|
||||
# Save any changes to the configuration as a precaution
|
||||
# About to make temporary changes to the config
|
||||
configurator.save("Before performing sni_challenge")
|
||||
|
||||
for tup in listSNITuple:
|
||||
vhost = configurator.choose_virtual_host(tup[0])
|
||||
@@ -224,6 +247,8 @@ def perform_sni_cert_challenge(listSNITuple, csr, key, configurator):
|
||||
createChallengeCert(tup[3], ext, tup[2], csr, key)
|
||||
|
||||
modifyApacheConfig(findApacheConfigFile(), listSNITuple, key, configurator)
|
||||
# Save reversible changes and restart the server
|
||||
configurator.save("SNI Challenge", True)
|
||||
apache_restart()
|
||||
|
||||
def main():
|
||||
@@ -252,8 +277,17 @@ def main():
|
||||
|
||||
config = configurator.Configurator()
|
||||
|
||||
perform_sni_cert_challenge([("example.com", y, nonce, "1.3.3.7"), ("www.example.com",y2, nonce2, "1.3.3.7")], csr, key, config)
|
||||
#perform_sni_cert_challenge([("127.0.0.1", y, nonce, "1.3.3.7"), ("localhost", y2, nonce2, "1.3.3.7")], csr, key, config)
|
||||
#challenges = [("example.com", y, nonce, "1.3.3.7"), ("www.example.com",y2, nonce2, "1.3.3.7")]
|
||||
challenges = [("127.0.0.1", y, nonce, "1.3.3.7"), ("localhost", y2, nonce2, "1.3.3.7")]
|
||||
perform_sni_cert_challenge(challenges, csr, key, config)
|
||||
|
||||
# Waste some time without importing time module... just for testing
|
||||
for i in range(0, 12000):
|
||||
if i % 2000 == 0:
|
||||
print "Waiting:", i
|
||||
|
||||
print "Cleaning up"
|
||||
cleanup(challenges, config)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user