def testMatch(self): """Tests the Match function.""" test_filter = event_filter.EventObjectFilter() test_filter.CompileFilter( 'timestamp is DATETIME("2020-12-23T15:00:00")') event = events.EventObject() event.timestamp = 1608735600000000 result = test_filter.Match(event, None, None, None) self.assertTrue(result) test_filter = event_filter.EventObjectFilter() test_filter.CompileFilter('filename contains PATH("etc/issue")') event_data = events.EventData() event_data.filename = '/usr/local/etc/issue' result = test_filter.Match(None, event_data, None, None) self.assertTrue(result) event_data.filename = '/etc/issue.net' result = test_filter.Match(None, event_data, None, None) self.assertFalse(result)
def testCompilerFilter(self): """Tests the CompileFilter function.""" test_filter = event_filter.EventObjectFilter() test_filter.CompileFilter( 'some_stuff is "random" and other_stuff is not "random"') test_filter.CompileFilter('timestamp is "2020-12-23 15:00:00"') test_filter.CompileFilter( 'timestamp is DATETIME("2020-12-23T15:00:00")') test_filter.CompileFilter('filename contains PATH("/etc/issue")') with self.assertRaises(errors.ParseError): test_filter.CompileFilter( 'SELECT stuff FROM machine WHERE conditions are met') with self.assertRaises(errors.ParseError): test_filter.CompileFilter( '/tmp/file_that_most_likely_does_not_exist') with self.assertRaises(errors.ParseError): test_filter.CompileFilter( 'some random stuff that is destined to fail') with self.assertRaises(errors.ParseError): test_filter.CompileFilter( 'some_stuff is "random" and other_stuff ')
def GetEventTaggingRules(self): """Retrieves the event tagging rules from the tagging file. Returns: dict[str, EventObjectFilter]: tagging rules, that consists of one or more filter objects per label. Raises: TaggingFileError: if a filter expression cannot be compiled. """ rules_per_label = {} label_name = None with io.open(self._path, 'r', encoding='utf-8') as tagging_file: for line in tagging_file.readlines(): line = line.rstrip() stripped_line = line.lstrip() if not stripped_line: label_name = None continue if stripped_line[0] == '#': continue if not line[0].isspace(): label_name = line rules_per_label[label_name] = [] elif label_name: rules_per_label[label_name].append(stripped_line) filter_objects_per_label = {} for label_name, rules in rules_per_label.items(): filter_object = event_filter.EventObjectFilter() try: filter_rule = ' OR '.join(['({0:s})'.format(rule) for rule in rules]) filter_object.CompileFilter(filter_rule) except errors.ParseError as exception: raise errors.TaggingFileError(( 'Unable to compile filter for label: {0:s} with error: ' '{1!s}').format(label_name, exception)) # TODO: change other code remove list around filter_object filter_objects_per_label[label_name] = [filter_object] return filter_objects_per_label
def _ParseFilterOptions(self, options): """Parses the filter options. Args: options (argparse.Namespace): command line arguments. Raises: BadConfigOption: if the options are invalid. """ self._event_filter_expression = self.ParseStringOption( options, 'filter') if self._event_filter_expression: self._event_filter = event_filter.EventObjectFilter() try: self._event_filter.CompileFilter(self._event_filter_expression) except errors.ParseError as exception: raise errors.BadConfigOption( ('Unable to compile filter expression with error: ' '{0!s}').format(exception)) time_slice_event_time_string = getattr(options, 'slice', None) time_slice_duration = getattr(options, 'slice_size', 5) self._use_time_slicer = getattr(options, 'slicer', False) # The slice and slicer cannot be set at the same time. if time_slice_event_time_string and self._use_time_slicer: raise errors.BadConfigOption( 'Time slice and slicer cannot be used at the same time.') time_slice_event_timestamp = None if time_slice_event_time_string: # Note self._preferred_time_zone is None when not set but represents UTC. preferred_time_zone = self._preferred_time_zone or 'UTC' timezone = pytz.timezone(preferred_time_zone) time_slice_event_timestamp = timelib.Timestamp.FromTimeString( time_slice_event_time_string, timezone=timezone) if time_slice_event_timestamp is None: raise errors.BadConfigOption( 'Unsupported time slice event date and time: {0:s}'.format( time_slice_event_time_string)) if time_slice_event_timestamp is not None or self._use_time_slicer: # Note that time slicer uses the time slice to determine the duration. self._time_slice = time_slices.TimeSlice( time_slice_event_timestamp, duration=time_slice_duration)
def GetEventTaggingRules(self): """Retrieves the event tagging rules from the tagging file. Returns: dict[str, FilterObject]: tagging rules, that consists of one or more filter objects per label. Raises: TaggingFileError: if a filter expression cannot be compiled. """ tagging_rules = {} label_name = None with io.open(self._path, 'r', encoding='utf-8') as tagging_file: for line in tagging_file.readlines(): line = line.rstrip() stripped_line = line.lstrip() if not stripped_line or stripped_line[0] == '#': continue if not line[0].isspace(): label_name = line tagging_rules[label_name] = [] continue if not label_name: continue filter_object = event_filter.EventObjectFilter() try: filter_object.CompileFilter(stripped_line) except errors.ParseError as exception: raise errors.TaggingFileError(( 'Unable to compile filter for label: {0:s} with error: ' '{1!s}').format(label_name, exception)) if filter_object not in tagging_rules[label_name]: tagging_rules[label_name].append(filter_object) return tagging_rules
def testCompilerFilter(self): """Tests the CompileFilter function.""" test_filter = event_filter.EventObjectFilter() test_filter.CompileFilter( 'some_stuff is "random" and other_stuff is not "random"') with self.assertRaises(errors.ParseError): test_filter.CompileFilter( 'SELECT stuff FROM machine WHERE conditions are met') with self.assertRaises(errors.ParseError): test_filter.CompileFilter( '/tmp/file_that_most_likely_does_not_exist') with self.assertRaises(errors.ParseError): test_filter.CompileFilter( 'some random stuff that is destined to fail') with self.assertRaises(errors.ParseError): test_filter.CompileFilter( 'some_stuff is "random" and other_stuff ')
def ParseOptions(cls, options, configuration_object): """Parses and validates options. Args: options (argparse.Namespace): parser options. configuration_object (CLITool): object to be configured by the argument helper. Raises: BadConfigObject: when the configuration object is of the wrong type. BadConfigOption: when a configuration parameter fails validation. """ if not isinstance(configuration_object, tools.CLITool): raise errors.BadConfigObject( 'Configuration object is not an instance of CLITool') filter_expression = cls._ParseStringOption(options, 'filter') filter_object = None if filter_expression: filter_object = event_filter.EventObjectFilter() try: filter_object.CompileFilter(filter_expression) except errors.ParseError as exception: raise errors.BadConfigOption( ('Unable to compile filter expression with error: ' '{0!s}').format(exception)) time_slice_event_time_string = getattr(options, 'slice', None) time_slice_duration = getattr(options, 'slice_size', 5) use_time_slicer = getattr(options, 'slicer', False) # The slice and slicer cannot be set at the same time. if time_slice_event_time_string and use_time_slicer: raise errors.BadConfigOption( 'Time slice and slicer cannot be used at the same time.') time_slice_event_timestamp = None if time_slice_event_time_string: # Note self._preferred_time_zone is None when not set but represents UTC. preferred_time_zone = getattr( configuration_object, '_preferred_time_zone', None) or 'UTC' timezone = pytz.timezone(preferred_time_zone) time_slice_event_timestamp = timelib.Timestamp.FromTimeString( time_slice_event_time_string, timezone=timezone) if time_slice_event_timestamp is None: raise errors.BadConfigOption( 'Unsupported time slice event date and time: {0:s}'.format( time_slice_event_time_string)) setattr(configuration_object, '_event_filter_expression', filter_expression) if filter_object: setattr(configuration_object, '_event_filter', filter_object) setattr(configuration_object, '_use_time_slicer', use_time_slicer) if time_slice_event_timestamp is not None or use_time_slicer: # Note that time slicer uses the time slice to determine the duration. # TODO: refactor TimeSlice to filters. time_slice = time_slices.TimeSlice(time_slice_event_timestamp, duration=time_slice_duration) setattr(configuration_object, '_time_slice', time_slice)
def ParseOptions(cls, options, configuration_object): """Parses and validates options. Args: options (argparse.Namespace): parser options. configuration_object (CLITool): object to be configured by the argument helper. Raises: BadConfigObject: when the configuration object is of the wrong type. BadConfigOption: when a configuration parameter fails validation. """ if not isinstance(configuration_object, tools.CLITool): raise errors.BadConfigObject( 'Configuration object is not an instance of CLITool') filter_expression = cls._ParseStringOption(options, 'filter') filter_object = None if filter_expression: filter_object = event_filter.EventObjectFilter() try: filter_object.CompileFilter(filter_expression) except errors.ParseError as exception: raise errors.BadConfigOption( ('Unable to compile filter expression with error: ' '{0!s}').format(exception)) time_slice_event_time_string = getattr(options, 'slice', None) time_slice_duration = getattr(options, 'slice_size', 5) use_time_slicer = getattr(options, 'slicer', False) # The slice and slicer cannot be set at the same time. if time_slice_event_time_string and use_time_slicer: raise errors.BadConfigOption( 'Time slice and slicer cannot be used at the same time.') time_slice_event_timestamp = None if time_slice_event_time_string: if ' ' in time_slice_event_time_string: raise errors.BadConfigOption( 'Time slice date and time must be defined in ISO 8601 format, ' 'for example: 20200619T20:09:23+02:00.') date_time = dfdatetime_time_elements.TimeElements() try: date_time.CopyFromStringISO8601(time_slice_event_time_string) except ValueError: raise errors.BadConfigOption(( 'Unsupported time slice date and time: {0:s}. The date and time ' 'must be defined in ISO 8601 format, for example: ' '20200619T20:09:23+02:00' ).format(time_slice_event_time_string)) # TODO: directly use dfDateTime objects in time slice. time_slice_event_timestamp = date_time.GetPlasoTimestamp() setattr(configuration_object, '_event_filter_expression', filter_expression) if filter_object: setattr(configuration_object, '_event_filter', filter_object) setattr(configuration_object, '_use_time_slicer', use_time_slicer) if time_slice_event_timestamp is not None or use_time_slicer: # Note that time slicer uses the time slice to determine the duration. # TODO: refactor TimeSlice to filters. time_slice = time_slices.TimeSlice(time_slice_event_timestamp, duration=time_slice_duration) setattr(configuration_object, '_time_slice', time_slice)