Compare commits
20 Commits
test-apach
...
fix_centos
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d811a784d | ||
|
|
794c1dc13f | ||
|
|
bd727d3127 | ||
|
|
967bb574c2 | ||
|
|
f01a1a6fc7 | ||
|
|
18d0e14101 | ||
|
|
0d79f262c4 | ||
|
|
e7ae0e23cb | ||
|
|
28befb31e9 | ||
|
|
a2124fbd4a | ||
|
|
51343c8e4c | ||
|
|
836a1b537b | ||
|
|
375b2f5b4e | ||
|
|
780ec86815 | ||
|
|
ebcde9cf67 | ||
|
|
07bfd8ed53 | ||
|
|
dbeb7c8caa | ||
|
|
9b0f8af70b | ||
|
|
f4e022442a | ||
|
|
da436b0a12 |
@@ -28,6 +28,9 @@ Certbot adheres to [Semantic Versioning](https://semver.org/).
|
|||||||
* Certbot uses the Python library cryptography for OCSP when cryptography>=2.5
|
* Certbot uses the Python library cryptography for OCSP when cryptography>=2.5
|
||||||
is installed. We fixed a bug in Certbot causing it to interpret timestamps in
|
is installed. We fixed a bug in Certbot causing it to interpret timestamps in
|
||||||
the OCSP response as being in the local timezone rather than UTC.
|
the OCSP response as being in the local timezone rather than UTC.
|
||||||
|
* Issue causing the default CentOS 6 TLS configuration to ignore some of the
|
||||||
|
HTTPS VirtualHosts created by Certbot. mod_ssl loading is now moved to main
|
||||||
|
http.conf for this environment where possible.
|
||||||
|
|
||||||
Despite us having broken lockstep, we are continuing to release new versions of
|
Despite us having broken lockstep, we are continuing to release new versions of
|
||||||
all Certbot components during releases for the time being, however, the only
|
all Certbot components during releases for the time being, however, the only
|
||||||
|
|||||||
@@ -1,13 +1,21 @@
|
|||||||
""" Distribution specific override class for CentOS family (RHEL, Fedora) """
|
""" Distribution specific override class for CentOS family (RHEL, Fedora) """
|
||||||
|
import logging
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
|
|
||||||
|
from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module
|
||||||
|
|
||||||
import zope.interface
|
import zope.interface
|
||||||
|
|
||||||
from certbot import interfaces
|
from certbot import interfaces
|
||||||
|
|
||||||
|
|
||||||
from certbot_apache import apache_util
|
from certbot_apache import apache_util
|
||||||
from certbot_apache import configurator
|
from certbot_apache import configurator
|
||||||
from certbot_apache import parser
|
from certbot_apache import parser
|
||||||
|
from certbot.errors import MisconfigurationError
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@zope.interface.provider(interfaces.IPluginFactory)
|
@zope.interface.provider(interfaces.IPluginFactory)
|
||||||
class CentOSConfigurator(configurator.ApacheConfigurator):
|
class CentOSConfigurator(configurator.ApacheConfigurator):
|
||||||
@@ -47,6 +55,84 @@ class CentOSConfigurator(configurator.ApacheConfigurator):
|
|||||||
self.aug, self.option("server_root"), self.option("vhost_root"),
|
self.aug, self.option("server_root"), self.option("vhost_root"),
|
||||||
self.version, configurator=self)
|
self.version, configurator=self)
|
||||||
|
|
||||||
|
def _deploy_cert(self, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Override _deploy_cert in order to ensure that the Apache configuration
|
||||||
|
has "LoadModule ssl_module..." before parsing the VirtualHost configuration
|
||||||
|
that was created by Certbot
|
||||||
|
"""
|
||||||
|
super(CentOSConfigurator, self)._deploy_cert(*args, **kwargs)
|
||||||
|
if self.version < (2, 4, 0):
|
||||||
|
self._deploy_loadmodule_ssl_if_needed()
|
||||||
|
|
||||||
|
|
||||||
|
def _deploy_loadmodule_ssl_if_needed(self):
|
||||||
|
"""
|
||||||
|
Add "LoadModule ssl_module <pre-existing path>" to main httpd.conf if
|
||||||
|
it doesn't exist there already.
|
||||||
|
"""
|
||||||
|
|
||||||
|
loadmods = self.parser.find_dir("LoadModule", "ssl_module", exclude=False)
|
||||||
|
|
||||||
|
correct_ifmods = [] # type: List[str]
|
||||||
|
loadmod_args = [] # type: List[str]
|
||||||
|
loadmod_paths = [] # type: List[str]
|
||||||
|
for m in loadmods:
|
||||||
|
noarg_path = m.rpartition("/")[0]
|
||||||
|
path_args = self.parser.get_all_args(noarg_path)
|
||||||
|
if loadmod_args:
|
||||||
|
if loadmod_args != path_args:
|
||||||
|
msg = ("Certbot encountered multiple LoadModule directives "
|
||||||
|
"for LoadModule ssl_module with differing library paths. "
|
||||||
|
"Please remove or comment out the one(s) that are not in "
|
||||||
|
"use, and run Certbot again.")
|
||||||
|
raise MisconfigurationError(msg)
|
||||||
|
else:
|
||||||
|
loadmod_args = path_args
|
||||||
|
|
||||||
|
if self.parser.not_modssl_ifmodule(noarg_path): # pylint: disable=no-member
|
||||||
|
if self.parser.loc["default"] in noarg_path:
|
||||||
|
# LoadModule already in the main configuration file
|
||||||
|
if ("ifmodule/" in noarg_path.lower() or
|
||||||
|
"ifmodule[1]" in noarg_path.lower()):
|
||||||
|
# It's the first or only IfModule in the file
|
||||||
|
return
|
||||||
|
# Populate the list of known !mod_ssl.c IfModules
|
||||||
|
nodir_path = noarg_path.rpartition("/directive")[0]
|
||||||
|
correct_ifmods.append(nodir_path)
|
||||||
|
else:
|
||||||
|
loadmod_paths.append(noarg_path)
|
||||||
|
|
||||||
|
if not loadmod_args:
|
||||||
|
# Do not try to enable mod_ssl
|
||||||
|
return
|
||||||
|
|
||||||
|
# Force creation as the directive wasn't found from the beginning of
|
||||||
|
# httpd.conf
|
||||||
|
rootconf_ifmod = self.parser.create_ifmod(
|
||||||
|
parser.get_aug_path(self.parser.loc["default"]),
|
||||||
|
"!mod_ssl.c", beginning=True)
|
||||||
|
# parser.get_ifmod returns a path postfixed with "/", remove that
|
||||||
|
self.parser.add_dir(rootconf_ifmod[:-1], "LoadModule", loadmod_args)
|
||||||
|
correct_ifmods.append(rootconf_ifmod[:-1])
|
||||||
|
self.save_notes += "Added LoadModule ssl_module to main configuration.\n"
|
||||||
|
|
||||||
|
# Wrap LoadModule mod_ssl inside of <IfModule !mod_ssl.c> if it's not
|
||||||
|
# configured like this already.
|
||||||
|
for loadmod_path in loadmod_paths:
|
||||||
|
nodir_path = loadmod_path.split("/directive")[0]
|
||||||
|
# Remove the old LoadModule directive
|
||||||
|
self.aug.remove(loadmod_path)
|
||||||
|
|
||||||
|
# Create a new IfModule !mod_ssl.c if not already found on path
|
||||||
|
ssl_ifmod = self.parser.get_ifmod(nodir_path, "!mod_ssl.c",
|
||||||
|
beginning=True)[:-1]
|
||||||
|
if ssl_ifmod not in correct_ifmods:
|
||||||
|
self.parser.add_dir(ssl_ifmod, "LoadModule", loadmod_args)
|
||||||
|
correct_ifmods.append(ssl_ifmod)
|
||||||
|
self.save_notes += ("Wrapped pre-existing LoadModule ssl_module "
|
||||||
|
"inside of <IfModule !mod_ssl> block.\n")
|
||||||
|
|
||||||
|
|
||||||
class CentOSParser(parser.ApacheParser):
|
class CentOSParser(parser.ApacheParser):
|
||||||
"""CentOS specific ApacheParser override class"""
|
"""CentOS specific ApacheParser override class"""
|
||||||
@@ -66,3 +152,33 @@ class CentOSParser(parser.ApacheParser):
|
|||||||
defines = apache_util.parse_define_file(self.sysconfig_filep, "OPTIONS")
|
defines = apache_util.parse_define_file(self.sysconfig_filep, "OPTIONS")
|
||||||
for k in defines.keys():
|
for k in defines.keys():
|
||||||
self.variables[k] = defines[k]
|
self.variables[k] = defines[k]
|
||||||
|
|
||||||
|
def not_modssl_ifmodule(self, path):
|
||||||
|
"""Checks if the provided Augeas path has argument !mod_ssl"""
|
||||||
|
|
||||||
|
if "ifmodule" not in path.lower():
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Trim the path to the last ifmodule
|
||||||
|
workpath = path.lower()
|
||||||
|
while workpath:
|
||||||
|
# Get path to the last IfModule (ignore the tail)
|
||||||
|
parts = workpath.rpartition("ifmodule")
|
||||||
|
|
||||||
|
if not parts[0]:
|
||||||
|
# IfModule not found
|
||||||
|
break
|
||||||
|
ifmod_path = parts[0] + parts[1]
|
||||||
|
# Check if ifmodule had an index
|
||||||
|
if parts[2].startswith("["):
|
||||||
|
# Append the index from tail
|
||||||
|
ifmod_path += parts[2].partition("/")[0]
|
||||||
|
# Get the original path trimmed to correct length
|
||||||
|
# This is required to preserve cases
|
||||||
|
ifmod_real_path = path[0:len(ifmod_path)]
|
||||||
|
if "!mod_ssl.c" in self.get_all_args(ifmod_real_path):
|
||||||
|
return True
|
||||||
|
# Set the workpath to the heading part
|
||||||
|
workpath = parts[0]
|
||||||
|
|
||||||
|
return False
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ class ApacheParser(object):
|
|||||||
"""
|
"""
|
||||||
# TODO: Add error checking code... does the path given even exist?
|
# TODO: Add error checking code... does the path given even exist?
|
||||||
# Does it throw exceptions?
|
# Does it throw exceptions?
|
||||||
if_mod_path = self._get_ifmod(aug_conf_path, "mod_ssl.c")
|
if_mod_path = 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(if_mod_path + "arg", "directive", False)
|
self.aug.insert(if_mod_path + "arg", "directive", False)
|
||||||
nvh_path = if_mod_path + "directive[1]"
|
nvh_path = if_mod_path + "directive[1]"
|
||||||
@@ -292,22 +292,54 @@ class ApacheParser(object):
|
|||||||
for i, arg in enumerate(args):
|
for i, arg in enumerate(args):
|
||||||
self.aug.set("%s/arg[%d]" % (nvh_path, i + 1), arg)
|
self.aug.set("%s/arg[%d]" % (nvh_path, i + 1), arg)
|
||||||
|
|
||||||
def _get_ifmod(self, aug_conf_path, mod):
|
def get_ifmod(self, aug_conf_path, mod, beginning=False):
|
||||||
"""Returns the path to <IfMod mod> and creates one if it doesn't exist.
|
"""Returns the path to <IfMod mod> and creates one if it doesn't exist.
|
||||||
|
|
||||||
:param str aug_conf_path: Augeas configuration path
|
:param str aug_conf_path: Augeas configuration path
|
||||||
:param str mod: module ie. mod_ssl.c
|
:param str mod: module ie. mod_ssl.c
|
||||||
|
:param bool beginning: If the IfModule should be created to the beginning
|
||||||
|
of augeas path DOM tree.
|
||||||
|
|
||||||
|
:returns: Augeas path of the requested IfModule directive that pre-existed
|
||||||
|
or was created during the process. The path may be dynamic,
|
||||||
|
i.e. .../IfModule[last()]
|
||||||
|
:rtype: str
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if_mods = self.aug.match(("%s/IfModule/*[self::arg='%s']" %
|
if_mods = self.aug.match(("%s/IfModule/*[self::arg='%s']" %
|
||||||
(aug_conf_path, mod)))
|
(aug_conf_path, mod)))
|
||||||
if len(if_mods) == 0:
|
if not if_mods:
|
||||||
self.aug.set("%s/IfModule[last() + 1]" % aug_conf_path, "")
|
return self.create_ifmod(aug_conf_path, mod, beginning)
|
||||||
self.aug.set("%s/IfModule[last()]/arg" % aug_conf_path, mod)
|
|
||||||
if_mods = self.aug.match(("%s/IfModule/*[self::arg='%s']" %
|
|
||||||
(aug_conf_path, mod)))
|
|
||||||
# Strip off "arg" at end of first ifmod path
|
# Strip off "arg" at end of first ifmod path
|
||||||
return if_mods[0][:len(if_mods[0]) - 3]
|
return if_mods[0].rpartition("arg")[0]
|
||||||
|
|
||||||
|
def create_ifmod(self, aug_conf_path, mod, beginning=False):
|
||||||
|
"""Creates a new <IfMod mod> and returns its path.
|
||||||
|
|
||||||
|
:param str aug_conf_path: Augeas configuration path
|
||||||
|
:param str mod: module ie. mod_ssl.c
|
||||||
|
:param bool beginning: If the IfModule should be created to the beginning
|
||||||
|
of augeas path DOM tree.
|
||||||
|
|
||||||
|
:returns: Augeas path of the newly created IfModule directive.
|
||||||
|
The path may be dynamic, i.e. .../IfModule[last()]
|
||||||
|
:rtype: str
|
||||||
|
|
||||||
|
"""
|
||||||
|
if beginning:
|
||||||
|
c_path_arg = "{}/IfModule[1]/arg".format(aug_conf_path)
|
||||||
|
# Insert IfModule before the first directive
|
||||||
|
self.aug.insert("{}/directive[1]".format(aug_conf_path),
|
||||||
|
"IfModule", True)
|
||||||
|
retpath = "{}/IfModule[1]/".format(aug_conf_path)
|
||||||
|
else:
|
||||||
|
c_path = "{}/IfModule[last() + 1]".format(aug_conf_path)
|
||||||
|
c_path_arg = "{}/IfModule[last()]/arg".format(aug_conf_path)
|
||||||
|
self.aug.set(c_path, "")
|
||||||
|
retpath = "{}/IfModule[last()]/".format(aug_conf_path)
|
||||||
|
self.aug.set(c_path_arg, mod)
|
||||||
|
return retpath
|
||||||
|
|
||||||
def add_dir(self, aug_conf_path, directive, args):
|
def add_dir(self, aug_conf_path, directive, args):
|
||||||
"""Appends directive to the end fo the file given by aug_conf_path.
|
"""Appends directive to the end fo the file given by aug_conf_path.
|
||||||
@@ -453,6 +485,20 @@ class ApacheParser(object):
|
|||||||
|
|
||||||
return ordered_matches
|
return ordered_matches
|
||||||
|
|
||||||
|
def get_all_args(self, match):
|
||||||
|
"""
|
||||||
|
Tries to fetch all arguments for a directive. See get_arg.
|
||||||
|
|
||||||
|
Note that if match is an ancestor node, it returns all names of
|
||||||
|
child directives as well as the list of arguments.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
if match[-1] != "/":
|
||||||
|
match = match+"/"
|
||||||
|
allargs = self.aug.match(match + '*')
|
||||||
|
return [self.get_arg(arg) for arg in allargs]
|
||||||
|
|
||||||
def get_arg(self, match):
|
def get_arg(self, match):
|
||||||
"""Uses augeas.get to get argument value and interprets result.
|
"""Uses augeas.get to get argument value and interprets result.
|
||||||
|
|
||||||
|
|||||||
224
certbot-apache/certbot_apache/tests/centos6_test.py
Normal file
224
certbot-apache/certbot_apache/tests/centos6_test.py
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
"""Test for certbot_apache.configurator for CentOS 6 overrides"""
|
||||||
|
import os
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from certbot_apache import obj
|
||||||
|
from certbot_apache import override_centos
|
||||||
|
from certbot_apache import parser
|
||||||
|
from certbot_apache.tests import util
|
||||||
|
from certbot.errors import MisconfigurationError
|
||||||
|
|
||||||
|
def get_vh_truth(temp_dir, config_name):
|
||||||
|
"""Return the ground truth for the specified directory."""
|
||||||
|
prefix = os.path.join(
|
||||||
|
temp_dir, config_name, "httpd/conf.d")
|
||||||
|
|
||||||
|
aug_pre = "/files" + prefix
|
||||||
|
vh_truth = [
|
||||||
|
obj.VirtualHost(
|
||||||
|
os.path.join(prefix, "test.example.com.conf"),
|
||||||
|
os.path.join(aug_pre, "test.example.com.conf/VirtualHost"),
|
||||||
|
set([obj.Addr.fromstring("*:80")]),
|
||||||
|
False, True, "test.example.com"),
|
||||||
|
obj.VirtualHost(
|
||||||
|
os.path.join(prefix, "ssl.conf"),
|
||||||
|
os.path.join(aug_pre, "ssl.conf/VirtualHost"),
|
||||||
|
set([obj.Addr.fromstring("_default_:443")]),
|
||||||
|
True, True, None)
|
||||||
|
]
|
||||||
|
return vh_truth
|
||||||
|
|
||||||
|
class CentOS6Tests(util.ApacheTest):
|
||||||
|
"""Tests for CentOS 6"""
|
||||||
|
|
||||||
|
def setUp(self): # pylint: disable=arguments-differ
|
||||||
|
test_dir = "centos6_apache/apache"
|
||||||
|
config_root = "centos6_apache/apache/httpd"
|
||||||
|
vhost_root = "centos6_apache/apache/httpd/conf.d"
|
||||||
|
super(CentOS6Tests, self).setUp(test_dir=test_dir,
|
||||||
|
config_root=config_root,
|
||||||
|
vhost_root=vhost_root)
|
||||||
|
|
||||||
|
self.config = util.get_apache_configurator(
|
||||||
|
self.config_path, self.vhost_path, self.config_dir, self.work_dir,
|
||||||
|
version=(2, 2, 15), os_info="centos")
|
||||||
|
self.vh_truth = get_vh_truth(
|
||||||
|
self.temp_dir, "centos6_apache/apache")
|
||||||
|
|
||||||
|
def test_get_parser(self):
|
||||||
|
self.assertTrue(isinstance(self.config.parser,
|
||||||
|
override_centos.CentOSParser))
|
||||||
|
|
||||||
|
def test_get_virtual_hosts(self):
|
||||||
|
"""Make sure all vhosts are being properly found."""
|
||||||
|
vhs = self.config.get_virtual_hosts()
|
||||||
|
self.assertEqual(len(vhs), 2)
|
||||||
|
found = 0
|
||||||
|
|
||||||
|
for vhost in vhs:
|
||||||
|
for centos_truth in self.vh_truth:
|
||||||
|
if vhost == centos_truth:
|
||||||
|
found += 1
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise Exception("Missed: %s" % vhost) # pragma: no cover
|
||||||
|
self.assertEqual(found, 2)
|
||||||
|
|
||||||
|
def test_loadmod_default(self):
|
||||||
|
ssl_loadmods = self.config.parser.find_dir(
|
||||||
|
"LoadModule", "ssl_module", exclude=False)
|
||||||
|
self.assertEqual(len(ssl_loadmods), 1)
|
||||||
|
# Make sure the LoadModule ssl_module is in ssl.conf (default)
|
||||||
|
self.assertTrue("ssl.conf" in ssl_loadmods[0])
|
||||||
|
# ...and that it's not inside of <IfModule>
|
||||||
|
self.assertFalse("IfModule" in ssl_loadmods[0])
|
||||||
|
|
||||||
|
# Get the example vhost
|
||||||
|
self.config.assoc["test.example.com"] = self.vh_truth[0]
|
||||||
|
self.config.deploy_cert(
|
||||||
|
"random.demo", "example/cert.pem", "example/key.pem",
|
||||||
|
"example/cert_chain.pem", "example/fullchain.pem")
|
||||||
|
self.config.save()
|
||||||
|
|
||||||
|
post_loadmods = self.config.parser.find_dir(
|
||||||
|
"LoadModule", "ssl_module", exclude=False)
|
||||||
|
|
||||||
|
# We should now have LoadModule ssl_module in root conf and ssl.conf
|
||||||
|
self.assertEqual(len(post_loadmods), 2)
|
||||||
|
for lm in post_loadmods:
|
||||||
|
# lm[:-7] removes "/arg[#]" from the path
|
||||||
|
arguments = self.config.parser.get_all_args(lm[:-7])
|
||||||
|
self.assertEqual(arguments, ["ssl_module", "modules/mod_ssl.so"])
|
||||||
|
# ...and both of them should be wrapped in <IfModule !mod_ssl.c>
|
||||||
|
# lm[:-17] strips off /directive/arg[1] from the path.
|
||||||
|
ifmod_args = self.config.parser.get_all_args(lm[:-17])
|
||||||
|
self.assertTrue("!mod_ssl.c" in ifmod_args)
|
||||||
|
|
||||||
|
def test_loadmod_multiple(self):
|
||||||
|
sslmod_args = ["ssl_module", "modules/mod_ssl.so"]
|
||||||
|
# Adds another LoadModule to main httpd.conf in addtition to ssl.conf
|
||||||
|
self.config.parser.add_dir(self.config.parser.loc["default"], "LoadModule",
|
||||||
|
sslmod_args)
|
||||||
|
self.config.save()
|
||||||
|
pre_loadmods = self.config.parser.find_dir(
|
||||||
|
"LoadModule", "ssl_module", exclude=False)
|
||||||
|
# LoadModules are not within IfModule blocks
|
||||||
|
self.assertFalse(any(["ifmodule" in m.lower() for m in pre_loadmods]))
|
||||||
|
self.config.assoc["test.example.com"] = self.vh_truth[0]
|
||||||
|
self.config.deploy_cert(
|
||||||
|
"random.demo", "example/cert.pem", "example/key.pem",
|
||||||
|
"example/cert_chain.pem", "example/fullchain.pem")
|
||||||
|
post_loadmods = self.config.parser.find_dir(
|
||||||
|
"LoadModule", "ssl_module", exclude=False)
|
||||||
|
|
||||||
|
for mod in post_loadmods:
|
||||||
|
self.assertTrue(self.config.parser.not_modssl_ifmodule(mod)) #pylint: disable=no-member
|
||||||
|
|
||||||
|
def test_loadmod_rootconf_exists(self):
|
||||||
|
sslmod_args = ["ssl_module", "modules/mod_ssl.so"]
|
||||||
|
rootconf_ifmod = self.config.parser.get_ifmod(
|
||||||
|
parser.get_aug_path(self.config.parser.loc["default"]),
|
||||||
|
"!mod_ssl.c", beginning=True)
|
||||||
|
self.config.parser.add_dir(rootconf_ifmod[:-1], "LoadModule", sslmod_args)
|
||||||
|
self.config.save()
|
||||||
|
# Get the example vhost
|
||||||
|
self.config.assoc["test.example.com"] = self.vh_truth[0]
|
||||||
|
self.config.deploy_cert(
|
||||||
|
"random.demo", "example/cert.pem", "example/key.pem",
|
||||||
|
"example/cert_chain.pem", "example/fullchain.pem")
|
||||||
|
self.config.save()
|
||||||
|
|
||||||
|
root_loadmods = self.config.parser.find_dir(
|
||||||
|
"LoadModule", "ssl_module",
|
||||||
|
start=parser.get_aug_path(self.config.parser.loc["default"]),
|
||||||
|
exclude=False)
|
||||||
|
|
||||||
|
mods = [lm for lm in root_loadmods if self.config.parser.loc["default"] in lm]
|
||||||
|
|
||||||
|
self.assertEqual(len(mods), 1)
|
||||||
|
# [:-7] removes "/arg[#]" from the path
|
||||||
|
self.assertEqual(
|
||||||
|
self.config.parser.get_all_args(mods[0][:-7]),
|
||||||
|
sslmod_args)
|
||||||
|
|
||||||
|
def test_neg_loadmod_already_on_path(self):
|
||||||
|
loadmod_args = ["ssl_module", "modules/mod_ssl.so"]
|
||||||
|
ifmod = self.config.parser.get_ifmod(
|
||||||
|
self.vh_truth[1].path, "!mod_ssl.c", beginning=True)
|
||||||
|
self.config.parser.add_dir(ifmod[:-1], "LoadModule", loadmod_args)
|
||||||
|
self.config.parser.add_dir(self.vh_truth[1].path, "LoadModule", loadmod_args)
|
||||||
|
self.config.save()
|
||||||
|
pre_loadmods = self.config.parser.find_dir(
|
||||||
|
"LoadModule", "ssl_module", start=self.vh_truth[1].path, exclude=False)
|
||||||
|
self.assertEqual(len(pre_loadmods), 2)
|
||||||
|
# The ssl.conf now has two LoadModule directives, one inside of
|
||||||
|
# !mod_ssl.c IfModule
|
||||||
|
self.config.assoc["test.example.com"] = self.vh_truth[0]
|
||||||
|
self.config.deploy_cert(
|
||||||
|
"random.demo", "example/cert.pem", "example/key.pem",
|
||||||
|
"example/cert_chain.pem", "example/fullchain.pem")
|
||||||
|
self.config.save()
|
||||||
|
# Ensure that the additional LoadModule wasn't written into the IfModule
|
||||||
|
post_loadmods = self.config.parser.find_dir(
|
||||||
|
"LoadModule", "ssl_module", start=self.vh_truth[1].path, exclude=False)
|
||||||
|
self.assertEqual(len(post_loadmods), 1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_loadmod_non_duplicate(self):
|
||||||
|
# the modules/mod_ssl.so exists in ssl.conf
|
||||||
|
sslmod_args = ["ssl_module", "modules/mod_somethingelse.so"]
|
||||||
|
rootconf_ifmod = self.config.parser.get_ifmod(
|
||||||
|
parser.get_aug_path(self.config.parser.loc["default"]),
|
||||||
|
"!mod_ssl.c", beginning=True)
|
||||||
|
self.config.parser.add_dir(rootconf_ifmod[:-1], "LoadModule", sslmod_args)
|
||||||
|
self.config.save()
|
||||||
|
self.config.assoc["test.example.com"] = self.vh_truth[0]
|
||||||
|
pre_matches = self.config.parser.find_dir("LoadModule",
|
||||||
|
"ssl_module", exclude=False)
|
||||||
|
|
||||||
|
self.assertRaises(MisconfigurationError, self.config.deploy_cert,
|
||||||
|
"random.demo", "example/cert.pem", "example/key.pem",
|
||||||
|
"example/cert_chain.pem", "example/fullchain.pem")
|
||||||
|
|
||||||
|
post_matches = self.config.parser.find_dir("LoadModule",
|
||||||
|
"ssl_module", exclude=False)
|
||||||
|
# Make sure that none was changed
|
||||||
|
self.assertEqual(pre_matches, post_matches)
|
||||||
|
|
||||||
|
def test_loadmod_not_found(self):
|
||||||
|
# Remove all existing LoadModule ssl_module... directives
|
||||||
|
orig_loadmods = self.config.parser.find_dir("LoadModule",
|
||||||
|
"ssl_module",
|
||||||
|
exclude=False)
|
||||||
|
for mod in orig_loadmods:
|
||||||
|
noarg_path = mod.rpartition("/")[0]
|
||||||
|
self.config.aug.remove(noarg_path)
|
||||||
|
self.config.save()
|
||||||
|
self.config.deploy_cert(
|
||||||
|
"random.demo", "example/cert.pem", "example/key.pem",
|
||||||
|
"example/cert_chain.pem", "example/fullchain.pem")
|
||||||
|
|
||||||
|
post_loadmods = self.config.parser.find_dir("LoadModule",
|
||||||
|
"ssl_module",
|
||||||
|
exclude=False)
|
||||||
|
self.assertFalse(post_loadmods)
|
||||||
|
|
||||||
|
def test_no_ifmod_search_false(self):
|
||||||
|
#pylint: disable=no-member
|
||||||
|
|
||||||
|
self.assertFalse(self.config.parser.not_modssl_ifmodule(
|
||||||
|
"/path/does/not/include/ifmod"
|
||||||
|
))
|
||||||
|
self.assertFalse(self.config.parser.not_modssl_ifmodule(
|
||||||
|
""
|
||||||
|
))
|
||||||
|
self.assertFalse(self.config.parser.not_modssl_ifmodule(
|
||||||
|
"/path/includes/IfModule/but/no/arguments"
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main() # pragma: no cover
|
||||||
9
certbot-apache/certbot_apache/tests/testdata/centos6_apache/apache/httpd/conf.d/README
vendored
Normal file
9
certbot-apache/certbot_apache/tests/testdata/centos6_apache/apache/httpd/conf.d/README
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
This directory holds Apache 2.0 module-specific configuration files;
|
||||||
|
any files in this directory which have the ".conf" extension will be
|
||||||
|
processed as Apache configuration files.
|
||||||
|
|
||||||
|
Files are processed in alphabetical order, so if using configuration
|
||||||
|
directives which depend on, say, mod_perl being loaded, ensure that
|
||||||
|
these are placed in a filename later in the sort order than "perl.conf".
|
||||||
|
|
||||||
222
certbot-apache/certbot_apache/tests/testdata/centos6_apache/apache/httpd/conf.d/ssl.conf
vendored
Normal file
222
certbot-apache/certbot_apache/tests/testdata/centos6_apache/apache/httpd/conf.d/ssl.conf
vendored
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
#
|
||||||
|
# This is the Apache server configuration file providing SSL support.
|
||||||
|
# It contains the configuration directives to instruct the server how to
|
||||||
|
# serve pages over an https connection. For detailing information about these
|
||||||
|
# directives see <URL:http://httpd.apache.org/docs/2.2/mod/mod_ssl.html>
|
||||||
|
#
|
||||||
|
# Do NOT simply read the instructions in here without understanding
|
||||||
|
# what they do. They're here only as hints or reminders. If you are unsure
|
||||||
|
# consult the online docs. You have been warned.
|
||||||
|
#
|
||||||
|
|
||||||
|
LoadModule ssl_module modules/mod_ssl.so
|
||||||
|
|
||||||
|
#
|
||||||
|
# When we also provide SSL we have to listen to the
|
||||||
|
# the HTTPS port in addition.
|
||||||
|
#
|
||||||
|
Listen 443
|
||||||
|
|
||||||
|
##
|
||||||
|
## SSL Global Context
|
||||||
|
##
|
||||||
|
## All SSL configuration in this context applies both to
|
||||||
|
## the main server and all SSL-enabled virtual hosts.
|
||||||
|
##
|
||||||
|
|
||||||
|
# Pass Phrase Dialog:
|
||||||
|
# Configure the pass phrase gathering process.
|
||||||
|
# The filtering dialog program (`builtin' is a internal
|
||||||
|
# terminal dialog) has to provide the pass phrase on stdout.
|
||||||
|
SSLPassPhraseDialog builtin
|
||||||
|
|
||||||
|
# Inter-Process Session Cache:
|
||||||
|
# Configure the SSL Session Cache: First the mechanism
|
||||||
|
# to use and second the expiring timeout (in seconds).
|
||||||
|
SSLSessionCache shmcb:/var/cache/mod_ssl/scache(512000)
|
||||||
|
SSLSessionCacheTimeout 300
|
||||||
|
|
||||||
|
# Semaphore:
|
||||||
|
# Configure the path to the mutual exclusion semaphore the
|
||||||
|
# SSL engine uses internally for inter-process synchronization.
|
||||||
|
SSLMutex default
|
||||||
|
|
||||||
|
# Pseudo Random Number Generator (PRNG):
|
||||||
|
# Configure one or more sources to seed the PRNG of the
|
||||||
|
# SSL library. The seed data should be of good random quality.
|
||||||
|
# WARNING! On some platforms /dev/random blocks if not enough entropy
|
||||||
|
# is available. This means you then cannot use the /dev/random device
|
||||||
|
# because it would lead to very long connection times (as long as
|
||||||
|
# it requires to make more entropy available). But usually those
|
||||||
|
# platforms additionally provide a /dev/urandom device which doesn't
|
||||||
|
# block. So, if available, use this one instead. Read the mod_ssl User
|
||||||
|
# Manual for more details.
|
||||||
|
SSLRandomSeed startup file:/dev/urandom 256
|
||||||
|
SSLRandomSeed connect builtin
|
||||||
|
#SSLRandomSeed startup file:/dev/random 512
|
||||||
|
#SSLRandomSeed connect file:/dev/random 512
|
||||||
|
#SSLRandomSeed connect file:/dev/urandom 512
|
||||||
|
|
||||||
|
#
|
||||||
|
# Use "SSLCryptoDevice" to enable any supported hardware
|
||||||
|
# accelerators. Use "openssl engine -v" to list supported
|
||||||
|
# engine names. NOTE: If you enable an accelerator and the
|
||||||
|
# server does not start, consult the error logs and ensure
|
||||||
|
# your accelerator is functioning properly.
|
||||||
|
#
|
||||||
|
SSLCryptoDevice builtin
|
||||||
|
#SSLCryptoDevice ubsec
|
||||||
|
|
||||||
|
##
|
||||||
|
## SSL Virtual Host Context
|
||||||
|
##
|
||||||
|
|
||||||
|
<VirtualHost _default_:443>
|
||||||
|
|
||||||
|
# General setup for the virtual host, inherited from global configuration
|
||||||
|
#DocumentRoot "/var/www/html"
|
||||||
|
#ServerName www.example.com:443
|
||||||
|
|
||||||
|
# Use separate log files for the SSL virtual host; note that LogLevel
|
||||||
|
# is not inherited from httpd.conf.
|
||||||
|
ErrorLog logs/ssl_error_log
|
||||||
|
TransferLog logs/ssl_access_log
|
||||||
|
LogLevel warn
|
||||||
|
|
||||||
|
# SSL Engine Switch:
|
||||||
|
# Enable/Disable SSL for this virtual host.
|
||||||
|
SSLEngine on
|
||||||
|
|
||||||
|
# SSL Protocol support:
|
||||||
|
# List the enable protocol levels with which clients will be able to
|
||||||
|
# connect. Disable SSLv2 access by default:
|
||||||
|
SSLProtocol all -SSLv2
|
||||||
|
|
||||||
|
# SSL Cipher Suite:
|
||||||
|
# List the ciphers that the client is permitted to negotiate.
|
||||||
|
# See the mod_ssl documentation for a complete list.
|
||||||
|
SSLCipherSuite DEFAULT:!EXP:!SSLv2:!DES:!IDEA:!SEED:+3DES
|
||||||
|
|
||||||
|
# Server Certificate:
|
||||||
|
# Point SSLCertificateFile at a PEM encoded certificate. If
|
||||||
|
# the certificate is encrypted, then you will be prompted for a
|
||||||
|
# pass phrase. Note that a kill -HUP will prompt again. A new
|
||||||
|
# certificate can be generated using the genkey(1) command.
|
||||||
|
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
|
||||||
|
|
||||||
|
# Server Private Key:
|
||||||
|
# If the key is not combined with the certificate, use this
|
||||||
|
# directive to point at the key file. Keep in mind that if
|
||||||
|
# you've both a RSA and a DSA private key you can configure
|
||||||
|
# both in parallel (to also allow the use of DSA ciphers, etc.)
|
||||||
|
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
|
||||||
|
|
||||||
|
# Server Certificate Chain:
|
||||||
|
# Point SSLCertificateChainFile at a file containing the
|
||||||
|
# concatenation of PEM encoded CA certificates which form the
|
||||||
|
# certificate chain for the server certificate. Alternatively
|
||||||
|
# the referenced file can be the same as SSLCertificateFile
|
||||||
|
# when the CA certificates are directly appended to the server
|
||||||
|
# certificate for convinience.
|
||||||
|
#SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
|
||||||
|
|
||||||
|
# Certificate Authority (CA):
|
||||||
|
# Set the CA certificate verification path where to find CA
|
||||||
|
# certificates for client authentication or alternatively one
|
||||||
|
# huge file containing all of them (file must be PEM encoded)
|
||||||
|
#SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt
|
||||||
|
|
||||||
|
# Client Authentication (Type):
|
||||||
|
# Client certificate verification type and depth. Types are
|
||||||
|
# none, optional, require and optional_no_ca. Depth is a
|
||||||
|
# number which specifies how deeply to verify the certificate
|
||||||
|
# issuer chain before deciding the certificate is not valid.
|
||||||
|
#SSLVerifyClient require
|
||||||
|
#SSLVerifyDepth 10
|
||||||
|
|
||||||
|
# Access Control:
|
||||||
|
# With SSLRequire you can do per-directory access control based
|
||||||
|
# on arbitrary complex boolean expressions containing server
|
||||||
|
# variable checks and other lookup directives. The syntax is a
|
||||||
|
# mixture between C and Perl. See the mod_ssl documentation
|
||||||
|
# for more details.
|
||||||
|
#<Location />
|
||||||
|
#SSLRequire ( %{SSL_CIPHER} !~ m/^(EXP|NULL)/ \
|
||||||
|
# and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \
|
||||||
|
# and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \
|
||||||
|
# and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \
|
||||||
|
# and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20 ) \
|
||||||
|
# or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/
|
||||||
|
#</Location>
|
||||||
|
|
||||||
|
# SSL Engine Options:
|
||||||
|
# Set various options for the SSL engine.
|
||||||
|
# o FakeBasicAuth:
|
||||||
|
# Translate the client X.509 into a Basic Authorisation. This means that
|
||||||
|
# the standard Auth/DBMAuth methods can be used for access control. The
|
||||||
|
# user name is the `one line' version of the client's X.509 certificate.
|
||||||
|
# Note that no password is obtained from the user. Every entry in the user
|
||||||
|
# file needs this password: `xxj31ZMTZzkVA'.
|
||||||
|
# o ExportCertData:
|
||||||
|
# This exports two additional environment variables: SSL_CLIENT_CERT and
|
||||||
|
# SSL_SERVER_CERT. These contain the PEM-encoded certificates of the
|
||||||
|
# server (always existing) and the client (only existing when client
|
||||||
|
# authentication is used). This can be used to import the certificates
|
||||||
|
# into CGI scripts.
|
||||||
|
# o StdEnvVars:
|
||||||
|
# This exports the standard SSL/TLS related `SSL_*' environment variables.
|
||||||
|
# Per default this exportation is switched off for performance reasons,
|
||||||
|
# because the extraction step is an expensive operation and is usually
|
||||||
|
# useless for serving static content. So one usually enables the
|
||||||
|
# exportation for CGI and SSI requests only.
|
||||||
|
# o StrictRequire:
|
||||||
|
# This denies access when "SSLRequireSSL" or "SSLRequire" applied even
|
||||||
|
# under a "Satisfy any" situation, i.e. when it applies access is denied
|
||||||
|
# and no other module can change it.
|
||||||
|
# o OptRenegotiate:
|
||||||
|
# This enables optimized SSL connection renegotiation handling when SSL
|
||||||
|
# directives are used in per-directory context.
|
||||||
|
#SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
|
||||||
|
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
|
||||||
|
SSLOptions +StdEnvVars
|
||||||
|
</Files>
|
||||||
|
<Directory "/var/www/cgi-bin">
|
||||||
|
SSLOptions +StdEnvVars
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
# SSL Protocol Adjustments:
|
||||||
|
# The safe and default but still SSL/TLS standard compliant shutdown
|
||||||
|
# approach is that mod_ssl sends the close notify alert but doesn't wait for
|
||||||
|
# the close notify alert from client. When you need a different shutdown
|
||||||
|
# approach you can use one of the following variables:
|
||||||
|
# o ssl-unclean-shutdown:
|
||||||
|
# This forces an unclean shutdown when the connection is closed, i.e. no
|
||||||
|
# SSL close notify alert is send or allowed to received. This violates
|
||||||
|
# the SSL/TLS standard but is needed for some brain-dead browsers. Use
|
||||||
|
# this when you receive I/O errors because of the standard approach where
|
||||||
|
# mod_ssl sends the close notify alert.
|
||||||
|
# o ssl-accurate-shutdown:
|
||||||
|
# This forces an accurate shutdown when the connection is closed, i.e. a
|
||||||
|
# SSL close notify alert is send and mod_ssl waits for the close notify
|
||||||
|
# alert of the client. This is 100% SSL/TLS standard compliant, but in
|
||||||
|
# practice often causes hanging connections with brain-dead browsers. Use
|
||||||
|
# this only for browsers where you know that their SSL implementation
|
||||||
|
# works correctly.
|
||||||
|
# Notice: Most problems of broken clients are also related to the HTTP
|
||||||
|
# keep-alive facility, so you usually additionally want to disable
|
||||||
|
# keep-alive for those clients, too. Use variable "nokeepalive" for this.
|
||||||
|
# Similarly, one has to force some clients to use HTTP/1.0 to workaround
|
||||||
|
# their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and
|
||||||
|
# "force-response-1.0" for this.
|
||||||
|
SetEnvIf User-Agent ".*MSIE.*" \
|
||||||
|
nokeepalive ssl-unclean-shutdown \
|
||||||
|
downgrade-1.0 force-response-1.0
|
||||||
|
|
||||||
|
# Per-Server Logging:
|
||||||
|
# The home of a custom SSL log file. Use this when you want a
|
||||||
|
# compact non-error SSL logfile on a virtual host basis.
|
||||||
|
CustomLog logs/ssl_request_log \
|
||||||
|
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
|
||||||
|
|
||||||
|
</VirtualHost>
|
||||||
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<VirtualHost *:80>
|
||||||
|
ServerName test.example.com
|
||||||
|
ServerAdmin webmaster@dummy-host.example.com
|
||||||
|
DocumentRoot /var/www/htdocs
|
||||||
|
ErrorLog logs/dummy-host.example.com-error_log
|
||||||
|
CustomLog logs/dummy-host.example.com-access_log common
|
||||||
|
</VirtualHost>
|
||||||
11
certbot-apache/certbot_apache/tests/testdata/centos6_apache/apache/httpd/conf.d/welcome.conf
vendored
Normal file
11
certbot-apache/certbot_apache/tests/testdata/centos6_apache/apache/httpd/conf.d/welcome.conf
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#
|
||||||
|
# This configuration file enables the default "Welcome"
|
||||||
|
# page if there is no default index page present for
|
||||||
|
# the root URL. To disable the Welcome page, comment
|
||||||
|
# out all the lines below.
|
||||||
|
#
|
||||||
|
<LocationMatch "^/+$">
|
||||||
|
Options -Indexes
|
||||||
|
ErrorDocument 403 /error/noindex.html
|
||||||
|
</LocationMatch>
|
||||||
|
|
||||||
1009
certbot-apache/certbot_apache/tests/testdata/centos6_apache/apache/httpd/conf/httpd.conf
vendored
Normal file
1009
certbot-apache/certbot_apache/tests/testdata/centos6_apache/apache/httpd/conf/httpd.conf
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user