示例#1
0
    def test_not_executable(self):
        file_path = os.path.join(self.tempdir, "foo")

        # On Windows a file created within Certbot will always have all permissions to the
        # Administrators group set. Since the unit tests are typically executed under elevated
        # privileges, it means that current user will always have effective execute rights on the
        # hook script, and so the test will fail. To prevent that and represent a file created
        # outside Certbot as typically a hook file is, we mock the _generate_dacl function in
        # certbot.compat.filesystem to give rights only to the current user. This implies removing
        # all ACEs except the first one from the DACL created by original _generate_dacl function.

        from certbot.compat.filesystem import _generate_dacl

        def _execute_mock(user_sid, mode):
            dacl = _generate_dacl(user_sid, mode)
            for _ in range(1, dacl.GetAceCount()):
                dacl.DeleteAce(
                    1
                )  # DeleteAce dynamically updates the internal index mapping.
            return dacl

        # create a non-executable file
        with mock.patch("certbot.compat.filesystem._generate_dacl",
                        side_effect=_execute_mock):
            os.close(
                filesystem.open(file_path, os.O_CREAT | os.O_WRONLY, 0o666))

        self.assertFalse(filesystem.is_executable(file_path))
示例#2
0
    def save(self):
        """Saves PluginStorage content to disk

        :raises .errors.PluginStorageError: when unable to serialize the data
            or write it to the filesystem
        """
        if not self._initialized:
            errmsg = "Unable to save, no values have been added to PluginStorage."
            logger.error(errmsg)
            raise errors.PluginStorageError(errmsg)

        try:
            serialized = json.dumps(self._data)
        except TypeError as e:
            errmsg = "Could not serialize PluginStorage data: {0}".format(
                str(e))
            logger.error(errmsg)
            raise errors.PluginStorageError(errmsg)
        try:
            with os.fdopen(
                    filesystem.open(self._storagepath,
                                    os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
                                    0o600), 'w') as fh:
                fh.write(serialized)
        except IOError as e:
            errmsg = "Could not write PluginStorage data to file {0} : {1}".format(
                self._storagepath, str(e))
            logger.error(errmsg)
            raise errors.PluginStorageError(errmsg)
示例#3
0
    def acquire(self):
        """Acquire the lock"""
        open_mode = os.O_RDWR | os.O_CREAT | os.O_TRUNC

        fd = None
        try:
            # Under Windows, filesystem.open will raise directly an EACCES error
            # if the lock file is already locked.
            fd = filesystem.open(self._path, open_mode, 0o600)
            # 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(fd, msvcrt.LK_NBLCK, 1)  # type: ignore
        except (IOError, OSError) as err:
            if fd:
                os.close(fd)
            # Anything except EACCES is unexpected. Raise directly the error in that case.
            if err.errno != errno.EACCES:
                raise
            logger.debug('A lock on %s is held by another process.',
                         self._path)
            raise errors.LockError(
                'Another instance of Certbot is already running.')

        self._fd = fd
示例#4
0
    def acquire(self):
        """Acquire the lock"""
        open_mode = os.O_RDWR | os.O_CREAT | os.O_TRUNC

        fd = None
        try:
            # Under Windows, filesystem.open will raise directly an EACCES error
            # if the lock file is already locked.
            fd = filesystem.open(self._path, open_mode, 0o600)
            # 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(fd, msvcrt.LK_NBLCK, 1)  # type: ignore
        except (IOError, OSError) as err:
            if fd:
                os.close(fd)
            # Anything except EACCES is unexpected. Raise directly the error in that case.
            if err.errno != errno.EACCES:
                raise
            logger.debug('A lock on %s is held by another process.',
                         self._path)
            raise errors.LockError(
                'Another instance of Certbot is already running.')

        self._fd = fd
示例#5
0
 def _create_file(path, mode=0o777):
     file_desc = None
     try:
         file_desc = filesystem.open(path, flags=os.O_CREAT, mode=mode)
     finally:
         if file_desc:
             os.close(file_desc)
示例#6
0
 def test_not_executable(self):
     file_path = os.path.join(self.tempdir, "foo")
     # create a non-executable file
     os.close(filesystem.open(file_path, os.O_CREAT | os.O_WRONLY, 0o666))
     # prevent unnecessary modifications to PATH
     with mock.patch("certbot.hooks.plug_util.path_surgery"):
         self.assertRaises(errors.HookCommandNotFound,
                           self._call, file_path, "foo")
示例#7
0
    def test_new_file_correct_permissions(self):
        path = os.path.join(self.tempdir, 'file')

        desc = filesystem.open(path, os.O_CREAT | os.O_EXCL | os.O_RDWR, 0o700)
        os.close(desc)

        dacl = _get_security_dacl(path).GetSecurityDescriptorDacl()
        everybody = win32security.ConvertStringSidToSid(EVERYBODY_SID)

        self.assertFalse([dacl.GetAce(index) for index in range(0, dacl.GetAceCount())
                          if dacl.GetAce(index)[2] == everybody])
示例#8
0
    def _test_one_creation(self, num, file_exist, flags):
        one_file = os.path.join(self.tempdir, str(num))
        if file_exist and not os.path.exists(one_file):
            with open(one_file, 'w'):
                pass

        handler = None
        try:
            handler = filesystem.open(one_file, flags)
        finally:
            if handler:
                os.close(handler)
示例#9
0
    def _test_one_creation(self, num, file_exist, flags):
        one_file = os.path.join(self.tempdir, str(num))
        if file_exist and not os.path.exists(one_file):
            open(one_file, 'w').close()

        handler = None
        try:
            handler = filesystem.open(one_file, flags)
        except BaseException as err:
            if handler:
                os.close(handler)
            raise err
示例#10
0
 def acquire(self) -> None:
     """Acquire the lock."""
     while self._fd is None:
         # Open the file
         fd = filesystem.open(self._path, os.O_CREAT | os.O_WRONLY, 0o600)
         try:
             self._try_lock(fd)
             if self._lock_success(fd):
                 self._fd = fd
         finally:
             # Close the file if it is not the required one
             if self._fd is None:
                 os.close(fd)
示例#11
0
def safe_open(path, mode="w", chmod=None):
    """Safely open a file.

    :param str path: Path to a file.
    :param str mode: Same os `mode` for `open`.
    :param int chmod: Same as `mode` for `filesystem.open`, uses Python defaults
        if ``None``.

    """
    open_args = ()  # type: Union[Tuple[()], Tuple[int]]
    if chmod is not None:
        open_args = (chmod, )
    fdopen_args = ()  # type: Union[Tuple[()], Tuple[int]]
    fd = filesystem.open(path, os.O_CREAT | os.O_EXCL | os.O_RDWR, *open_args)
    return os.fdopen(fd, mode, *fdopen_args)
示例#12
0
    def acquire(self):
        """Acquire the lock"""
        open_mode = os.O_RDWR | os.O_CREAT | os.O_TRUNC

        fd = None
        try:
            # Under Windows, filesystem.open will raise directly an EACCES error
            # if the lock file is already locked.
            fd = filesystem.open(self._path, open_mode, 0o600)
            msvcrt.locking(fd, msvcrt.LK_NBLCK, 1)
        except (IOError, OSError) as err:
            if fd:
                os.close(fd)
            # Anything except EACCES is unexpected. Raise directly the error in that case.
            if err.errno != errno.EACCES:
                raise
            logger.debug('A lock on %s is held by another process.', self._path)
            raise errors.LockError('Another instance of Certbot is already running.')

        self._fd = fd