class AuthenticatorTest(test_util.TempDirTestCase): """Tests for certbot.plugins.manual.Authenticator.""" def setUp(self): super(AuthenticatorTest, self).setUp() self.http_achall = acme_util.HTTP01_A self.dns_achall = acme_util.DNS01_A self.dns_achall_2 = acme_util.DNS01_A_2 self.achalls = [self.http_achall, self.dns_achall, self.dns_achall_2] for d in ["config_dir", "work_dir", "in_progress"]: filesystem.mkdir(os.path.join(self.tempdir, d)) # "backup_dir" and "temp_checkpoint_dir" get created in # certbot.util.make_or_verify_dir() during the Reverter # initialization. self.config = mock.MagicMock( http01_port=0, manual_auth_hook=None, manual_cleanup_hook=None, manual_public_ip_logging_ok=False, noninteractive_mode=False, validate_hooks=False, config_dir=os.path.join(self.tempdir, "config_dir"), work_dir=os.path.join(self.tempdir, "work_dir"), backup_dir=os.path.join(self.tempdir, "backup_dir"), temp_checkpoint_dir=os.path.join( self.tempdir, "temp_checkpoint_dir"), in_progress_dir=os.path.join(self.tempdir, "in_progess")) from certbot.plugins.manual import Authenticator self.auth = Authenticator(self.config, name='manual') def test_prepare_no_hook_noninteractive(self): self.config.noninteractive_mode = True self.assertRaises(errors.PluginError, self.auth.prepare) def test_prepare_bad_hook(self): self.config.manual_auth_hook = os.path.abspath(os.sep) # is / on UNIX self.config.validate_hooks = True self.assertRaises(errors.HookCommandNotFound, self.auth.prepare) def test_more_info(self): self.assertTrue(isinstance(self.auth.more_info(), six.string_types)) def test_get_chall_pref(self): self.assertEqual(self.auth.get_chall_pref('example.org'), [challenges.HTTP01, challenges.DNS01]) @test_util.patch_get_utility() def test_ip_logging_not_ok(self, mock_get_utility): mock_get_utility().yesno.return_value = False self.assertRaises(errors.PluginError, self.auth.perform, []) @test_util.patch_get_utility() def test_ip_logging_ok(self, mock_get_utility): mock_get_utility().yesno.return_value = True self.auth.perform([]) self.assertTrue(self.config.manual_public_ip_logging_ok) def test_script_perform(self): self.config.manual_public_ip_logging_ok = True self.config.manual_auth_hook = ( '{0} -c "from __future__ import print_function;' 'from certbot.compat import os; print(os.environ.get(\'CERTBOT_DOMAIN\'));' 'print(os.environ.get(\'CERTBOT_TOKEN\', \'notoken\'));' 'print(os.environ.get(\'CERTBOT_VALIDATION\', \'novalidation\'));"' .format(sys.executable)) dns_expected = '{0}\n{1}\n{2}'.format( self.dns_achall.domain, 'notoken', self.dns_achall.validation(self.dns_achall.account_key)) http_expected = '{0}\n{1}\n{2}'.format( self.http_achall.domain, self.http_achall.chall.encode('token'), self.http_achall.validation(self.http_achall.account_key)) self.assertEqual( self.auth.perform(self.achalls), [achall.response(achall.account_key) for achall in self.achalls]) self.assertEqual( self.auth.env[self.dns_achall]['CERTBOT_AUTH_OUTPUT'], dns_expected) self.assertEqual( self.auth.env[self.http_achall]['CERTBOT_AUTH_OUTPUT'], http_expected) @test_util.patch_get_utility() def test_manual_perform(self, mock_get_utility): self.config.manual_public_ip_logging_ok = True self.assertEqual( self.auth.perform(self.achalls), [achall.response(achall.account_key) for achall in self.achalls]) for i, (args, kwargs) in enumerate(mock_get_utility().notification.call_args_list): achall = self.achalls[i] self.assertTrue( achall.validation(achall.account_key) in args[0]) self.assertFalse(kwargs['wrap']) def test_cleanup(self): self.config.manual_public_ip_logging_ok = True self.config.manual_auth_hook = ('{0} -c "import sys; sys.stdout.write(\'foo\')"' .format(sys.executable)) self.config.manual_cleanup_hook = '# cleanup' self.auth.perform(self.achalls) for achall in self.achalls: self.auth.cleanup([achall]) self.assertEqual(os.environ['CERTBOT_AUTH_OUTPUT'], 'foo') self.assertEqual(os.environ['CERTBOT_DOMAIN'], achall.domain) if isinstance(achall.chall, (challenges.HTTP01, challenges.DNS01)): self.assertEqual( os.environ['CERTBOT_VALIDATION'], achall.validation(achall.account_key)) if isinstance(achall.chall, challenges.HTTP01): self.assertEqual( os.environ['CERTBOT_TOKEN'], achall.chall.encode('token')) else: self.assertFalse('CERTBOT_TOKEN' in os.environ)
class AuthenticatorTest(unittest.TestCase): """Tests for certbot.plugins.manual.Authenticator.""" def setUp(self): from certbot.plugins.manual import Authenticator self.config = mock.MagicMock(http01_port=8080, manual_test_mode=False, manual_public_ip_logging_ok=False, noninteractive_mode=True) self.auth = Authenticator(config=self.config, name="manual") self.http01 = achallenges.KeyAuthorizationAnnotatedChallenge( challb=acme_util.HTTP01_P, domain="foo.com", account_key=KEY) self.dns01 = achallenges.KeyAuthorizationAnnotatedChallenge( challb=acme_util.DNS01_P, domain="foo.com", account_key=KEY) self.achalls = [self.http01, self.dns01] config_test_mode = mock.MagicMock(http01_port=8080, manual_test_mode=True, noninteractive_mode=True) self.auth_test_mode = Authenticator(config=config_test_mode, name="manual") def test_prepare(self): self.assertRaises(errors.PluginError, self.auth.prepare) self.auth_test_mode.prepare() # error not raised def test_more_info(self): self.assertTrue(isinstance(self.auth.more_info(), str)) def test_get_chall_pref(self): self.assertTrue( all( issubclass(pref, challenges.Challenge) for pref in self.auth.get_chall_pref("foo.com"))) @mock.patch("certbot.plugins.manual.zope.component.getUtility") def test_perform_empty(self, mock_interaction): mock_interaction().yesno.return_value = True self.assertEqual([], self.auth.perform([])) @mock.patch("certbot.plugins.manual.zope.component.getUtility") @mock.patch("certbot.plugins.manual.sys.stdout") @mock.patch("acme.challenges.HTTP01Response.simple_verify") @mock.patch("six.moves.input") def test_perform(self, mock_raw_input, mock_verify, mock_stdout, mock_interaction): mock_verify.return_value = True mock_interaction().yesno.return_value = True resp_http = self.http01.response(KEY) resp_dns = self.dns01.response(KEY) self.assertEqual([resp_http, resp_dns], self.auth.perform(self.achalls)) self.assertEqual(2, mock_raw_input.call_count) mock_verify.assert_called_with(self.http01.challb.chall, "foo.com", KEY.public_key(), 8080) message = mock_stdout.write.mock_calls[0][1][0] self.assertTrue(self.http01.chall.encode("token") in message) mock_verify.return_value = False with mock.patch("certbot.plugins.manual.logger") as mock_logger: self.auth.perform(self.achalls) self.assertEqual(2, mock_logger.warning.call_count) @mock.patch("certbot.plugins.manual.zope.component.getUtility") @mock.patch("acme.challenges.DNS01Response.simple_verify") @mock.patch("six.moves.input") def test_perform_missing_dependency(self, mock_raw_input, mock_verify, mock_interaction): mock_interaction().yesno.return_value = True mock_verify.side_effect = acme_errors.DependencyError() with mock.patch("certbot.plugins.manual.logger") as mock_logger: self.auth.perform([self.dns01]) self.assertEqual(1, mock_logger.warning.call_count) mock_raw_input.assert_called_once_with("Press ENTER to continue") @mock.patch("certbot.plugins.manual.zope.component.getUtility") @mock.patch("certbot.plugins.manual.Authenticator._notify_and_wait") def test_disagree_with_ip_logging(self, mock_notify, mock_interaction): mock_interaction().yesno.return_value = False mock_notify.side_effect = errors.Error("Exception not raised, \ continued execution even after disagreeing with IP logging") self.assertRaises(errors.PluginError, self.auth.perform, self.achalls) @mock.patch("certbot.plugins.manual.subprocess.Popen", autospec=True) def test_perform_test_command_oserror(self, mock_popen): mock_popen.side_effect = OSError self.assertEqual([False], self.auth_test_mode.perform([self.http01])) @mock.patch("certbot.plugins.manual.socket.socket") @mock.patch("certbot.plugins.manual.time.sleep", autospec=True) @mock.patch("certbot.plugins.manual.subprocess.Popen", autospec=True) def test_perform_test_command_run_failure(self, mock_popen, unused_mock_sleep, unused_mock_socket): mock_popen.poll.return_value = 10 mock_popen.return_value.pid = 1234 self.assertRaises(errors.Error, self.auth_test_mode.perform, self.achalls) def test_cleanup_test_mode_already_terminated(self): # pylint: disable=protected-access self.auth_test_mode._httpd = httpd = mock.Mock() httpd.poll.return_value = 0 self.auth_test_mode.cleanup(self.achalls) def test_cleanup_test_mode_kills_still_running(self): # pylint: disable=protected-access self.auth_test_mode._httpd = httpd = mock.Mock(pid=1234) httpd.poll.return_value = None self.auth_test_mode.cleanup(self.achalls) httpd.terminate.assert_called_once_with()
class AuthenticatorTest(unittest.TestCase): """Tests for certbot.plugins.manual.Authenticator.""" def setUp(self): self.http_achall = acme_util.HTTP01_A self.dns_achall = acme_util.DNS01_A self.achalls = [self.http_achall, self.dns_achall] self.config = mock.MagicMock( http01_port=0, manual_auth_hook=None, manual_cleanup_hook=None, manual_public_ip_logging_ok=False, noninteractive_mode=False, validate_hooks=False) from certbot.plugins.manual import Authenticator self.auth = Authenticator(self.config, name='manual') def test_prepare_no_hook_noninteractive(self): self.config.noninteractive_mode = True self.assertRaises(errors.PluginError, self.auth.prepare) def test_prepare_bad_hook(self): self.config.manual_auth_hook = os.path.abspath(os.sep) # is / on UNIX self.config.validate_hooks = True self.assertRaises(errors.HookCommandNotFound, self.auth.prepare) def test_more_info(self): self.assertTrue(isinstance(self.auth.more_info(), six.string_types)) def test_get_chall_pref(self): self.assertEqual(self.auth.get_chall_pref('example.org'), [challenges.HTTP01, challenges.DNS01]) @test_util.patch_get_utility() def test_ip_logging_not_ok(self, mock_get_utility): mock_get_utility().yesno.return_value = False self.assertRaises(errors.PluginError, self.auth.perform, []) @test_util.patch_get_utility() def test_ip_logging_ok(self, mock_get_utility): mock_get_utility().yesno.return_value = True self.auth.perform([]) self.assertTrue(self.config.manual_public_ip_logging_ok) def test_script_perform(self): self.config.manual_public_ip_logging_ok = True self.config.manual_auth_hook = ( 'echo $CERTBOT_DOMAIN; echo ${CERTBOT_TOKEN:-notoken}; ' 'echo $CERTBOT_VALIDATION;') dns_expected = '{0}\n{1}\n{2}'.format( self.dns_achall.domain, 'notoken', self.dns_achall.validation(self.dns_achall.account_key)) http_expected = '{0}\n{1}\n{2}'.format( self.http_achall.domain, self.http_achall.chall.encode('token'), self.http_achall.validation(self.http_achall.account_key)) self.assertEqual( self.auth.perform(self.achalls), [achall.response(achall.account_key) for achall in self.achalls]) self.assertEqual( self.auth.env[self.dns_achall.domain]['CERTBOT_AUTH_OUTPUT'], dns_expected) self.assertEqual( self.auth.env[self.http_achall.domain]['CERTBOT_AUTH_OUTPUT'], http_expected) @test_util.patch_get_utility() def test_manual_perform(self, mock_get_utility): self.config.manual_public_ip_logging_ok = True self.assertEqual( self.auth.perform(self.achalls), [achall.response(achall.account_key) for achall in self.achalls]) for i, (args, kwargs) in enumerate(mock_get_utility().notification.call_args_list): achall = self.achalls[i] self.assertTrue(achall.validation(achall.account_key) in args[0]) self.assertFalse(kwargs['wrap']) def test_cleanup(self): self.config.manual_public_ip_logging_ok = True self.config.manual_auth_hook = 'echo foo;' self.config.manual_cleanup_hook = '# cleanup' self.auth.perform(self.achalls) for achall in self.achalls: self.auth.cleanup([achall]) self.assertEqual(os.environ['CERTBOT_AUTH_OUTPUT'], 'foo') self.assertEqual(os.environ['CERTBOT_DOMAIN'], achall.domain) self.assertEqual( os.environ['CERTBOT_VALIDATION'], achall.validation(achall.account_key)) if isinstance(achall.chall, challenges.HTTP01): self.assertEqual( os.environ['CERTBOT_TOKEN'], achall.chall.encode('token')) else: self.assertFalse('CERTBOT_TOKEN' in os.environ)
class AuthenticatorTest(test_util.TempDirTestCase): """Tests for certbot.plugins.manual.Authenticator.""" def setUp(self): super(AuthenticatorTest, self).setUp() self.http_achall = acme_util.HTTP01_A self.dns_achall = acme_util.DNS01_A self.tls_sni_achall = acme_util.TLSSNI01_A self.achalls = [self.http_achall, self.dns_achall, self.tls_sni_achall] for d in ["config_dir", "work_dir", "in_progress"]: os.mkdir(os.path.join(self.tempdir, d)) # "backup_dir" and "temp_checkpoint_dir" get created in # certbot.util.make_or_verify_dir() during the Reverter # initialization. self.config = mock.MagicMock( http01_port=0, manual_auth_hook=None, manual_cleanup_hook=None, manual_public_ip_logging_ok=False, noninteractive_mode=False, validate_hooks=False, config_dir=os.path.join(self.tempdir, "config_dir"), work_dir=os.path.join(self.tempdir, "work_dir"), backup_dir=os.path.join(self.tempdir, "backup_dir"), temp_checkpoint_dir=os.path.join( self.tempdir, "temp_checkpoint_dir"), in_progress_dir=os.path.join(self.tempdir, "in_progess"), tls_sni_01_port=5001) from certbot.plugins.manual import Authenticator self.auth = Authenticator(self.config, name='manual') def test_prepare_no_hook_noninteractive(self): self.config.noninteractive_mode = True self.assertRaises(errors.PluginError, self.auth.prepare) def test_prepare_bad_hook(self): self.config.manual_auth_hook = os.path.abspath(os.sep) # is / on UNIX self.config.validate_hooks = True self.assertRaises(errors.HookCommandNotFound, self.auth.prepare) def test_more_info(self): self.assertTrue(isinstance(self.auth.more_info(), six.string_types)) def test_get_chall_pref(self): self.assertEqual(self.auth.get_chall_pref('example.org'), [challenges.HTTP01, challenges.DNS01, challenges.TLSSNI01]) @test_util.patch_get_utility() def test_ip_logging_not_ok(self, mock_get_utility): mock_get_utility().yesno.return_value = False self.assertRaises(errors.PluginError, self.auth.perform, []) @test_util.patch_get_utility() def test_ip_logging_ok(self, mock_get_utility): mock_get_utility().yesno.return_value = True self.auth.perform([]) self.assertTrue(self.config.manual_public_ip_logging_ok) def test_script_perform(self): self.config.manual_public_ip_logging_ok = True self.config.manual_auth_hook = ( 'echo ${CERTBOT_DOMAIN}; ' 'echo ${CERTBOT_TOKEN:-notoken}; ' 'echo ${CERTBOT_CERT_PATH:-nocert}; ' 'echo ${CERTBOT_KEY_PATH:-nokey}; ' 'echo ${CERTBOT_SNI_DOMAIN:-nosnidomain}; ' 'echo ${CERTBOT_VALIDATION:-novalidation};') dns_expected = '{0}\n{1}\n{2}\n{3}\n{4}\n{5}'.format( self.dns_achall.domain, 'notoken', 'nocert', 'nokey', 'nosnidomain', self.dns_achall.validation(self.dns_achall.account_key)) http_expected = '{0}\n{1}\n{2}\n{3}\n{4}\n{5}'.format( self.http_achall.domain, self.http_achall.chall.encode('token'), 'nocert', 'nokey', 'nosnidomain', self.http_achall.validation(self.http_achall.account_key)) self.assertEqual( self.auth.perform(self.achalls), [achall.response(achall.account_key) for achall in self.achalls]) self.assertEqual( self.auth.env[self.dns_achall.domain]['CERTBOT_AUTH_OUTPUT'], dns_expected) self.assertEqual( self.auth.env[self.http_achall.domain]['CERTBOT_AUTH_OUTPUT'], http_expected) # tls_sni_01 challenge must be perform()ed above before we can # get the cert_path and key_path. tls_sni_expected = '{0}\n{1}\n{2}\n{3}\n{4}\n{5}'.format( self.tls_sni_achall.domain, 'notoken', self.auth.tls_sni_01.get_cert_path(self.tls_sni_achall), self.auth.tls_sni_01.get_key_path(self.tls_sni_achall), self.auth.tls_sni_01.get_z_domain(self.tls_sni_achall), 'novalidation') self.assertEqual( self.auth.env[self.tls_sni_achall.domain]['CERTBOT_AUTH_OUTPUT'], tls_sni_expected) @test_util.patch_get_utility() def test_manual_perform(self, mock_get_utility): self.config.manual_public_ip_logging_ok = True self.assertEqual( self.auth.perform(self.achalls), [achall.response(achall.account_key) for achall in self.achalls]) for i, (args, kwargs) in enumerate(mock_get_utility().notification.call_args_list): achall = self.achalls[i] if isinstance(achall.chall, challenges.TLSSNI01): self.assertTrue( self.auth.tls_sni_01.get_cert_path( self.tls_sni_achall) in args[0]) else: self.assertTrue( achall.validation(achall.account_key) in args[0]) self.assertFalse(kwargs['wrap']) def test_cleanup(self): self.config.manual_public_ip_logging_ok = True self.config.manual_auth_hook = 'echo foo;' self.config.manual_cleanup_hook = '# cleanup' self.auth.perform(self.achalls) for achall in self.achalls: self.auth.cleanup([achall]) self.assertEqual(os.environ['CERTBOT_AUTH_OUTPUT'], 'foo') self.assertEqual(os.environ['CERTBOT_DOMAIN'], achall.domain) if (isinstance(achall.chall, challenges.HTTP01) or isinstance(achall.chall, challenges.DNS01)): self.assertEqual( os.environ['CERTBOT_VALIDATION'], achall.validation(achall.account_key)) if isinstance(achall.chall, challenges.HTTP01): self.assertEqual( os.environ['CERTBOT_TOKEN'], achall.chall.encode('token')) else: self.assertFalse('CERTBOT_TOKEN' in os.environ) if isinstance(achall.chall, challenges.TLSSNI01): self.assertEqual( os.environ['CERTBOT_CERT_PATH'], self.auth.tls_sni_01.get_cert_path(achall)) self.assertEqual( os.environ['CERTBOT_KEY_PATH'], self.auth.tls_sni_01.get_key_path(achall)) self.assertFalse( os.path.exists(os.environ['CERTBOT_CERT_PATH'])) self.assertFalse( os.path.exists(os.environ['CERTBOT_KEY_PATH']))
class AuthenticatorTest(test_util.TempDirTestCase): """Tests for certbot.plugins.manual.Authenticator.""" def setUp(self): super(AuthenticatorTest, self).setUp() self.http_achall = acme_util.HTTP01_A self.dns_achall = acme_util.DNS01_A self.dns_achall_2 = acme_util.DNS01_A_2 self.achalls = [self.http_achall, self.dns_achall, self.dns_achall_2] for d in ["config_dir", "work_dir", "in_progress"]: os.mkdir(os.path.join(self.tempdir, d)) # "backup_dir" and "temp_checkpoint_dir" get created in # certbot.util.make_or_verify_dir() during the Reverter # initialization. self.config = mock.MagicMock( http01_port=0, manual_auth_hook=None, manual_cleanup_hook=None, manual_public_ip_logging_ok=False, noninteractive_mode=False, validate_hooks=False, config_dir=os.path.join(self.tempdir, "config_dir"), work_dir=os.path.join(self.tempdir, "work_dir"), backup_dir=os.path.join(self.tempdir, "backup_dir"), temp_checkpoint_dir=os.path.join( self.tempdir, "temp_checkpoint_dir"), in_progress_dir=os.path.join(self.tempdir, "in_progess")) from certbot.plugins.manual import Authenticator self.auth = Authenticator(self.config, name='manual') def test_prepare_no_hook_noninteractive(self): self.config.noninteractive_mode = True self.assertRaises(errors.PluginError, self.auth.prepare) def test_prepare_bad_hook(self): self.config.manual_auth_hook = os.path.abspath(os.sep) # is / on UNIX self.config.validate_hooks = True self.assertRaises(errors.HookCommandNotFound, self.auth.prepare) def test_more_info(self): self.assertTrue(isinstance(self.auth.more_info(), six.string_types)) def test_get_chall_pref(self): self.assertEqual(self.auth.get_chall_pref('example.org'), [challenges.HTTP01, challenges.DNS01]) @test_util.patch_get_utility() def test_ip_logging_not_ok(self, mock_get_utility): mock_get_utility().yesno.return_value = False self.assertRaises(errors.PluginError, self.auth.perform, []) @test_util.patch_get_utility() def test_ip_logging_ok(self, mock_get_utility): mock_get_utility().yesno.return_value = True self.auth.perform([]) self.assertTrue(self.config.manual_public_ip_logging_ok) def test_script_perform(self): self.config.manual_public_ip_logging_ok = True self.config.manual_auth_hook = ( '{0} -c "from __future__ import print_function;' 'import os; print(os.environ.get(\'CERTBOT_DOMAIN\'));' 'print(os.environ.get(\'CERTBOT_TOKEN\', \'notoken\'));' 'print(os.environ.get(\'CERTBOT_VALIDATION\', \'novalidation\'));"' .format(sys.executable)) dns_expected = '{0}\n{1}\n{2}'.format( self.dns_achall.domain, 'notoken', self.dns_achall.validation(self.dns_achall.account_key)) http_expected = '{0}\n{1}\n{2}'.format( self.http_achall.domain, self.http_achall.chall.encode('token'), self.http_achall.validation(self.http_achall.account_key)) self.assertEqual( self.auth.perform(self.achalls), [achall.response(achall.account_key) for achall in self.achalls]) self.assertEqual( self.auth.env[self.dns_achall]['CERTBOT_AUTH_OUTPUT'], dns_expected) self.assertEqual( self.auth.env[self.http_achall]['CERTBOT_AUTH_OUTPUT'], http_expected) @test_util.patch_get_utility() def test_manual_perform(self, mock_get_utility): self.config.manual_public_ip_logging_ok = True self.assertEqual( self.auth.perform(self.achalls), [achall.response(achall.account_key) for achall in self.achalls]) for i, (args, kwargs) in enumerate(mock_get_utility().notification.call_args_list): achall = self.achalls[i] self.assertTrue( achall.validation(achall.account_key) in args[0]) self.assertFalse(kwargs['wrap']) @test_util.broken_on_windows def test_cleanup(self): self.config.manual_public_ip_logging_ok = True self.config.manual_auth_hook = 'echo foo;' self.config.manual_cleanup_hook = '# cleanup' self.auth.perform(self.achalls) for achall in self.achalls: self.auth.cleanup([achall]) self.assertEqual(os.environ['CERTBOT_AUTH_OUTPUT'], 'foo') self.assertEqual(os.environ['CERTBOT_DOMAIN'], achall.domain) if (isinstance(achall.chall, challenges.HTTP01) or isinstance(achall.chall, challenges.DNS01)): self.assertEqual( os.environ['CERTBOT_VALIDATION'], achall.validation(achall.account_key)) if isinstance(achall.chall, challenges.HTTP01): self.assertEqual( os.environ['CERTBOT_TOKEN'], achall.chall.encode('token')) else: self.assertFalse('CERTBOT_TOKEN' in os.environ)
class AuthenticatorTest(unittest.TestCase): """Tests for certbot.plugins.manual.Authenticator.""" def setUp(self): from certbot.plugins.manual import Authenticator self.config = mock.MagicMock( http01_port=8080, manual_test_mode=False, manual_public_ip_logging_ok=False, noninteractive_mode=True) self.auth = Authenticator(config=self.config, name="manual") self.achalls = [achallenges.KeyAuthorizationAnnotatedChallenge( challb=acme_util.HTTP01_P, domain="foo.com", account_key=KEY)] config_test_mode = mock.MagicMock( http01_port=8080, manual_test_mode=True, noninteractive_mode=True) self.auth_test_mode = Authenticator( config=config_test_mode, name="manual") def test_prepare(self): self.assertRaises(errors.PluginError, self.auth.prepare) self.auth_test_mode.prepare() # error not raised def test_more_info(self): self.assertTrue(isinstance(self.auth.more_info(), str)) def test_get_chall_pref(self): self.assertTrue(all(issubclass(pref, challenges.Challenge) for pref in self.auth.get_chall_pref("foo.com"))) def test_perform_empty(self): self.assertEqual([], self.auth.perform([])) @mock.patch("certbot.plugins.manual.zope.component.getUtility") @mock.patch("certbot.plugins.manual.sys.stdout") @mock.patch("acme.challenges.HTTP01Response.simple_verify") @mock.patch("six.moves.input") def test_perform(self, mock_raw_input, mock_verify, mock_stdout, mock_interaction): mock_verify.return_value = True mock_interaction().yesno.return_value = True resp = self.achalls[0].response(KEY) self.assertEqual([resp], self.auth.perform(self.achalls)) self.assertEqual(1, mock_raw_input.call_count) mock_verify.assert_called_with( self.achalls[0].challb.chall, "foo.com", KEY.public_key(), 8080) message = mock_stdout.write.mock_calls[0][1][0] self.assertTrue(self.achalls[0].chall.encode("token") in message) mock_verify.return_value = False with mock.patch("certbot.plugins.manual.logger") as mock_logger: self.auth.perform(self.achalls) mock_logger.warning.assert_called_once_with(mock.ANY) @mock.patch("certbot.plugins.manual.zope.component.getUtility") @mock.patch("certbot.plugins.manual.Authenticator._notify_and_wait") def test_disagree_with_ip_logging(self, mock_notify, mock_interaction): mock_interaction().yesno.return_value = False mock_notify.side_effect = errors.Error("Exception not raised, \ continued execution even after disagreeing with IP logging") self.assertRaises(errors.PluginError, self.auth.perform, self.achalls) @mock.patch("certbot.plugins.manual.subprocess.Popen", autospec=True) def test_perform_test_command_oserror(self, mock_popen): mock_popen.side_effect = OSError self.assertEqual([False], self.auth_test_mode.perform(self.achalls)) @mock.patch("certbot.plugins.manual.socket.socket") @mock.patch("certbot.plugins.manual.time.sleep", autospec=True) @mock.patch("certbot.plugins.manual.subprocess.Popen", autospec=True) def test_perform_test_command_run_failure( self, mock_popen, unused_mock_sleep, unused_mock_socket): mock_popen.poll.return_value = 10 mock_popen.return_value.pid = 1234 self.assertRaises( errors.Error, self.auth_test_mode.perform, self.achalls) def test_cleanup_test_mode_already_terminated(self): # pylint: disable=protected-access self.auth_test_mode._httpd = httpd = mock.Mock() httpd.poll.return_value = 0 self.auth_test_mode.cleanup(self.achalls) @mock.patch("certbot.plugins.manual.os.killpg", autospec=True) def test_cleanup_test_mode_kills_still_running(self, mock_killpg): # pylint: disable=protected-access self.auth_test_mode._httpd = httpd = mock.Mock(pid=1234) httpd.poll.return_value = None self.auth_test_mode.cleanup(self.achalls) mock_killpg.assert_called_once_with(1234, signal.SIGTERM)
class AuthenticatorTest(unittest.TestCase): """Tests for certbot.plugins.manual.Authenticator.""" def setUp(self): self.http_achall = acme_util.HTTP01_A self.dns_achall = acme_util.DNS01_A self.achalls = [self.http_achall, self.dns_achall] self.config = mock.MagicMock(http01_port=0, manual_auth_hook=None, manual_cleanup_hook=None, manual_public_ip_logging_ok=False, noninteractive_mode=False, validate_hooks=False) from certbot.plugins.manual import Authenticator self.auth = Authenticator(self.config, name='manual') def test_prepare_no_hook_noninteractive(self): self.config.noninteractive_mode = True self.assertRaises(errors.PluginError, self.auth.prepare) def test_prepare_bad_hook(self): self.config.manual_auth_hook = os.path.abspath(os.sep) # is / on UNIX self.config.validate_hooks = True self.assertRaises(errors.HookCommandNotFound, self.auth.prepare) def test_more_info(self): self.assertTrue(isinstance(self.auth.more_info(), six.string_types)) def test_get_chall_pref(self): self.assertEqual(self.auth.get_chall_pref('example.org'), [challenges.HTTP01, challenges.DNS01]) @test_util.patch_get_utility() def test_ip_logging_not_ok(self, mock_get_utility): mock_get_utility().yesno.return_value = False self.assertRaises(errors.PluginError, self.auth.perform, []) @test_util.patch_get_utility() def test_ip_logging_ok(self, mock_get_utility): mock_get_utility().yesno.return_value = True self.auth.perform([]) self.assertTrue(self.config.manual_public_ip_logging_ok) def test_script_perform(self): self.config.manual_public_ip_logging_ok = True self.config.manual_auth_hook = ( 'echo $CERTBOT_DOMAIN; echo ${CERTBOT_TOKEN:-notoken}; ' 'echo $CERTBOT_VALIDATION;') dns_expected = '{0}\n{1}\n{2}'.format( self.dns_achall.domain, 'notoken', self.dns_achall.validation(self.dns_achall.account_key)) http_expected = '{0}\n{1}\n{2}'.format( self.http_achall.domain, self.http_achall.chall.encode('token'), self.http_achall.validation(self.http_achall.account_key)) self.assertEqual( self.auth.perform(self.achalls), [achall.response(achall.account_key) for achall in self.achalls]) self.assertEqual( self.auth.env[self.dns_achall.domain]['CERTBOT_AUTH_OUTPUT'], dns_expected) self.assertEqual( self.auth.env[self.http_achall.domain]['CERTBOT_AUTH_OUTPUT'], http_expected) @test_util.patch_get_utility() def test_manual_perform(self, mock_get_utility): self.config.manual_public_ip_logging_ok = True self.assertEqual( self.auth.perform(self.achalls), [achall.response(achall.account_key) for achall in self.achalls]) for i, (args, kwargs) in enumerate( mock_get_utility().notification.call_args_list): achall = self.achalls[i] self.assertTrue(achall.validation(achall.account_key) in args[0]) self.assertFalse(kwargs['wrap']) def test_cleanup(self): self.config.manual_public_ip_logging_ok = True self.config.manual_auth_hook = 'echo foo;' self.config.manual_cleanup_hook = '# cleanup' self.auth.perform(self.achalls) for achall in self.achalls: self.auth.cleanup([achall]) self.assertEqual(os.environ['CERTBOT_AUTH_OUTPUT'], 'foo') self.assertEqual(os.environ['CERTBOT_DOMAIN'], achall.domain) self.assertEqual(os.environ['CERTBOT_VALIDATION'], achall.validation(achall.account_key)) if isinstance(achall.chall, challenges.HTTP01): self.assertEqual(os.environ['CERTBOT_TOKEN'], achall.chall.encode('token')) else: self.assertFalse('CERTBOT_TOKEN' in os.environ)
class AuthenticatorTest(test_util.TempDirTestCase): """Tests for certbot.plugins.manual.Authenticator.""" def setUp(self): super(AuthenticatorTest, self).setUp() self.http_achall = acme_util.HTTP01_A self.dns_achall = acme_util.DNS01_A self.tls_sni_achall = acme_util.TLSSNI01_A self.achalls = [self.http_achall, self.dns_achall, self.tls_sni_achall] for d in ["config_dir", "work_dir", "in_progress"]: os.mkdir(os.path.join(self.tempdir, d)) # "backup_dir" and "temp_checkpoint_dir" get created in # certbot.util.make_or_verify_dir() during the Reverter # initialization. self.config = mock.MagicMock( http01_port=0, manual_auth_hook=None, manual_cleanup_hook=None, manual_public_ip_logging_ok=False, noninteractive_mode=False, validate_hooks=False, config_dir=os.path.join(self.tempdir, "config_dir"), work_dir=os.path.join(self.tempdir, "work_dir"), backup_dir=os.path.join(self.tempdir, "backup_dir"), temp_checkpoint_dir=os.path.join(self.tempdir, "temp_checkpoint_dir"), in_progress_dir=os.path.join(self.tempdir, "in_progess"), tls_sni_01_port=5001) from certbot.plugins.manual import Authenticator self.auth = Authenticator(self.config, name='manual') def test_prepare_no_hook_noninteractive(self): self.config.noninteractive_mode = True self.assertRaises(errors.PluginError, self.auth.prepare) def test_prepare_bad_hook(self): self.config.manual_auth_hook = os.path.abspath(os.sep) # is / on UNIX self.config.validate_hooks = True self.assertRaises(errors.HookCommandNotFound, self.auth.prepare) def test_more_info(self): self.assertTrue(isinstance(self.auth.more_info(), six.string_types)) def test_get_chall_pref(self): self.assertEqual( self.auth.get_chall_pref('example.org'), [challenges.HTTP01, challenges.DNS01, challenges.TLSSNI01]) @test_util.patch_get_utility() def test_ip_logging_not_ok(self, mock_get_utility): mock_get_utility().yesno.return_value = False self.assertRaises(errors.PluginError, self.auth.perform, []) @test_util.patch_get_utility() def test_ip_logging_ok(self, mock_get_utility): mock_get_utility().yesno.return_value = True self.auth.perform([]) self.assertTrue(self.config.manual_public_ip_logging_ok) def test_script_perform(self): self.config.manual_public_ip_logging_ok = True self.config.manual_auth_hook = ( 'echo ${CERTBOT_DOMAIN}; ' 'echo ${CERTBOT_TOKEN:-notoken}; ' 'echo ${CERTBOT_CERT_PATH:-nocert}; ' 'echo ${CERTBOT_KEY_PATH:-nokey}; ' 'echo ${CERTBOT_SNI_DOMAIN:-nosnidomain}; ' 'echo ${CERTBOT_VALIDATION:-novalidation};') dns_expected = '{0}\n{1}\n{2}\n{3}\n{4}\n{5}'.format( self.dns_achall.domain, 'notoken', 'nocert', 'nokey', 'nosnidomain', self.dns_achall.validation(self.dns_achall.account_key)) http_expected = '{0}\n{1}\n{2}\n{3}\n{4}\n{5}'.format( self.http_achall.domain, self.http_achall.chall.encode('token'), 'nocert', 'nokey', 'nosnidomain', self.http_achall.validation(self.http_achall.account_key)) self.assertEqual( self.auth.perform(self.achalls), [achall.response(achall.account_key) for achall in self.achalls]) self.assertEqual( self.auth.env[self.dns_achall.domain]['CERTBOT_AUTH_OUTPUT'], dns_expected) self.assertEqual( self.auth.env[self.http_achall.domain]['CERTBOT_AUTH_OUTPUT'], http_expected) # tls_sni_01 challenge must be perform()ed above before we can # get the cert_path and key_path. tls_sni_expected = '{0}\n{1}\n{2}\n{3}\n{4}\n{5}'.format( self.tls_sni_achall.domain, 'notoken', self.auth.tls_sni_01.get_cert_path(self.tls_sni_achall), self.auth.tls_sni_01.get_key_path(self.tls_sni_achall), self.auth.tls_sni_01.get_z_domain(self.tls_sni_achall), 'novalidation') self.assertEqual( self.auth.env[self.tls_sni_achall.domain]['CERTBOT_AUTH_OUTPUT'], tls_sni_expected) @test_util.patch_get_utility() def test_manual_perform(self, mock_get_utility): self.config.manual_public_ip_logging_ok = True self.assertEqual( self.auth.perform(self.achalls), [achall.response(achall.account_key) for achall in self.achalls]) for i, (args, kwargs) in enumerate( mock_get_utility().notification.call_args_list): achall = self.achalls[i] if isinstance(achall.chall, challenges.TLSSNI01): self.assertTrue( self.auth.tls_sni_01.get_cert_path(self.tls_sni_achall) in args[0]) else: self.assertTrue( achall.validation(achall.account_key) in args[0]) self.assertFalse(kwargs['wrap']) def test_cleanup(self): self.config.manual_public_ip_logging_ok = True self.config.manual_auth_hook = 'echo foo;' self.config.manual_cleanup_hook = '# cleanup' self.auth.perform(self.achalls) for achall in self.achalls: self.auth.cleanup([achall]) self.assertEqual(os.environ['CERTBOT_AUTH_OUTPUT'], 'foo') self.assertEqual(os.environ['CERTBOT_DOMAIN'], achall.domain) if (isinstance(achall.chall, challenges.HTTP01) or isinstance(achall.chall, challenges.DNS01)): self.assertEqual(os.environ['CERTBOT_VALIDATION'], achall.validation(achall.account_key)) if isinstance(achall.chall, challenges.HTTP01): self.assertEqual(os.environ['CERTBOT_TOKEN'], achall.chall.encode('token')) else: self.assertFalse('CERTBOT_TOKEN' in os.environ) if isinstance(achall.chall, challenges.TLSSNI01): self.assertEqual(os.environ['CERTBOT_CERT_PATH'], self.auth.tls_sni_01.get_cert_path(achall)) self.assertEqual(os.environ['CERTBOT_KEY_PATH'], self.auth.tls_sni_01.get_key_path(achall)) self.assertFalse( os.path.exists(os.environ['CERTBOT_CERT_PATH'])) self.assertFalse(os.path.exists( os.environ['CERTBOT_KEY_PATH']))