예제 #1
0
파일: cli.py 프로젝트: tkfu/letsencrypt
def main(cli_args=sys.argv[1:]):
    """Command line argument parsing and main script execution."""
    sys.excepthook = functools.partial(_handle_exception, args=None)

    # note: arg parser internally handles --help (and exits afterwards)
    plugins = plugins_disco.PluginsRegistry.find_all()
    parser, tweaked_cli_args = create_parser(plugins, cli_args)
    args = parser.parse_args(tweaked_cli_args)
    config = configuration.NamespaceConfig(args)
    zope.component.provideUtility(config)

    # 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(),
            "--strict-permissions" in cli_args)
    # 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(), "--strict-permissions" in cli_args)
    setup_logging(args, _cli_log_handler, logfile='letsencrypt.log')

    # 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)

    sys.excepthook = functools.partial(_handle_exception, args=args)

    # Displayer
    if args.text_mode:
        displayer = display_util.FileDisplay(sys.stdout)
    else:
        displayer = display_util.NcursesDisplay()
    zope.component.provideUtility(displayer)

    # Reporter
    report = reporter.Reporter()
    zope.component.provideUtility(report)
    atexit.register(report.atexit_print_messages)

    # TODO: remove developer EULA prompt for the launch
    if not config.eula:
        eula = pkg_resources.resource_string("letsencrypt", "EULA")
        if not zope.component.getUtility(interfaces.IDisplay).yesno(
                eula, "Agree", "Cancel"):
            raise Error("Must agree to TOS")

    if not os.geteuid() == 0:
        logger.warning(
            "Root (sudo) is required to run most of letsencrypt functionality.")
        # check must be done after arg parsing as --help should work
        # w/o root; on the other hand, e.g. "letsencrypt run
        # --authenticator dns" or "letsencrypt plugins" does not
        # require root as well
        #return (
        #    "{0}Root is required to run letsencrypt.  Please use sudo.{0}"
        #    .format(os.linesep))

    return args.func(args, config, plugins)
예제 #2
0
def main2(cli_args, args, config, plugins):
    """Continued main script execution."""

    # Displayer
    if args.text_mode:
        displayer = display_util.FileDisplay(sys.stdout)
    else:
        displayer = display_util.NcursesDisplay()
    zope.component.provideUtility(displayer)

    # 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)

    # Reporter
    report = reporter.Reporter()
    zope.component.provideUtility(report)
    atexit.register(report.atexit_print_messages)

    if not os.geteuid() == 0:
        logger.warning(
            "Root (sudo) is required to run most of letsencrypt functionality.")
        # check must be done after arg parsing as --help should work
        # w/o root; on the other hand, e.g. "letsencrypt run
        # --authenticator dns" or "letsencrypt plugins" does not
        # require root as well
        #return (
        #    "{0}Root is required to run letsencrypt.  Please use sudo.{0}"
        #    .format(os.linesep))

    return args.func(args, config, plugins)
예제 #3
0
def main(cli_args=sys.argv[1:]):
    """Main function for autorenewer script."""
    # TODO: Distinguish automated invocation from manual invocation,
    #       perhaps by looking at sys.argv[0] and inhibiting automated
    #       invocations if /etc/letsencrypt/renewal.conf defaults have
    #       turned it off. (The boolean parameter should probably be
    #       called renewer_enabled.)

    # TODO: When we have a more elaborate renewer command line, we will
    #       presumably also be able to specify a config file on the
    #       command line, which, if provided, should take precedence over
    #       te default config files

    zope.component.provideUtility(display_util.FileDisplay(sys.stdout))

    args = _create_parser().parse_args(cli_args)

    uid = os.geteuid()
    le_util.make_or_verify_dir(args.logs_dir, 0o700, uid)
    cli.setup_logging(args, _cli_log_handler, logfile='renewer.log')

    cli_config = configuration.RenewerConfiguration(args)

    # Ensure that all of the needed folders have been created before continuing
    le_util.make_or_verify_dir(cli_config.work_dir,
                               constants.CONFIG_DIRS_MODE, uid)

    for renewal_file in os.listdir(cli_config.renewal_configs_dir):
        print "Processing", renewal_file
        try:
            # TODO: Before trying to initialize the RenewableCert object,
            #       we could check here whether the combination of the config
            #       and the rc_config together disables all autorenewal and
            #       autodeployment applicable to this cert.  In that case, we
            #       can simply continue and don't need to instantiate a
            #       RenewableCert object for this cert at all, which could
            #       dramatically improve performance for large deployments
            #       where autorenewal is widely turned off.
            cert = storage.RenewableCert(renewal_file, cli_config)
        except errors.CertStorageError:
            # This indicates an invalid renewal configuration file, such
            # as one missing a required parameter (in the future, perhaps
            # also one that is internally inconsistent or is missing a
            # required parameter).  As a TODO, maybe we should warn the
            # user about the existence of an invalid or corrupt renewal
            # config rather than simply ignoring it.
            continue
        if cert.should_autorenew():
            # Note: not cert.current_version() because the basis for
            # the renewal is the latest version, even if it hasn't been
            # deployed yet!
            old_version = cert.latest_common_version()
            renew(cert, old_version)
            notify.notify("Autorenewed a cert!!!", "root", "It worked!")
            # TODO: explain what happened
        if cert.should_autodeploy():
            cert.update_all_links_to(cert.latest_common_version())
            # TODO: restart web server (invoke IInstaller.restart() method)
            notify.notify("Autodeployed a cert!!!", "root", "It worked!")
    def setUp(self):
        from letsencrypt.revoker import Cert
        self.cert0 = Cert(test_util.vector_path("cert.pem"))
        self.cert1 = Cert(test_util.vector_path("cert-san.pem"))

        self.certs = [self.cert0, self.cert1]

        zope.component.provideUtility(display_util.FileDisplay(sys.stdout))
    def setUp(self):
        super(ApacheParserTest, self).setUp()

        zope.component.provideUtility(display_util.FileDisplay(sys.stdout))

        from letsencrypt_apache.parser import ApacheParser
        self.aug = augeas.Augeas(flags=augeas.Augeas.NONE)
        self.parser = ApacheParser(self.aug, self.config_path,
                                   self.ssl_options)
예제 #6
0
 def setUp(self):
     zope.component.provideUtility(display_util.FileDisplay(sys.stdout))
     self.mock_apache = mock.Mock(description_with_name="a",
                                  misconfigured=True)
     self.mock_stand = mock.Mock(description_with_name="s",
                                 misconfigured=False)
     self.mock_stand.init().more_info.return_value = "standalone"
     self.plugins = [
         self.mock_apache,
         self.mock_stand,
     ]
    def setUp(self):
        from letsencrypt.revoker import Cert
        base_package = "letsencrypt.tests"
        self.cert0 = Cert(
            pkg_resources.resource_filename(
                base_package, os.path.join("testdata", "cert.pem")))
        self.cert1 = Cert(
            pkg_resources.resource_filename(
                base_package, os.path.join("testdata", "cert-san.pem")))

        self.certs = [self.cert0, self.cert1]

        zope.component.provideUtility(display_util.FileDisplay(sys.stdout))
예제 #8
0
파일: util.py 프로젝트: jepler/letsencrypt
    def setUp(self, test_dir="debian_apache_2_4/two_vhost_80",
              config_root="debian_apache_2_4/two_vhost_80/apache2"):
        super(ParserTest, self).setUp(test_dir, config_root)

        zope.component.provideUtility(display_util.FileDisplay(sys.stdout))

        from letsencrypt_apache.parser import ApacheParser
        self.aug = augeas.Augeas(
            flags=augeas.Augeas.NONE | augeas.Augeas.NO_MODL_AUTOLOAD)
        with mock.patch("letsencrypt_apache.parser.ApacheParser."
                        "update_runtime_variables"):
            self.parser = ApacheParser(
                self.aug, self.config_path, "dummy_ctl_path")
예제 #9
0
def main(cli_args=sys.argv[1:]):
    """Command line argument parsing and main script execution."""
    sys.excepthook = functools.partial(_handle_exception, config=None)
    plugins = plugins_disco.PluginsRegistry.find_all()

    # note: arg parser internally handles --help (and exits afterwards)
    args = cli.prepare_and_parse_args(plugins, cli_args)
    config = configuration.NamespaceConfig(args)
    zope.component.provideUtility(config)

    # 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(), "--strict-permissions"
                                   in cli_args)
    # TODO: logs might contain sensitive data such as contents of the
    # private key! #525
    le_util.make_or_verify_dir(config.logs_dir, 0o700, os.geteuid(),
                               "--strict-permissions" in cli_args)
    setup_logging(config, _cli_log_handler, logfile='letsencrypt.log')

    logger.debug("letsencrypt version: %s", letsencrypt.__version__)
    # do not log `config`, as it contains sensitive data (e.g. revoke --key)!
    logger.debug("Arguments: %r", cli_args)
    logger.debug("Discovered plugins: %r", plugins)

    sys.excepthook = functools.partial(_handle_exception, config=config)

    # Displayer
    if config.quiet:
        config.noninteractive_mode = True
        displayer = display_util.NoninteractiveDisplay(open(os.devnull, "w"))
    elif config.noninteractive_mode:
        displayer = display_util.NoninteractiveDisplay(sys.stdout)
    elif config.text_mode:
        displayer = display_util.FileDisplay(sys.stdout)
    elif config.verb == "renew":
        config.noninteractive_mode = True
        displayer = display_util.NoninteractiveDisplay(sys.stdout)
    else:
        displayer = display_util.NcursesDisplay()
    zope.component.provideUtility(displayer)

    # Reporter
    report = reporter.Reporter(config)
    zope.component.provideUtility(report)
    atexit.register(report.atexit_print_messages)

    return config.func(config, plugins)
예제 #10
0
    def setUp(self):
        zope.component.provideUtility(display_util.FileDisplay(sys.stdout))

        self.accounts_dir = tempfile.mkdtemp("accounts")
        self.account_keys_dir = os.path.join(self.accounts_dir, "keys")
        os.makedirs(self.account_keys_dir, 0o700)

        self.config = mock.MagicMock(accounts_dir=self.accounts_dir,
                                     account_keys_dir=self.account_keys_dir,
                                     server="letsencrypt-demo.org")
        self.key = le_util.Key("keypath", "pem")

        self.acc1 = account.Account(self.config, self.key, "*****@*****.**")
        self.acc2 = account.Account(self.config, self.key, "*****@*****.**",
                                    "phone")
        self.acc1.save()
        self.acc2.save()
예제 #11
0
    def setUp(self):
        zope.component.provideUtility(display_util.FileDisplay(sys.stdout))

        self.accounts_dir = tempfile.mkdtemp("accounts")
        self.account_keys_dir = os.path.join(self.accounts_dir, "keys")
        os.makedirs(self.account_keys_dir, 0o700)

        self.config = mock.MagicMock(
            accounts_dir=self.accounts_dir,
            account_keys_dir=self.account_keys_dir,
            server="letsencrypt-demo.org")
        self.key = KEY

        self.acc1 = account.Account(messages.RegistrationResource(
            uri=None, new_authzr_uri=None, body=messages.Registration.from_data(
                email="*****@*****.**")), self.key)
        self.acc2 = account.Account(messages.RegistrationResource(
            uri=None, new_authzr_uri=None, body=messages.Registration.from_data(
                email="*****@*****.**", phone="phone")), self.key)
예제 #12
0
def main(args=sys.argv[1:]):
    """Command line argument parsing and main script execution."""
    # note: arg parser internally handles --help (and exits afterwards)
    plugins = plugins_disco.PluginsRegistry.find_all()
    args = create_parser(plugins).parse_args(args)
    config = configuration.NamespaceConfig(args)

    # Displayer
    if args.text_mode:
        displayer = display_util.FileDisplay(sys.stdout)
    else:
        displayer = display_util.NcursesDisplay()
    zope.component.provideUtility(displayer)

    # Reporter
    report = reporter.Reporter()
    zope.component.provideUtility(report)
    atexit.register(report.atexit_print_messages)

    # Logging
    level = -args.verbose_count * 10
    logger = logging.getLogger()
    logger.setLevel(level)
    logging.debug("Logging level set at %d", level)
    if not args.text_mode:
        logger.addHandler(log.DialogHandler())

    logging.debug("Discovered plugins: %r", plugins)

    if not os.geteuid() == 0:
        logging.warning(
            "Root (sudo) is required to run most of letsencrypt functionality.")
        # check must be done after arg parsing as --help should work
        # w/o root; on the other hand, e.g. "letsencrypt run
        # --authenticator dns" or "letsencrypt plugins" does not
        # require root as well
        #return (
        #    "{0}Root is required to run letsencrypt.  Please use sudo.{0}"
        #    .format(os.linesep))

    return args.func(args, config, plugins)
예제 #13
0
 def setUp(self):
     zope.component.provideUtility(display_util.FileDisplay(sys.stdout))
     self.base_dir = "/example_path"
     self.vhosts = util.get_vh_truth(
         self.base_dir, "debian_apache_2_4/multiple_vhosts")
예제 #14
0
 def setUp(self):
     zope.component.provideUtility(display_util.FileDisplay(sys.stdout))
     self.mock_install = mock.MagicMock()
예제 #15
0
 def setUp(self):
     zope.component.provideUtility(display_util.FileDisplay(sys.stdout))
예제 #16
0
 def setUp(self):
     super(FileOutputDisplayTest, self).setUp()
     self.mock_stdout = mock.MagicMock()
     self.displayer = display_util.FileDisplay(self.mock_stdout)
예제 #17
0
"""Manual test of display functions."""
import sys

from letsencrypt.display import util
from letsencrypt.tests.display import util_test


def test_visual(displayer, choices):
    """Visually test all of the display functions."""
    displayer.notification("Random notification!")
    displayer.menu("Question?",
                   choices,
                   ok_label="O",
                   cancel_label="Can",
                   help_label="??")
    displayer.menu("Question?", [choice[1] for choice in choices],
                   ok_label="O",
                   cancel_label="Can",
                   help_label="??")
    displayer.input("Input Message")
    displayer.yesno("YesNo Message", yes_label="Yessir", no_label="Nosir")
    displayer.checklist("Checklist Message", [choice[0] for choice in choices])


if __name__ == "__main__":
    for displayer in util.NcursesDisplay(), util.FileDisplay(sys.stdout):
        test_visual(displayer, util_test.CHOICES)
예제 #18
0
def main(config=None, args=sys.argv[1:]):
    """Main function for autorenewer script."""
    # TODO: Distinguish automated invocation from manual invocation,
    #       perhaps by looking at sys.argv[0] and inhibiting automated
    #       invocations if /etc/letsencrypt/renewal.conf defaults have
    #       turned it off. (The boolean parameter should probably be
    #       called renewer_enabled.)

    zope.component.provideUtility(display_util.FileDisplay(sys.stdout))

    cli_config = configuration.RenewerConfiguration(
        _create_parser().parse_args(args))

    config = storage.config_with_defaults(config)
    # Now attempt to read the renewer config file and augment or replace
    # the renewer defaults with any options contained in that file.  If
    # renewer_config_file is undefined or if the file is nonexistent or
    # empty, this .merge() will have no effect.  TODO: when we have a more
    # elaborate renewer command line, we will presumably also be able to
    # specify a config file on the command line, which, if provided, should
    # take precedence over this one.
    config.merge(configobj.ConfigObj(cli_config.renewer_config_file))

    for i in os.listdir(cli_config.renewal_configs_dir):
        print "Processing", i
        if not i.endswith(".conf"):
            continue
        rc_config = configobj.ConfigObj(cli_config.renewer_config_file)
        rc_config.merge(
            configobj.ConfigObj(os.path.join(cli_config.renewal_configs_dir,
                                             i)))
        # TODO: this is a dirty hack!
        rc_config.filename = os.path.join(cli_config.renewal_configs_dir, i)
        try:
            # TODO: Before trying to initialize the RenewableCert object,
            #       we could check here whether the combination of the config
            #       and the rc_config together disables all autorenewal and
            #       autodeployment applicable to this cert.  In that case, we
            #       can simply continue and don't need to instantiate a
            #       RenewableCert object for this cert at all, which could
            #       dramatically improve performance for large deployments
            #       where autorenewal is widely turned off.
            cert = storage.RenewableCert(rc_config, cli_config=cli_config)
        except errors.CertStorageError:
            # This indicates an invalid renewal configuration file, such
            # as one missing a required parameter (in the future, perhaps
            # also one that is internally inconsistent or is missing a
            # required parameter).  As a TODO, maybe we should warn the
            # user about the existence of an invalid or corrupt renewal
            # config rather than simply ignoring it.
            continue
        if cert.should_autorenew():
            # Note: not cert.current_version() because the basis for
            # the renewal is the latest version, even if it hasn't been
            # deployed yet!
            old_version = cert.latest_common_version()
            renew(cert, old_version)
            notify.notify("Autorenewed a cert!!!", "root", "It worked!")
            # TODO: explain what happened
        if cert.should_autodeploy():
            cert.update_all_links_to(cert.latest_common_version())
            # TODO: restart web server (invoke IInstaller.restart() method)
            notify.notify("Autodeployed a cert!!!", "root", "It worked!")