diff options
| author | 2024-12-02 00:31:59 -0500 | |
|---|---|---|
| committer | 2024-12-02 00:31:59 -0500 | |
| commit | 1981ccaaea6eab2cf32536ec5afe132a870914d8 (patch) | |
| tree | 013f1e17d922d3a6abf7f57aa6a175c2ce5d93bc /gallery_dl/cookies.py | |
| parent | fc004701f923bb954a22c7fec2ae8d607e78cb2b (diff) | |
New upstream version 1.28.0.upstream/1.28.0
Diffstat (limited to 'gallery_dl/cookies.py')
| -rw-r--r-- | gallery_dl/cookies.py | 78 |
1 files changed, 52 insertions, 26 deletions
diff --git a/gallery_dl/cookies.py b/gallery_dl/cookies.py index cec2ea0..71b0b6b 100644 --- a/gallery_dl/cookies.py +++ b/gallery_dl/cookies.py @@ -126,20 +126,29 @@ def load_cookies_chromium(browser_name, profile=None, with DatabaseConnection(path) as db: db.text_factory = bytes + cursor = db.cursor() try: - rows = db.execute( + meta_version = int(cursor.execute( + "SELECT value FROM meta WHERE key = 'version'").fetchone()[0]) + except Exception as exc: + _log_warning("Failed to get cookie database meta version (%s: %s)", + exc.__class__.__name__, exc) + meta_version = 0 + + try: + rows = cursor.execute( "SELECT host_key, name, value, encrypted_value, path, " "expires_utc, is_secure FROM cookies" + condition, parameters) except sqlite3.OperationalError: - rows = db.execute( + rows = cursor.execute( "SELECT host_key, name, value, encrypted_value, path, " "expires_utc, secure FROM cookies" + condition, parameters) failed_cookies = 0 unencrypted_cookies = 0 decryptor = _chromium_cookie_decryptor( - config["directory"], config["keyring"], keyring) + config["directory"], config["keyring"], keyring, meta_version) cookies = [] for domain, name, value, enc_value, path, expires, secure in rows: @@ -432,13 +441,16 @@ def _chromium_browser_settings(browser_name): def _chromium_cookie_decryptor( - browser_root, browser_keyring_name, keyring=None): + browser_root, browser_keyring_name, keyring=None, meta_version=0): if sys.platform in ("win32", "cygwin"): - return WindowsChromiumCookieDecryptor(browser_root) + return WindowsChromiumCookieDecryptor( + browser_root, meta_version) elif sys.platform == "darwin": - return MacChromiumCookieDecryptor(browser_keyring_name) + return MacChromiumCookieDecryptor( + browser_keyring_name, meta_version) else: - return LinuxChromiumCookieDecryptor(browser_keyring_name, keyring) + return LinuxChromiumCookieDecryptor( + browser_keyring_name, keyring, meta_version) class ChromiumCookieDecryptor: @@ -480,11 +492,13 @@ class ChromiumCookieDecryptor: class LinuxChromiumCookieDecryptor(ChromiumCookieDecryptor): - def __init__(self, browser_keyring_name, keyring=None): - self._v10_key = self.derive_key(b"peanuts") + def __init__(self, browser_keyring_name, keyring=None, meta_version=0): password = _get_linux_keyring_password(browser_keyring_name, keyring) + self._empty_key = self.derive_key(b"") + self._v10_key = self.derive_key(b"peanuts") self._v11_key = None if password is None else self.derive_key(password) self._cookie_counts = {"v10": 0, "v11": 0, "other": 0} + self._offset = (32 if meta_version >= 24 else 0) @staticmethod def derive_key(password): @@ -504,25 +518,32 @@ class LinuxChromiumCookieDecryptor(ChromiumCookieDecryptor): if version == b"v10": self._cookie_counts["v10"] += 1 - return _decrypt_aes_cbc(ciphertext, self._v10_key) + value = _decrypt_aes_cbc(ciphertext, self._v10_key, self._offset) elif version == b"v11": self._cookie_counts["v11"] += 1 if self._v11_key is None: _log_warning("Unable to decrypt v11 cookies: no key found") return None - return _decrypt_aes_cbc(ciphertext, self._v11_key) + value = _decrypt_aes_cbc(ciphertext, self._v11_key, self._offset) else: self._cookie_counts["other"] += 1 return None + if value is None: + value = _decrypt_aes_cbc(ciphertext, self._empty_key, self._offset) + if value is None: + _log_warning("Failed to decrypt cookie (AES-CBC)") + return value + class MacChromiumCookieDecryptor(ChromiumCookieDecryptor): - def __init__(self, browser_keyring_name): + def __init__(self, browser_keyring_name, meta_version=0): password = _get_mac_keyring_password(browser_keyring_name) self._v10_key = None if password is None else self.derive_key(password) self._cookie_counts = {"v10": 0, "other": 0} + self._offset = (32 if meta_version >= 24 else 0) @staticmethod def derive_key(password): @@ -545,8 +566,7 @@ class MacChromiumCookieDecryptor(ChromiumCookieDecryptor): if self._v10_key is None: _log_warning("Unable to decrypt v10 cookies: no key found") return None - - return _decrypt_aes_cbc(ciphertext, self._v10_key) + return _decrypt_aes_cbc(ciphertext, self._v10_key, self._offset) else: self._cookie_counts["other"] += 1 @@ -558,9 +578,10 @@ class MacChromiumCookieDecryptor(ChromiumCookieDecryptor): class WindowsChromiumCookieDecryptor(ChromiumCookieDecryptor): - def __init__(self, browser_root): + def __init__(self, browser_root, meta_version=0): self._v10_key = _get_windows_v10_key(browser_root) self._cookie_counts = {"v10": 0, "other": 0} + self._offset = (32 if meta_version >= 24 else 0) @property def cookie_counts(self): @@ -591,7 +612,8 @@ class WindowsChromiumCookieDecryptor(ChromiumCookieDecryptor): authentication_tag = raw_ciphertext[-authentication_tag_length:] return _decrypt_aes_gcm( - ciphertext, self._v10_key, nonce, authentication_tag) + ciphertext, self._v10_key, nonce, authentication_tag, + self._offset) else: self._cookie_counts["other"] += 1 @@ -975,21 +997,25 @@ def pbkdf2_sha1(password, salt, iterations, key_length): return pbkdf2_hmac("sha1", password, salt, iterations, key_length) -def _decrypt_aes_cbc(ciphertext, key, initialization_vector=b" " * 16): +def _decrypt_aes_cbc(ciphertext, key, offset=0, + initialization_vector=b" " * 16): + plaintext = aes.unpad_pkcs7(aes.aes_cbc_decrypt_bytes( + ciphertext, key, initialization_vector)) + if offset: + plaintext = plaintext[offset:] try: - return aes.unpad_pkcs7(aes.aes_cbc_decrypt_bytes( - ciphertext, key, initialization_vector)).decode() + return plaintext.decode() except UnicodeDecodeError: - _log_warning("Failed to decrypt cookie (AES-CBC Unicode)") - except ValueError: - _log_warning("Failed to decrypt cookie (AES-CBC)") - return None + return None -def _decrypt_aes_gcm(ciphertext, key, nonce, authentication_tag): +def _decrypt_aes_gcm(ciphertext, key, nonce, authentication_tag, offset=0): try: - return aes.aes_gcm_decrypt_and_verify_bytes( - ciphertext, key, authentication_tag, nonce).decode() + plaintext = aes.aes_gcm_decrypt_and_verify_bytes( + ciphertext, key, authentication_tag, nonce) + if offset: + plaintext = plaintext[offset:] + return plaintext.decode() except UnicodeDecodeError: _log_warning("Failed to decrypt cookie (AES-GCM Unicode)") except ValueError: |
