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))
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)
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
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
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)
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")
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])
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)
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
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)
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)
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