def test_double_redirect(self): # Test that we add one redirect for each domain example_conf = self.config.parser.abs_path('sites-enabled/example.com') self.config.enhance("example.com", "redirect") self.config.enhance("example.org", "redirect") expected1 = UnspacedList(_redirect_block_for_domain("example.com"))[0] expected2 = UnspacedList(_redirect_block_for_domain("example.org"))[0] generated_conf = self.config.parser.parsed[example_conf] self.assertTrue(util.contains_at_depth(generated_conf, expected1, 2)) self.assertTrue(util.contains_at_depth(generated_conf, expected2, 2))
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_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_staple_ocsp(self): chain_path = "example/chain.pem" self.config.enhance("www.example.com", "staple-ocsp", chain_path) example_conf = self.config.parser.abs_path('sites-enabled/example.com') generated_conf = self.config.parser.parsed[example_conf] self.assertTrue(util.contains_at_depth( generated_conf, ['ssl_trusted_certificate', 'example/chain.pem'], 2)) self.assertTrue(util.contains_at_depth( generated_conf, ['ssl_stapling', 'on'], 2)) self.assertTrue(util.contains_at_depth( generated_conf, ['ssl_stapling_verify', 'on'], 2))
def test_deploy_cert_stapling(self): # Choose a version of Nginx greater than 1.3.7 so stapling code gets # invoked. self.config.version = (1, 9, 6) example_conf = self.config.parser.abs_path("sites-enabled/example.com") self.config.deploy_cert( "www.example.com", "example/cert.pem", "example/key.pem", "example/chain.pem", "example/fullchain.pem" ) self.config.save() self.config.parser.load() generated_conf = self.config.parser.parsed[example_conf] self.assertTrue(util.contains_at_depth(generated_conf, ["ssl_stapling", "on"], 2)) self.assertTrue(util.contains_at_depth(generated_conf, ["ssl_stapling_verify", "on"], 2)) self.assertTrue(util.contains_at_depth(generated_conf, ["ssl_trusted_certificate", "example/chain.pem"], 2))
def test_deploy_no_match_add_redirect(self): default_conf = self.config.parser.abs_path('sites-enabled/default') foo_conf = self.config.parser.abs_path('foo.conf') del self.config.parser.parsed[foo_conf][2][1][0][1][0] # remove default_server self.config.version = (1, 3, 1) self.config.deploy_cert( "www.nomatch.com", "example/cert.pem", "example/key.pem", "example/chain.pem", "example/fullchain.pem") self.config.deploy_cert( "nomatch.com", "example/cert.pem", "example/key.pem", "example/chain.pem", "example/fullchain.pem") self.config.enhance("www.nomatch.com", "redirect") self.config.save() self.config.parser.load() expected = ['return', '301', 'https://$host$request_uri'] generated_conf = self.config.parser.parsed[default_conf] self.assertTrue(util.contains_at_depth(generated_conf, expected, 2))
def test_non_certbot_redirect_exists_has_ssl_copy(self, mock_has_redirect, mock_contains_list): # Test that we add a redirect as a comment if there is already a # redirect-class statement in the block that isn't managed by certbot example_conf = self.config.parser.abs_path('sites-enabled/example.com') self.config.deploy_cert( "example.org", "example/cert.pem", "example/key.pem", "example/chain.pem", "example/fullchain.pem") # Has a non-Certbot redirect, and has no existing comment mock_contains_list.return_value = False mock_has_redirect.return_value = True with mock.patch("certbot_nginx.configurator.logger") as mock_logger: self.config.enhance("www.example.com", "redirect") self.assertEqual(mock_logger.info.call_args[0][0], "The appropriate server block is already redirecting " "traffic. To enable redirect anyway, uncomment the " "redirect lines in %s.") generated_conf = self.config.parser.parsed[example_conf] expected = [ ['#', ' Redirect non-https traffic to https'], ['#', ' return 301 https://$host$request_uri;'], ] for line in expected: self.assertTrue(util.contains_at_depth(generated_conf, line, 2))
def test_deploy_cert(self): server_conf = self.config.parser.abs_path('server.conf') nginx_conf = self.config.parser.abs_path('nginx.conf') example_conf = self.config.parser.abs_path('sites-enabled/example.com') self.config.version = (1, 3, 1) # Get the default SSL vhost self.config.deploy_cert( "www.example.com", "example/cert.pem", "example/key.pem", "example/chain.pem", "example/fullchain.pem") self.config.deploy_cert( "another.alias", "/etc/nginx/cert.pem", "/etc/nginx/key.pem", "/etc/nginx/chain.pem", "/etc/nginx/fullchain.pem") self.config.save() self.config.parser.load() parsed_example_conf = util.filter_comments(self.config.parser.parsed[example_conf]) parsed_server_conf = util.filter_comments(self.config.parser.parsed[server_conf]) parsed_nginx_conf = util.filter_comments(self.config.parser.parsed[nginx_conf]) self.assertEqual([[['server'], [ ['listen', '69.50.225.155:9000'], ['listen', '127.0.0.1'], ['server_name', '.example.com'], ['server_name', 'example.*'], ['listen', '5001', 'ssl'], ['ssl_certificate', 'example/fullchain.pem'], ['ssl_certificate_key', 'example/key.pem'], ['include', self.config.mod_ssl_conf], ['ssl_dhparam', self.config.ssl_dhparams], ]]], parsed_example_conf) self.assertEqual([['server_name', 'somename', 'alias', 'another.alias']], parsed_server_conf) self.assertTrue(util.contains_at_depth( parsed_nginx_conf, [['server'], [ ['listen', '8000'], ['listen', 'somename:8080'], ['include', 'server.conf'], [['location', '/'], [['root', 'html'], ['index', 'index.html', 'index.htm']]], ['listen', '5001', 'ssl'], ['ssl_certificate', '/etc/nginx/fullchain.pem'], ['ssl_certificate_key', '/etc/nginx/key.pem'], ['include', self.config.mod_ssl_conf], ['ssl_dhparam', self.config.ssl_dhparams], ]], 2))
def test_deploy_no_match_add_redirect(self): default_conf = self.config.parser.abs_path('sites-enabled/default') foo_conf = self.config.parser.abs_path('foo.conf') del self.config.parser.parsed[foo_conf][2][1][0][1][ 0] # remove default_server self.config.version = (1, 3, 1) self.config.deploy_cert("www.nomatch.com", "example/cert.pem", "example/key.pem", "example/chain.pem", "example/fullchain.pem") self.config.deploy_cert("nomatch.com", "example/cert.pem", "example/key.pem", "example/chain.pem", "example/fullchain.pem") self.config.enhance("www.nomatch.com", "redirect") self.config.save() self.config.parser.load() expected = UnspacedList( _redirect_block_for_domain("www.nomatch.com"))[0] generated_conf = self.config.parser.parsed[default_conf] self.assertTrue(util.contains_at_depth(generated_conf, expected, 2))
def test_perform2(self): acme_responses = [] for achall in self.achalls: self.sni.add_chall(achall) acme_responses.append(achall.response(self.account_key)) mock_setup_cert = mock.MagicMock(side_effect=acme_responses) # pylint: disable=protected-access self.sni._setup_challenge_cert = mock_setup_cert sni_responses = self.sni.perform() self.assertEqual(mock_setup_cert.call_count, 4) for index, achall in enumerate(self.achalls): self.assertEqual( mock_setup_cert.call_args_list[index], mock.call(achall)) http = self.sni.configurator.parser.parsed[ self.sni.configurator.parser.config_root][-1] self.assertTrue(['include', self.sni.challenge_conf] in http[1]) self.assertFalse( util.contains_at_depth(http, ['server_name', 'another.alias'], 3)) self.assertEqual(len(sni_responses), 4) for i in six.moves.range(4): self.assertEqual(sni_responses[i], acme_responses[i])
def test_deploy_cert(self): server_conf = self.config.parser.abs_path('server.conf') nginx_conf = self.config.parser.abs_path('nginx.conf') example_conf = self.config.parser.abs_path('sites-enabled/example.com') # Choose a version of Nginx less than 1.3.7 so stapling code doesn't get # invoked. self.config.version = (1, 3, 1) # Get the default SSL vhost self.config.deploy_cert( "www.example.com", "example/cert.pem", "example/key.pem", "example/chain.pem", "example/fullchain.pem") self.config.deploy_cert( "another.alias", "/etc/nginx/cert.pem", "/etc/nginx/key.pem", "/etc/nginx/chain.pem", "/etc/nginx/fullchain.pem") self.config.save() self.config.parser.load() parsed_example_conf = util.filter_comments(self.config.parser.parsed[example_conf]) parsed_server_conf = util.filter_comments(self.config.parser.parsed[server_conf]) parsed_nginx_conf = util.filter_comments(self.config.parser.parsed[nginx_conf]) self.assertEqual([[['server'], [ ['listen', '69.50.225.155:9000'], ['listen', '127.0.0.1'], ['server_name', '.example.com'], ['server_name', 'example.*'], ['listen', '5001 ssl'], ['ssl_certificate', 'example/fullchain.pem'], ['ssl_certificate_key', 'example/key.pem']] + util.filter_comments(self.config.parser.loc["ssl_options"]) ]], parsed_example_conf) self.assertEqual([['server_name', 'somename alias another.alias']], parsed_server_conf) self.assertTrue(util.contains_at_depth( parsed_nginx_conf, [['server'], [ ['listen', '8000'], ['listen', 'somename:8080'], ['include', 'server.conf'], [['location', '/'], [['root', 'html'], ['index', 'index.html index.htm']]], ['listen', '5001 ssl'], ['ssl_certificate', '/etc/nginx/fullchain.pem'], ['ssl_certificate_key', '/etc/nginx/key.pem']] + util.filter_comments(self.config.parser.loc["ssl_options"]) ], 2))
def test_multiple_headers_hsts(self): headers_conf = self.config.parser.abs_path('sites-enabled/headers.com') self.config.enhance("headers.com", "ensure-http-header", "Strict-Transport-Security") expected = ['add_header', 'Strict-Transport-Security', '"max-age=31536000"', 'always'] generated_conf = self.config.parser.parsed[headers_conf] self.assertTrue(util.contains_at_depth(generated_conf, expected, 2))
def test_perform2(self): acme_responses = [] for achall in self.achalls: self.sni.add_chall(achall) acme_responses.append(achall.response(self.account_key)) mock_setup_cert = mock.MagicMock(side_effect=acme_responses) # pylint: disable=protected-access self.sni._setup_challenge_cert = mock_setup_cert sni_responses = self.sni.perform() self.assertEqual(mock_setup_cert.call_count, 3) for index, achall in enumerate(self.achalls): self.assertEqual(mock_setup_cert.call_args_list[index], mock.call(achall)) http = self.sni.configurator.parser.parsed[ self.sni.configurator.parser.loc["root"]][-1] self.assertTrue(['include', self.sni.challenge_conf] in http[1]) self.assertTrue( util.contains_at_depth(http, ['server_name', 'blah'], 3)) self.assertEqual(len(sni_responses), 3) for i in xrange(3): self.assertEqual(sni_responses[i], acme_responses[i])
def test_deploy_no_match_add_redirect(self): default_conf = self.config.parser.abs_path('sites-enabled/default') foo_conf = self.config.parser.abs_path('foo.conf') del self.config.parser.parsed[foo_conf][2][1][0][1][0] # remove default_server self.config.version = (1, 3, 1) self.config.deploy_cert( "www.nomatch.com", "example/cert.pem", "example/key.pem", "example/chain.pem", "example/fullchain.pem") self.config.deploy_cert( "nomatch.com", "example/cert.pem", "example/key.pem", "example/chain.pem", "example/fullchain.pem") self.config.enhance("www.nomatch.com", "redirect") self.config.save() self.config.parser.load() expected = UnspacedList(_redirect_block_for_domain("www.nomatch.com"))[0] generated_conf = self.config.parser.parsed[default_conf] self.assertTrue(util.contains_at_depth(generated_conf, expected, 2))
def test_redirect_enhance(self): expected = [["if", '($scheme != "https")'], [["return", "301 https://$host$request_uri"]]] example_conf = self.config.parser.abs_path("sites-enabled/example.com") self.config.enhance("www.example.com", "redirect") generated_conf = self.config.parser.parsed[example_conf] self.assertTrue(util.contains_at_depth(generated_conf, expected, 2))
def test_redirect_enhance(self): expected = [['if', '($scheme != "https") '], [['return', '301 https://$host$request_uri']]] example_conf = self.config.parser.abs_path('sites-enabled/example.com') self.config.enhance("www.example.com", "redirect") generated_conf = self.config.parser.parsed[example_conf] self.assertTrue(util.contains_at_depth(generated_conf, expected, 2))
def test_redirect_enhance(self): # Test that we successfully add a redirect when there is # a listen directive expected = ['return', '301', 'https://$host$request_uri'] example_conf = self.config.parser.abs_path('sites-enabled/example.com') self.config.enhance("www.example.com", "redirect") generated_conf = self.config.parser.parsed[example_conf] self.assertTrue(util.contains_at_depth(generated_conf, expected, 2)) # Test that we successfully add a redirect when there is # no listen directive migration_conf = self.config.parser.abs_path('sites-enabled/migration.com') self.config.enhance("migration.com", "redirect") generated_conf = self.config.parser.parsed[migration_conf] self.assertTrue(util.contains_at_depth(generated_conf, expected, 2))
def test_redirect_enhance(self): # Test that we successfully add a redirect when there is # a listen directive expected = UnspacedList(_redirect_block_for_domain("www.example.com"))[0] example_conf = self.config.parser.abs_path('sites-enabled/example.com') self.config.enhance("www.example.com", "redirect") generated_conf = self.config.parser.parsed[example_conf] self.assertTrue(util.contains_at_depth(generated_conf, expected, 2)) # Test that we successfully add a redirect when there is # no listen directive migration_conf = self.config.parser.abs_path('sites-enabled/migration.com') self.config.enhance("migration.com", "redirect") expected = UnspacedList(_redirect_block_for_domain("migration.com"))[0] generated_conf = self.config.parser.parsed[migration_conf] self.assertTrue(util.contains_at_depth(generated_conf, expected, 2))
def test_redirect_enhance(self): # Test that we successfully add a redirect when there is # a listen directive expected = [ ['if', '($scheme != "https") '], [['return', '301 https://$host$request_uri']] ] example_conf = self.config.parser.abs_path('sites-enabled/example.com') self.config.enhance("www.example.com", "redirect") generated_conf = self.config.parser.parsed[example_conf] self.assertTrue(util.contains_at_depth(generated_conf, expected, 2)) # Test that we successfully add a redirect when there is # no listen directive migration_conf = self.config.parser.abs_path('sites-enabled/migration.com') self.config.enhance("migration.com", "redirect") generated_conf = self.config.parser.parsed[migration_conf] self.assertTrue(util.contains_at_depth(generated_conf, expected, 2))
def test_deploy_cert_stapling(self): # Choose a version of Nginx greater than 1.3.7 so stapling code gets # invoked. self.config.version = (1, 9, 6) example_conf = self.config.parser.abs_path('sites-enabled/example.com') self.config.deploy_cert("www.example.com", "example/cert.pem", "example/key.pem", "example/chain.pem", "example/fullchain.pem") self.config.save() self.config.parser.load() generated_conf = self.config.parser.parsed[example_conf] self.assertTrue( util.contains_at_depth(generated_conf, ['ssl_stapling', 'on'], 2)) self.assertTrue( util.contains_at_depth(generated_conf, ['ssl_stapling_verify', 'on'], 2)) self.assertTrue( util.contains_at_depth( generated_conf, ['ssl_trusted_certificate', 'example/chain.pem'], 2))
def test_deploy_no_match_default_set(self): default_conf = self.config.parser.abs_path('sites-enabled/default') foo_conf = self.config.parser.abs_path('foo.conf') del self.config.parser.parsed[foo_conf][2][1][0][1][0] # remove default_server self.config.version = (1, 3, 1) self.config.deploy_cert( "www.nomatch.com", "example/cert.pem", "example/key.pem", "example/chain.pem", "example/fullchain.pem") self.config.save() self.config.parser.load() parsed_default_conf = util.filter_comments(self.config.parser.parsed[default_conf]) self.assertEqual([[['server'], [['listen', 'myhost', 'default_server'], ['listen', 'otherhost', 'default_server'], ['server_name', '"www.example.org"'], [['location', '/'], [['root', 'html'], ['index', 'index.html', 'index.htm']]]]], [['server'], [['listen', 'myhost'], ['listen', 'otherhost'], ['server_name', 'www.nomatch.com'], [['location', '/'], [['root', 'html'], ['index', 'index.html', 'index.htm']]], ['listen', '5001', 'ssl'], ['ssl_certificate', 'example/fullchain.pem'], ['ssl_certificate_key', 'example/key.pem'], ['include', self.config.mod_ssl_conf], ['ssl_dhparam', self.config.ssl_dhparams]]]], parsed_default_conf) self.config.deploy_cert( "nomatch.com", "example/cert.pem", "example/key.pem", "example/chain.pem", "example/fullchain.pem") self.config.save() self.config.parser.load() parsed_default_conf = util.filter_comments(self.config.parser.parsed[default_conf]) self.assertTrue(util.contains_at_depth(parsed_default_conf, "nomatch.com", 3))
def test_no_double_redirect(self): # Test that we don't also add the commented redirect if we've just added # a redirect to that vhost this run example_conf = self.config.parser.abs_path('sites-enabled/example.com') self.config.enhance("example.com", "redirect") self.config.enhance("example.org", "redirect") unexpected = [['#', ' Redirect non-https traffic to https'], ['#', ' if ($scheme != "https") {'], ['#', ' return 301 https://$host$request_uri;'], ['#', ' } # managed by Certbot']] generated_conf = self.config.parser.parsed[example_conf] for line in unexpected: self.assertFalse(util.contains_at_depth(generated_conf, line, 2))
def test_deploy_cert(self): server_conf = self.config.parser.abs_path('server.conf') nginx_conf = self.config.parser.abs_path('nginx.conf') example_conf = self.config.parser.abs_path('sites-enabled/example.com') # Choose a version of Nginx less than 1.3.7 so stapling code doesn't get # invoked. self.config.version = (1, 3, 1) # Get the default SSL vhost self.config.deploy_cert("www.example.com", "example/cert.pem", "example/key.pem", "example/chain.pem", "example/fullchain.pem") self.config.deploy_cert("another.alias", "/etc/nginx/cert.pem", "/etc/nginx/key.pem", "/etc/nginx/chain.pem", "/etc/nginx/fullchain.pem") self.config.save() self.config.parser.load() parsed_example_conf = util.filter_comments( self.config.parser.parsed[example_conf]) parsed_server_conf = util.filter_comments( self.config.parser.parsed[server_conf]) parsed_nginx_conf = util.filter_comments( self.config.parser.parsed[nginx_conf]) self.assertEqual( [[['server'], [['listen', '69.50.225.155:9000'], ['listen', '127.0.0.1'], ['server_name', '.example.com'], ['server_name', 'example.*'], ['listen', '5001 ssl'], ['ssl_certificate', 'example/fullchain.pem'], ['ssl_certificate_key', 'example/key.pem']] + util.filter_comments(self.config.parser.loc["ssl_options"])]], parsed_example_conf) self.assertEqual([['server_name', 'somename alias another.alias']], parsed_server_conf) self.assertTrue( util.contains_at_depth( parsed_nginx_conf, [['server'], [['listen', '8000'], ['listen', 'somename:8080'], ['include', 'server.conf'], [['location', '/'], [['root', 'html'], ['index', 'index.html index.htm']]], ['listen', '5001 ssl'], ['ssl_certificate', '/etc/nginx/fullchain.pem'], ['ssl_certificate_key', '/etc/nginx/key.pem']] + util.filter_comments(self.config.parser.loc["ssl_options"])], 2))
def test_perform1(self, mock_save): self.sni.add_chall(self.achalls[0]) response = self.achalls[0].response(self.account_key) mock_setup_cert = mock.MagicMock(return_value=response) # pylint: disable=protected-access self.sni._setup_challenge_cert = mock_setup_cert responses = self.sni.perform() mock_setup_cert.assert_called_once_with(self.achalls[0]) self.assertEqual([response], responses) self.assertEqual(mock_save.call_count, 1) # Make sure challenge config is included in main config http = self.sni.configurator.parser.parsed[ self.sni.configurator.parser.config_root][-1] self.assertTrue( util.contains_at_depth(http, ['include', self.sni.challenge_conf], 1))
def test_non_certbot_redirect_exists(self, mock_has_redirect, mock_contains_list): # Test that we add a redirect as a comment if there is already a # redirect-class statement in the block that isn't managed by certbot example_conf = self.config.parser.abs_path('sites-enabled/example.com') # Has a non-Certbot redirect, and has no existing comment mock_contains_list.return_value = False mock_has_redirect.return_value = True with mock.patch("certbot_nginx.configurator.logger") as mock_logger: self.config.enhance("www.example.com", "redirect") self.assertEqual(mock_logger.info.call_args[0][0], "The appropriate server block is already redirecting " "traffic. To enable redirect anyway, uncomment the " "redirect lines in %s.") generated_conf = self.config.parser.parsed[example_conf] expected = [ ['#', ' Redirect non-https traffic to https'], ['#', ' if ($scheme != "https") {'], ['#', ' return 301 https://$host$request_uri;'], ['#', ' } # managed by Certbot'] ] for line in expected: self.assertTrue(util.contains_at_depth(generated_conf, line, 2))
def test_deploy_cert(self): server_conf = self.config.parser.abs_path("server.conf") nginx_conf = self.config.parser.abs_path("nginx.conf") example_conf = self.config.parser.abs_path("sites-enabled/example.com") # Choose a version of Nginx less than 1.3.7 so stapling code doesn't get # invoked. self.config.version = (1, 3, 1) # Get the default SSL vhost self.config.deploy_cert( "www.example.com", "example/cert.pem", "example/key.pem", "example/chain.pem", "example/fullchain.pem" ) self.config.deploy_cert( "another.alias", "/etc/nginx/cert.pem", "/etc/nginx/key.pem", "/etc/nginx/chain.pem", "/etc/nginx/fullchain.pem", ) self.config.save() self.config.parser.load() parsed_example_conf = util.filter_comments(self.config.parser.parsed[example_conf]) parsed_server_conf = util.filter_comments(self.config.parser.parsed[server_conf]) parsed_nginx_conf = util.filter_comments(self.config.parser.parsed[nginx_conf]) self.assertEqual( [ [ ["server"], [ ["listen", "69.50.225.155:9000"], ["listen", "127.0.0.1"], ["server_name", ".example.com"], ["server_name", "example.*"], ["listen", "5001 ssl"], ["ssl_certificate", "example/fullchain.pem"], ["ssl_certificate_key", "example/key.pem"], ["include", self.config.parser.loc["ssl_options"]], ], ] ], parsed_example_conf, ) self.assertEqual([["server_name", "somename alias another.alias"]], parsed_server_conf) self.assertTrue( util.contains_at_depth( parsed_nginx_conf, [ ["server"], [ ["listen", "8000"], ["listen", "somename:8080"], ["include", "server.conf"], [["location", "/"], [["root", "html"], ["index", "index.html index.htm"]]], ["listen", "5001 ssl"], ["ssl_certificate", "/etc/nginx/fullchain.pem"], ["ssl_certificate_key", "/etc/nginx/key.pem"], ["include", self.config.parser.loc["ssl_options"]], ], ], 2, ) )