0001-Disable-use-of-ctypes-and-dynamic-loading.patch (9452B)
- From 1b166dc9a491440db655fa3c7b49df329683ef45 Mon Sep 17 00:00:00 2001
- From: Michael Forney <mforney@mforney.org>
- Date: Mon, 4 Jul 2016 16:14:18 -0700
- Subject: [PATCH] Disable use of ctypes and dynamic loading
- ---
- yt_dlp/cookies.py | 104 -----------------------------------------
- yt_dlp/utils/_utils.py | 85 +--------------------------------
- 2 files changed, 2 insertions(+), 187 deletions(-)
- diff --git a/yt_dlp/cookies.py b/yt_dlp/cookies.py
- index fad323c90..5e5c9df81 100644
- --- a/yt_dlp/cookies.py
- +++ b/yt_dlp/cookies.py
- @@ -416,8 +416,6 @@ def decrypt(self, encrypted_value):
- def get_cookie_decryptor(browser_root, browser_keyring_name, logger, *, keyring=None, meta_version=None):
- if sys.platform == 'darwin':
- return MacChromeCookieDecryptor(browser_keyring_name, logger, meta_version=meta_version)
- - elif sys.platform in ('win32', 'cygwin'):
- - return WindowsChromeCookieDecryptor(browser_root, logger, meta_version=meta_version)
- return LinuxChromeCookieDecryptor(browser_keyring_name, logger, keyring=keyring, meta_version=meta_version)
- @@ -511,46 +509,6 @@ def decrypt(self, encrypted_value):
- return encrypted_value
- -class WindowsChromeCookieDecryptor(ChromeCookieDecryptor):
- - def __init__(self, browser_root, logger, meta_version=None):
- - self._logger = logger
- - self._v10_key = _get_windows_v10_key(browser_root, logger)
- - self._cookie_counts = {'v10': 0, 'other': 0}
- - self._meta_version = meta_version or 0
- -
- - def decrypt(self, encrypted_value):
- - version = encrypted_value[:3]
- - ciphertext = encrypted_value[3:]
- -
- - if version == b'v10':
- - self._cookie_counts['v10'] += 1
- - if self._v10_key is None:
- - self._logger.warning('cannot decrypt v10 cookies: no key found', only_once=True)
- - return None
- -
- - # https://chromium.googlesource.com/chromium/src/+/refs/heads/main/components/os_crypt/sync/os_crypt_win.cc
- - # kNonceLength
- - nonce_length = 96 // 8
- - # boringssl
- - # EVP_AEAD_AES_GCM_TAG_LEN
- - authentication_tag_length = 16
- -
- - raw_ciphertext = ciphertext
- - nonce = raw_ciphertext[:nonce_length]
- - ciphertext = raw_ciphertext[nonce_length:-authentication_tag_length]
- - authentication_tag = raw_ciphertext[-authentication_tag_length:]
- -
- - return _decrypt_aes_gcm(
- - ciphertext, self._v10_key, nonce, authentication_tag, self._logger,
- - hash_prefix=self._meta_version >= 24)
- -
- - else:
- - self._cookie_counts['other'] += 1
- - # any other prefix means the data is DPAPI encrypted
- - # https://chromium.googlesource.com/chromium/src/+/refs/heads/main/components/os_crypt/sync/os_crypt_win.cc
- - return _decrypt_windows_dpapi(encrypted_value, self._logger).decode()
- -
- -
- def _extract_safari_cookies(profile, logger):
- if sys.platform != 'darwin':
- raise ValueError(f'unsupported platform: {sys.platform}')
- @@ -997,33 +955,6 @@ def _get_mac_keyring_password(browser_keyring_name, logger):
- return None
- -def _get_windows_v10_key(browser_root, logger):
- - """
- - References:
- - - [1] https://chromium.googlesource.com/chromium/src/+/refs/heads/main/components/os_crypt/sync/os_crypt_win.cc
- - """
- - path = _newest(_find_files(browser_root, 'Local State', logger))
- - if path is None:
- - logger.error('could not find local state file')
- - return None
- - logger.debug(f'Found local state file at "{path}"')
- - with open(path, encoding='utf8') as f:
- - data = json.load(f)
- - try:
- - # kOsCryptEncryptedKeyPrefName in [1]
- - base64_key = data['os_crypt']['encrypted_key']
- - except KeyError:
- - logger.error('no encrypted key in Local State')
- - return None
- - encrypted_key = base64.b64decode(base64_key)
- - # kDPAPIKeyPrefix in [1]
- - prefix = b'DPAPI'
- - if not encrypted_key.startswith(prefix):
- - logger.error('invalid key')
- - return None
- - return _decrypt_windows_dpapi(encrypted_key[len(prefix):], logger)
- -
- -
- def pbkdf2_sha1(password, salt, iterations, key_length):
- return hashlib.pbkdf2_hmac('sha1', password, salt, iterations, key_length)
- @@ -1057,41 +988,6 @@ def _decrypt_aes_gcm(ciphertext, key, nonce, authentication_tag, logger, hash_pr
- return None
- -def _decrypt_windows_dpapi(ciphertext, logger):
- - """
- - References:
- - - https://docs.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptunprotectdata
- - """
- -
- - import ctypes
- - import ctypes.wintypes
- -
- - class DATA_BLOB(ctypes.Structure):
- - _fields_ = [('cbData', ctypes.wintypes.DWORD),
- - ('pbData', ctypes.POINTER(ctypes.c_char))]
- -
- - buffer = ctypes.create_string_buffer(ciphertext)
- - blob_in = DATA_BLOB(ctypes.sizeof(buffer), buffer)
- - blob_out = DATA_BLOB()
- - ret = ctypes.windll.crypt32.CryptUnprotectData(
- - ctypes.byref(blob_in), # pDataIn
- - None, # ppszDataDescr: human readable description of pDataIn
- - None, # pOptionalEntropy: salt?
- - None, # pvReserved: must be NULL
- - None, # pPromptStruct: information about prompts to display
- - 0, # dwFlags
- - ctypes.byref(blob_out), # pDataOut
- - )
- - if not ret:
- - message = 'Failed to decrypt with DPAPI. See https://github.com/yt-dlp/yt-dlp/issues/10927 for more info'
- - logger.error(message)
- - raise DownloadError(message) # force exit
- -
- - result = ctypes.string_at(blob_out.pbData, blob_out.cbData)
- - ctypes.windll.kernel32.LocalFree(blob_out.pbData)
- - return result
- -
- -
- def _config_home():
- return os.environ.get('XDG_CONFIG_HOME', os.path.expanduser('~/.config'))
- diff --git a/yt_dlp/utils/_utils.py b/yt_dlp/utils/_utils.py
- index 699bf1e7f..710668036 100644
- --- a/yt_dlp/utils/_utils.py
- +++ b/yt_dlp/utils/_utils.py
- @@ -1506,64 +1506,7 @@ def __init__(self):
- super().__init__(self.msg)
- -# Cross-platform file locking
- -if sys.platform == 'win32':
- - import ctypes
- - import ctypes.wintypes
- - import msvcrt
- -
- - class OVERLAPPED(ctypes.Structure):
- - _fields_ = [
- - ('Internal', ctypes.wintypes.LPVOID),
- - ('InternalHigh', ctypes.wintypes.LPVOID),
- - ('Offset', ctypes.wintypes.DWORD),
- - ('OffsetHigh', ctypes.wintypes.DWORD),
- - ('hEvent', ctypes.wintypes.HANDLE),
- - ]
- -
- - kernel32 = ctypes.WinDLL('kernel32')
- - LockFileEx = kernel32.LockFileEx
- - LockFileEx.argtypes = [
- - ctypes.wintypes.HANDLE, # hFile
- - ctypes.wintypes.DWORD, # dwFlags
- - ctypes.wintypes.DWORD, # dwReserved
- - ctypes.wintypes.DWORD, # nNumberOfBytesToLockLow
- - ctypes.wintypes.DWORD, # nNumberOfBytesToLockHigh
- - ctypes.POINTER(OVERLAPPED), # Overlapped
- - ]
- - LockFileEx.restype = ctypes.wintypes.BOOL
- - UnlockFileEx = kernel32.UnlockFileEx
- - UnlockFileEx.argtypes = [
- - ctypes.wintypes.HANDLE, # hFile
- - ctypes.wintypes.DWORD, # dwReserved
- - ctypes.wintypes.DWORD, # nNumberOfBytesToLockLow
- - ctypes.wintypes.DWORD, # nNumberOfBytesToLockHigh
- - ctypes.POINTER(OVERLAPPED), # Overlapped
- - ]
- - UnlockFileEx.restype = ctypes.wintypes.BOOL
- - whole_low = 0xffffffff
- - whole_high = 0x7fffffff
- -
- - def _lock_file(f, exclusive, block):
- - overlapped = OVERLAPPED()
- - overlapped.Offset = 0
- - overlapped.OffsetHigh = 0
- - overlapped.hEvent = 0
- - f._lock_file_overlapped_p = ctypes.pointer(overlapped)
- -
- - if not LockFileEx(msvcrt.get_osfhandle(f.fileno()),
- - (0x2 if exclusive else 0x0) | (0x0 if block else 0x1),
- - 0, whole_low, whole_high, f._lock_file_overlapped_p):
- - # NB: No argument form of "ctypes.FormatError" does not work on PyPy
- - raise BlockingIOError(f'Locking file failed: {ctypes.FormatError(ctypes.GetLastError())!r}')
- -
- - def _unlock_file(f):
- - assert f._lock_file_overlapped_p
- - handle = msvcrt.get_osfhandle(f.fileno())
- - if not UnlockFileEx(handle, 0, whole_low, whole_high, f._lock_file_overlapped_p):
- - raise OSError(f'Unlocking file failed: {ctypes.FormatError()!r}')
- -
- -else:
- +if True:
- try:
- import fcntl
- @@ -1912,31 +1855,7 @@ def fix_xml_ampersands(xml_str):
- def setproctitle(title):
- - assert isinstance(title, str)
- -
- - # Workaround for https://github.com/yt-dlp/yt-dlp/issues/4541
- - try:
- - import ctypes
- - except ImportError:
- - return
- -
- - try:
- - libc = ctypes.cdll.LoadLibrary('libc.so.6')
- - except OSError:
- - return
- - except TypeError:
- - # LoadLibrary in Windows Python 2.7.13 only expects
- - # a bytestring, but since unicode_literals turns
- - # every string into a unicode string, it fails.
- - return
- - title_bytes = title.encode()
- - buf = ctypes.create_string_buffer(len(title_bytes))
- - buf.value = title_bytes
- - try:
- - # PR_SET_NAME = 15 Ref: /usr/include/linux/prctl.h
- - libc.prctl(15, buf, 0, 0, 0)
- - except AttributeError:
- - return # Strange libc, just skip this
- + return
- def remove_start(s, start):
- --
- 2.45.2