예제 #1
0
def _search_lineages(cli_config, func, initial_rv, *args):
    """Iterate func over unbroken lineages, allowing custom return conditions.

    Allows flexible customization of return values, including multiple
    return values and complex checks.

    :param `configuration.NamespaceConfig` cli_config: parsed command line arguments
    :param function func: function used while searching over lineages
    :param initial_rv: initial return value of the function (any type)

    :returns: Whatever was specified by `func` if a match is found.
    """
    configs_dir = cli_config.renewal_configs_dir
    # Verify the directory is there
    util.make_or_verify_dir(configs_dir, mode=0o755, uid=misc.os_geteuid())

    rv = initial_rv
    for renewal_file in storage.renewal_conf_files(cli_config):
        try:
            candidate_lineage = storage.RenewableCert(renewal_file, cli_config)
        except (errors.CertStorageError, IOError):
            logger.debug("Renewal conf file %s is broken. Skipping.",
                         renewal_file)
            logger.debug("Traceback was:\n%s", traceback.format_exc())
            continue
        rv = func(candidate_lineage, rv, *args)
    return rv
예제 #2
0
def init_save_key(key_size, key_dir, keyname="key-certbot.pem"):
    """Initializes and saves a privkey.

    Inits key and saves it in PEM format on the filesystem.

    .. note:: keyname is the attempted filename, it may be different if a file
        already exists at the path.

    :param int key_size: RSA key size in bits
    :param str key_dir: Key save directory.
    :param str keyname: Filename of key

    :returns: Key
    :rtype: :class:`certbot.util.Key`

    :raises ValueError: If unable to generate the key given key_size.

    """
    try:
        key_pem = make_key(key_size)
    except ValueError as err:
        logger.error("", exc_info=True)
        raise err

    config = zope.component.getUtility(interfaces.IConfig)
    # Save file
    util.make_or_verify_dir(key_dir, 0o700, misc.os_geteuid(),
                            config.strict_permissions)
    key_f, key_path = util.unique_file(os.path.join(key_dir, keyname), 0o600,
                                       "wb")
    with key_f:
        key_f.write(key_pem)
    logger.debug("Generating key (%d bits): %s", key_size, key_path)

    return util.Key(key_path, key_pem)
예제 #3
0
def _search_lineages(cli_config, func, initial_rv, *args):
    """Iterate func over unbroken lineages, allowing custom return conditions.

    Allows flexible customization of return values, including multiple
    return values and complex checks.

    :param `configuration.NamespaceConfig` cli_config: parsed command line arguments
    :param function func: function used while searching over lineages
    :param initial_rv: initial return value of the function (any type)

    :returns: Whatever was specified by `func` if a match is found.
    """
    configs_dir = cli_config.renewal_configs_dir
    # Verify the directory is there
    util.make_or_verify_dir(configs_dir, mode=0o755, uid=misc.os_geteuid())

    rv = initial_rv
    for renewal_file in storage.renewal_conf_files(cli_config):
        try:
            candidate_lineage = storage.RenewableCert(renewal_file, cli_config)
        except (errors.CertStorageError, IOError):
            logger.debug("Renewal conf file %s is broken. Skipping.", renewal_file)
            logger.debug("Traceback was:\n%s", traceback.format_exc())
            continue
        rv = func(candidate_lineage, rv, *args)
    return rv
예제 #4
0
    def setUp(self):
        super(MakeOrVerifyDirTest, self).setUp()

        self.path = os.path.join(self.tempdir, "foo")
        os.mkdir(self.path, 0o600)

        self.uid = misc.os_geteuid()
예제 #5
0
파일: account.py 프로젝트: certbot/certbot
 def _save(self, account, acme, regr_only):
     account_dir_path = self._account_dir_path(account.id)
     util.make_or_verify_dir(account_dir_path, 0o700, misc.os_geteuid(),
                             self.config.strict_permissions)
     try:
         with open(self._regr_path(account_dir_path), "w") as regr_file:
             regr = account.regr
             # If we have a value for new-authz, save it for forwards
             # compatibility with older versions of Certbot. If we don't
             # have a value for new-authz, this is an ACMEv2 directory where
             # an older version of Certbot won't work anyway.
             if hasattr(acme.directory, "new-authz"):
                 regr = RegistrationResourceWithNewAuthzrURI(
                     new_authzr_uri=acme.directory.new_authz,
                     body={},
                     uri=regr.uri)
             else:
                 regr = messages.RegistrationResource(
                     body={},
                     uri=regr.uri)
             regr_file.write(regr.json_dumps())
         if not regr_only:
             with util.safe_open(self._key_path(account_dir_path),
                                 "w", chmod=0o400) as key_file:
                 key_file.write(account.key.json_dumps())
             with open(self._metadata_path(
                     account_dir_path), "w") as metadata_file:
                 metadata_file.write(account.meta.json_dumps())
     except IOError as error:
         raise errors.AccountStorageError(error)
예제 #6
0
def init_save_key(key_size, key_dir, keyname="key-certbot.pem"):
    """Initializes and saves a privkey.

    Inits key and saves it in PEM format on the filesystem.

    .. note:: keyname is the attempted filename, it may be different if a file
        already exists at the path.

    :param int key_size: RSA key size in bits
    :param str key_dir: Key save directory.
    :param str keyname: Filename of key

    :returns: Key
    :rtype: :class:`certbot.util.Key`

    :raises ValueError: If unable to generate the key given key_size.

    """
    try:
        key_pem = make_key(key_size)
    except ValueError as err:
        logger.error("", exc_info=True)
        raise err

    config = zope.component.getUtility(interfaces.IConfig)
    # Save file
    util.make_or_verify_dir(key_dir, 0o700, misc.os_geteuid(),
                            config.strict_permissions)
    key_f, key_path = util.unique_file(
        os.path.join(key_dir, keyname), 0o600, "wb")
    with key_f:
        key_f.write(key_pem)
    logger.debug("Generating key (%d bits): %s", key_size, key_path)

    return util.Key(key_path, key_pem)
예제 #7
0
def init_save_csr(privkey, names, path):
    """Initialize a CSR with the given private key.

    :param privkey: Key to include in the CSR
    :type privkey: :class:`certbot.util.Key`

    :param set names: `str` names to include in the CSR

    :param str path: Certificate save directory.

    :returns: CSR
    :rtype: :class:`certbot.util.CSR`

    """
    config = zope.component.getUtility(interfaces.IConfig)

    csr_pem = acme_crypto_util.make_csr(
        privkey.pem, names, must_staple=config.must_staple)

    # Save CSR
    util.make_or_verify_dir(path, 0o755, misc.os_geteuid(),
                            config.strict_permissions)
    csr_f, csr_filename = util.unique_file(
        os.path.join(path, "csr-certbot.pem"), 0o644, "wb")
    with csr_f:
        csr_f.write(csr_pem)
    logger.debug("Creating CSR: %s", csr_filename)

    return util.CSR(csr_filename, csr_pem, "pem")
예제 #8
0
def setup_log_file_handler(config, logfile, fmt):
    """Setup file debug logging.

    :param certbot.interface.IConfig config: Configuration object
    :param str logfile: basename for the log file
    :param str fmt: logging format string

    :returns: file handler and absolute path to the log file
    :rtype: tuple

    """
    # TODO: logs might contain sensitive data such as contents of the
    # private key! #525
    util.set_up_core_dir(config.logs_dir, 0o700, misc.os_geteuid(),
                         config.strict_permissions)
    log_file_path = os.path.join(config.logs_dir, logfile)
    try:
        handler = logging.handlers.RotatingFileHandler(
            log_file_path, maxBytes=2**20, backupCount=config.max_log_backups)
    except IOError as error:
        raise errors.Error(util.PERM_ERR_FMT.format(error))
    # rotate on each invocation, rollover only possible when maxBytes
    # is nonzero and backupCount is nonzero, so we set maxBytes as big
    # as possible not to overrun in single CLI invocation (1MB).
    handler.doRollover()  # TODO: creates empty letsencrypt.log.1 file
    handler.setLevel(logging.DEBUG)
    handler_formatter = logging.Formatter(fmt=fmt)
    handler.setFormatter(handler_formatter)
    return handler, log_file_path
예제 #9
0
    def setUp(self):
        super(MakeOrVerifyDirTest, self).setUp()

        self.path = os.path.join(self.tempdir, "foo")
        os.mkdir(self.path, 0o600)

        self.uid = misc.os_geteuid()
예제 #10
0
 def _save(self, account, acme, regr_only):
     account_dir_path = self._account_dir_path(account.id)
     util.make_or_verify_dir(account_dir_path, 0o700, misc.os_geteuid(),
                             self.config.strict_permissions)
     try:
         with open(self._regr_path(account_dir_path), "w") as regr_file:
             regr = account.regr
             # If we have a value for new-authz, save it for forwards
             # compatibility with older versions of Certbot. If we don't
             # have a value for new-authz, this is an ACMEv2 directory where
             # an older version of Certbot won't work anyway.
             if hasattr(acme.directory, "new-authz"):
                 regr = RegistrationResourceWithNewAuthzrURI(
                     new_authzr_uri=acme.directory.new_authz,
                     body={},
                     uri=regr.uri)
             else:
                 regr = messages.RegistrationResource(body={}, uri=regr.uri)
             regr_file.write(regr.json_dumps())
         if not regr_only:
             with util.safe_open(self._key_path(account_dir_path),
                                 "w",
                                 chmod=0o400) as key_file:
                 key_file.write(account.key.json_dumps())
             with open(self._metadata_path(account_dir_path),
                       "w") as metadata_file:
                 metadata_file.write(account.meta.json_dumps())
     except IOError as error:
         raise errors.AccountStorageError(error)
예제 #11
0
def init_save_csr(privkey, names, path):
    """Initialize a CSR with the given private key.

    :param privkey: Key to include in the CSR
    :type privkey: :class:`certbot.util.Key`

    :param set names: `str` names to include in the CSR

    :param str path: Certificate save directory.

    :returns: CSR
    :rtype: :class:`certbot.util.CSR`

    """
    config = zope.component.getUtility(interfaces.IConfig)

    csr_pem = acme_crypto_util.make_csr(privkey.pem,
                                        names,
                                        must_staple=config.must_staple)

    # Save CSR
    util.make_or_verify_dir(path, 0o755, misc.os_geteuid(),
                            config.strict_permissions)
    csr_f, csr_filename = util.unique_file(
        os.path.join(path, "csr-certbot.pem"), 0o644, "wb")
    with csr_f:
        csr_f.write(csr_pem)
    logger.debug("Creating CSR: %s", csr_filename)

    return util.CSR(csr_filename, csr_pem, "pem")
예제 #12
0
파일: reverter.py 프로젝트: OCForks/certbot
    def _get_cp_dir(self, temporary):
        """Return the proper reverter directory."""
        if temporary:
            cp_dir = self.config.temp_checkpoint_dir
        else:
            cp_dir = self.config.in_progress_dir

        util.make_or_verify_dir(cp_dir, constants.CONFIG_DIRS_MODE,
                                misc.os_geteuid(),
                                self.config.strict_permissions)

        return cp_dir
예제 #13
0
파일: reverter.py 프로젝트: certbot/certbot
    def _get_cp_dir(self, temporary):
        """Return the proper reverter directory."""
        if temporary:
            cp_dir = self.config.temp_checkpoint_dir
        else:
            cp_dir = self.config.in_progress_dir

        util.make_or_verify_dir(
            cp_dir, constants.CONFIG_DIRS_MODE, misc.os_geteuid(),
            self.config.strict_permissions)

        return cp_dir
예제 #14
0
파일: main.py 프로젝트: vforks/certbot
def make_or_verify_needed_dirs(config):
    """Create or verify existence of config, work, and hook directories.

    :param config: Configuration object
    :type config: interfaces.IConfig

    :returns: `None`
    :rtype: None

    """
    util.set_up_core_dir(config.config_dir, constants.CONFIG_DIRS_MODE,
                         misc.os_geteuid(), config.strict_permissions)
    util.set_up_core_dir(config.work_dir, constants.CONFIG_DIRS_MODE,
                         misc.os_geteuid(), config.strict_permissions)

    hook_dirs = (config.renewal_pre_hooks_dir,
                 config.renewal_deploy_hooks_dir,
                 config.renewal_post_hooks_dir,)
    for hook_dir in hook_dirs:
        util.make_or_verify_dir(hook_dir,
                                uid=misc.os_geteuid(),
                                strict=config.strict_permissions)
예제 #15
0
def lineage_for_certname(cli_config, certname):
    """Find a lineage object with name certname."""
    configs_dir = cli_config.renewal_configs_dir
    # Verify the directory is there
    util.make_or_verify_dir(configs_dir, mode=0o755, uid=misc.os_geteuid())
    try:
        renewal_file = storage.renewal_file_for_certname(cli_config, certname)
    except errors.CertStorageError:
        return None
    try:
        return storage.RenewableCert(renewal_file, cli_config)
    except (errors.CertStorageError, IOError):
        logger.debug("Renewal conf file %s is broken.", renewal_file)
        logger.debug("Traceback was:\n%s", traceback.format_exc())
        return None
예제 #16
0
def lineage_for_certname(cli_config, certname):
    """Find a lineage object with name certname."""
    configs_dir = cli_config.renewal_configs_dir
    # Verify the directory is there
    util.make_or_verify_dir(configs_dir, mode=0o755, uid=misc.os_geteuid())
    try:
        renewal_file = storage.renewal_file_for_certname(cli_config, certname)
    except errors.CertStorageError:
        return None
    try:
        return storage.RenewableCert(renewal_file, cli_config)
    except (errors.CertStorageError, IOError):
        logger.debug("Renewal conf file %s is broken.", renewal_file)
        logger.debug("Traceback was:\n%s", traceback.format_exc())
        return None
예제 #17
0
    def _verify_setup(self):
        """Verify the setup to ensure safe operating environment.

        Make sure that files/directories are setup with appropriate permissions
        Aim for defensive coding... make sure all input files
        have permissions of root.

        """
        uid = misc.os_geteuid()
        util.make_or_verify_dir(self.config.work_dir,
                                core_constants.CONFIG_DIRS_MODE, uid)
        util.make_or_verify_dir(self.config.backup_dir,
                                core_constants.CONFIG_DIRS_MODE, uid)
        util.make_or_verify_dir(self.config.config_dir,
                                core_constants.CONFIG_DIRS_MODE, uid)
예제 #18
0
    def _verify_setup(self):
        """Verify the setup to ensure safe operating environment.

        Make sure that files/directories are setup with appropriate permissions
        Aim for defensive coding... make sure all input files
        have permissions of root.

        """
        uid = misc.os_geteuid()
        util.make_or_verify_dir(
            self.config.work_dir, core_constants.CONFIG_DIRS_MODE, uid)
        util.make_or_verify_dir(
            self.config.backup_dir, core_constants.CONFIG_DIRS_MODE, uid)
        util.make_or_verify_dir(
            self.config.config_dir, core_constants.CONFIG_DIRS_MODE, uid)
예제 #19
0
파일: reverter.py 프로젝트: OCForks/certbot
    def _add_to_checkpoint_dir(self, cp_dir, save_files, save_notes):
        """Add save files to checkpoint directory.

        :param str cp_dir: Checkpoint directory filepath
        :param set save_files: set of files to save
        :param str save_notes: notes about changes made during the save

        :raises IOError: if unable to open cp_dir + FILEPATHS file
        :raises .ReverterError: if unable to add checkpoint

        """
        util.make_or_verify_dir(cp_dir, constants.CONFIG_DIRS_MODE,
                                misc.os_geteuid(),
                                self.config.strict_permissions)

        op_fd, existing_filepaths = self._read_and_append(
            os.path.join(cp_dir, "FILEPATHS"))

        idx = len(existing_filepaths)

        for filename in save_files:
            # No need to copy/index already existing files
            # The oldest copy already exists in the directory...
            if filename not in existing_filepaths:
                # Tag files with index so multiple files can
                # have the same filename
                logger.debug("Creating backup of %s", filename)
                try:
                    shutil.copy2(
                        filename,
                        os.path.join(
                            cp_dir,
                            os.path.basename(filename) + "_" + str(idx)))
                    op_fd.write('{0}\n'.format(filename))
                # http://stackoverflow.com/questions/4726260/effective-use-of-python-shutil-copy2
                except IOError:
                    op_fd.close()
                    logger.error("Unable to add file %s to checkpoint %s",
                                 filename, cp_dir)
                    raise errors.ReverterError(
                        "Unable to add file {0} to checkpoint "
                        "{1}".format(filename, cp_dir))
                idx += 1
        op_fd.close()

        with open(os.path.join(cp_dir, "CHANGES_SINCE"), "a") as notes_fd:
            notes_fd.write(save_notes)
예제 #20
0
파일: reverter.py 프로젝트: certbot/certbot
    def _add_to_checkpoint_dir(self, cp_dir, save_files, save_notes):
        """Add save files to checkpoint directory.

        :param str cp_dir: Checkpoint directory filepath
        :param set save_files: set of files to save
        :param str save_notes: notes about changes made during the save

        :raises IOError: if unable to open cp_dir + FILEPATHS file
        :raises .ReverterError: if unable to add checkpoint

        """
        util.make_or_verify_dir(
            cp_dir, constants.CONFIG_DIRS_MODE, misc.os_geteuid(),
            self.config.strict_permissions)

        op_fd, existing_filepaths = self._read_and_append(
            os.path.join(cp_dir, "FILEPATHS"))

        idx = len(existing_filepaths)

        for filename in save_files:
            # No need to copy/index already existing files
            # The oldest copy already exists in the directory...
            if filename not in existing_filepaths:
                # Tag files with index so multiple files can
                # have the same filename
                logger.debug("Creating backup of %s", filename)
                try:
                    shutil.copy2(filename, os.path.join(
                        cp_dir, os.path.basename(filename) + "_" + str(idx)))
                    op_fd.write('{0}\n'.format(filename))
                # http://stackoverflow.com/questions/4726260/effective-use-of-python-shutil-copy2
                except IOError:
                    op_fd.close()
                    logger.error(
                        "Unable to add file %s to checkpoint %s",
                        filename, cp_dir)
                    raise errors.ReverterError(
                        "Unable to add file {0} to checkpoint "
                        "{1}".format(filename, cp_dir))
                idx += 1
        op_fd.close()

        with open(os.path.join(cp_dir, "CHANGES_SINCE"), "a") as notes_fd:
            notes_fd.write(save_notes)
예제 #21
0
파일: client.py 프로젝트: certbot/certbot
    def save_certificate(self, cert_pem, chain_pem,
                         cert_path, chain_path, fullchain_path):
        """Saves the certificate received from the ACME server.

        :param str cert_pem:
        :param str chain_pem:
        :param str cert_path: Candidate path to a certificate.
        :param str chain_path: Candidate path to a certificate chain.
        :param str fullchain_path: Candidate path to a full cert chain.

        :returns: cert_path, chain_path, and fullchain_path as absolute
            paths to the actual files
        :rtype: `tuple` of `str`

        :raises IOError: If unable to find room to write the cert files

        """
        for path in cert_path, chain_path, fullchain_path:
            util.make_or_verify_dir(
                os.path.dirname(path), 0o755, misc.os_geteuid(),
                self.config.strict_permissions)


        cert_file, abs_cert_path = _open_pem_file('cert_path', cert_path)

        try:
            cert_file.write(cert_pem)
        finally:
            cert_file.close()
        logger.info("Server issued certificate; certificate written to %s",
                    abs_cert_path)

        chain_file, abs_chain_path =\
                _open_pem_file('chain_path', chain_path)
        fullchain_file, abs_fullchain_path =\
                _open_pem_file('fullchain_path', fullchain_path)

        _save_chain(chain_pem, chain_file)
        _save_chain(cert_pem + chain_pem, fullchain_file)

        return abs_cert_path, abs_chain_path, abs_fullchain_path
예제 #22
0
    def save_certificate(self, cert_pem, chain_pem,
                         cert_path, chain_path, fullchain_path):
        """Saves the certificate received from the ACME server.

        :param str cert_pem:
        :param str chain_pem:
        :param str cert_path: Candidate path to a certificate.
        :param str chain_path: Candidate path to a certificate chain.
        :param str fullchain_path: Candidate path to a full cert chain.

        :returns: cert_path, chain_path, and fullchain_path as absolute
            paths to the actual files
        :rtype: `tuple` of `str`

        :raises IOError: If unable to find room to write the cert files

        """
        for path in cert_path, chain_path, fullchain_path:
            util.make_or_verify_dir(
                os.path.dirname(path), 0o755, misc.os_geteuid(),
                self.config.strict_permissions)


        cert_file, abs_cert_path = _open_pem_file('cert_path', cert_path)

        try:
            cert_file.write(cert_pem)
        finally:
            cert_file.close()
        logger.info("Server issued certificate; certificate written to %s",
                    abs_cert_path)

        chain_file, abs_chain_path =\
                _open_pem_file('chain_path', chain_path)
        fullchain_file, abs_fullchain_path =\
                _open_pem_file('fullchain_path', fullchain_path)

        _save_chain(chain_pem, chain_file)
        _save_chain(cert_pem + chain_pem, fullchain_file)

        return abs_cert_path, abs_chain_path, abs_fullchain_path
예제 #23
0
    def setUp(self):
        super(CheckPermissionsTest, self).setUp()

        self.uid = misc.os_geteuid()
예제 #24
0
파일: log_test.py 프로젝트: certbot/certbot
 def test_permissions(self):
     self.assertTrue(
         util.check_permissions(self.handler.path, 0o600, misc.os_geteuid()))
예제 #25
0
파일: account.py 프로젝트: certbot/certbot
 def __init__(self, config):
     self.config = config
     util.make_or_verify_dir(config.accounts_dir, 0o700, misc.os_geteuid(),
                             self.config.strict_permissions)
예제 #26
0
    def setUp(self):
        super(CheckPermissionsTest, self).setUp()

        self.uid = misc.os_geteuid()
예제 #27
0
 def test_failure(self, mock_make_or_verify):
     mock_make_or_verify.side_effect = OSError
     self.assertRaises(errors.Error, self._call, self.tempdir, 0o700,
                       misc.os_geteuid(), False)
예제 #28
0
 def test_success(self, mock_lock):
     new_dir = os.path.join(self.tempdir, 'new')
     self._call(new_dir, 0o700, misc.os_geteuid(), False)
     self.assertTrue(os.path.exists(new_dir))
     self.assertEqual(mock_lock.call_count, 1)
예제 #29
0
파일: reverter.py 프로젝트: certbot/certbot
    def __init__(self, config):
        self.config = config

        util.make_or_verify_dir(
            config.backup_dir, constants.CONFIG_DIRS_MODE, misc.os_geteuid(),
            self.config.strict_permissions)
예제 #30
0
 def test_permissions(self):
     self.assertTrue(
         util.check_permissions(self.handler.path, 0o600, misc.os_geteuid()))
예제 #31
0
 def test_failure(self, mock_make_or_verify):
     mock_make_or_verify.side_effect = OSError
     self.assertRaises(errors.Error, self._call,
                       self.tempdir, 0o700, misc.os_geteuid(), False)
예제 #32
0
 def __init__(self, config):
     self.config = config
     util.make_or_verify_dir(config.accounts_dir, 0o700, misc.os_geteuid(),
                             self.config.strict_permissions)
예제 #33
0
파일: reverter.py 프로젝트: OCForks/certbot
    def __init__(self, config):
        self.config = config

        util.make_or_verify_dir(config.backup_dir, constants.CONFIG_DIRS_MODE,
                                misc.os_geteuid(),
                                self.config.strict_permissions)
예제 #34
0
 def test_success(self, mock_lock):
     new_dir = os.path.join(self.tempdir, 'new')
     self._call(new_dir, 0o700, misc.os_geteuid(), False)
     self.assertTrue(os.path.exists(new_dir))
     self.assertEqual(mock_lock.call_count, 1)