1"""Test for certbot_apache._internal.configurator for CentOS 6 overrides""" 2import unittest 3from unittest import mock 4 5from certbot.compat import os 6from certbot.errors import MisconfigurationError 7from certbot_apache._internal import obj 8from certbot_apache._internal import override_centos 9from certbot_apache._internal import parser 10import util 11 12 13def get_vh_truth(temp_dir, config_name): 14 """Return the ground truth for the specified directory.""" 15 prefix = os.path.join( 16 temp_dir, config_name, "httpd/conf.d") 17 18 aug_pre = "/files" + prefix 19 vh_truth = [ 20 obj.VirtualHost( 21 os.path.join(prefix, "test.example.com.conf"), 22 os.path.join(aug_pre, "test.example.com.conf/VirtualHost"), 23 {obj.Addr.fromstring("*:80")}, 24 False, True, "test.example.com"), 25 obj.VirtualHost( 26 os.path.join(prefix, "ssl.conf"), 27 os.path.join(aug_pre, "ssl.conf/VirtualHost"), 28 {obj.Addr.fromstring("_default_:443")}, 29 True, True, None) 30 ] 31 return vh_truth 32 33class CentOS6Tests(util.ApacheTest): 34 """Tests for CentOS 6""" 35 36 def setUp(self): # pylint: disable=arguments-differ 37 test_dir = "centos6_apache/apache" 38 config_root = "centos6_apache/apache/httpd" 39 vhost_root = "centos6_apache/apache/httpd/conf.d" 40 super().setUp(test_dir=test_dir, 41 config_root=config_root, 42 vhost_root=vhost_root) 43 44 self.config = util.get_apache_configurator( 45 self.config_path, self.vhost_path, self.config_dir, self.work_dir, 46 version=(2, 2, 15), os_info="centos") 47 self.vh_truth = get_vh_truth( 48 self.temp_dir, "centos6_apache/apache") 49 50 def test_get_parser(self): 51 self.assertTrue(isinstance(self.config.parser, 52 override_centos.CentOSParser)) 53 54 def test_get_virtual_hosts(self): 55 """Make sure all vhosts are being properly found.""" 56 vhs = self.config.get_virtual_hosts() 57 self.assertEqual(len(vhs), 2) 58 found = 0 59 60 for vhost in vhs: 61 for centos_truth in self.vh_truth: 62 if vhost == centos_truth: 63 found += 1 64 break 65 else: 66 raise Exception("Missed: %s" % vhost) # pragma: no cover 67 self.assertEqual(found, 2) 68 69 @mock.patch("certbot_apache._internal.configurator.display_util.notify") 70 def test_loadmod_default(self, unused_mock_notify): 71 ssl_loadmods = self.config.parser.find_dir( 72 "LoadModule", "ssl_module", exclude=False) 73 self.assertEqual(len(ssl_loadmods), 1) 74 # Make sure the LoadModule ssl_module is in ssl.conf (default) 75 self.assertTrue("ssl.conf" in ssl_loadmods[0]) 76 # ...and that it's not inside of <IfModule> 77 self.assertFalse("IfModule" in ssl_loadmods[0]) 78 79 # Get the example vhost 80 self.config.assoc["test.example.com"] = self.vh_truth[0] 81 self.config.deploy_cert( 82 "random.demo", "example/cert.pem", "example/key.pem", 83 "example/cert_chain.pem", "example/fullchain.pem") 84 self.config.save() 85 86 post_loadmods = self.config.parser.find_dir( 87 "LoadModule", "ssl_module", exclude=False) 88 89 # We should now have LoadModule ssl_module in root conf and ssl.conf 90 self.assertEqual(len(post_loadmods), 2) 91 for lm in post_loadmods: 92 # lm[:-7] removes "/arg[#]" from the path 93 arguments = self.config.parser.get_all_args(lm[:-7]) 94 self.assertEqual(arguments, ["ssl_module", "modules/mod_ssl.so"]) 95 # ...and both of them should be wrapped in <IfModule !mod_ssl.c> 96 # lm[:-17] strips off /directive/arg[1] from the path. 97 ifmod_args = self.config.parser.get_all_args(lm[:-17]) 98 self.assertTrue("!mod_ssl.c" in ifmod_args) 99 100 @mock.patch("certbot_apache._internal.configurator.display_util.notify") 101 def test_loadmod_multiple(self, unused_mock_notify): 102 sslmod_args = ["ssl_module", "modules/mod_ssl.so"] 103 # Adds another LoadModule to main httpd.conf in addtition to ssl.conf 104 self.config.parser.add_dir(self.config.parser.loc["default"], "LoadModule", 105 sslmod_args) 106 self.config.save() 107 pre_loadmods = self.config.parser.find_dir( 108 "LoadModule", "ssl_module", exclude=False) 109 # LoadModules are not within IfModule blocks 110 self.assertFalse(any("ifmodule" in m.lower() for m in pre_loadmods)) 111 self.config.assoc["test.example.com"] = self.vh_truth[0] 112 self.config.deploy_cert( 113 "random.demo", "example/cert.pem", "example/key.pem", 114 "example/cert_chain.pem", "example/fullchain.pem") 115 post_loadmods = self.config.parser.find_dir( 116 "LoadModule", "ssl_module", exclude=False) 117 118 for mod in post_loadmods: 119 self.assertTrue(self.config.parser.not_modssl_ifmodule(mod)) #pylint: disable=no-member 120 121 @mock.patch("certbot_apache._internal.configurator.display_util.notify") 122 def test_loadmod_rootconf_exists(self, unused_mock_notify): 123 sslmod_args = ["ssl_module", "modules/mod_ssl.so"] 124 rootconf_ifmod = self.config.parser.get_ifmod( 125 parser.get_aug_path(self.config.parser.loc["default"]), 126 "!mod_ssl.c", beginning=True) 127 self.config.parser.add_dir(rootconf_ifmod[:-1], "LoadModule", sslmod_args) 128 self.config.save() 129 # Get the example vhost 130 self.config.assoc["test.example.com"] = self.vh_truth[0] 131 self.config.deploy_cert( 132 "random.demo", "example/cert.pem", "example/key.pem", 133 "example/cert_chain.pem", "example/fullchain.pem") 134 self.config.save() 135 136 root_loadmods = self.config.parser.find_dir( 137 "LoadModule", "ssl_module", 138 start=parser.get_aug_path(self.config.parser.loc["default"]), 139 exclude=False) 140 141 mods = [lm for lm in root_loadmods if self.config.parser.loc["default"] in lm] 142 143 self.assertEqual(len(mods), 1) 144 # [:-7] removes "/arg[#]" from the path 145 self.assertEqual( 146 self.config.parser.get_all_args(mods[0][:-7]), 147 sslmod_args) 148 149 @mock.patch("certbot_apache._internal.configurator.display_util.notify") 150 def test_neg_loadmod_already_on_path(self, unused_mock_notify): 151 loadmod_args = ["ssl_module", "modules/mod_ssl.so"] 152 ifmod = self.config.parser.get_ifmod( 153 self.vh_truth[1].path, "!mod_ssl.c", beginning=True) 154 self.config.parser.add_dir(ifmod[:-1], "LoadModule", loadmod_args) 155 self.config.parser.add_dir(self.vh_truth[1].path, "LoadModule", loadmod_args) 156 self.config.save() 157 pre_loadmods = self.config.parser.find_dir( 158 "LoadModule", "ssl_module", start=self.vh_truth[1].path, exclude=False) 159 self.assertEqual(len(pre_loadmods), 2) 160 # The ssl.conf now has two LoadModule directives, one inside of 161 # !mod_ssl.c IfModule 162 self.config.assoc["test.example.com"] = self.vh_truth[0] 163 self.config.deploy_cert( 164 "random.demo", "example/cert.pem", "example/key.pem", 165 "example/cert_chain.pem", "example/fullchain.pem") 166 self.config.save() 167 # Ensure that the additional LoadModule wasn't written into the IfModule 168 post_loadmods = self.config.parser.find_dir( 169 "LoadModule", "ssl_module", start=self.vh_truth[1].path, exclude=False) 170 self.assertEqual(len(post_loadmods), 1) 171 172 def test_loadmod_non_duplicate(self): 173 # the modules/mod_ssl.so exists in ssl.conf 174 sslmod_args = ["ssl_module", "modules/mod_somethingelse.so"] 175 rootconf_ifmod = self.config.parser.get_ifmod( 176 parser.get_aug_path(self.config.parser.loc["default"]), 177 "!mod_ssl.c", beginning=True) 178 self.config.parser.add_dir(rootconf_ifmod[:-1], "LoadModule", sslmod_args) 179 self.config.save() 180 self.config.assoc["test.example.com"] = self.vh_truth[0] 181 pre_matches = self.config.parser.find_dir("LoadModule", 182 "ssl_module", exclude=False) 183 184 self.assertRaises(MisconfigurationError, self.config.deploy_cert, 185 "random.demo", "example/cert.pem", "example/key.pem", 186 "example/cert_chain.pem", "example/fullchain.pem") 187 188 post_matches = self.config.parser.find_dir("LoadModule", 189 "ssl_module", exclude=False) 190 # Make sure that none was changed 191 self.assertEqual(pre_matches, post_matches) 192 193 @mock.patch("certbot_apache._internal.configurator.display_util.notify") 194 def test_loadmod_not_found(self, unused_mock_notify): 195 # Remove all existing LoadModule ssl_module... directives 196 orig_loadmods = self.config.parser.find_dir("LoadModule", 197 "ssl_module", 198 exclude=False) 199 for mod in orig_loadmods: 200 noarg_path = mod.rpartition("/")[0] 201 self.config.parser.aug.remove(noarg_path) 202 self.config.save() 203 self.config.deploy_cert( 204 "random.demo", "example/cert.pem", "example/key.pem", 205 "example/cert_chain.pem", "example/fullchain.pem") 206 207 post_loadmods = self.config.parser.find_dir("LoadModule", 208 "ssl_module", 209 exclude=False) 210 self.assertFalse(post_loadmods) 211 212 def test_no_ifmod_search_false(self): 213 #pylint: disable=no-member 214 215 self.assertFalse(self.config.parser.not_modssl_ifmodule( 216 "/path/does/not/include/ifmod" 217 )) 218 self.assertFalse(self.config.parser.not_modssl_ifmodule( 219 "" 220 )) 221 self.assertFalse(self.config.parser.not_modssl_ifmodule( 222 "/path/includes/IfModule/but/no/arguments" 223 )) 224 225 226if __name__ == "__main__": 227 unittest.main() # pragma: no cover 228