def test_create_new_vhost_from_default(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.create_new_vhost_from_default(default) 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_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']], replace=False) nparser.add_server_directives(mock_vhost, [['\n ', 'include', ' ', nparser.abs_path('comment_in_file.conf')]], replace=False) from certbot_nginx.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 prepare(self): """Prepare the authenticator/installer. :raises .errors.NoInstallationError: If Nginx ctl cannot be found :raises .errors.MisconfigurationError: If Nginx is misconfigured """ # Verify Nginx is installed if not util.exe_exists(self.conf('ctl')): raise errors.NoInstallationError( "Could not find a usable 'nginx' binary. Ensure nginx exists, " "the binary is executable, and your PATH is set correctly.") # Make sure configuration is valid self.config_test() self.parser = parser.NginxParser(self.conf('server-root')) # Set Version if self.version is None: self.version = self.get_version() if self.openssl_version is None: self.openssl_version = self._get_openssl_version() self.install_ssl_options_conf(self.mod_ssl_conf, self.updated_mod_ssl_conf_digest) self.install_ssl_dhparams() # Prevent two Nginx plugins from modifying a config at once try: util.lock_dir_until_exit(self.conf('server-root')) except (OSError, errors.LockError): logger.debug('Encountered error:', exc_info=True) raise errors.PluginError('Unable to lock {0}'.format(self.conf('server-root')))
def prepare(self): """Prepare the authenticator/installer. :raises .errors.NoInstallationError: If Nginx ctl cannot be found :raises .errors.MisconfigurationError: If Nginx is misconfigured """ # Verify Nginx is installed if not util.exe_exists(self.conf('ctl')): raise errors.NoInstallationError # Make sure configuration is valid self.config_test() self.parser = parser.NginxParser(self.conf('server-root')) install_ssl_options_conf(self.mod_ssl_conf, self.updated_mod_ssl_conf_digest) self.install_ssl_dhparams() # Set Version if self.version is None: self.version = self.get_version() # Prevent two Nginx plugins from modifying a config at once try: util.lock_dir_until_exit(self.conf('server-root')) except (OSError, errors.LockError): logger.debug('Encountered error:', exc_info=True) raise errors.PluginError( 'Unable to lock %s', self.conf('server-root'))
def test_abs_path(self): nparser = parser.NginxParser(self.config_path) self.assertEqual('/etc/nginx/*', nparser.abs_path('/etc/nginx/*')) self.assertEqual(os.path.join(self.config_path, 'foo/bar/'), nparser.abs_path('foo/bar/')) self.assertEqual(os.path.join(self.config_path, 'foo/bar/'), nparser.abs_path('"foo/bar/"'))
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_add_server_directives(self): nparser = parser.NginxParser(self.config_path, self.ssl_options) nparser.add_server_directives( nparser.abs_path('nginx.conf'), set(['localhost', r'~^(www\.)?(example|bar)\.']), [['foo', 'bar'], ['\n ', 'ssl_certificate', ' ', '/etc/ssl/cert.pem']], replace=False) 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))) server_conf = nparser.abs_path('server.conf') names = set(['alias', 'another.alias', 'somename']) nparser.add_server_directives( server_conf, names, [['foo', 'bar'], ['ssl_certificate', '/etc/ssl/cert2.pem']], replace=False) nparser.add_server_directives(server_conf, names, [['foo', 'bar']], replace=False) self.assertEqual( nparser.parsed[server_conf], [['server_name', 'somename alias another.alias'], ['foo', 'bar'], ['ssl_certificate', '/etc/ssl/cert2.pem']])
def test_load(self): """Test recursive conf file parsing. """ nparser = parser.NginxParser(self.config_path) nparser.load() self.assertEqual(set([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_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.add_server_directives(mock_vhost, [['server_name', 'foobar.com']], replace=True) from certbot_nginx.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.add_server_directives(mock_vhost, [['ssl_certificate', 'cert.pem']], replace=True) 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_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_get_vhosts_global_ssl(self): nparser = parser.NginxParser(self.config_path, self.ssl_options) vhosts = nparser.get_vhosts() vhost = obj.VirtualHost(nparser.abs_path('sites-enabled/globalssl.com'), [obj.Addr('4.8.2.6', '57', True, 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_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_get_all_certs_keys(self): nparser = parser.NginxParser(self.config_path, self.ssl_options) filep = nparser.abs_path('sites-enabled/example.com') nparser.add_server_directives( filep, set(['.example.com', 'example.*']), [['ssl_certificate', 'foo.pem'], ['ssl_certificate_key', 'bar.key'], ['listen', '443 ssl']], replace=False) c_k = nparser.get_all_certs_keys() self.assertEqual(set([('foo.pem', 'bar.key', filep)]), c_k)
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_add_http_directives(self): nparser = parser.NginxParser(self.config_path, self.ssl_options) filep = nparser.abs_path('nginx.conf') block = [['server'], [['listen', '80'], ['server_name', 'localhost']]] nparser.add_http_directives(filep, block) root = nparser.parsed[filep] self.assertTrue(util.contains_at_depth(root, ['http'], 1)) self.assertTrue(util.contains_at_depth(root, block, 2)) # Check that our server block got inserted first among all server # blocks. http_block = [x for x in root if x[0] == ['http']][0][1] server_blocks = [x for x in http_block if x[0] == ['server']] self.assertEqual(server_blocks[0], block)
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( 5, 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_add_server_directives(self): nparser = parser.NginxParser(self.config_path, self.ssl_options) 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']], replace=False) 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']], replace=False) nparser.add_server_directives(mock_vhost, [['foo', 'bar']], replace=False) from certbot_nginx.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']], replace=False)
def test_get_all_certs_keys(self): nparser = parser.NginxParser(self.config_path, self.ssl_options) filep = nparser.abs_path('sites-enabled/example.com') mock_vhost = obj.VirtualHost(filep, None, None, None, set(['.example.com', 'example.*']), None, [0]) nparser.add_server_directives( mock_vhost, [['ssl_certificate', 'foo.pem'], ['ssl_certificate_key', 'bar.key'], ['listen', '443 ssl']], replace=False) c_k = nparser.get_all_certs_keys() migration_file = nparser.abs_path('sites-enabled/migration.com') self.assertEqual( set([('foo.pem', 'bar.key', filep), ('cert.pem', 'cert.key', migration_file)]), c_k)
def test_ssl_options_should_be_parsed_ssl_directives(self): nparser = parser.NginxParser(self.config_path, self.ssl_options) self.assertEqual(nginxparser.UnspacedList(nparser.loc["ssl_options"]), [['ssl_session_cache', 'shared:le_nginx_SSL:1m'], ['ssl_session_timeout', '1440m'], ['ssl_protocols', 'TLSv1 TLSv1.1 TLSv1.2'], ['ssl_prefer_server_ciphers', 'on'], ['ssl_ciphers', '"ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-ECDSA-'+ 'AES256-GCM-SHA384 ECDHE-ECDSA-AES128-SHA ECDHE-ECDSA-AES256'+ '-SHA ECDHE-ECDSA-AES128-SHA256 ECDHE-ECDSA-AES256-SHA384'+ ' ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES256-GCM-SHA384'+ ' ECDHE-RSA-AES128-SHA ECDHE-RSA-AES128-SHA256 ECDHE-RSA-'+ 'AES256-SHA384 DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES256-GCM'+ '-SHA384 DHE-RSA-AES128-SHA DHE-RSA-AES256-SHA DHE-RSA-'+ 'AES128-SHA256 DHE-RSA-AES256-SHA256 EDH-RSA-DES-CBC3-SHA"'] ])
def test_replace_server_directives(self): nparser = parser.NginxParser(self.config_path, self.ssl_options) target = set(['.example.com', 'example.*']) filep = nparser.abs_path('sites-enabled/example.com') nparser.add_server_directives( filep, target, [['server_name', 'foobar.com']], replace=True) self.assertEqual( nparser.parsed[filep], [[['server'], [['listen', '69.50.225.155:9000'], ['listen', '127.0.0.1'], ['server_name', 'foobar.com'], ['server_name', 'example.*'], ]]]) self.assertRaises(errors.MisconfigurationError, nparser.add_server_directives, filep, set(['foobar.com', 'example.*']), [['ssl_certificate', 'cert.pem']], replace=True)
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)
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 prepare(self): """Prepare the authenticator/installer. :raises .errors.NoInstallationError: If Nginx ctl cannot be found :raises .errors.MisconfigurationError: If Nginx is misconfigured """ # Verify Nginx is installed if not util.exe_exists(self.conf('ctl')): raise errors.NoInstallationError # Make sure configuration is valid self.config_test() # temp_install must be run before creating the NginxParser temp_install(self.mod_ssl_conf) self.parser = parser.NginxParser(self.conf('server-root'), self.mod_ssl_conf) # Set Version if self.version is None: self.version = self.get_version()
def test_ssl_options_should_be_parsed_ssl_directives(self): nparser = parser.NginxParser(self.config_path, self.ssl_options) self.assertEqual(nginxparser.UnspacedList(nparser.loc["ssl_options"]), [['ssl_session_cache', 'shared:le_nginx_SSL:1m'], ['ssl_session_timeout', '1440m'], ['ssl_protocols', 'TLSv1', 'TLSv1.1', 'TLSv1.2'], ['ssl_prefer_server_ciphers', 'on'], ['ssl_ciphers', '"ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-'+ 'RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:'+ 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-'+ 'SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-'+ 'SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-'+ 'SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:'+ 'ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-'+ 'AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:'+ 'DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-'+ 'SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-'+ 'RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:'+ 'AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:'+ 'AES256-SHA:DES-CBC3-SHA:!DSS"'] ])
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_root_no_trailing_slash(self): nparser = parser.NginxParser(self.config_path + os.path.sep) self.assertEqual(nparser.root, self.config_path)
def test_root_absolute(self): nparser = parser.NginxParser(os.path.relpath(self.config_path)) self.assertEqual(nparser.root, self.config_path)
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 setUp(self): super(SelectVhostMultiTest, self).setUp() nparser = parser.NginxParser(self.config_path) self.vhosts = nparser.get_vhosts()