mirror of
https://github.com/certbot/certbot.git
synced 2026-06-03 13:59:02 -04:00
parent
7a24499f15
commit
7d775ae9f3
8 changed files with 113 additions and 19 deletions
|
|
@ -193,6 +193,7 @@ def auth(args, config, plugins):
|
|||
domains, authenticator, installer, plugins):
|
||||
return "Certificate could not be obtained"
|
||||
|
||||
|
||||
def install(args, config, plugins):
|
||||
"""Install a previously obtained cert in a server."""
|
||||
# XXX: Update for renewer/RenewableCert
|
||||
|
|
@ -621,6 +622,16 @@ def main(cli_args=sys.argv[1:]):
|
|||
args = create_parser(plugins, cli_args).parse_args(cli_args)
|
||||
config = configuration.NamespaceConfig(args)
|
||||
|
||||
# Setup logging ASAP, otherwise "No handlers could be found for
|
||||
# logger ..." TODO: this should be done before plugins discovery
|
||||
for directory in config.config_dir, config.work_dir:
|
||||
le_util.make_or_verify_dir(
|
||||
directory, constants.CONFIG_DIRS_MODE, os.geteuid())
|
||||
# TODO: logs might contain sensitive data such as contents of the
|
||||
# private key! #525
|
||||
le_util.make_or_verify_dir(args.logs_dir, 0o700, os.geteuid())
|
||||
_setup_logging(args)
|
||||
|
||||
# Displayer
|
||||
if args.text_mode:
|
||||
displayer = display_util.FileDisplay(sys.stdout)
|
||||
|
|
@ -628,14 +639,6 @@ def main(cli_args=sys.argv[1:]):
|
|||
displayer = display_util.NcursesDisplay()
|
||||
zope.component.provideUtility(displayer)
|
||||
|
||||
for directory in config.config_dir, config.work_dir:
|
||||
le_util.make_or_verify_dir(
|
||||
directory, constants.CONFIG_DIRS_MODE, os.geteuid())
|
||||
# TODO: logs might contain sensitive data such as contents of the
|
||||
# private key! #525
|
||||
le_util.make_or_verify_dir(args.logs_dir, 0o700, os.geteuid())
|
||||
|
||||
_setup_logging(args)
|
||||
# do not log `args`, as it contains sensitive data (e.g. revoke --key)!
|
||||
logger.debug("Arguments: %r", cli_args)
|
||||
logger.debug("Discovered plugins: %r", plugins)
|
||||
|
|
|
|||
|
|
@ -83,6 +83,8 @@ class IPlugin(zope.interface.Interface):
|
|||
Should describe the steps taken and any relevant info to help the user
|
||||
decide which plugin to use.
|
||||
|
||||
:rtype str:
|
||||
|
||||
"""
|
||||
|
||||
|
||||
|
|
@ -200,7 +202,11 @@ class IInstaller(IPlugin):
|
|||
"""
|
||||
|
||||
def get_all_names():
|
||||
"""Returns all names that may be authenticated."""
|
||||
"""Returns all names that may be authenticated.
|
||||
|
||||
:rtype: `list` of `str`
|
||||
|
||||
"""
|
||||
|
||||
def deploy_cert(domain, cert_path, key_path, chain_path=None):
|
||||
"""Deploy certificate.
|
||||
|
|
|
|||
|
|
@ -71,11 +71,11 @@ class PluginEntryPoint(object):
|
|||
for iface in ifaces: # zope.interface.providedBy(plugin)
|
||||
try:
|
||||
zope.interface.verify.verifyObject(iface, self.init())
|
||||
except zope.interface.exceptions.BrokenImplementation:
|
||||
except zope.interface.exceptions.BrokenImplementation as error:
|
||||
if iface.implementedBy(self.plugin_cls):
|
||||
logger.debug(
|
||||
"%s implements %s but object does "
|
||||
"not verify", self.plugin_cls, iface.__name__)
|
||||
"%s implements %s but object does not verify: %s",
|
||||
self.plugin_cls, iface.__name__, error)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
|
|
|||
|
|
@ -11,19 +11,20 @@ from acme import challenges
|
|||
from acme import jose
|
||||
|
||||
from letsencrypt import interfaces
|
||||
from letsencrypt.plugins import common
|
||||
from letsencrypt.plugins import null
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ManualAuthenticator(common.Plugin):
|
||||
class ManualAuthenticator(null.Installer):
|
||||
"""Manual Authenticator.
|
||||
|
||||
.. todo:: Support for `~.challenges.DVSNI`.
|
||||
|
||||
"""
|
||||
zope.interface.implements(interfaces.IAuthenticator)
|
||||
zope.interface.implements(
|
||||
interfaces.IAuthenticator, interfaces.IInstaller)
|
||||
zope.interface.classProvides(interfaces.IPluginFactory)
|
||||
|
||||
description = "Manual Authenticator"
|
||||
|
|
|
|||
57
letsencrypt/plugins/null.py
Normal file
57
letsencrypt/plugins/null.py
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
"""Null plugin."""
|
||||
import logging
|
||||
|
||||
import zope.component
|
||||
import zope.interface
|
||||
|
||||
from letsencrypt import interfaces
|
||||
from letsencrypt.plugins import common
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Installer(common.Plugin):
|
||||
"""Null installer."""
|
||||
zope.interface.implements(interfaces.IInstaller)
|
||||
zope.interface.classProvides(interfaces.IPluginFactory)
|
||||
|
||||
description = "Null Installer"
|
||||
|
||||
# pylint: disable=missing-docstring,no-self-use
|
||||
|
||||
def prepare(self):
|
||||
pass # pragma: no cover
|
||||
|
||||
def more_info(self):
|
||||
return "Installer that doesn't do anything (for testing)."
|
||||
|
||||
def get_all_names(self):
|
||||
return []
|
||||
|
||||
def deploy_cert(self, domain, cert_path, key_path, chain_path=None):
|
||||
pass # pragma: no cover
|
||||
|
||||
def enhance(self, domain, enhancement, options=None):
|
||||
pass # pragma: no cover
|
||||
|
||||
def supported_enhancements(self):
|
||||
return []
|
||||
|
||||
def get_all_certs_keys(self):
|
||||
return []
|
||||
|
||||
def save(self, title=None, temporary=False):
|
||||
pass # pragma: no cover
|
||||
|
||||
def rollback_checkpoints(self, rollback=1):
|
||||
pass # pragma: no cover
|
||||
|
||||
def view_config_changes(self):
|
||||
pass # pragma: no cover
|
||||
|
||||
def config_test(self):
|
||||
pass # pragma: no cover
|
||||
|
||||
def restart(self):
|
||||
pass # pragma: no cover
|
||||
22
letsencrypt/plugins/null_test.py
Normal file
22
letsencrypt/plugins/null_test.py
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
"""Tests for letsencrypt.plugins.null."""
|
||||
import unittest
|
||||
|
||||
import mock
|
||||
|
||||
|
||||
class InstallerTest(unittest.TestCase):
|
||||
"""Tests for letsencrypt.plugins.null.Installer."""
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.plugins.null import Installer
|
||||
self.installer = Installer(config=mock.MagicMock(), name="null")
|
||||
|
||||
def test_it(self):
|
||||
self.assertTrue(isinstance(self.installer.more_info(), str))
|
||||
self.assertEqual([], self.installer.get_all_names())
|
||||
self.assertEqual([], self.installer.supported_enhancements())
|
||||
self.assertEqual([], self.installer.get_all_certs_keys())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main() # pragma: no cover
|
||||
2
setup.py
2
setup.py
|
|
@ -181,6 +181,8 @@ setup(
|
|||
],
|
||||
'letsencrypt.plugins': [
|
||||
'manual = letsencrypt.plugins.manual:ManualAuthenticator',
|
||||
# TODO: null should probably not be presented to the user
|
||||
'null = letsencrypt.plugins.null:Installer',
|
||||
'standalone = letsencrypt.plugins.standalone.authenticator'
|
||||
':StandaloneAuthenticator',
|
||||
|
||||
|
|
|
|||
|
|
@ -19,13 +19,16 @@ common() {
|
|||
--agree-eula \
|
||||
--email "" \
|
||||
--authenticator standalone \
|
||||
--installer null \
|
||||
-vvvvvvv "$@"
|
||||
}
|
||||
|
||||
common --domains le.wtf auth
|
||||
common --domains le1.wtf auth
|
||||
common --domains le2.wtf run
|
||||
common --domains le3.wtf install
|
||||
|
||||
export CSR_PATH="${root}/csr.der" OPENSSL_CNF=examples/openssl.cnf
|
||||
./examples/generate-csr.sh le.wtf
|
||||
./examples/generate-csr.sh le4.wtf
|
||||
common auth --csr "$CSR_PATH" \
|
||||
--cert-path "${root}/csr/cert.pem" \
|
||||
--chain-path "${root}/csr/chain.pem"
|
||||
|
|
@ -39,10 +42,10 @@ renew_before_expiry = 10 years
|
|||
deploy_before_expiry = 10 years
|
||||
EOF
|
||||
letsencrypt-renewer $store_flags
|
||||
dir="$root/conf/archive/le.wtf"
|
||||
dir="$root/conf/archive/le1.wtf"
|
||||
for x in cert chain fullchain privkey;
|
||||
do
|
||||
latest="$(ls -1t $dir/ | grep -e "^${x}" | head -n1)"
|
||||
live="$(readlink -f "$root/conf/live/le.wtf/${x}.pem")"
|
||||
live="$(readlink -f "$root/conf/live/le1.wtf/${x}.pem")"
|
||||
#[ "${dir}/${latest}" = "$live" ] # renewer fails this test
|
||||
done
|
||||
|
|
|
|||
Loading…
Reference in a new issue