Skip to content

Commit

Permalink
Added session configuration attribute container #109 (#2936)
Browse files Browse the repository at this point in the history
  • Loading branch information
joachimmetz authored Jun 19, 2020
1 parent 0fb2576 commit 95fd0f1
Show file tree
Hide file tree
Showing 6 changed files with 303 additions and 97 deletions.
32 changes: 30 additions & 2 deletions plaso/containers/artifacts.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,34 @@ def IsEquivalent(self, other):
return False


class SourceConfigurationArtifact(ArtifactAttributeContainer):
"""Source configuration artifact attribute container.
The source configuration contains the configuration data of a source
that is (or going to be) processed such as volume in a storage media
image or a mounted directory.
Attributes:
path_spec (dfvfs.PathSpec): path specification of the source that is
processed.
system_configuration (SystemConfigurationArtifact): system configuration of
a specific system installation, such as Windows or Linux, detected by
the pre-processing on the source.
"""
CONTAINER_TYPE = 'source_configuration'

def __init__(self, path_spec=None):
"""Initializes a source configuration artifact.
Args:
path_spec (Optional[dfvfs.PathSpec]): path specification of the source
that is processed.
"""
super(SourceConfigurationArtifact, self).__init__()
self.path_spec = path_spec
self.system_configuration = None


class SystemConfigurationArtifact(ArtifactAttributeContainer):
"""System configuration artifact attribute container.
Expand Down Expand Up @@ -331,5 +359,5 @@ def GetUserDirectoryPathSegments(self):


manager.AttributeContainersManager.RegisterAttributeContainers([
EnvironmentVariableArtifact, HostnameArtifact, SystemConfigurationArtifact,
TimeZoneArtifact, UserAccountArtifact])
EnvironmentVariableArtifact, HostnameArtifact, SourceConfigurationArtifact,
SystemConfigurationArtifact, TimeZoneArtifact, UserAccountArtifact])
136 changes: 108 additions & 28 deletions plaso/containers/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ class Session(interface.AttributeContainer):
product_name (str): name of the product that created the session for
example "log2timeline".
product_version (str): version of the product that created the session.
source_configurations (list[SourceConfiguration]): configuration of sources
that are (or going to be) processed.
start_time (int): time that the session was started. Contains the number
of micro seconds since January 1, 1970, 00:00:00 UTC.
"""
Expand All @@ -64,6 +66,7 @@ def __init__(self):
self.preferred_year = None
self.product_name = 'plaso'
self.product_version = plaso.__version__
self.source_configurations = None
self.start_time = int(time.time() * 1000000)

def CopyAttributesFromSessionCompletion(self, session_completion):
Expand Down Expand Up @@ -94,25 +97,62 @@ def CopyAttributesFromSessionCompletion(self, session_completion):
if session_completion.parsers_counter:
self.parsers_counter = session_completion.parsers_counter

def CopyAttributesFromSessionConfiguration(self, session_configuration):
"""Copies attributes from a session configuration.
Args:
session_configuration (SessionConfiguration): session configuration
attribute container.
Raises:
ValueError: if the identifier of the session configuration does not match
that of the session.
"""
if self.identifier != session_configuration.identifier:
raise ValueError('Session identifier mismatch.')

self.artifact_filters = session_configuration.artifact_filters
self.command_line_arguments = session_configuration.command_line_arguments
self.debug_mode = session_configuration.debug_mode
self.enabled_parser_names = session_configuration.enabled_parser_names
self.filter_file = session_configuration.filter_file
self.parser_filter_expression = (
session_configuration.parser_filter_expression)
self.preferred_encoding = session_configuration.preferred_encoding
self.preferred_time_zone = session_configuration.preferred_time_zone
self.source_configurations = session_configuration.source_configurations

def CopyAttributesFromSessionStart(self, session_start):
"""Copies attributes from a session start.
Args:
session_start (SessionStart): session start attribute container.
"""
self.artifact_filters = session_start.artifact_filters
self.command_line_arguments = session_start.command_line_arguments
self.debug_mode = session_start.debug_mode
self.enabled_parser_names = session_start.enabled_parser_names
self.filter_file = session_start.filter_file
self.identifier = session_start.identifier
self.parser_filter_expression = session_start.parser_filter_expression
self.preferred_encoding = session_start.preferred_encoding
self.preferred_time_zone = session_start.preferred_time_zone
self.product_name = session_start.product_name
self.product_version = session_start.product_version
self.start_time = session_start.timestamp

# The following is for backward compatibility with older session start
# attribute containers.
self.artifact_filters = getattr(
session_start, 'artifact_filters', self.artifact_filters)
self.command_line_arguments = getattr(
session_start, 'command_line_arguments', self.command_line_arguments)
self.debug_mode = getattr(
session_start, 'debug_mode', self.debug_mode)
self.enabled_parser_names = getattr(
session_start, 'enabled_parser_names', self.enabled_parser_names)
self.filter_file = getattr(
session_start, 'filter_file', self.filter_file)
self.parser_filter_expression = getattr(
session_start, 'parser_filter_expression',
self.parser_filter_expression)
self.preferred_encoding = getattr(
session_start, 'preferred_encoding', self.preferred_encoding)
self.preferred_time_zone = getattr(
session_start, 'preferred_time_zone', self.preferred_time_zone)

def CreateSessionCompletion(self):
"""Creates a session completion.
Expand All @@ -130,22 +170,34 @@ def CreateSessionCompletion(self):
session_completion.timestamp = self.completion_time
return session_completion

def CreateSessionConfiguration(self):
"""Creates a session configuration.
Returns:
SessionConfiguration: session configuration attribute container.
"""
session_configuration = SessionConfiguration()
session_configuration.artifact_filters = self.artifact_filters
session_configuration.command_line_arguments = self.command_line_arguments
session_configuration.debug_mode = self.debug_mode
session_configuration.enabled_parser_names = self.enabled_parser_names
session_configuration.filter_file = self.filter_file
session_configuration.identifier = self.identifier
session_configuration.parser_filter_expression = (
self.parser_filter_expression)
session_configuration.preferred_encoding = self.preferred_encoding
session_configuration.preferred_time_zone = self.preferred_time_zone
session_configuration.source_configurations = self.source_configurations
return session_configuration

def CreateSessionStart(self):
"""Creates a session start.
Returns:
SessionStart: session start attribute container.
"""
session_start = SessionStart()
session_start.artifact_filters = self.artifact_filters
session_start.command_line_arguments = self.command_line_arguments
session_start.debug_mode = self.debug_mode
session_start.enabled_parser_names = self.enabled_parser_names
session_start.filter_file = self.filter_file
session_start.identifier = self.identifier
session_start.parser_filter_expression = self.parser_filter_expression
session_start.preferred_encoding = self.preferred_encoding
session_start.preferred_time_zone = self.preferred_time_zone
session_start.product_name = self.product_name
session_start.product_version = self.product_version
session_start.timestamp = self.start_time
Expand Down Expand Up @@ -185,8 +237,13 @@ def __init__(self, identifier=None):
self.timestamp = None


class SessionStart(interface.AttributeContainer):
"""Session start attribute container.
class SessionConfiguration(interface.AttributeContainer):
"""Session configuration attribute container.
The session configuration contains various settings used within a session,
such as parser and collection filters that are used, and information about
the source being processed, such as the system configuration determined by
pre-processing.
Attributes:
artifact_filters (list[str]): names of artifact definitions that are
Expand All @@ -201,23 +258,20 @@ class SessionStart(interface.AttributeContainer):
preferred_encoding (str): preferred encoding.
preferred_time_zone (str): preferred time zone.
preferred_year (int): preferred year.
product_name (str): name of the product that created the session for
example "log2timeline".
product_version (str): version of the product that created the session.
timestamp (int): time that the session was started. Contains the number
of micro seconds since January 1, 1970, 00:00:00 UTC.
source_configurations (list[SourceConfiguration]): configuration of sources
that are (or going to be) processed.
"""
CONTAINER_TYPE = 'session_start'
CONTAINER_TYPE = 'session_configuration'

def __init__(self, identifier=None):
"""Initializes a session start attribute container.
"""Initializes a session configuration attribute container.
Args:
identifier (Optional[str]): unique identifier of the session.
The identifier should match that of the corresponding
session completion information.
session start information.
"""
super(SessionStart, self).__init__()
super(SessionConfiguration, self).__init__()
self.artifact_filters = None
self.command_line_arguments = None
self.debug_mode = False
Expand All @@ -228,10 +282,36 @@ def __init__(self, identifier=None):
self.preferred_encoding = None
self.preferred_time_zone = None
self.preferred_year = None
self.source_configurations = None


class SessionStart(interface.AttributeContainer):
"""Session start attribute container.
Attributes:
identifier (str): unique identifier of the session.
product_name (str): name of the product that created the session for
example "log2timeline".
product_version (str): version of the product that created the session.
timestamp (int): time that the session was started. Contains the number
of micro seconds since January 1, 1970, 00:00:00 UTC.
"""
CONTAINER_TYPE = 'session_start'

def __init__(self, identifier=None):
"""Initializes a session start attribute container.
Args:
identifier (Optional[str]): unique identifier of the session.
The identifier should match that of the corresponding
session completion information.
"""
super(SessionStart, self).__init__()
self.identifier = identifier
self.product_name = None
self.product_version = None
self.timestamp = None


manager.AttributeContainersManager.RegisterAttributeContainers([
Session, SessionCompletion, SessionStart])
Session, SessionCompletion, SessionConfiguration, SessionStart])
26 changes: 22 additions & 4 deletions plaso/serializer/json_serializer.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
"""The json serializer object implementation."""
"""The JSON serializer object implementation."""

from __future__ import unicode_literals

Expand All @@ -18,7 +18,19 @@


class JSONAttributeContainerSerializer(interface.AttributeContainerSerializer):
"""Class that implements the json attribute container serializer."""
"""JSON attribute container serializer."""

# Backwards compatibility for older session attribute containers that
# contain session configuration attributes.
_SESSION_START_LEGACY_ATTRIBUTE_NAMES = frozenset([
'artifact_filters',
'command_line_arguments',
'debug_mode',
'enabled_parser_names',
'filter_file',
'parser_filter_expression',
'preferred_encoding',
'preferred_time_zone'])

@classmethod
def _ConvertAttributeContainerToDict(cls, attribute_container):
Expand Down Expand Up @@ -227,10 +239,16 @@ def _ConvertDictToObject(cls, json_dict):
attribute_name == 'event_row_identifier'):
attribute_name = '_event_row_identifier'

# Backwards compatibility for older session attribute containers that
# contain session configuration attributes.
if (container_type == 'session_start' and
attribute_name in cls._SESSION_START_LEGACY_ATTRIBUTE_NAMES):
pass

# Be strict about which attributes to set in non event data attribute
# containers.
if (container_type != 'event_data' and
attribute_name not in supported_attribute_names):
elif (container_type != 'event_data' and
attribute_name not in supported_attribute_names):

if attribute_name not in ('__container_type__', '__type__'):
logger.debug((
Expand Down
13 changes: 13 additions & 0 deletions tests/containers/artifacts.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,19 @@ def testGetAttributeNames(self):
self.assertEqual(attribute_names, expected_attribute_names)


class SourceConfigurationArtifactTest(shared_test_lib.BaseTestCase):
"""Tests for the source configuration artifact."""

def testGetAttributeNames(self):
"""Tests the GetAttributeNames function."""
attribute_container = artifacts.SourceConfigurationArtifact()

expected_attribute_names = ['path_spec', 'system_configuration']

attribute_names = sorted(attribute_container.GetAttributeNames())
self.assertEqual(attribute_names, expected_attribute_names)


class SystemConfigurationArtifactTest(shared_test_lib.BaseTestCase):
"""Tests for the system configuration artifact."""

Expand Down
Loading

0 comments on commit 95fd0f1

Please sign in to comment.