aboutsummaryrefslogtreecommitdiffstats
path: root/gallery_dl/cookies.py
diff options
context:
space:
mode:
authorLibravatarUnit 193 <unit193@unit193.net>2024-12-02 00:32:05 -0500
committerLibravatarUnit 193 <unit193@unit193.net>2024-12-02 00:32:05 -0500
commit7c235d96e2417306334cd93517a2723039a5a0b5 (patch)
treecd29cbb34195d8f384237d70a3f8e7405827496a /gallery_dl/cookies.py
parentc68fa03f6af81fc1a23a7021fe28e73bacf71f66 (diff)
parent1981ccaaea6eab2cf32536ec5afe132a870914d8 (diff)
Update upstream source from tag 'upstream/1.28.0'
Update to upstream version '1.28.0' with Debian dir d2219dc8130062139eee5a8e4e0da3dc60db3a4e
Diffstat (limited to 'gallery_dl/cookies.py')
-rw-r--r--gallery_dl/cookies.py78
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: