Added make_server_sni_ready, fixed vhost.addrs bug, cleaned up some code

This commit is contained in:
James Kasten
2012-07-30 14:03:06 -04:00
parent 67da1f65dd
commit 94d1827838
+69 -33
View File
@@ -113,7 +113,7 @@ class Configurator(object):
paths = self.aug.match("/files" + BASE_DIR + "sites-available//VirtualHost") paths = self.aug.match("/files" + BASE_DIR + "sites-available//VirtualHost")
for p in paths: for p in paths:
addrs = [] addrs = []
args = self.aug.match(p + "/*") args = self.aug.match(p + "/arg")
for arg in args: for arg in args:
addrs.append(self.aug.get(arg)) addrs.append(self.aug.get(arg))
self.vhosts.append(VH(p, addrs)) self.vhosts.append(VH(p, addrs))
@@ -127,16 +127,14 @@ class Configurator(object):
# search for NameVirtualHost directive for ip_addr # search for NameVirtualHost directive for ip_addr
# check httpd.conf, ports.conf, # check httpd.conf, ports.conf,
# note ip_addr can be FQDN # note ip_addr can be FQDN
paths = self.aug.match("/files" + BASE_DIR + "/*[self::directive=NameVirtualHost']/arg") paths = self.find_directive("NameVirtualHost", None)
name_vh = [] name_vh = []
for p in paths: for p in paths:
name_vh.append(self.aug.get(p)) name_vh.append(self.aug.get(p))
# TODO: Should be reviewed for efficiency/completeness
# TODO: Check ramifications for FQDN/IP_ADDR mismatch overlap # TODO: Check ramifications for FQDN/IP_ADDR mismatch overlap
# ie. NameVirtualHost FQDN ... <VirtualHost IPADDR> # ie. NameVirtualHost FQDN ... <VirtualHost IPADDR>
# Does adding additional NameVirtualHost directives cause problems # Does adding additional NameVirtualHost directives cause problems
# TODO: Test matching
# Check for exact match # Check for exact match
for vh in name_vh: for vh in name_vh:
if vh == addr: if vh == addr:
@@ -159,44 +157,69 @@ class Configurator(object):
is included along the main path... it is by default is included along the main path... it is by default
""" """
aug_file_path = "/files" + BASE_DIR + "ports.conf" aug_file_path = "/files" + BASE_DIR + "ports.conf"
# Some testing code self.add_dir_to_ifmodssl(aug_file_path, "NameVirtualHost", addr)
#self.aug.add_transform("Httpd.lns", BASE_DIR+"ports_test.conf")
#self.aug.load() if len(self.find_directive("NameVirtualHost", addr)) == 0:
ifMods = self.aug.match(aug_file_path + "/IfModule/*[self::arg='mod_ssl.c']") 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)
# No IfModule mod_ssl.c in ports.conf... create one return True
if len(ifMods) == 0:
self.append_ifmod(aug_file_path, "mod_ssl.c")
ifMods = self.aug.match(aug_file_path + "/IfModule/*[self::arg='mod_ssl.c']")
# Get first mod_ssl IfMod from main tree and strip arg from it def add_dir_to_ifmodssl(self, aug_conf_path, directive, val):
# Three because 'arg' # TODO: Add error checking code... does the path given even exist?
ifModPath = ifMods[0][:len(ifMods[0]) - 3] # Does it throw exceptions?
ifModPath = self.get_ifmod(aug_conf_path, "mod_ssl.c")
# IfModule can have only one valid argument, so append after # IfModule can have only one valid argument, so append after
self.aug.insert(ifMods[0], "directive", False) self.aug.insert(ifModPath + "arg", "directive", False)
nvhPath = ifModPath + "directive[1]" nvhPath = ifModPath + "directive[1]"
self.aug.set(nvhPath, "NameVirtualHost") self.aug.set(nvhPath, directive)
self.aug.set(nvhPath + "/arg", addr) self.aug.set(nvhPath + "/arg", val)
# testing printout
#file = self.aug.match(aug_file_path + "//*")
#for p in file:
#print p, self.aug.get(p)
self.aug.save() self.aug.save()
def append_ifmod(self, aug_conf_path, mod): def make_server_sni_ready(self, addr):
#print "No " + mod + " IfModule section... creating!" """
self.aug.set(aug_conf_path + "/IfModule[last() + 1]", "") Checks to see if the server is ready for SNI challenges
self.aug.set(aug_conf_path + "/IfModule[last()]/arg", mod) """
# Check if mod_ssl is loaded
if not self.check_ssl_loaded():
print "Please load the SSL module with Apache"
return False
# Check for Listen 443
if len(self.find_directive("Listen", "443")) == 0:
print self.find_directive("Listen", "443")
print "Setting the Apache Server to Listen on port 443"
self.add_dir_to_ifmodssl("/files" + BASE_DIR + "ports.conf", "Listen", "443")
# Check for NameVirtualHost
if not self.is_name_vhost(addr):
print "Setting VirtualHost at", addr, "to be a name based virtual host"
self.add_name_vhost(addr)
return True
def get_ifmod(self, aug_conf_path, mod):
ifMods = self.aug.match(aug_conf_path + "/IfModule/*[self::arg='" + mod + "']")
if len(ifMods) == 0:
self.aug.set(aug_conf_path + "/IfModule[last() + 1]", "")
self.aug.set(aug_conf_path + "/IfModule[last()]/arg", mod)
ifMods = self.aug.match(aug_conf_path + "/IfModule/*[self::arg='" + mod + "']")
# Strip off "arg" at end of first ifmod path
return ifMods[0][:len(ifMods[0]) - 3]
def find_directive(self, directive, arg, start="/files"+BASE_DIR+"apache2.conf"): def find_directive(self, directive, arg, start="/files"+BASE_DIR+"apache2.conf"):
""" """
Recursively searches through config files to find directives Recursively searches through config files to find directives
TODO: arg should probably be a list TODO: arg should probably be a list
TODO: Allow unknown args
""" """
matches = self.aug.match(start + "//* [self::directive='"+directive+"']/* [self::arg='" + arg + "']") if arg is None:
matches = self.aug.match(start + "//* [self::directive='"+directive+"']/arg")
else:
matches = self.aug.match(start + "//* [self::directive='"+directive+"']/* [self::arg='" + arg + "']")
includes = self.aug.match(start + "//* [self::directive='Include']/* [label()='arg']") includes = self.aug.match(start + "//* [self::directive='Include']/* [label()='arg']")
for include in includes: for include in includes:
@@ -258,7 +281,7 @@ class Configurator(object):
def check_ssl_loaded(self): def check_ssl_loaded(self):
""" """
Checks apachectl to get loaded module list Checks apache2ctl to get loaded module list
""" """
try: try:
p = subprocess.check_output(["sudo", "apache2ctl", "-M"], stderr=open("/dev/null")) p = subprocess.check_output(["sudo", "apache2ctl", "-M"], stderr=open("/dev/null"))
@@ -315,6 +338,12 @@ class Configurator(object):
self.aug.add_transform("Httpd.lns", self.httpd_files) self.aug.add_transform("Httpd.lns", self.httpd_files)
self.aug.load() self.aug.load()
def revert_config(self):
"""
This function should reload the users original configuration files
"""
return False
def recurmatch(aug, path): def recurmatch(aug, path):
if path: if path:
if path != "/": if path != "/":
@@ -330,12 +359,19 @@ def main():
config = Configurator() config = Configurator()
config.get_virtual_hosts() config.get_virtual_hosts()
for v in config.vhosts: for v in config.vhosts:
for name in v.names: for a in v.addrs:
print name for name in v.names:
print a, name
for m in config.find_directive("Listen", "443"): for m in config.find_directive("Listen", "443"):
print "Directive Path:", m, "Value:", config.aug.get(m) print "Directive Path:", m, "Value:", config.aug.get(m)
for v in config.vhosts:
for a in v.addrs:
print a, config.is_name_vhost(a)
print config.make_server_sni_ready("127.0.0.1:443")
#for m in config.aug.match("/augeas/load/Httpd/incl"): #for m in config.aug.match("/augeas/load/Httpd/incl"):
# print m, config.aug.get(m) # print m, config.aug.get(m)
#config.add_name_vhost("example2.com:443") #config.add_name_vhost("example2.com:443")