1
0
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:
James Kasten
2012-08-02 18:46:01 -04:00
parent 6fd9d01644
commit 6804ccb41f
3 changed files with 81 additions and 35 deletions

View File

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

View File

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

View File

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