Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/certbot/certbot.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'certbot-nginx/tests/parser_test.py')
-rw-r--r--certbot-nginx/tests/parser_test.py487
1 files changed, 487 insertions, 0 deletions
diff --git a/certbot-nginx/tests/parser_test.py b/certbot-nginx/tests/parser_test.py
new file mode 100644
index 000000000..2f3b260ca
--- /dev/null
+++ b/certbot-nginx/tests/parser_test.py
@@ -0,0 +1,487 @@
+"""Tests for certbot_nginx._internal.parser."""
+import glob
+import re
+import shutil
+import unittest
+
+from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module
+from certbot import errors
+from certbot.compat import os
+from certbot_nginx._internal import nginxparser
+from certbot_nginx._internal import obj
+from certbot_nginx._internal import parser
+import test_util as util
+
+
+class NginxParserTest(util.NginxTest):
+ """Nginx Parser Test."""
+
+ def tearDown(self):
+ shutil.rmtree(self.temp_dir)
+ shutil.rmtree(self.config_dir)
+ shutil.rmtree(self.work_dir)
+
+ def test_root_normalized(self):
+ path = os.path.join(self.temp_dir, "etc_nginx/////"
+ "ubuntu_nginx/../../etc_nginx")
+ nparser = parser.NginxParser(path)
+ self.assertEqual(nparser.root, self.config_path)
+
+ def test_root_absolute(self):
+ curr_dir = os.getcwd()
+ try:
+ # On Windows current directory may be on a different drive than self.tempdir.
+ # However a relative path between two different drives is invalid. So we move to
+ # self.tempdir to ensure that we stay on the same drive.
+ os.chdir(self.temp_dir)
+ nparser = parser.NginxParser(os.path.relpath(self.config_path))
+ self.assertEqual(nparser.root, self.config_path)
+ finally:
+ os.chdir(curr_dir)
+
+ def test_root_no_trailing_slash(self):
+ nparser = parser.NginxParser(self.config_path + os.path.sep)
+ self.assertEqual(nparser.root, self.config_path)
+
+ def test_load(self):
+ """Test recursive conf file parsing.
+
+ """
+ nparser = parser.NginxParser(self.config_path)
+ nparser.load()
+ self.assertEqual({nparser.abs_path(x) for x in
+ ['foo.conf', 'nginx.conf', 'server.conf',
+ 'sites-enabled/default',
+ 'sites-enabled/example.com',
+ 'sites-enabled/headers.com',
+ 'sites-enabled/migration.com',
+ 'sites-enabled/sslon.com',
+ 'sites-enabled/globalssl.com',
+ 'sites-enabled/ipv6.com',
+ 'sites-enabled/ipv6ssl.com']},
+ set(nparser.parsed.keys()))
+ self.assertEqual([['server_name', 'somename', 'alias', 'another.alias']],
+ nparser.parsed[nparser.abs_path('server.conf')])
+ self.assertEqual([[['server'], [['listen', '69.50.225.155:9000'],
+ ['listen', '127.0.0.1'],
+ ['server_name', '.example.com'],
+ ['server_name', 'example.*']]]],
+ nparser.parsed[nparser.abs_path(
+ 'sites-enabled/example.com')])
+
+ def test_abs_path(self):
+ nparser = parser.NginxParser(self.config_path)
+ if os.name != 'nt':
+ self.assertEqual('/etc/nginx/*', nparser.abs_path('/etc/nginx/*'))
+ self.assertEqual(os.path.join(self.config_path, 'foo/bar'),
+ nparser.abs_path('foo/bar'))
+ else:
+ self.assertEqual('C:\\etc\\nginx\\*', nparser.abs_path('C:\\etc\\nginx\\*'))
+ self.assertEqual(os.path.join(self.config_path, 'foo\\bar'),
+ nparser.abs_path('foo\\bar'))
+
+
+ def test_filedump(self):
+ nparser = parser.NginxParser(self.config_path)
+ nparser.filedump('test', lazy=False)
+ # pylint: disable=protected-access
+ parsed = nparser._parse_files(nparser.abs_path(
+ 'sites-enabled/example.com.test'))
+ self.assertEqual(3, len(glob.glob(nparser.abs_path('*.test'))))
+ self.assertEqual(8, len(
+ glob.glob(nparser.abs_path('sites-enabled/*.test'))))
+ self.assertEqual([[['server'], [['listen', '69.50.225.155:9000'],
+ ['listen', '127.0.0.1'],
+ ['server_name', '.example.com'],
+ ['server_name', 'example.*']]]],
+ parsed[0])
+
+ def test__do_for_subarray(self):
+ # pylint: disable=protected-access
+ mylists = [([[2], [3], [2]], [[0], [2]]),
+ ([[2], [3], [4]], [[0]]),
+ ([[4], [3], [2]], [[2]]),
+ ([], []),
+ (2, []),
+ ([[[2], [3], [2]], [[2], [3], [2]]],
+ [[0, 0], [0, 2], [1, 0], [1, 2]]),
+ ([[[0], [3], [2]], [[2], [3], [2]]], [[0, 2], [1, 0], [1, 2]]),
+ ([[[0], [3], [4]], [[2], [3], [2]]], [[1, 0], [1, 2]]),
+ ([[[0], [3], [4]], [[5], [3], [2]]], [[1, 2]]),
+ ([[[0], [3], [4]], [[5], [3], [0]]], [])]
+
+ for mylist, result in mylists:
+ paths = [] # type: List[List[int]]
+ parser._do_for_subarray(mylist,
+ lambda x: isinstance(x, list) and
+ len(x) >= 1 and
+ x[0] == 2,
+ lambda x, y, pts=paths: pts.append(y))
+ self.assertEqual(paths, result)
+
+ def test_get_vhosts_global_ssl(self):
+ nparser = parser.NginxParser(self.config_path)
+ vhosts = nparser.get_vhosts()
+
+ vhost = obj.VirtualHost(nparser.abs_path('sites-enabled/globalssl.com'),
+ [obj.Addr('4.8.2.6', '57', True, False,
+ False, False)],
+ True, True, set(['globalssl.com']), [], [0])
+
+ globalssl_com = [x for x in vhosts if 'globalssl.com' in x.filep][0]
+ self.assertEqual(vhost, globalssl_com)
+
+ def test_get_vhosts(self):
+ nparser = parser.NginxParser(self.config_path)
+ vhosts = nparser.get_vhosts()
+
+ vhost1 = obj.VirtualHost(nparser.abs_path('nginx.conf'),
+ [obj.Addr('', '8080', False, False,
+ False, False)],
+ False, True,
+ set(['localhost',
+ r'~^(www\.)?(example|bar)\.']),
+ [], [10, 1, 9])
+ vhost2 = obj.VirtualHost(nparser.abs_path('nginx.conf'),
+ [obj.Addr('somename', '8080', False, False,
+ False, False),
+ obj.Addr('', '8000', False, False,
+ False, False)],
+ False, True,
+ set(['somename', 'another.alias', 'alias']),
+ [], [10, 1, 12])
+ vhost3 = obj.VirtualHost(nparser.abs_path('sites-enabled/example.com'),
+ [obj.Addr('69.50.225.155', '9000',
+ False, False, False, False),
+ obj.Addr('127.0.0.1', '', False, False,
+ False, False)],
+ False, True,
+ set(['.example.com', 'example.*']), [], [0])
+ vhost4 = obj.VirtualHost(nparser.abs_path('sites-enabled/default'),
+ [obj.Addr('myhost', '', False, True,
+ False, False),
+ obj.Addr('otherhost', '', False, True,
+ False, False)],
+ False, True, set(['www.example.org']),
+ [], [0])
+ vhost5 = obj.VirtualHost(nparser.abs_path('foo.conf'),
+ [obj.Addr('*', '80', True, True,
+ False, False)],
+ True, True, set(['*.www.foo.com',
+ '*.www.example.com']),
+ [], [2, 1, 0])
+
+ self.assertEqual(13, len(vhosts))
+ example_com = [x for x in vhosts if 'example.com' in x.filep][0]
+ self.assertEqual(vhost3, example_com)
+ default = [x for x in vhosts if 'default' in x.filep][0]
+ self.assertEqual(vhost4, default)
+ fooconf = [x for x in vhosts if 'foo.conf' in x.filep][0]
+ self.assertEqual(vhost5, fooconf)
+ localhost = [x for x in vhosts if 'localhost' in x.names][0]
+ self.assertEqual(vhost1, localhost)
+ somename = [x for x in vhosts if 'somename' in x.names][0]
+ self.assertEqual(vhost2, somename)
+
+ def test_has_ssl_on_directive(self):
+ nparser = parser.NginxParser(self.config_path)
+ mock_vhost = obj.VirtualHost(None, None, None, None, None,
+ [['listen', 'myhost default_server'],
+ ['server_name', 'www.example.org'],
+ [['location', '/'], [['root', 'html'], ['index', 'index.html index.htm']]]
+ ], None)
+ self.assertFalse(nparser.has_ssl_on_directive(mock_vhost))
+ mock_vhost.raw = [['listen', '*:80', 'default_server', 'ssl'],
+ ['server_name', '*.www.foo.com', '*.www.example.com'],
+ ['root', '/home/ubuntu/sites/foo/']]
+ self.assertFalse(nparser.has_ssl_on_directive(mock_vhost))
+ mock_vhost.raw = [['listen', '80 ssl'],
+ ['server_name', '*.www.foo.com', '*.www.example.com']]
+ self.assertFalse(nparser.has_ssl_on_directive(mock_vhost))
+ mock_vhost.raw = [['listen', '80'],
+ ['ssl', 'on'],
+ ['server_name', '*.www.foo.com', '*.www.example.com']]
+ self.assertTrue(nparser.has_ssl_on_directive(mock_vhost))
+
+
+ def test_remove_server_directives(self):
+ nparser = parser.NginxParser(self.config_path)
+ mock_vhost = obj.VirtualHost(nparser.abs_path('nginx.conf'),
+ None, None, None,
+ set(['localhost',
+ r'~^(www\.)?(example|bar)\.']),
+ None, [10, 1, 9])
+ example_com = nparser.abs_path('sites-enabled/example.com')
+ names = set(['.example.com', 'example.*'])
+ mock_vhost.filep = example_com
+ mock_vhost.names = names
+ mock_vhost.path = [0]
+ nparser.add_server_directives(mock_vhost,
+ [['foo', 'bar'], ['ssl_certificate',
+ '/etc/ssl/cert2.pem']])
+ nparser.remove_server_directives(mock_vhost, 'foo')
+ nparser.remove_server_directives(mock_vhost, 'ssl_certificate')
+ self.assertEqual(nparser.parsed[example_com],
+ [[['server'], [['listen', '69.50.225.155:9000'],
+ ['listen', '127.0.0.1'],
+ ['server_name', '.example.com'],
+ ['server_name', 'example.*'],
+ []]]])
+
+ def test_add_server_directives(self):
+ nparser = parser.NginxParser(self.config_path)
+ mock_vhost = obj.VirtualHost(nparser.abs_path('nginx.conf'),
+ None, None, None,
+ set(['localhost',
+ r'~^(www\.)?(example|bar)\.']),
+ None, [10, 1, 9])
+ nparser.add_server_directives(mock_vhost,
+ [['foo', 'bar'], ['\n ', 'ssl_certificate', ' ',
+ '/etc/ssl/cert.pem']])
+ ssl_re = re.compile(r'\n\s+ssl_certificate /etc/ssl/cert.pem')
+ dump = nginxparser.dumps(nparser.parsed[nparser.abs_path('nginx.conf')])
+ self.assertEqual(1, len(re.findall(ssl_re, dump)))
+
+ example_com = nparser.abs_path('sites-enabled/example.com')
+ names = set(['.example.com', 'example.*'])
+ mock_vhost.filep = example_com
+ mock_vhost.names = names
+ mock_vhost.path = [0]
+ nparser.add_server_directives(mock_vhost,
+ [['foo', 'bar'], ['ssl_certificate',
+ '/etc/ssl/cert2.pem']])
+ nparser.add_server_directives(mock_vhost, [['foo', 'bar']])
+ from certbot_nginx._internal.parser import COMMENT
+ self.assertEqual(nparser.parsed[example_com],
+ [[['server'], [['listen', '69.50.225.155:9000'],
+ ['listen', '127.0.0.1'],
+ ['server_name', '.example.com'],
+ ['server_name', 'example.*'],
+ ['foo', 'bar'],
+ ['#', COMMENT],
+ ['ssl_certificate', '/etc/ssl/cert2.pem'],
+ ['#', COMMENT], [], []
+ ]]])
+
+ server_conf = nparser.abs_path('server.conf')
+ names = set(['alias', 'another.alias', 'somename'])
+ mock_vhost.filep = server_conf
+ mock_vhost.names = names
+ mock_vhost.path = []
+ self.assertRaises(errors.MisconfigurationError,
+ nparser.add_server_directives,
+ mock_vhost,
+ [['foo', 'bar'],
+ ['ssl_certificate', '/etc/ssl/cert2.pem']])
+
+ def test_comment_is_repeatable(self):
+ nparser = parser.NginxParser(self.config_path)
+ example_com = nparser.abs_path('sites-enabled/example.com')
+ mock_vhost = obj.VirtualHost(example_com,
+ None, None, None,
+ set(['.example.com', 'example.*']),
+ None, [0])
+ nparser.add_server_directives(mock_vhost,
+ [['\n ', '#', ' ', 'what a nice comment']])
+ nparser.add_server_directives(mock_vhost,
+ [['\n ', 'include', ' ',
+ nparser.abs_path('comment_in_file.conf')]])
+ from certbot_nginx._internal.parser import COMMENT
+ self.assertEqual(nparser.parsed[example_com],
+ [[['server'], [['listen', '69.50.225.155:9000'],
+ ['listen', '127.0.0.1'],
+ ['server_name', '.example.com'],
+ ['server_name', 'example.*'],
+ ['#', ' ', 'what a nice comment'],
+ [],
+ ['include', nparser.abs_path('comment_in_file.conf')],
+ ['#', COMMENT],
+ []]]]
+)
+
+ def test_replace_server_directives(self):
+ nparser = parser.NginxParser(self.config_path)
+ target = set(['.example.com', 'example.*'])
+ filep = nparser.abs_path('sites-enabled/example.com')
+ mock_vhost = obj.VirtualHost(filep, None, None, None, target, None, [0])
+ nparser.update_or_add_server_directives(
+ mock_vhost, [['server_name', 'foobar.com']])
+ from certbot_nginx._internal.parser import COMMENT
+ self.assertEqual(
+ nparser.parsed[filep],
+ [[['server'], [['listen', '69.50.225.155:9000'],
+ ['listen', '127.0.0.1'],
+ ['server_name', 'foobar.com'], ['#', COMMENT],
+ ['server_name', 'example.*'], []
+ ]]])
+ mock_vhost.names = set(['foobar.com', 'example.*'])
+ nparser.update_or_add_server_directives(
+ mock_vhost, [['ssl_certificate', 'cert.pem']])
+ self.assertEqual(
+ nparser.parsed[filep],
+ [[['server'], [['listen', '69.50.225.155:9000'],
+ ['listen', '127.0.0.1'],
+ ['server_name', 'foobar.com'], ['#', COMMENT],
+ ['server_name', 'example.*'], [],
+ ['ssl_certificate', 'cert.pem'], ['#', COMMENT], [],
+ ]]])
+
+ def test_get_best_match(self):
+ target_name = 'www.eff.org'
+ names = [set(['www.eff.org', 'irrelevant.long.name.eff.org', '*.org']),
+ set(['eff.org', 'ww2.eff.org', 'test.www.eff.org']),
+ set(['*.eff.org', '.www.eff.org']),
+ set(['.eff.org', '*.org']),
+ set(['www.eff.', 'www.eff.*', '*.www.eff.org']),
+ set(['example.com', r'~^(www\.)?(eff.+)', '*.eff.*']),
+ set(['*', r'~^(www\.)?(eff.+)']),
+ set(['www.*', r'~^(www\.)?(eff.+)', '.test.eff.org']),
+ set(['*.org', r'*.eff.org', 'www.eff.*']),
+ set(['*.www.eff.org', 'www.*']),
+ set(['*.org']),
+ set([]),
+ set(['example.com'])]
+ winners = [('exact', 'www.eff.org'),
+ (None, None),
+ ('exact', '.www.eff.org'),
+ ('wildcard_start', '.eff.org'),
+ ('wildcard_end', 'www.eff.*'),
+ ('regex', r'~^(www\.)?(eff.+)'),
+ ('wildcard_start', '*'),
+ ('wildcard_end', 'www.*'),
+ ('wildcard_start', '*.eff.org'),
+ ('wildcard_end', 'www.*'),
+ ('wildcard_start', '*.org'),
+ (None, None),
+ (None, None)]
+
+ for i, winner in enumerate(winners):
+ self.assertEqual(winner,
+ parser.get_best_match(target_name, names[i]))
+
+ def test_comment_directive(self):
+ # pylint: disable=protected-access
+ block = nginxparser.UnspacedList([
+ ["\n", "a", " ", "b", "\n"],
+ ["c", " ", "d"],
+ ["\n", "e", " ", "f"]])
+ from certbot_nginx._internal.parser import comment_directive, COMMENT_BLOCK
+ comment_directive(block, 1)
+ comment_directive(block, 0)
+ self.assertEqual(block.spaced, [
+ ["\n", "a", " ", "b", "\n"],
+ COMMENT_BLOCK,
+ "\n",
+ ["c", " ", "d"],
+ COMMENT_BLOCK,
+ ["\n", "e", " ", "f"]])
+
+ def test_comment_out_directive(self):
+ server_block = nginxparser.loads("""
+ server {
+ listen 80;
+ root /var/www/html;
+ index star.html;
+
+ server_name *.functorkitten.xyz;
+ ssl_session_timeout 1440m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
+
+ ssl_prefer_server_ciphers on;
+ }""")
+ block = server_block[0][1]
+ from certbot_nginx._internal.parser import _comment_out_directive
+ _comment_out_directive(block, 4, "blah1")
+ _comment_out_directive(block, 5, "blah2")
+ _comment_out_directive(block, 6, "blah3")
+ self.assertEqual(block.spaced, [
+ ['\n ', 'listen', ' ', '80'],
+ ['\n ', 'root', ' ', '/var/www/html'],
+ ['\n ', 'index', ' ', 'star.html'],
+ ['\n\n ', 'server_name', ' ', '*.functorkitten.xyz'],
+ ['\n ', '#', ' ssl_session_timeout 1440m; # duplicated in blah1'],
+ [' ', '#', ' ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # duplicated in blah2'],
+ ['\n\n ', '#', ' ssl_prefer_server_ciphers on; # duplicated in blah3'],
+ '\n '])
+
+ def test_parse_server_raw_ssl(self):
+ server = parser._parse_server_raw([ #pylint: disable=protected-access
+ ['listen', '443']
+ ])
+ self.assertFalse(server['ssl'])
+
+ server = parser._parse_server_raw([ #pylint: disable=protected-access
+ ['listen', '443', 'ssl']
+ ])
+ self.assertTrue(server['ssl'])
+
+ server = parser._parse_server_raw([ #pylint: disable=protected-access
+ ['listen', '443'], ['ssl', 'off']
+ ])
+ self.assertFalse(server['ssl'])
+
+ server = parser._parse_server_raw([ #pylint: disable=protected-access
+ ['listen', '443'], ['ssl', 'on']
+ ])
+ self.assertTrue(server['ssl'])
+
+ def test_parse_server_raw_unix(self):
+ server = parser._parse_server_raw([ #pylint: disable=protected-access
+ ['listen', 'unix:/var/run/nginx.sock']
+ ])
+ self.assertEqual(len(server['addrs']), 0)
+
+ def test_parse_server_global_ssl_applied(self):
+ nparser = parser.NginxParser(self.config_path)
+ server = nparser.parse_server([
+ ['listen', '443']
+ ])
+ self.assertTrue(server['ssl'])
+
+ def test_duplicate_vhost(self):
+ nparser = parser.NginxParser(self.config_path)
+
+ vhosts = nparser.get_vhosts()
+ default = [x for x in vhosts if 'default' in x.filep][0]
+ new_vhost = nparser.duplicate_vhost(default, remove_singleton_listen_params=True)
+ nparser.filedump(ext='')
+
+ # check properties of new vhost
+ self.assertFalse(next(iter(new_vhost.addrs)).default)
+ self.assertNotEqual(new_vhost.path, default.path)
+
+ # check that things are written to file correctly
+ new_nparser = parser.NginxParser(self.config_path)
+ new_vhosts = new_nparser.get_vhosts()
+ new_defaults = [x for x in new_vhosts if 'default' in x.filep]
+ self.assertEqual(len(new_defaults), 2)
+ new_vhost_parsed = new_defaults[1]
+ self.assertFalse(next(iter(new_vhost_parsed.addrs)).default)
+ self.assertEqual(next(iter(default.names)), next(iter(new_vhost_parsed.names)))
+ self.assertEqual(len(default.raw), len(new_vhost_parsed.raw))
+ self.assertTrue(next(iter(default.addrs)).super_eq(next(iter(new_vhost_parsed.addrs))))
+
+ def test_duplicate_vhost_remove_ipv6only(self):
+ nparser = parser.NginxParser(self.config_path)
+
+ vhosts = nparser.get_vhosts()
+ ipv6ssl = [x for x in vhosts if 'ipv6ssl' in x.filep][0]
+ new_vhost = nparser.duplicate_vhost(ipv6ssl, remove_singleton_listen_params=True)
+ nparser.filedump(ext='')
+
+ for addr in new_vhost.addrs:
+ self.assertFalse(addr.ipv6only)
+
+ identical_vhost = nparser.duplicate_vhost(ipv6ssl, remove_singleton_listen_params=False)
+ nparser.filedump(ext='')
+
+ called = False
+ for addr in identical_vhost.addrs:
+ if addr.ipv6:
+ self.assertTrue(addr.ipv6only)
+ called = True
+ self.assertTrue(called)
+
+
+
+if __name__ == "__main__":
+ unittest.main() # pragma: no cover