示例#1
0
    def cleanup(self, achalls):  # pylint: disable=missing-function-docstring
        for achall in achalls:
            root_path = self.full_roots.get(achall.domain, None)
            if root_path is not None:
                validation_path = self._get_validation_path(root_path, achall)
                logger.debug("Removing %s", validation_path)
                os.remove(validation_path)
                self.performed[root_path].remove(achall)

                if not filesystem.POSIX_MODE:
                    web_config_path = os.path.join(root_path, "web.config")
                    if os.path.exists(web_config_path):
                        sha256sum = crypto_util.sha256sum(web_config_path)
                        if sha256sum in _WEB_CONFIG_SHA256SUMS:
                            logger.info("Cleaning web.config file generated by Certbot in %s.",
                                        root_path)
                            os.remove(web_config_path)
                        else:
                            logger.info("Not cleaning up the web.config file in %s "
                                        "because it is not generated by Certbot.", root_path)


        not_removed: List[str] = []
        while self._created_dirs:
            path = self._created_dirs.pop()
            try:
                os.rmdir(path)
            except OSError as exc:
                not_removed.insert(0, path)
                logger.info("Challenge directory %s was not empty, didn't remove", path)
                logger.debug("Error was: %s", exc)
        self._created_dirs = not_removed
        logger.debug("All challenges cleaned up")
示例#2
0
文件: util.py 项目: certbot/certbot
    def setUp(self, test_dir="debian_apache_2_4/multiple_vhosts",
              config_root="debian_apache_2_4/multiple_vhosts/apache2",
              vhost_root="debian_apache_2_4/multiple_vhosts/apache2/sites-available"):
        # pylint: disable=arguments-differ
        super(ApacheTest, self).setUp()

        self.temp_dir, self.config_dir, self.work_dir = common.dir_setup(
            test_dir=test_dir,
            pkg="certbot_apache.tests")

        self.config_path = os.path.join(self.temp_dir, config_root)
        self.vhost_path = os.path.join(self.temp_dir, vhost_root)

        self.rsa512jwk = jose.JWKRSA.load(test_util.load_vector(
            "rsa512_key.pem"))

        self.config = get_apache_configurator(self.config_path, vhost_root,
                                              self.config_dir, self.work_dir)

        # Make sure all vhosts in sites-enabled are symlinks (Python packaging
        # does not preserve symlinks)
        sites_enabled = os.path.join(self.config_path, "sites-enabled")
        if not os.path.exists(sites_enabled):
            return

        for vhost_basename in os.listdir(sites_enabled):
            # Keep the one non-symlink test vhost in place
            if vhost_basename == "non-symlink.conf":
                continue
            vhost = os.path.join(sites_enabled, vhost_basename)
            if not os.path.islink(vhost):  # pragma: no cover
                os.remove(vhost)
                target = os.path.join(
                    os.path.pardir, "sites-available", vhost_basename)
                os.symlink(target, vhost)
示例#3
0
 def test_no_file(self):
     # prepare should have placed a file there
     self._assert_current_file()
     os.remove(self.config.mod_ssl_conf)
     self.assertFalse(os.path.isfile(self.config.mod_ssl_conf))
     self._call()
     self._assert_current_file()
示例#4
0
def safely_remove(path):
    """Remove a file that may not exist."""
    try:
        os.remove(path)
    except OSError as err:
        if err.errno != errno.ENOENT:
            raise
示例#5
0
    def setUp(
        self,
        test_dir="debian_apache_2_4/multiple_vhosts",
        config_root="debian_apache_2_4/multiple_vhosts/apache2",
        vhost_root="debian_apache_2_4/multiple_vhosts/apache2/sites-available"
    ):
        # pylint: disable=arguments-differ
        self.temp_dir, self.config_dir, self.work_dir = common.dir_setup(
            test_dir=test_dir, pkg=__name__)

        self.config_path = os.path.join(self.temp_dir, config_root)
        self.vhost_path = os.path.join(self.temp_dir, vhost_root)

        self.rsa512jwk = jose.JWKRSA.load(
            test_util.load_vector("rsa512_key.pem"))

        self.config = get_apache_configurator(self.config_path, vhost_root,
                                              self.config_dir, self.work_dir)

        # Make sure all vhosts in sites-enabled are symlinks (Python packaging
        # does not preserve symlinks)
        sites_enabled = os.path.join(self.config_path, "sites-enabled")
        if not os.path.exists(sites_enabled):
            return

        for vhost_basename in os.listdir(sites_enabled):
            # Keep the one non-symlink test vhost in place
            if vhost_basename == "non-symlink.conf":
                continue
            vhost = os.path.join(sites_enabled, vhost_basename)
            if not os.path.islink(vhost):  # pragma: no cover
                os.remove(vhost)
                target = os.path.join(os.path.pardir, "sites-available",
                                      vhost_basename)
                os.symlink(target, vhost)
示例#6
0
文件: util.py 项目: certbot/certbot
def safely_remove(path):
    """Remove a file that may not exist."""
    try:
        os.remove(path)
    except OSError as err:
        if err.errno != errno.ENOENT:
            raise
示例#7
0
 def test_no_file(self):
     # prepare should have placed a file there
     self._assert_current_file()
     os.remove(self.config.mod_ssl_conf)
     self.assertFalse(os.path.isfile(self.config.mod_ssl_conf))
     self._call()
     self._assert_current_file()
示例#8
0
    def test_no_hooks(self):
        self.config.pre_hook = None
        self.config.verb = "renew"
        os.remove(self.dir_hook)

        with mock.patch("certbot.hooks.logger") as mock_logger:
            mock_execute = self._call_with_mock_execute(self.config)
        self.assertFalse(mock_execute.called)
        self.assertFalse(mock_logger.info.called)
示例#9
0
 def test_no_readme_file(self):
     os.remove(os.path.join(
         self.config.live_dir, "example.org", "README"))
     self._call()
     self.assertFalse(os.path.exists(self.config_file.filename))
     self.assertFalse(os.path.exists(os.path.join(
         self.config.live_dir, "example.org")))
     self.assertFalse(os.path.exists(os.path.join(
         self.config.config_dir, "archive", "example.org")))
示例#10
0
    def test_no_hooks(self):
        self.config.renew_hook = None
        os.remove(self.dir_hook)

        with mock.patch("certbot.hooks.logger") as mock_logger:
            mock_execute = self._call_with_mock_execute(
                self.config, ["example.org"], "/foo/bar")
        self.assertFalse(mock_execute.called)
        self.assertFalse(mock_logger.info.called)
示例#11
0
 def test_no_readme_file(self):
     os.remove(os.path.join(
         self.config.live_dir, "example.org", "README"))
     self._call()
     self.assertFalse(os.path.exists(self.config_file.filename))
     self.assertFalse(os.path.exists(os.path.join(
         self.config.live_dir, "example.org")))
     self.assertFalse(os.path.exists(os.path.join(
         self.config.config_dir, "archive", "example.org")))
示例#12
0
    def test_no_hooks(self):
        self.config.renew_hook = None
        os.remove(self.dir_hook)

        with mock.patch("certbot._internal.hooks.logger") as mock_logger:
            mock_execute = self._call_with_mock_execute(
                self.config, ["example.org"], "/foo/bar")
        self.assertFalse(mock_execute.called)
        self.assertFalse(mock_logger.info.called)
示例#13
0
    def test_no_hooks(self):
        self.config.pre_hook = None
        self.config.verb = "renew"
        os.remove(self.dir_hook)

        with mock.patch("certbot._internal.hooks.logger") as mock_logger:
            mock_execute = self._call_with_mock_execute(self.config)
        self.assertFalse(mock_execute.called)
        self.assertFalse(mock_logger.info.called)
示例#14
0
 def handle_rw_files(_, path, __):
     """Handle read-only files, that will fail to be removed on Windows."""
     filesystem.chmod(path, stat.S_IWRITE)
     try:
         os.remove(path)
     except (IOError, OSError):
         # TODO: remote the try/except once all logic from windows file permissions is merged
         if os.name != 'nt':
             raise
示例#15
0
文件: client.py 项目: weitanx/certbot
 def _retry_obtain_certificate(
     self, key: util.Key, csr: util.CSR, domains: List[str],
     successful_domains: List[str]
 ) -> Tuple[bytes, bytes, util.Key, util.CSR]:
     failed_domains = [d for d in domains if d not in successful_domains]
     domains_list = ", ".join(failed_domains)
     display_util.notify(
         "Unable to obtain a certificate with every requested "
         f"domain. Retrying without: {domains_list}")
     if not self.config.dry_run:
         os.remove(key.file)
         os.remove(csr.file)
     return self.obtain_certificate(successful_domains)
示例#16
0
    def release(self):
        """Release the lock."""
        try:
            msvcrt.locking(self._fd, msvcrt.LK_UNLCK, 1)
            os.close(self._fd)

            try:
                os.remove(self._path)
            except OSError as e:
                # If the lock file cannot be removed, it is not a big deal.
                # Likely another instance is acquiring the lock we just released.
                logger.debug(str(e))
        finally:
            self._fd = None
示例#17
0
文件: lock.py 项目: certbot/certbot
    def release(self):
        """Release the lock."""
        try:
            msvcrt.locking(self._fd, msvcrt.LK_UNLCK, 1)
            os.close(self._fd)

            try:
                os.remove(self._path)
            except OSError as e:
                # If the lock file cannot be removed, it is not a big deal.
                # Likely another instance is acquiring the lock we just released.
                logger.debug(str(e))
        finally:
            self._fd = None
示例#18
0
    def release(self):
        """Release the lock."""
        try:
            # This "type: ignore" is currently needed because msvcrt methods
            # are only defined on Windows. See
            # https://github.com/python/typeshed/blob/16ae4c61201cd8b96b8b22cdfb2ab9e89ba5bcf2/stdlib/msvcrt.pyi.
            msvcrt.locking(self._fd, msvcrt.LK_UNLCK, 1)  # type: ignore
            os.close(self._fd)

            try:
                os.remove(self._path)
            except OSError as e:
                # If the lock file cannot be removed, it is not a big deal.
                # Likely another instance is acquiring the lock we just released.
                logger.debug(str(e))
        finally:
            self._fd = None
示例#19
0
    def close(self):
        """Close the handler and the temporary log file.

        The temporary log file is deleted if it wasn't used.

        """
        self.acquire()
        try:
            # StreamHandler.close() doesn't close the stream to allow a
            # stream like stderr to be used
            self.stream.close()
            if self._delete:
                os.remove(self.path)
            self._delete = False
            super(TempHandler, self).close()
        finally:
            self.release()
示例#20
0
    def release(self):
        """Release the lock."""
        try:
            # The need for this "type: ignore" was fixed in
            # https://github.com/python/typeshed/pull/3607 and included in
            # newer versions of mypy so it can be removed when mypy is
            # upgraded.
            msvcrt.locking(self._fd, msvcrt.LK_UNLCK, 1)  # type: ignore
            os.close(self._fd)

            try:
                os.remove(self._path)
            except OSError as e:
                # If the lock file cannot be removed, it is not a big deal.
                # Likely another instance is acquiring the lock we just released.
                logger.debug(str(e))
        finally:
            self._fd = None
示例#21
0
    def cleanup(self, achalls):  # pylint: disable=missing-function-docstring
        for achall in achalls:
            root_path = self.full_roots.get(achall.domain, None)
            if root_path is not None:
                validation_path = self._get_validation_path(root_path, achall)
                logger.debug("Removing %s", validation_path)
                os.remove(validation_path)
                self.performed[root_path].remove(achall)

        not_removed = []  # type: List[str]
        while self._created_dirs:
            path = self._created_dirs.pop()
            try:
                os.rmdir(path)
            except OSError as exc:
                not_removed.insert(0, path)
                logger.info("Challenge directory %s was not empty, didn't remove", path)
                logger.debug("Error was: %s", exc)
        self._created_dirs = not_removed
        logger.debug("All challenges cleaned up")
示例#22
0
    def cleanup(self, achalls):  # pylint: disable=missing-docstring
        for achall in achalls:
            root_path = self.full_roots.get(achall.domain, None)
            if root_path is not None:
                validation_path = self._get_validation_path(root_path, achall)
                logger.debug("Removing %s", validation_path)
                os.remove(validation_path)
                self.performed[root_path].remove(achall)

        not_removed = []  # type: List[str]
        while self._created_dirs:
            path = self._created_dirs.pop()
            try:
                os.rmdir(path)
            except OSError as exc:
                not_removed.insert(0, path)
                logger.info("Challenge directory %s was not empty, didn't remove", path)
                logger.debug("Error was: %s", exc)
        self._created_dirs = not_removed
        logger.debug("All challenges cleaned up")
示例#23
0
 def release(self) -> None:
     """Remove, close, and release the lock file."""
     # It is important the lock file is removed before it's released,
     # otherwise:
     #
     # process A: open lock file
     # process B: release lock file
     # process A: lock file
     # process A: check device and inode
     # process B: delete file
     # process C: open and lock a different file at the same path
     try:
         os.remove(self._path)
     finally:
         # Following check is done to make mypy happy: it ensure that self._fd, marked
         # as Optional[int] is effectively int to make it compatible with os.close signature.
         if self._fd is None:  # pragma: no cover
             raise TypeError('Error, self._fd is None.')
         try:
             os.close(self._fd)
         finally:
             self._fd = None
示例#24
0
文件: lock.py 项目: certbot/certbot
 def release(self):
     # type: () -> None
     """Remove, close, and release the lock file."""
     # It is important the lock file is removed before it's released,
     # otherwise:
     #
     # process A: open lock file
     # process B: release lock file
     # process A: lock file
     # process A: check device and inode
     # process B: delete file
     # process C: open and lock a different file at the same path
     try:
         os.remove(self._path)
     finally:
         # Following check is done to make mypy happy: it ensure that self._fd, marked
         # as Optional[int] is effectively int to make it compatible with os.close signature.
         if self._fd is None:  # pragma: no cover
             raise TypeError('Error, self._fd is None.')
         try:
             os.close(self._fd)
         finally:
             self._fd = None
示例#25
0
    def _remove_contained_files(self, file_list):  # pylint: disable=no-self-use
        """Erase all files contained within file_list.

        :param str file_list: file containing list of file paths to be deleted

        :returns: Success
        :rtype: bool

        :raises certbot.errors.ReverterError: If
            all files within file_list cannot be removed

        """
        # Check to see that file exists to differentiate can't find file_list
        # and can't remove filepaths within file_list errors.
        if not os.path.isfile(file_list):
            return False
        try:
            with open(file_list, "r") as list_fd:
                filepaths = list_fd.read().splitlines()
                for path in filepaths:
                    # Files are registered before they are added... so
                    # check to see if file exists first
                    if os.path.lexists(path):
                        os.remove(path)
                    else:
                        logger.warning(
                            "File: %s - Could not be found to be deleted %s - "
                            "Certbot probably shut down unexpectedly",
                            os.linesep, path)
        except (IOError, OSError):
            logger.critical(
                "Unable to remove filepaths contained within %s", file_list)
            raise errors.ReverterError(
                "Unable to remove filepaths contained within "
                "{0}".format(file_list))

        return True
示例#26
0
    def _remove_contained_files(self, file_list):  # pylint: disable=no-self-use
        """Erase all files contained within file_list.

        :param str file_list: file containing list of file paths to be deleted

        :returns: Success
        :rtype: bool

        :raises certbot.errors.ReverterError: If
            all files within file_list cannot be removed

        """
        # Check to see that file exists to differentiate can't find file_list
        # and can't remove filepaths within file_list errors.
        if not os.path.isfile(file_list):
            return False
        try:
            with open(file_list, "r") as list_fd:
                filepaths = list_fd.read().splitlines()
                for path in filepaths:
                    # Files are registered before they are added... so
                    # check to see if file exists first
                    if os.path.lexists(path):
                        os.remove(path)
                    else:
                        logger.warning(
                            "File: %s - Could not be found to be deleted %s - "
                            "Certbot probably shut down unexpectedly",
                            os.linesep, path)
        except (IOError, OSError):
            logger.critical("Unable to remove filepaths contained within %s",
                            file_list)
            raise errors.ReverterError(
                "Unable to remove filepaths contained within "
                "{0}".format(file_list))

        return True
示例#27
0
 def test_renew_no_dir_hook(self):
     os.remove(self.dir_hook)
     self._test_renew_common([self.config.post_hook])
示例#28
0
 def delete_and_stat(path):
     """Wrap os.stat and maybe delete the file first."""
     if path == self.lock_path and should_delete.pop(0):
         os.remove(path)
     return stat(path)
示例#29
0
 def delete_and_stat(path):
     """Wrap os.stat and maybe delete the file first."""
     if path == self.lock_path and should_delete.pop(0):
         os.remove(path)
     return stat(path)
示例#30
0
文件: util.py 项目: certbot/certbot
 def handle_rw_files(_, path, __):
     """Handle read-only files, that will fail to be removed on Windows."""
     os.chmod(path, stat.S_IWRITE)
     os.remove(path)
示例#31
0
def delete_files(config, certname):
    """Delete all files related to the certificate.

    If some files are not found, ignore them and continue.
    """
    renewal_filename = renewal_file_for_certname(config, certname)
    # file exists
    full_default_archive_dir = full_archive_path(None, config, certname)
    full_default_live_dir = _full_live_path(config, certname)
    try:
        renewal_config = configobj.ConfigObj(renewal_filename)
    except configobj.ConfigObjError:
        # config is corrupted
        logger.warning(
            "Could not parse %s. You may wish to manually "
            "delete the contents of %s and %s.", renewal_filename,
            full_default_live_dir, full_default_archive_dir)
        raise errors.CertStorageError(
            "error parsing {0}".format(renewal_filename))
    finally:
        # we couldn't read it, but let's at least delete it
        # if this was going to fail, it already would have.
        os.remove(renewal_filename)
        logger.debug("Removed %s", renewal_filename)

    # cert files and (hopefully) live directory
    # it's not guaranteed that the files are in our default storage
    # structure. so, first delete the cert files.
    directory_names = set()
    for kind in ALL_FOUR:
        link = renewal_config.get(kind)
        try:
            os.remove(link)
            logger.debug("Removed %s", link)
        except OSError:
            logger.debug("Unable to delete %s", link)
        directory = os.path.dirname(link)
        directory_names.add(directory)

    # if all four were in the same directory, and the only thing left
    # is the README file (or nothing), delete that directory.
    # this will be wrong in very few but some cases.
    if len(directory_names) == 1:
        # delete the README file
        directory = directory_names.pop()
        readme_path = os.path.join(directory, README)
        try:
            os.remove(readme_path)
            logger.debug("Removed %s", readme_path)
        except OSError:
            logger.debug("Unable to delete %s", readme_path)
        # if it's now empty, delete the directory
        try:
            os.rmdir(directory)  # only removes empty directories
            logger.debug("Removed %s", directory)
        except OSError:
            logger.debug("Unable to remove %s; may not be empty.", directory)

    # archive directory
    try:
        archive_path = full_archive_path(renewal_config, config, certname)
        shutil.rmtree(archive_path)
        logger.debug("Removed %s", archive_path)
    except OSError:
        logger.debug("Unable to remove %s", archive_path)
示例#32
0
 def test_find_config_root_no_root(self):
     # pylint: disable=protected-access
     os.remove(self.parser.loc["root"])
     self.assertRaises(
         errors.NoInstallationError, self.parser._find_config_root)
示例#33
0
 def handle_rw_files(_, path, __):
     """Handle read-only files, that will fail to be removed on Windows."""
     os.chmod(path, stat.S_IWRITE)
     os.remove(path)
示例#34
0
文件: client.py 项目: certbot/certbot
    def obtain_certificate(self, domains, old_keypath=None):
        """Obtains a certificate from the ACME server.

        `.register` must be called before `.obtain_certificate`

        :param list domains: domains to get a certificate

        :returns: certificate as PEM string, chain as PEM string,
            newly generated private key (`.util.Key`), and DER-encoded
            Certificate Signing Request (`.util.CSR`).
        :rtype: tuple

        """

        # We need to determine the key path, key PEM data, CSR path,
        # and CSR PEM data.  For a dry run, the paths are None because
        # they aren't permanently saved to disk.  For a lineage with
        # --reuse-key, the key path and PEM data are derived from an
        # existing file.

        if old_keypath is not None:
            # We've been asked to reuse a specific existing private key.
            # Therefore, we'll read it now and not generate a new one in
            # either case below.
            #
            # We read in bytes here because the type of `key.pem`
            # created below is also bytes.
            with open(old_keypath, "rb") as f:
                keypath = old_keypath
                keypem = f.read()
            key = util.Key(file=keypath, pem=keypem) # type: Optional[util.Key]
            logger.info("Reusing existing private key from %s.", old_keypath)
        else:
            # The key is set to None here but will be created below.
            key = None

        # Create CSR from names
        if self.config.dry_run:
            key = key or util.Key(file=None,
                                  pem=crypto_util.make_key(self.config.rsa_key_size))
            csr = util.CSR(file=None, form="pem",
                           data=acme_crypto_util.make_csr(
                               key.pem, domains, self.config.must_staple))
        else:
            key = key or crypto_util.init_save_key(self.config.rsa_key_size,
                                                   self.config.key_dir)
            csr = crypto_util.init_save_csr(key, domains, self.config.csr_dir)

        orderr = self._get_order_and_authorizations(csr.data, self.config.allow_subset_of_names)
        authzr = orderr.authorizations
        auth_domains = set(a.body.identifier.value for a in authzr)  # pylint: disable=not-an-iterable
        successful_domains = [d for d in domains if d in auth_domains]

        # allow_subset_of_names is currently disabled for wildcard
        # certificates. The reason for this and checking allow_subset_of_names
        # below is because successful_domains == domains is never true if
        # domains contains a wildcard because the ACME spec forbids identifiers
        # in authzs from containing a wildcard character.
        if self.config.allow_subset_of_names and successful_domains != domains:
            if not self.config.dry_run:
                os.remove(key.file)
                os.remove(csr.file)
            return self.obtain_certificate(successful_domains)
        else:
            cert, chain = self.obtain_certificate_from_csr(csr, orderr)

            return cert, chain, key, csr
示例#35
0
 def test_renew_no_hooks(self):
     self.config.post_hook = None
     os.remove(self.dir_hook)
     self._test_renew_common([])
示例#36
0
 def test_no_renewal_config(self):
     os.remove(self.config_file.filename)
     self.assertRaises(errors.CertStorageError, self._call)
     self.assertTrue(
         os.path.exists(os.path.join(self.config.live_dir, "example.org")))
     self.assertFalse(os.path.exists(self.config_file.filename))
示例#37
0
def delete_files(config, certname):
    """Delete all files related to the certificate.

    If some files are not found, ignore them and continue.
    """
    renewal_filename = renewal_file_for_certname(config, certname)
    # file exists
    full_default_archive_dir = full_archive_path(None, config, certname)
    full_default_live_dir = _full_live_path(config, certname)
    try:
        renewal_config = configobj.ConfigObj(renewal_filename)
    except configobj.ConfigObjError:
        # config is corrupted
        logger.warning("Could not parse %s. You may wish to manually "
            "delete the contents of %s and %s.", renewal_filename,
            full_default_live_dir, full_default_archive_dir)
        raise errors.CertStorageError(
            "error parsing {0}".format(renewal_filename))
    finally:
        # we couldn't read it, but let's at least delete it
        # if this was going to fail, it already would have.
        os.remove(renewal_filename)
        logger.debug("Removed %s", renewal_filename)

    # cert files and (hopefully) live directory
    # it's not guaranteed that the files are in our default storage
    # structure. so, first delete the cert files.
    directory_names = set()
    for kind in ALL_FOUR:
        link = renewal_config.get(kind)
        try:
            os.remove(link)
            logger.debug("Removed %s", link)
        except OSError:
            logger.debug("Unable to delete %s", link)
        directory = os.path.dirname(link)
        directory_names.add(directory)

    # if all four were in the same directory, and the only thing left
    # is the README file (or nothing), delete that directory.
    # this will be wrong in very few but some cases.
    if len(directory_names) == 1:
        # delete the README file
        directory = directory_names.pop()
        readme_path = os.path.join(directory, README)
        try:
            os.remove(readme_path)
            logger.debug("Removed %s", readme_path)
        except OSError:
            logger.debug("Unable to delete %s", readme_path)
        # if it's now empty, delete the directory
        try:
            os.rmdir(directory) # only removes empty directories
            logger.debug("Removed %s", directory)
        except OSError:
            logger.debug("Unable to remove %s; may not be empty.", directory)

    # archive directory
    try:
        archive_path = full_archive_path(renewal_config, config, certname)
        shutil.rmtree(archive_path)
        logger.debug("Removed %s", archive_path)
    except OSError:
        logger.debug("Unable to remove %s", archive_path)
示例#38
0
 def test_renew_no_dir_hook(self):
     os.remove(self.dir_hook)
     self._test_renew_common([self.config.post_hook])
示例#39
0
 def test_no_delete(self):
     self.handler.emit(mock.MagicMock())
     self.handler.close()
     self.assertTrue(os.path.exists(self.handler.path))
     os.remove(self.handler.path)
示例#40
0
 def test_renew_no_hooks(self):
     self.config.post_hook = None
     os.remove(self.dir_hook)
     self._test_renew_common([])
示例#41
0
 def test_find_config_root_no_root(self):
     # pylint: disable=protected-access
     os.remove(self.parser.loc["root"])
     self.assertRaises(errors.NoInstallationError,
                       self.parser._find_config_root)
示例#42
0
 def test_no_delete(self):
     self.handler.emit(mock.MagicMock())
     self.handler.close()
     self.assertTrue(os.path.exists(self.handler.path))
     os.remove(self.handler.path)
示例#43
0
    def obtain_certificate(self, domains, old_keypath=None):
        """Obtains a certificate from the ACME server.

        `.register` must be called before `.obtain_certificate`

        :param list domains: domains to get a certificate

        :returns: certificate as PEM string, chain as PEM string,
            newly generated private key (`.util.Key`), and DER-encoded
            Certificate Signing Request (`.util.CSR`).
        :rtype: tuple

        """
        # We need to determine the key path, key PEM data, CSR path,
        # and CSR PEM data.  For a dry run, the paths are None because
        # they aren't permanently saved to disk.  For a lineage with
        # --reuse-key, the key path and PEM data are derived from an
        # existing file.

        if old_keypath is not None:
            # We've been asked to reuse a specific existing private key.
            # Therefore, we'll read it now and not generate a new one in
            # either case below.
            #
            # We read in bytes here because the type of `key.pem`
            # created below is also bytes.
            with open(old_keypath, "rb") as f:
                keypath = old_keypath
                keypem = f.read()
            key: Optional[util.Key] = util.Key(file=keypath, pem=keypem)
            logger.info("Reusing existing private key from %s.", old_keypath)
        else:
            # The key is set to None here but will be created below.
            key = None

        key_size = self.config.rsa_key_size
        elliptic_curve = "secp256r1"

        # key-type defaults to a list, but we are only handling 1 currently
        if isinstance(self.config.key_type, list):
            self.config.key_type = self.config.key_type[0]
        if self.config.elliptic_curve and self.config.key_type == 'ecdsa':
            elliptic_curve = self.config.elliptic_curve
            self.config.auth_chain_path = "./chain-ecdsa.pem"
            self.config.auth_cert_path = "./cert-ecdsa.pem"
            self.config.key_path = "./key-ecdsa.pem"
        elif self.config.rsa_key_size and self.config.key_type.lower(
        ) == 'rsa':
            key_size = self.config.rsa_key_size

        # Create CSR from names
        if self.config.dry_run:
            key = key or util.Key(
                file=None,
                pem=crypto_util.make_key(
                    bits=key_size,
                    elliptic_curve=elliptic_curve,
                    key_type=self.config.key_type,
                ),
            )
            csr = util.CSR(file=None,
                           form="pem",
                           data=acme_crypto_util.make_csr(
                               key.pem, domains, self.config.must_staple))
        else:
            key = key or crypto_util.generate_key(
                key_size=key_size,
                key_dir=self.config.key_dir,
                key_type=self.config.key_type,
                elliptic_curve=elliptic_curve,
                strict_permissions=self.config.strict_permissions,
            )
            csr = crypto_util.generate_csr(key, domains, self.config.csr_dir,
                                           self.config.must_staple,
                                           self.config.strict_permissions)

        orderr = self._get_order_and_authorizations(
            csr.data, self.config.allow_subset_of_names)
        authzr = orderr.authorizations
        auth_domains = set(a.body.identifier.value for a in authzr)
        successful_domains = [d for d in domains if d in auth_domains]

        # allow_subset_of_names is currently disabled for wildcard
        # certificates. The reason for this and checking allow_subset_of_names
        # below is because successful_domains == domains is never true if
        # domains contains a wildcard because the ACME spec forbids identifiers
        # in authzs from containing a wildcard character.
        if self.config.allow_subset_of_names and successful_domains != domains:
            if not self.config.dry_run:
                os.remove(key.file)
                os.remove(csr.file)
            return self.obtain_certificate(successful_domains)
        else:
            cert, chain = self.obtain_certificate_from_csr(csr, orderr)
            return cert, chain, key, csr
示例#44
0
 def test_no_renewal_config(self):
     os.remove(self.config_file.filename)
     self.assertRaises(errors.CertStorageError, self._call)
     self.assertTrue(os.path.exists(os.path.join(
         self.config.live_dir, "example.org")))
     self.assertFalse(os.path.exists(self.config_file.filename))