Exemple #1
0
 def test_save_successor_maintains_group_mode(self, mock_rv):
     # Mock relevant_values() to claim that all values are relevant here
     # (to avoid instantiating parser)
     mock_rv.side_effect = lambda x: x
     for kind in ALL_FOUR:
         self._write_out_kind(kind, 1)
     self.test_rc.update_all_links_to(1)
     self.assertTrue(
         misc.compare_file_modes(
             os.stat(self.test_rc.version("privkey", 1)).st_mode, 0o600))
     filesystem.chmod(self.test_rc.version("privkey", 1), 0o444)
     # If no new key, permissions should be the same (we didn't write any keys)
     self.test_rc.save_successor(1, b"newcert", None, b"new chain",
                                 self.config)
     self.assertTrue(
         misc.compare_file_modes(
             os.stat(self.test_rc.version("privkey", 2)).st_mode, 0o444))
     # If new key, permissions should be kept as 644
     self.test_rc.save_successor(2, b"newcert", b"new_privkey",
                                 b"new chain", self.config)
     self.assertTrue(
         misc.compare_file_modes(
             os.stat(self.test_rc.version("privkey", 3)).st_mode, 0o644))
     # If permissions reverted, next renewal will also revert permissions of new key
     filesystem.chmod(self.test_rc.version("privkey", 3), 0o400)
     self.test_rc.save_successor(3, b"newcert", b"new_privkey",
                                 b"new chain", self.config)
     self.assertTrue(
         misc.compare_file_modes(
             os.stat(self.test_rc.version("privkey", 4)).st_mode, 0o600))
Exemple #2
0
 def test_right_mode(self):
     fd1, name1 = self._call(0o700)
     fd2, name2 = self._call(0o600)
     self.assertTrue(misc.compare_file_modes(0o700, os.stat(name1).st_mode))
     self.assertTrue(misc.compare_file_modes(0o600, os.stat(name2).st_mode))
     fd1.close()
     fd2.close()
Exemple #3
0
 def test_right_mode(self):
     fd1, name1 = self._call(0o700)
     fd2, name2 = self._call(0o600)
     self.assertTrue(misc.compare_file_modes(0o700, os.stat(name1).st_mode))
     self.assertTrue(misc.compare_file_modes(0o600, os.stat(name2).st_mode))
     fd1.close()
     fd2.close()
Exemple #4
0
def validate_file_permissions(filename):
    """Ensure that the specified file exists and warn about unsafe permissions."""

    validate_file(filename)

    permissions = stat.S_IMODE(os.stat(filename).st_mode)
    if permissions & stat.S_IRWXO:
        logger.warning('Unsafe permissions on credentials configuration file: %s', filename)
Exemple #5
0
def create_hook(file_path):
    """Creates an executable file at the specified path.

    :param str file_path: path to create the file at

    """
    open(file_path, "w").close()
    os.chmod(file_path, os.stat(file_path).st_mode | stat.S_IXUSR)
Exemple #6
0
def create_hook(file_path):
    """Creates an executable file at the specified path.

    :param str file_path: path to create the file at

    """
    open(file_path, "w").close()
    os.chmod(file_path, os.stat(file_path).st_mode | stat.S_IXUSR)
Exemple #7
0
    def test_new_lineage(self, mock_rv):
        """Test for new_lineage() class method."""
        # Mock relevant_values to say everything is relevant here (so we
        # don't have to mock the parser to help it decide!)
        mock_rv.side_effect = lambda x: x

        from certbot import storage
        result = storage.RenewableCert.new_lineage("the-lineage.com", b"cert",
                                                   b"privkey", b"chain",
                                                   self.config)
        # This consistency check tests most relevant properties about the
        # newly created cert lineage.
        # pylint: disable=protected-access
        self.assertTrue(result._consistent())
        self.assertTrue(
            os.path.exists(
                os.path.join(self.config.renewal_configs_dir,
                             "the-lineage.com.conf")))
        self.assertTrue(
            os.path.exists(os.path.join(self.config.live_dir, "README")))
        self.assertTrue(
            os.path.exists(
                os.path.join(self.config.live_dir, "the-lineage.com",
                             "README")))
        self.assertTrue(
            misc.compare_file_modes(os.stat(result.key_path).st_mode, 0o600))
        with open(result.fullchain, "rb") as f:
            self.assertEqual(f.read(), b"cert" + b"chain")
        # Let's do it again and make sure it makes a different lineage
        result = storage.RenewableCert.new_lineage("the-lineage.com", b"cert2",
                                                   b"privkey2", b"chain2",
                                                   self.config)
        self.assertTrue(
            os.path.exists(
                os.path.join(self.config.renewal_configs_dir,
                             "the-lineage.com-0001.conf")))
        self.assertTrue(
            os.path.exists(
                os.path.join(self.config.live_dir, "the-lineage.com-0001",
                             "README")))
        # Now trigger the detection of already existing files
        filesystem.mkdir(
            os.path.join(self.config.live_dir, "the-lineage.com-0002"))
        self.assertRaises(errors.CertStorageError,
                          storage.RenewableCert.new_lineage, "the-lineage.com",
                          b"cert3", b"privkey3", b"chain3", self.config)
        filesystem.mkdir(
            os.path.join(self.config.default_archive_dir, "other-example.com"))
        self.assertRaises(errors.CertStorageError,
                          storage.RenewableCert.new_lineage,
                          "other-example.com", b"cert4", b"privkey4",
                          b"chain4", self.config)
        # Make sure it can accept renewal parameters
        result = storage.RenewableCert.new_lineage("the-lineage.com", b"cert2",
                                                   b"privkey2", b"chain2",
                                                   self.config)
Exemple #8
0
    def test_save_and_restore(self):
        self.storage.save(self.acc, self.mock_client)
        account_path = os.path.join(self.config.accounts_dir, self.acc.id)
        self.assertTrue(os.path.exists(account_path))
        for file_name in "regr.json", "meta.json", "private_key.json":
            self.assertTrue(os.path.exists(
                os.path.join(account_path, file_name)))
        self.assertTrue(oct(os.stat(os.path.join(
            account_path, "private_key.json"))[stat.ST_MODE] & 0o777) in ("0400", "0o400"))

        # restore
        loaded = self.storage.load(self.acc.id)
        self.assertEqual(self.acc, loaded)
Exemple #9
0
def check_permissions(filepath, mode, uid=0):
    """Check file or directory permissions.

    :param str filepath: Path to the tested file (or directory).
    :param int mode: Expected file mode.
    :param int uid: Expected file owner.

    :returns: True if `mode` and `uid` match, False otherwise.
    :rtype: bool

    """
    file_stat = os.stat(filepath)
    return misc.compare_file_modes(file_stat.st_mode, mode) and file_stat.st_uid == uid
Exemple #10
0
 def test_save_successor_maintains_group_mode(self, mock_rv):
     # Mock relevant_values() to claim that all values are relevant here
     # (to avoid instantiating parser)
     mock_rv.side_effect = lambda x: x
     for kind in ALL_FOUR:
         self._write_out_kind(kind, 1)
     self.test_rc.update_all_links_to(1)
     self.assertTrue(misc.compare_file_modes(
         os.stat(self.test_rc.version("privkey", 1)).st_mode, 0o600))
     os.chmod(self.test_rc.version("privkey", 1), 0o444)
     # If no new key, permissions should be the same (we didn't write any keys)
     self.test_rc.save_successor(1, b"newcert", None, b"new chain", self.config)
     self.assertTrue(misc.compare_file_modes(
         os.stat(self.test_rc.version("privkey", 2)).st_mode, 0o444))
     # If new key, permissions should be kept as 644
     self.test_rc.save_successor(2, b"newcert", b"new_privkey", b"new chain", self.config)
     self.assertTrue(misc.compare_file_modes(
         os.stat(self.test_rc.version("privkey", 3)).st_mode, 0o644))
     # If permissions reverted, next renewal will also revert permissions of new key
     os.chmod(self.test_rc.version("privkey", 3), 0o400)
     self.test_rc.save_successor(3, b"newcert", b"new_privkey", b"new chain", self.config)
     self.assertTrue(misc.compare_file_modes(
         os.stat(self.test_rc.version("privkey", 4)).st_mode, 0o600))
Exemple #11
0
    def test_save_and_restore(self):
        self.storage.save(self.acc, self.mock_client)
        account_path = os.path.join(self.config.accounts_dir, self.acc.id)
        self.assertTrue(os.path.exists(account_path))
        for file_name in "regr.json", "meta.json", "private_key.json":
            self.assertTrue(
                os.path.exists(os.path.join(account_path, file_name)))
        self.assertTrue(
            oct(
                os.stat(os.path.join(account_path, "private_key.json"))[
                    stat.ST_MODE] & 0o777) in ("0400", "0o400"))

        # restore
        loaded = self.storage.load(self.acc.id)
        self.assertEqual(self.acc, loaded)
Exemple #12
0
    def _create_challenge_dirs(self):
        path_map = self.conf("map")
        if not path_map:
            raise errors.PluginError(
                "Missing parts of webroot configuration; please set either "
                "--webroot-path and --domains, or --webroot-map. Run with "
                " --help webroot for examples.")
        for name, path in path_map.items():
            self.full_roots[name] = os.path.join(
                path, challenges.HTTP01.URI_ROOT_PATH)
            logger.debug("Creating root challenges validation dir at %s",
                         self.full_roots[name])

            # Change the permissions to be writable (GH #1389)
            # Umask is used instead of chmod to ensure the client can also
            # run as non-root (GH #1795)
            old_umask = os.umask(0o022)
            try:
                stat_path = os.stat(path)
                # We ignore the last prefix in the next iteration,
                # as it does not correspond to a folder path ('/' or 'C:')
                for prefix in sorted(util.get_prefixes(
                        self.full_roots[name])[:-1],
                                     key=len):
                    try:
                        # This is coupled with the "umask" call above because
                        # os.mkdir's "mode" parameter may not always work:
                        # https://docs.python.org/3/library/os.html#os.mkdir
                        os.mkdir(prefix, 0o0755)
                        self._created_dirs.append(prefix)
                        # Set owner as parent directory if possible
                        try:
                            os.chown(prefix, stat_path.st_uid,
                                     stat_path.st_gid)
                        except (OSError, AttributeError) as exception:
                            logger.info(
                                "Unable to change owner and uid of webroot directory"
                            )
                            logger.debug("Error was: %s", exception)
                    except OSError as exception:
                        if exception.errno not in (errno.EEXIST, errno.EISDIR):
                            raise errors.PluginError(
                                "Couldn't create root for {0} http-01 "
                                "challenge responses: {1}".format(
                                    name, exception))
            finally:
                os.umask(old_umask)
Exemple #13
0
    def test_new_lineage(self, mock_rv):
        """Test for new_lineage() class method."""
        # Mock relevant_values to say everything is relevant here (so we
        # don't have to mock the parser to help it decide!)
        mock_rv.side_effect = lambda x: x

        from certbot import storage
        result = storage.RenewableCert.new_lineage(
            "the-lineage.com", b"cert", b"privkey", b"chain", self.config)
        # This consistency check tests most relevant properties about the
        # newly created cert lineage.
        # pylint: disable=protected-access
        self.assertTrue(result._consistent())
        self.assertTrue(os.path.exists(os.path.join(
            self.config.renewal_configs_dir, "the-lineage.com.conf")))
        self.assertTrue(os.path.exists(os.path.join(
            self.config.live_dir, "README")))
        self.assertTrue(os.path.exists(os.path.join(
            self.config.live_dir, "the-lineage.com", "README")))
        self.assertTrue(misc.compare_file_modes(os.stat(result.key_path).st_mode, 0o600))
        with open(result.fullchain, "rb") as f:
            self.assertEqual(f.read(), b"cert" + b"chain")
        # Let's do it again and make sure it makes a different lineage
        result = storage.RenewableCert.new_lineage(
            "the-lineage.com", b"cert2", b"privkey2", b"chain2", self.config)
        self.assertTrue(os.path.exists(os.path.join(
            self.config.renewal_configs_dir, "the-lineage.com-0001.conf")))
        self.assertTrue(os.path.exists(os.path.join(
            self.config.live_dir, "the-lineage.com-0001", "README")))
        # Now trigger the detection of already existing files
        os.mkdir(os.path.join(
            self.config.live_dir, "the-lineage.com-0002"))
        self.assertRaises(errors.CertStorageError,
                          storage.RenewableCert.new_lineage, "the-lineage.com",
                          b"cert3", b"privkey3", b"chain3", self.config)
        os.mkdir(os.path.join(self.config.default_archive_dir, "other-example.com"))
        self.assertRaises(errors.CertStorageError,
                          storage.RenewableCert.new_lineage,
                          "other-example.com", b"cert4",
                          b"privkey4", b"chain4", self.config)
        # Make sure it can accept renewal parameters
        result = storage.RenewableCert.new_lineage(
            "the-lineage.com", b"cert2", b"privkey2", b"chain2", self.config)
Exemple #14
0
    def _create_challenge_dirs(self):
        path_map = self.conf("map")
        if not path_map:
            raise errors.PluginError(
                "Missing parts of webroot configuration; please set either "
                "--webroot-path and --domains, or --webroot-map. Run with "
                " --help webroot for examples.")
        for name, path in path_map.items():
            self.full_roots[name] = os.path.join(path, challenges.HTTP01.URI_ROOT_PATH)
            logger.debug("Creating root challenges validation dir at %s",
                         self.full_roots[name])

            # Change the permissions to be writable (GH #1389)
            # Umask is used instead of chmod to ensure the client can also
            # run as non-root (GH #1795)
            old_umask = os.umask(0o022)
            try:
                stat_path = os.stat(path)
                # We ignore the last prefix in the next iteration,
                # as it does not correspond to a folder path ('/' or 'C:')
                for prefix in sorted(util.get_prefixes(self.full_roots[name])[:-1], key=len):
                    try:
                        # This is coupled with the "umask" call above because
                        # os.mkdir's "mode" parameter may not always work:
                        # https://docs.python.org/3/library/os.html#os.mkdir
                        os.mkdir(prefix, 0o0755)
                        self._created_dirs.append(prefix)
                        # Set owner as parent directory if possible
                        try:
                            os.chown(prefix, stat_path.st_uid, stat_path.st_gid)
                        except (OSError, AttributeError) as exception:
                            logger.info("Unable to change owner and uid of webroot directory")
                            logger.debug("Error was: %s", exception)
                    except OSError as exception:
                        if exception.errno not in (errno.EEXIST, errno.EISDIR):
                            raise errors.PluginError(
                                "Couldn't create root for {0} http-01 "
                                "challenge responses: {1}".format(name, exception))
            finally:
                os.umask(old_umask)
Exemple #15
0
    def _lock_success(self, fd):
        # type: (int) -> bool
        """
        Did we successfully grab the lock?
        Because this class deletes the locked file when the lock is
        released, it is possible another process removed and recreated
        the file between us opening the file and acquiring the lock.
        :param int fd: file descriptor of the opened file to lock
        :returns: True if the lock was successfully acquired
        :rtype: bool
        """
        try:
            stat1 = os.stat(self._path)
        except OSError as err:
            if err.errno == errno.ENOENT:
                return False
            raise

        stat2 = os.fstat(fd)
        # If our locked file descriptor and the file on disk refer to
        # the same device and inode, they're the same file.
        return stat1.st_dev == stat2.st_dev and stat1.st_ino == stat2.st_ino
Exemple #16
0
    def _lock_success(self, fd):
        # type: (int) -> bool
        """
        Did we successfully grab the lock?
        Because this class deletes the locked file when the lock is
        released, it is possible another process removed and recreated
        the file between us opening the file and acquiring the lock.
        :param int fd: file descriptor of the opened file to lock
        :returns: True if the lock was successfully acquired
        :rtype: bool
        """
        try:
            stat1 = os.stat(self._path)
        except OSError as err:
            if err.errno == errno.ENOENT:
                return False
            raise

        stat2 = os.fstat(fd)
        # If our locked file descriptor and the file on disk refer to
        # the same device and inode, they're the same file.
        return stat1.st_dev == stat2.st_dev and stat1.st_ino == stat2.st_ino
Exemple #17
0
    def test_perform_permissions(self):
        self.auth.prepare()

        # Remove exec bit from permission check, so that it
        # matches the file
        self.auth.perform([self.achall])
        self.assertTrue(misc.compare_file_modes(os.stat(self.validation_path).st_mode, 0o644))

        # Check permissions of the directories

        for dirpath, dirnames, _ in os.walk(self.path):
            for directory in dirnames:
                full_path = os.path.join(dirpath, directory)
                self.assertTrue(misc.compare_file_modes(os.stat(full_path).st_mode, 0o755))

        parent_gid = os.stat(self.path).st_gid
        parent_uid = os.stat(self.path).st_uid

        self.assertEqual(os.stat(self.validation_path).st_gid, parent_gid)
        self.assertEqual(os.stat(self.validation_path).st_uid, parent_uid)
Exemple #18
0
    def test_perform_permissions(self):
        self.auth.prepare()

        # Remove exec bit from permission check, so that it
        # matches the file
        self.auth.perform([self.achall])
        self.assertTrue(
            misc.compare_file_modes(
                os.stat(self.validation_path).st_mode, 0o644))

        # Check permissions of the directories

        for dirpath, dirnames, _ in os.walk(self.path):
            for directory in dirnames:
                full_path = os.path.join(dirpath, directory)
                self.assertTrue(
                    misc.compare_file_modes(os.stat(full_path).st_mode, 0o755))

        parent_gid = os.stat(self.path).st_gid
        parent_uid = os.stat(self.path).st_uid

        self.assertEqual(os.stat(self.validation_path).st_gid, parent_gid)
        self.assertEqual(os.stat(self.validation_path).st_uid, parent_uid)
Exemple #19
0
 def test_existing_correct_mode_does_not_fail(self):
     self._call(self.path, 0o600)
     self.assertTrue(misc.compare_file_modes(os.stat(self.path).st_mode, 0o600))
Exemple #20
0
 def test_existing_correct_mode_does_not_fail(self):
     self._call(self.path, 0o600)
     self.assertTrue(
         misc.compare_file_modes(os.stat(self.path).st_mode, 0o600))
Exemple #21
0
 def test_creates_dir_when_missing(self):
     path = os.path.join(self.tempdir, "bar")
     self._call(path, 0o650)
     self.assertTrue(os.path.isdir(path))
     self.assertTrue(misc.compare_file_modes(os.stat(path).st_mode, 0o650))
Exemple #22
0
    def save_successor(self, prior_version, new_cert, new_privkey, new_chain,
                       cli_config):
        """Save new cert and chain as a successor of a prior version.

        Returns the new version number that was created.

        .. note:: this function does NOT update links to deploy this
                  version

        :param int prior_version: the old version to which this version
            is regarded as a successor (used to choose a privkey, if the
            key has not changed, but otherwise this information is not
            permanently recorded anywhere)
        :param bytes new_cert: the new certificate, in PEM format
        :param bytes new_privkey: the new private key, in PEM format,
            or ``None``, if the private key has not changed
        :param bytes new_chain: the new chain, in PEM format
        :param .NamespaceConfig cli_config: parsed command line
            arguments

        :returns: the new version number that was created
        :rtype: int

        """
        # XXX: assumes official archive location rather than examining links
        # XXX: consider using os.open for availability of os.O_EXCL
        # XXX: ensure file permissions are correct; also create directories
        #      if needed (ensuring their permissions are correct)
        # Figure out what the new version is and hence where to save things

        self.cli_config = cli_config
        target_version = self.next_free_version()
        target = dict([(kind,
                        os.path.join(self.archive_dir,
                                     "{0}{1}.pem".format(kind,
                                                         target_version)))
                       for kind in ALL_FOUR])

        old_privkey = os.path.join(self.archive_dir,
                                   "privkey{0}.pem".format(prior_version))

        # Distinguish the cases where the privkey has changed and where it
        # has not changed (in the latter case, making an appropriate symlink
        # to an earlier privkey version)
        if new_privkey is None:
            # The behavior below keeps the prior key by creating a new
            # symlink to the old key or the target of the old key symlink.
            if os.path.islink(old_privkey):
                old_privkey = os.readlink(old_privkey)
            else:
                old_privkey = "privkey{0}.pem".format(prior_version)
            logger.debug("Writing symlink to old private key, %s.",
                         old_privkey)
            os.symlink(old_privkey, target["privkey"])
        else:
            with util.safe_open(target["privkey"],
                                "wb",
                                chmod=BASE_PRIVKEY_MODE) as f:
                logger.debug("Writing new private key to %s.",
                             target["privkey"])
                f.write(new_privkey)
            # Preserve gid and (mode & MASK_FOR_PRIVATE_KEY_PERMISSIONS)
            # from previous privkey in this lineage.
            old_mode = (stat.S_IMODE(os.stat(old_privkey).st_mode)
                        & misc.MASK_FOR_PRIVATE_KEY_PERMISSIONS)
            mode = BASE_PRIVKEY_MODE | old_mode
            filesystem.copy_ownership_and_apply_mode(old_privkey,
                                                     target["privkey"],
                                                     mode,
                                                     copy_user=False,
                                                     copy_group=True)

        # Save everything else
        with open(target["cert"], "wb") as f:
            logger.debug("Writing certificate to %s.", target["cert"])
            f.write(new_cert)
        with open(target["chain"], "wb") as f:
            logger.debug("Writing chain to %s.", target["chain"])
            f.write(new_chain)
        with open(target["fullchain"], "wb") as f:
            logger.debug("Writing full chain to %s.", target["fullchain"])
            f.write(new_cert + new_chain)

        symlinks = dict((kind, self.configuration[kind]) for kind in ALL_FOUR)
        # Update renewal config file
        self.configfile = update_configuration(self.lineagename,
                                               self.archive_dir, symlinks,
                                               cli_config)
        self.configuration = config_with_defaults(self.configfile)

        return target_version
Exemple #23
0
    def save_successor(self, prior_version, new_cert,
                       new_privkey, new_chain, cli_config):
        """Save new cert and chain as a successor of a prior version.

        Returns the new version number that was created.

        .. note:: this function does NOT update links to deploy this
                  version

        :param int prior_version: the old version to which this version
            is regarded as a successor (used to choose a privkey, if the
            key has not changed, but otherwise this information is not
            permanently recorded anywhere)
        :param bytes new_cert: the new certificate, in PEM format
        :param bytes new_privkey: the new private key, in PEM format,
            or ``None``, if the private key has not changed
        :param bytes new_chain: the new chain, in PEM format
        :param .NamespaceConfig cli_config: parsed command line
            arguments

        :returns: the new version number that was created
        :rtype: int

        """
        # XXX: assumes official archive location rather than examining links
        # XXX: consider using os.open for availability of os.O_EXCL
        # XXX: ensure file permissions are correct; also create directories
        #      if needed (ensuring their permissions are correct)
        # Figure out what the new version is and hence where to save things

        self.cli_config = cli_config
        target_version = self.next_free_version()
        target = dict(
            [(kind,
              os.path.join(self.archive_dir, "{0}{1}.pem".format(kind, target_version)))
             for kind in ALL_FOUR])

        old_privkey = os.path.join(
            self.archive_dir, "privkey{0}.pem".format(prior_version))

        # Distinguish the cases where the privkey has changed and where it
        # has not changed (in the latter case, making an appropriate symlink
        # to an earlier privkey version)
        if new_privkey is None:
            # The behavior below keeps the prior key by creating a new
            # symlink to the old key or the target of the old key symlink.
            if os.path.islink(old_privkey):
                old_privkey = os.readlink(old_privkey)
            else:
                old_privkey = "privkey{0}.pem".format(prior_version)
            logger.debug("Writing symlink to old private key, %s.", old_privkey)
            os.symlink(old_privkey, target["privkey"])
        else:
            with util.safe_open(target["privkey"], "wb", chmod=BASE_PRIVKEY_MODE) as f:
                logger.debug("Writing new private key to %s.", target["privkey"])
                f.write(new_privkey)
            # Preserve gid and (mode & 074) from previous privkey in this lineage.
            old_mode = stat.S_IMODE(os.stat(old_privkey).st_mode) & \
                (stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP | \
                 stat.S_IROTH)
            mode = BASE_PRIVKEY_MODE | old_mode
            os.chown(target["privkey"], -1, os.stat(old_privkey).st_gid)
            os.chmod(target["privkey"], mode)

        # Save everything else
        with open(target["cert"], "wb") as f:
            logger.debug("Writing certificate to %s.", target["cert"])
            f.write(new_cert)
        with open(target["chain"], "wb") as f:
            logger.debug("Writing chain to %s.", target["chain"])
            f.write(new_chain)
        with open(target["fullchain"], "wb") as f:
            logger.debug("Writing full chain to %s.", target["fullchain"])
            f.write(new_cert + new_chain)

        symlinks = dict((kind, self.configuration[kind]) for kind in ALL_FOUR)
        # Update renewal config file
        self.configfile = update_configuration(
            self.lineagename, self.archive_dir, symlinks, cli_config)
        self.configuration = config_with_defaults(self.configfile)

        return target_version
Exemple #24
0
 def _has_min_permissions(self, path, min_mode):
     """Tests the given file has at least the permissions in mode."""
     st_mode = os.stat(path).st_mode
     self.assertEqual(st_mode, st_mode | min_mode)
Exemple #25
0
 def test_creates_dir_when_missing(self):
     path = os.path.join(self.tempdir, "bar")
     self._call(path, 0o650)
     self.assertTrue(os.path.isdir(path))
     self.assertTrue(misc.compare_file_modes(os.stat(path).st_mode, 0o650))
Exemple #26
0
 def _has_min_permissions(self, path, min_mode):
     """Tests the given file has at least the permissions in mode."""
     st_mode = os.stat(path).st_mode
     self.assertEqual(st_mode, st_mode | min_mode)