logo

oasis

Own branch of Oasis Linux (upstream: <https://git.sr.ht/~mcf/oasis/>) git clone https://anongit.hacktivis.me/git/oasis.git

0001-Disable-use-of-ctypes-and-dynamic-loading.patch (9452B)


  1. From 1b166dc9a491440db655fa3c7b49df329683ef45 Mon Sep 17 00:00:00 2001
  2. From: Michael Forney <mforney@mforney.org>
  3. Date: Mon, 4 Jul 2016 16:14:18 -0700
  4. Subject: [PATCH] Disable use of ctypes and dynamic loading
  5. ---
  6. yt_dlp/cookies.py | 104 -----------------------------------------
  7. yt_dlp/utils/_utils.py | 85 +--------------------------------
  8. 2 files changed, 2 insertions(+), 187 deletions(-)
  9. diff --git a/yt_dlp/cookies.py b/yt_dlp/cookies.py
  10. index fad323c90..5e5c9df81 100644
  11. --- a/yt_dlp/cookies.py
  12. +++ b/yt_dlp/cookies.py
  13. @@ -416,8 +416,6 @@ def decrypt(self, encrypted_value):
  14. def get_cookie_decryptor(browser_root, browser_keyring_name, logger, *, keyring=None, meta_version=None):
  15. if sys.platform == 'darwin':
  16. return MacChromeCookieDecryptor(browser_keyring_name, logger, meta_version=meta_version)
  17. - elif sys.platform in ('win32', 'cygwin'):
  18. - return WindowsChromeCookieDecryptor(browser_root, logger, meta_version=meta_version)
  19. return LinuxChromeCookieDecryptor(browser_keyring_name, logger, keyring=keyring, meta_version=meta_version)
  20. @@ -511,46 +509,6 @@ def decrypt(self, encrypted_value):
  21. return encrypted_value
  22. -class WindowsChromeCookieDecryptor(ChromeCookieDecryptor):
  23. - def __init__(self, browser_root, logger, meta_version=None):
  24. - self._logger = logger
  25. - self._v10_key = _get_windows_v10_key(browser_root, logger)
  26. - self._cookie_counts = {'v10': 0, 'other': 0}
  27. - self._meta_version = meta_version or 0
  28. -
  29. - def decrypt(self, encrypted_value):
  30. - version = encrypted_value[:3]
  31. - ciphertext = encrypted_value[3:]
  32. -
  33. - if version == b'v10':
  34. - self._cookie_counts['v10'] += 1
  35. - if self._v10_key is None:
  36. - self._logger.warning('cannot decrypt v10 cookies: no key found', only_once=True)
  37. - return None
  38. -
  39. - # https://chromium.googlesource.com/chromium/src/+/refs/heads/main/components/os_crypt/sync/os_crypt_win.cc
  40. - # kNonceLength
  41. - nonce_length = 96 // 8
  42. - # boringssl
  43. - # EVP_AEAD_AES_GCM_TAG_LEN
  44. - authentication_tag_length = 16
  45. -
  46. - raw_ciphertext = ciphertext
  47. - nonce = raw_ciphertext[:nonce_length]
  48. - ciphertext = raw_ciphertext[nonce_length:-authentication_tag_length]
  49. - authentication_tag = raw_ciphertext[-authentication_tag_length:]
  50. -
  51. - return _decrypt_aes_gcm(
  52. - ciphertext, self._v10_key, nonce, authentication_tag, self._logger,
  53. - hash_prefix=self._meta_version >= 24)
  54. -
  55. - else:
  56. - self._cookie_counts['other'] += 1
  57. - # any other prefix means the data is DPAPI encrypted
  58. - # https://chromium.googlesource.com/chromium/src/+/refs/heads/main/components/os_crypt/sync/os_crypt_win.cc
  59. - return _decrypt_windows_dpapi(encrypted_value, self._logger).decode()
  60. -
  61. -
  62. def _extract_safari_cookies(profile, logger):
  63. if sys.platform != 'darwin':
  64. raise ValueError(f'unsupported platform: {sys.platform}')
  65. @@ -997,33 +955,6 @@ def _get_mac_keyring_password(browser_keyring_name, logger):
  66. return None
  67. -def _get_windows_v10_key(browser_root, logger):
  68. - """
  69. - References:
  70. - - [1] https://chromium.googlesource.com/chromium/src/+/refs/heads/main/components/os_crypt/sync/os_crypt_win.cc
  71. - """
  72. - path = _newest(_find_files(browser_root, 'Local State', logger))
  73. - if path is None:
  74. - logger.error('could not find local state file')
  75. - return None
  76. - logger.debug(f'Found local state file at "{path}"')
  77. - with open(path, encoding='utf8') as f:
  78. - data = json.load(f)
  79. - try:
  80. - # kOsCryptEncryptedKeyPrefName in [1]
  81. - base64_key = data['os_crypt']['encrypted_key']
  82. - except KeyError:
  83. - logger.error('no encrypted key in Local State')
  84. - return None
  85. - encrypted_key = base64.b64decode(base64_key)
  86. - # kDPAPIKeyPrefix in [1]
  87. - prefix = b'DPAPI'
  88. - if not encrypted_key.startswith(prefix):
  89. - logger.error('invalid key')
  90. - return None
  91. - return _decrypt_windows_dpapi(encrypted_key[len(prefix):], logger)
  92. -
  93. -
  94. def pbkdf2_sha1(password, salt, iterations, key_length):
  95. return hashlib.pbkdf2_hmac('sha1', password, salt, iterations, key_length)
  96. @@ -1057,41 +988,6 @@ def _decrypt_aes_gcm(ciphertext, key, nonce, authentication_tag, logger, hash_pr
  97. return None
  98. -def _decrypt_windows_dpapi(ciphertext, logger):
  99. - """
  100. - References:
  101. - - https://docs.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptunprotectdata
  102. - """
  103. -
  104. - import ctypes
  105. - import ctypes.wintypes
  106. -
  107. - class DATA_BLOB(ctypes.Structure):
  108. - _fields_ = [('cbData', ctypes.wintypes.DWORD),
  109. - ('pbData', ctypes.POINTER(ctypes.c_char))]
  110. -
  111. - buffer = ctypes.create_string_buffer(ciphertext)
  112. - blob_in = DATA_BLOB(ctypes.sizeof(buffer), buffer)
  113. - blob_out = DATA_BLOB()
  114. - ret = ctypes.windll.crypt32.CryptUnprotectData(
  115. - ctypes.byref(blob_in), # pDataIn
  116. - None, # ppszDataDescr: human readable description of pDataIn
  117. - None, # pOptionalEntropy: salt?
  118. - None, # pvReserved: must be NULL
  119. - None, # pPromptStruct: information about prompts to display
  120. - 0, # dwFlags
  121. - ctypes.byref(blob_out), # pDataOut
  122. - )
  123. - if not ret:
  124. - message = 'Failed to decrypt with DPAPI. See https://github.com/yt-dlp/yt-dlp/issues/10927 for more info'
  125. - logger.error(message)
  126. - raise DownloadError(message) # force exit
  127. -
  128. - result = ctypes.string_at(blob_out.pbData, blob_out.cbData)
  129. - ctypes.windll.kernel32.LocalFree(blob_out.pbData)
  130. - return result
  131. -
  132. -
  133. def _config_home():
  134. return os.environ.get('XDG_CONFIG_HOME', os.path.expanduser('~/.config'))
  135. diff --git a/yt_dlp/utils/_utils.py b/yt_dlp/utils/_utils.py
  136. index 699bf1e7f..710668036 100644
  137. --- a/yt_dlp/utils/_utils.py
  138. +++ b/yt_dlp/utils/_utils.py
  139. @@ -1506,64 +1506,7 @@ def __init__(self):
  140. super().__init__(self.msg)
  141. -# Cross-platform file locking
  142. -if sys.platform == 'win32':
  143. - import ctypes
  144. - import ctypes.wintypes
  145. - import msvcrt
  146. -
  147. - class OVERLAPPED(ctypes.Structure):
  148. - _fields_ = [
  149. - ('Internal', ctypes.wintypes.LPVOID),
  150. - ('InternalHigh', ctypes.wintypes.LPVOID),
  151. - ('Offset', ctypes.wintypes.DWORD),
  152. - ('OffsetHigh', ctypes.wintypes.DWORD),
  153. - ('hEvent', ctypes.wintypes.HANDLE),
  154. - ]
  155. -
  156. - kernel32 = ctypes.WinDLL('kernel32')
  157. - LockFileEx = kernel32.LockFileEx
  158. - LockFileEx.argtypes = [
  159. - ctypes.wintypes.HANDLE, # hFile
  160. - ctypes.wintypes.DWORD, # dwFlags
  161. - ctypes.wintypes.DWORD, # dwReserved
  162. - ctypes.wintypes.DWORD, # nNumberOfBytesToLockLow
  163. - ctypes.wintypes.DWORD, # nNumberOfBytesToLockHigh
  164. - ctypes.POINTER(OVERLAPPED), # Overlapped
  165. - ]
  166. - LockFileEx.restype = ctypes.wintypes.BOOL
  167. - UnlockFileEx = kernel32.UnlockFileEx
  168. - UnlockFileEx.argtypes = [
  169. - ctypes.wintypes.HANDLE, # hFile
  170. - ctypes.wintypes.DWORD, # dwReserved
  171. - ctypes.wintypes.DWORD, # nNumberOfBytesToLockLow
  172. - ctypes.wintypes.DWORD, # nNumberOfBytesToLockHigh
  173. - ctypes.POINTER(OVERLAPPED), # Overlapped
  174. - ]
  175. - UnlockFileEx.restype = ctypes.wintypes.BOOL
  176. - whole_low = 0xffffffff
  177. - whole_high = 0x7fffffff
  178. -
  179. - def _lock_file(f, exclusive, block):
  180. - overlapped = OVERLAPPED()
  181. - overlapped.Offset = 0
  182. - overlapped.OffsetHigh = 0
  183. - overlapped.hEvent = 0
  184. - f._lock_file_overlapped_p = ctypes.pointer(overlapped)
  185. -
  186. - if not LockFileEx(msvcrt.get_osfhandle(f.fileno()),
  187. - (0x2 if exclusive else 0x0) | (0x0 if block else 0x1),
  188. - 0, whole_low, whole_high, f._lock_file_overlapped_p):
  189. - # NB: No argument form of "ctypes.FormatError" does not work on PyPy
  190. - raise BlockingIOError(f'Locking file failed: {ctypes.FormatError(ctypes.GetLastError())!r}')
  191. -
  192. - def _unlock_file(f):
  193. - assert f._lock_file_overlapped_p
  194. - handle = msvcrt.get_osfhandle(f.fileno())
  195. - if not UnlockFileEx(handle, 0, whole_low, whole_high, f._lock_file_overlapped_p):
  196. - raise OSError(f'Unlocking file failed: {ctypes.FormatError()!r}')
  197. -
  198. -else:
  199. +if True:
  200. try:
  201. import fcntl
  202. @@ -1912,31 +1855,7 @@ def fix_xml_ampersands(xml_str):
  203. def setproctitle(title):
  204. - assert isinstance(title, str)
  205. -
  206. - # Workaround for https://github.com/yt-dlp/yt-dlp/issues/4541
  207. - try:
  208. - import ctypes
  209. - except ImportError:
  210. - return
  211. -
  212. - try:
  213. - libc = ctypes.cdll.LoadLibrary('libc.so.6')
  214. - except OSError:
  215. - return
  216. - except TypeError:
  217. - # LoadLibrary in Windows Python 2.7.13 only expects
  218. - # a bytestring, but since unicode_literals turns
  219. - # every string into a unicode string, it fails.
  220. - return
  221. - title_bytes = title.encode()
  222. - buf = ctypes.create_string_buffer(len(title_bytes))
  223. - buf.value = title_bytes
  224. - try:
  225. - # PR_SET_NAME = 15 Ref: /usr/include/linux/prctl.h
  226. - libc.prctl(15, buf, 0, 0, 0)
  227. - except AttributeError:
  228. - return # Strange libc, just skip this
  229. + return
  230. def remove_start(s, start):
  231. --
  232. 2.45.2