Skip to content

Commit

Permalink
Changes after review
Browse files Browse the repository at this point in the history
  • Loading branch information
joachimmetz committed Dec 16, 2023
1 parent 0a0ab98 commit eef5850
Showing 1 changed file with 96 additions and 98 deletions.
194 changes: 96 additions & 98 deletions plaso/parsers/sqlite_plugins/firefox_downloads.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import json

from dfdatetime import posix_time as dfdatetime_posix_time

from plaso.containers import events
from plaso.parsers import sqlite
from plaso.parsers.sqlite_plugins import interface
Expand Down Expand Up @@ -53,12 +54,12 @@ class Firefox118DownloadEventData(events.EventData):
"""Firefox download event data.
Attributes:
deleted (int): Firefox-tracked deleted state
download_state (int): Firefox State of the download
deleted (int): deleted state.
download_state (int): state of the download.
end_time (dfdatetime.DateTimeValues): date and time the download was
finished.
expiration (int): Firefox (potentially deprecated) expiration field
flags (int): Firefox flags associated with this download
expiration (int): expiration.
flags (int): flags associated with this download
full_path (str): full path of the target of the download.
mime_type (str): mime type of the download.
name (str): name of the download.
Expand All @@ -71,7 +72,7 @@ class Firefox118DownloadEventData(events.EventData):
started.
temporary_location (str): temporary location of the download.
total_bytes (int): total number of bytes of the download.
type (int): Firefox (potentially deprecated) type field
type (int): type field.
url (str): source URL of the download.
"""

Expand All @@ -95,55 +96,39 @@ def __init__(self):
self.url = None


class Firefox118DownloadsPlugin(interface.SQLitePlugin):
"""SQLite parser plugin for Mozilla Firefox file downloads as of version 118.
Likely, this will apply to versions earlier than 118, but this was built on
version 118.
class FirefoxDownloadsPlugin(interface.SQLitePlugin):
"""SQLite parser plugin for Mozilla Firefox downloads database files.
In this version of Firefox Downloads, the files are in a table in places.sql
The Mozilla Firefox downloads database file is typically stored in:
downloads.sqlite
"""
NAME = 'firefox_118_downloads'

NAME = 'firefox_downloads'
DATA_FORMAT = (
'Mozilla Firefox 118 downloads SQLite database (downloads.sqlite) file')
'Mozilla Firefox downloads SQLite database (downloads.sqlite) file')

REQUIRED_STRUCTURE = {
'moz_annos': frozenset([
'id', 'place_id', 'anno_attribute_id', 'content', 'flags',
'expiration', 'type', 'dateAdded', 'lastModified']),
'moz_places': frozenset([
'id', 'title', 'url', 'last_visit_date'])
}
'moz_downloads': frozenset([
'id', 'name', 'source', 'target', 'tempPath', 'startTime', 'endTime',
'state', 'referrer', 'currBytes', 'maxBytes', 'mimeType'])}

QUERIES = [
(('SELECT annos1.content, annos2.flags, annos2.expiration, annos2.type, '
'annos2.dateAdded, annos2.lastModified, annos2.content as dest_fpath, '
'places.url, places.title, places.last_visit_date '
'from moz_annos annos1, moz_annos annos2, moz_places places '
'WHERE annos1.anno_attribute_id == annos2.anno_attribute_id+1 '
'AND annos1.place_id == annos2.place_id '
'AND annos1.place_id == places.id'),
(('SELECT moz_downloads.id, moz_downloads.name, moz_downloads.source, '
'moz_downloads.target, moz_downloads.tempPath, '
'moz_downloads.startTime, moz_downloads.endTime, moz_downloads.state, '
'moz_downloads.referrer, moz_downloads.currBytes, '
'moz_downloads.maxBytes, moz_downloads.mimeType '
'FROM moz_downloads'),
'ParseDownloadsRow')]

SCHEMAS = [
{'moz_annos':
'CREATE TABLE moz_annos (id INTEGER PRIMARY KEY, '
'place_id INTEGER NOT NULL, anno_attribute_id INTEGER, '
'content LONGVARCHAR, flags INTEGER DEFAULT 0, '
'expiration INTEGER DEFAULT 0, type INTEGER DEFAULT 0, '
'dateAdded INTEGER DEFAULT 0, lastModified INTEGER DEFAULT 0)'},
{'moz_places':
'CREATE TABLE moz_places (id INTEGER PRIMARY KEY, url LONGVARCHAR, '
'title LONGVARCHAR, rev_host LONGVARCHAR, '
'visit_count INTEGER DEFAULT 0, hidden INTEGER DEFAULT 0 NOT NULL, '
'typed INTEGER DEFAULT 0 NOT NULL, '
'frecency INTEGER DEFAULT -1 NOT NULL, last_visit_date INTEGER, '
'guid TEXT, foreign_count INTEGER DEFAULT 0 NOT NULL, '
'url_hash INTEGER DEFAULT 0 NOT NULL , description TEXT, '
'preview_image_url TEXT, site_name TEXT, '
'origin_id INTEGER REFERENCES moz_origins(id), '
'recalc_frecency INTEGER NOT NULL DEFAULT 0, alt_frecency INTEGER, '
'recalc_alt_frecency INTEGER NOT NULL DEFAULT 0)'}
]
{'moz_downloads':
'CREATE TABLE moz_downloads (id INTEGER PRIMARY KEY, name TEXT, '
'source TEXT, target TEXT, tempPath TEXT, startTime INTEGER, endTime '
'INTEGER, state INTEGER, referrer TEXT, entityID TEXT, currBytes '
'INTEGER NOT NULL DEFAULT 0, maxBytes INTEGER NOT NULL DEFAULT -1, '
'mimeType TEXT, preferredApplication TEXT, preferredAction INTEGER '
'NOT NULL DEFAULT 0, autoResume INTEGER NOT NULL DEFAULT 0)'}]

def _GetDateTimeRowValue(self, query_hash, row, value_name):
"""Retrieves a date and time value from the row.
Expand Down Expand Up @@ -176,62 +161,72 @@ def ParseDownloadsRow(
"""
query_hash = hash(query)

content = self._GetRowValue(query_hash, row, 'content')
content_data = json.loads(content)

event_data = Firefox118DownloadEventData()

event_data.deleted = content_data.get('deleted', None)
event_data.download_state = content_data.get('state', None)
event_data.end_time = content_data.get('endTime', None)
event_data.expiration = self._GetRowValue(query_hash, row, 'expiration')
event_data.flags = self._GetRowValue(query_hash, row, 'flags')
event_data.full_path = self._GetRowValue(query_hash, row, 'dest_fpath')
event_data.name = self._GetRowValue(query_hash, row, 'title')
event_data = FirefoxDownloadEventData()
event_data.end_time = self._GetDateTimeRowValue(query_hash, row, 'endTime')
event_data.full_path = self._GetRowValue(query_hash, row, 'target')
event_data.mime_type = self._GetRowValue(query_hash, row, 'mimeType')
event_data.name = self._GetRowValue(query_hash, row, 'name')
event_data.offset = self._GetRowValue(query_hash, row, 'id')
event_data.query = query
event_data.received_bytes = content_data.get('fileSize', 0)
event_data.received_bytes = self._GetRowValue(query_hash, row, 'currBytes')
event_data.referrer = self._GetRowValue(query_hash, row, 'referrer')
event_data.start_time = self._GetDateTimeRowValue(
query_hash, row, 'dateAdded')
event_data.total_bytes = content_data.get('fileSize', 0)
event_data.type = self._GetRowValue(query_hash, row, 'type')
event_data.url = self._GetRowValue(query_hash, row, 'url')
query_hash, row, 'startTime')
event_data.temporary_location = self._GetRowValue(
query_hash, row, 'tempPath')
event_data.total_bytes = self._GetRowValue(query_hash, row, 'maxBytes')
event_data.url = self._GetRowValue(query_hash, row, 'source')

parser_mediator.ProduceEventData(event_data)


class FirefoxDownloadsPlugin(interface.SQLitePlugin):
"""SQLite parser plugin for Mozilla Firefox downloads database files.
class Firefox118DownloadsPlugin(interface.SQLitePlugin):
"""SQLite parser plugin for version 118 Firefox downloads database files.
The Mozilla Firefox downloads database file is typically stored in:
downloads.sqlite
The version 118 Firefox downloads database file is typically stored in:
places.sql
"""

NAME = 'firefox_downloads'
NAME = 'firefox_118_downloads'
DATA_FORMAT = (
'Mozilla Firefox downloads SQLite database (downloads.sqlite) file')
'Mozilla Firefox 118 downloads SQLite database (downloads.sqlite) file')

REQUIRED_STRUCTURE = {
'moz_downloads': frozenset([
'id', 'name', 'source', 'target', 'tempPath', 'startTime', 'endTime',
'state', 'referrer', 'currBytes', 'maxBytes', 'mimeType'])}
'moz_annos': frozenset([
'id', 'place_id', 'anno_attribute_id', 'content', 'flags',
'expiration', 'type', 'dateAdded', 'lastModified']),
'moz_places': frozenset([
'id', 'title', 'url', 'last_visit_date'])}

QUERIES = [
(('SELECT moz_downloads.id, moz_downloads.name, moz_downloads.source, '
'moz_downloads.target, moz_downloads.tempPath, '
'moz_downloads.startTime, moz_downloads.endTime, moz_downloads.state, '
'moz_downloads.referrer, moz_downloads.currBytes, '
'moz_downloads.maxBytes, moz_downloads.mimeType '
'FROM moz_downloads'),
(('SELECT annos1.content, annos2.flags, annos2.expiration, annos2.type, '
'annos2.dateAdded, annos2.lastModified, annos2.content as dest_fpath, '
'places.url, places.title, places.last_visit_date '
'from moz_annos annos1, moz_annos annos2, moz_places places '
'WHERE annos1.anno_attribute_id == annos2.anno_attribute_id+1 '
'AND annos1.place_id == annos2.place_id '
'AND annos1.place_id == places.id'),
'ParseDownloadsRow')]

SCHEMAS = [
{'moz_downloads':
'CREATE TABLE moz_downloads (id INTEGER PRIMARY KEY, name TEXT, '
'source TEXT, target TEXT, tempPath TEXT, startTime INTEGER, endTime '
'INTEGER, state INTEGER, referrer TEXT, entityID TEXT, currBytes '
'INTEGER NOT NULL DEFAULT 0, maxBytes INTEGER NOT NULL DEFAULT -1, '
'mimeType TEXT, preferredApplication TEXT, preferredAction INTEGER '
'NOT NULL DEFAULT 0, autoResume INTEGER NOT NULL DEFAULT 0)'}]
{'moz_annos':
'CREATE TABLE moz_annos (id INTEGER PRIMARY KEY, '
'place_id INTEGER NOT NULL, anno_attribute_id INTEGER, '
'content LONGVARCHAR, flags INTEGER DEFAULT 0, '
'expiration INTEGER DEFAULT 0, type INTEGER DEFAULT 0, '
'dateAdded INTEGER DEFAULT 0, lastModified INTEGER DEFAULT 0)'},
{'moz_places':
'CREATE TABLE moz_places (id INTEGER PRIMARY KEY, url LONGVARCHAR, '
'title LONGVARCHAR, rev_host LONGVARCHAR, '
'visit_count INTEGER DEFAULT 0, hidden INTEGER DEFAULT 0 NOT NULL, '
'typed INTEGER DEFAULT 0 NOT NULL, '
'frecency INTEGER DEFAULT -1 NOT NULL, last_visit_date INTEGER, '
'guid TEXT, foreign_count INTEGER DEFAULT 0 NOT NULL, '
'url_hash INTEGER DEFAULT 0 NOT NULL , description TEXT, '
'preview_image_url TEXT, site_name TEXT, '
'origin_id INTEGER REFERENCES moz_origins(id), '
'recalc_frecency INTEGER NOT NULL DEFAULT 0, alt_frecency INTEGER, '
'recalc_alt_frecency INTEGER NOT NULL DEFAULT 0)'}]

def _GetDateTimeRowValue(self, query_hash, row, value_name):
"""Retrieves a date and time value from the row.
Expand All @@ -252,8 +247,7 @@ def _GetDateTimeRowValue(self, query_hash, row, value_name):

return dfdatetime_posix_time.PosixTimeInMicroseconds(timestamp=timestamp)

def ParseDownloadsRow(
self, parser_mediator, query, row, **unused_kwargs):
def ParseDownloadsRow(self, parser_mediator, query, row, **unused_kwargs):
"""Parses a downloads row.
Args:
Expand All @@ -264,21 +258,25 @@ def ParseDownloadsRow(
"""
query_hash = hash(query)

event_data = FirefoxDownloadEventData()
event_data.end_time = self._GetDateTimeRowValue(query_hash, row, 'endTime')
event_data.full_path = self._GetRowValue(query_hash, row, 'target')
event_data.mime_type = self._GetRowValue(query_hash, row, 'mimeType')
event_data.name = self._GetRowValue(query_hash, row, 'name')
event_data.offset = self._GetRowValue(query_hash, row, 'id')
content = self._GetRowValue(query_hash, row, 'content')
content_data = json.loads(content)

event_data = Firefox118DownloadEventData()

event_data.deleted = content_data.get('deleted', None)
event_data.download_state = content_data.get('state', None)
event_data.end_time = content_data.get('endTime', None)
event_data.expiration = self._GetRowValue(query_hash, row, 'expiration')
event_data.flags = self._GetRowValue(query_hash, row, 'flags')
event_data.full_path = self._GetRowValue(query_hash, row, 'dest_fpath')
event_data.name = self._GetRowValue(query_hash, row, 'title')
event_data.query = query
event_data.received_bytes = self._GetRowValue(query_hash, row, 'currBytes')
event_data.referrer = self._GetRowValue(query_hash, row, 'referrer')
event_data.received_bytes = content_data.get('fileSize', 0)
event_data.start_time = self._GetDateTimeRowValue(
query_hash, row, 'startTime')
event_data.temporary_location = self._GetRowValue(
query_hash, row, 'tempPath')
event_data.total_bytes = self._GetRowValue(query_hash, row, 'maxBytes')
event_data.url = self._GetRowValue(query_hash, row, 'source')
query_hash, row, 'dateAdded')
event_data.total_bytes = content_data.get('fileSize', 0)
event_data.type = self._GetRowValue(query_hash, row, 'type')
event_data.url = self._GetRowValue(query_hash, row, 'url')

parser_mediator.ProduceEventData(event_data)

Expand Down

0 comments on commit eef5850

Please sign in to comment.