merge #8303: [cookies] add support for Orion
This commit is contained in:
@@ -27,8 +27,11 @@ from . import aes, text, util
|
|||||||
SUPPORTED_BROWSERS_CHROMIUM = {
|
SUPPORTED_BROWSERS_CHROMIUM = {
|
||||||
"brave", "chrome", "chromium", "edge", "opera", "thorium", "vivaldi"}
|
"brave", "chrome", "chromium", "edge", "opera", "thorium", "vivaldi"}
|
||||||
SUPPORTED_BROWSERS_FIREFOX = {"firefox", "librewolf", "zen"}
|
SUPPORTED_BROWSERS_FIREFOX = {"firefox", "librewolf", "zen"}
|
||||||
|
SUPPORTED_BROWSERS_WEBKIT = {"safari", "orion"}
|
||||||
SUPPORTED_BROWSERS = \
|
SUPPORTED_BROWSERS = \
|
||||||
SUPPORTED_BROWSERS_CHROMIUM | SUPPORTED_BROWSERS_FIREFOX | {"safari"}
|
SUPPORTED_BROWSERS_CHROMIUM \
|
||||||
|
| SUPPORTED_BROWSERS_FIREFOX \
|
||||||
|
| SUPPORTED_BROWSERS_WEBKIT
|
||||||
|
|
||||||
logger = logging.getLogger("cookies")
|
logger = logging.getLogger("cookies")
|
||||||
|
|
||||||
@@ -38,8 +41,8 @@ def load_cookies(browser_specification):
|
|||||||
_parse_browser_specification(*browser_specification)
|
_parse_browser_specification(*browser_specification)
|
||||||
if browser_name in SUPPORTED_BROWSERS_FIREFOX:
|
if browser_name in SUPPORTED_BROWSERS_FIREFOX:
|
||||||
return load_cookies_firefox(browser_name, profile, container, domain)
|
return load_cookies_firefox(browser_name, profile, container, domain)
|
||||||
elif browser_name == "safari":
|
elif browser_name in SUPPORTED_BROWSERS_WEBKIT:
|
||||||
return load_cookies_safari(profile, domain)
|
return load_cookies_webkit(browser_name, profile, domain)
|
||||||
elif browser_name in SUPPORTED_BROWSERS_CHROMIUM:
|
elif browser_name in SUPPORTED_BROWSERS_CHROMIUM:
|
||||||
return load_cookies_chromium(browser_name, profile, keyring, domain)
|
return load_cookies_chromium(browser_name, profile, keyring, domain)
|
||||||
else:
|
else:
|
||||||
@@ -92,7 +95,7 @@ def load_cookies_firefox(browser_name, profile=None,
|
|||||||
return cookies
|
return cookies
|
||||||
|
|
||||||
|
|
||||||
def load_cookies_safari(profile=None, domain=None):
|
def load_cookies_webkit(browser_name, profile=None, domain=None):
|
||||||
"""Ref.: https://github.com/libyal/dtformats/blob
|
"""Ref.: https://github.com/libyal/dtformats/blob
|
||||||
/main/documentation/Safari%20Cookies.asciidoc
|
/main/documentation/Safari%20Cookies.asciidoc
|
||||||
- This data appears to be out of date
|
- This data appears to be out of date
|
||||||
@@ -100,15 +103,24 @@ def load_cookies_safari(profile=None, domain=None):
|
|||||||
- There are a few bytes here and there
|
- There are a few bytes here and there
|
||||||
which are skipped during parsing
|
which are skipped during parsing
|
||||||
"""
|
"""
|
||||||
with _safari_cookies_database() as fp:
|
if browser_name == "safari":
|
||||||
data = fp.read()
|
with _safari_cookies_database() as fp:
|
||||||
page_sizes, body_start = _safari_parse_cookies_header(data)
|
data = fp.read()
|
||||||
|
elif browser_name == "orion":
|
||||||
|
with _orion_cookies_database() as fp:
|
||||||
|
data = fp.read()
|
||||||
|
else:
|
||||||
|
raise ValueError(f"unknown webkit browser '{browser_name}'")
|
||||||
|
|
||||||
|
page_sizes, body_start = _webkit_parse_cookies_header(data)
|
||||||
p = DataParser(data[body_start:])
|
p = DataParser(data[body_start:])
|
||||||
|
|
||||||
cookies = []
|
cookies = []
|
||||||
for page_size in page_sizes:
|
for page_size in page_sizes:
|
||||||
_safari_parse_cookies_page(p.read_bytes(page_size), cookies)
|
_webkit_parse_cookies_page(p.read_bytes(page_size), cookies)
|
||||||
_log_info("Extracted %s cookies from Safari", len(cookies))
|
_log_info("Extracted %s cookies from %s",
|
||||||
|
browser_name.capitalize(), len(cookies))
|
||||||
|
|
||||||
return cookies
|
return cookies
|
||||||
|
|
||||||
|
|
||||||
@@ -278,7 +290,8 @@ def _firefox_browser_directory(browser_name):
|
|||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
# safari
|
# safari/orion/webkit
|
||||||
|
|
||||||
|
|
||||||
def _safari_cookies_database():
|
def _safari_cookies_database():
|
||||||
try:
|
try:
|
||||||
@@ -291,7 +304,13 @@ def _safari_cookies_database():
|
|||||||
return open(path, "rb")
|
return open(path, "rb")
|
||||||
|
|
||||||
|
|
||||||
def _safari_parse_cookies_header(data):
|
def _orion_cookies_database():
|
||||||
|
path = os.path.expanduser(
|
||||||
|
"~/Library/HTTPStorages/com.kagi.kagimacOS.binarycookies")
|
||||||
|
return open(path, "rb")
|
||||||
|
|
||||||
|
|
||||||
|
def _webkit_parse_cookies_header(data):
|
||||||
p = DataParser(data)
|
p = DataParser(data)
|
||||||
p.expect_bytes(b"cook", "database signature")
|
p.expect_bytes(b"cook", "database signature")
|
||||||
number_of_pages = p.read_uint(big_endian=True)
|
number_of_pages = p.read_uint(big_endian=True)
|
||||||
@@ -300,7 +319,7 @@ def _safari_parse_cookies_header(data):
|
|||||||
return page_sizes, p.cursor
|
return page_sizes, p.cursor
|
||||||
|
|
||||||
|
|
||||||
def _safari_parse_cookies_page(data, cookies, domain=None):
|
def _webkit_parse_cookies_page(data, cookies, domain=None):
|
||||||
p = DataParser(data)
|
p = DataParser(data)
|
||||||
p.expect_bytes(b"\x00\x00\x01\x00", "page signature")
|
p.expect_bytes(b"\x00\x00\x01\x00", "page signature")
|
||||||
number_of_cookies = p.read_uint()
|
number_of_cookies = p.read_uint()
|
||||||
@@ -313,13 +332,13 @@ def _safari_parse_cookies_page(data, cookies, domain=None):
|
|||||||
|
|
||||||
for i, record_offset in enumerate(record_offsets):
|
for i, record_offset in enumerate(record_offsets):
|
||||||
p.skip_to(record_offset, "space between records")
|
p.skip_to(record_offset, "space between records")
|
||||||
record_length = _safari_parse_cookies_record(
|
record_length = _webkit_parse_cookies_record(
|
||||||
data[record_offset:], cookies, domain)
|
data[record_offset:], cookies, domain)
|
||||||
p.read_bytes(record_length)
|
p.read_bytes(record_length)
|
||||||
p.skip_to_end("space in between pages")
|
p.skip_to_end("space in between pages")
|
||||||
|
|
||||||
|
|
||||||
def _safari_parse_cookies_record(data, cookies, host=None):
|
def _webkit_parse_cookies_record(data, cookies, host=None):
|
||||||
p = DataParser(data)
|
p = DataParser(data)
|
||||||
record_size = p.read_uint()
|
record_size = p.read_uint()
|
||||||
p.skip(4, "unknown record field 1")
|
p.skip(4, "unknown record field 1")
|
||||||
@@ -355,7 +374,7 @@ def _safari_parse_cookies_record(data, cookies, host=None):
|
|||||||
p.skip_to(value_offset)
|
p.skip_to(value_offset)
|
||||||
value = p.read_cstring()
|
value = p.read_cstring()
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
_log_warning("Failed to parse Safari cookie")
|
_log_warning("Failed to parse WebKit cookie")
|
||||||
return record_size
|
return record_size
|
||||||
|
|
||||||
p.skip_to(record_size, "space at the end of the record")
|
p.skip_to(record_size, "space at the end of the record")
|
||||||
|
|||||||
Reference in New Issue
Block a user