tempfile.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. # -----------------------------------------------------------------------------
  2. # Copyright (c) 2023, PyInstaller Development Team.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. #
  7. # The full license is in the file COPYING.txt, distributed with this software.
  8. #
  9. # SPDX-License-Identifier: Apache-2.0
  10. # -----------------------------------------------------------------------------
  11. import os
  12. import sys
  13. import errno
  14. import tempfile
  15. # Helper for creating temporary directories with access restricted to the user running the process.
  16. # On POSIX systems, this is already achieved by `tempfile.mkdtemp`, which uses 0o700 permissions mask.
  17. # On Windows, however, the POSIX permissions semantics have no effect, and we need to provide our own implementation
  18. # that restricts the access by passing appropriate security attributes to the `CreateDirectory` function.
  19. if os.name == 'nt':
  20. from . import _win32
  21. def secure_mkdtemp(suffix=None, prefix=None, dir=None):
  22. """
  23. Windows-specific replacement for `tempfile.mkdtemp` that restricts access to the user running the process.
  24. Based on `mkdtemp` implementation from python 3.11 stdlib.
  25. """
  26. prefix, suffix, dir, output_type = tempfile._sanitize_params(prefix, suffix, dir)
  27. names = tempfile._get_candidate_names()
  28. if output_type is bytes:
  29. names = map(os.fsencode, names)
  30. for seq in range(tempfile.TMP_MAX):
  31. name = next(names)
  32. file = os.path.join(dir, prefix + name + suffix)
  33. sys.audit("tempfile.mkdtemp", file)
  34. try:
  35. _win32.secure_mkdir(file)
  36. except FileExistsError:
  37. continue # try again
  38. except PermissionError:
  39. # This exception is thrown when a directory with the chosen name already exists on windows.
  40. if (os.name == 'nt' and os.path.isdir(dir) and os.access(dir, os.W_OK)):
  41. continue
  42. else:
  43. raise
  44. return file
  45. raise FileExistsError(errno.EEXIST, "No usable temporary directory name found")
  46. else:
  47. secure_mkdtemp = tempfile.mkdtemp