def ParseRecord(self, parser_mediator, key, structure): """Parses a matching entry. Args: parser_mediator (ParserMediator): mediates interactions between parsers and other components, such as storage and dfvfs. key (str): name of the parsed structure. structure (pyparsing.ParseResults): elements parsed from the file. Raises: ParseError: when the structure type is unknown. """ if key not in self._SUPPORTED_KEYS: raise errors.ParseError( 'Unable to parse record, unknown structure: {0:s}'.format(key)) if key in ('chromeos_syslog_line', 'rsyslog_line'): date_time = dfdatetime_time_elements.TimeElementsInMicroseconds() iso8601_string = self._GetValueFromStructure(structure, 'datetime') try: date_time.CopyFromStringISO8601(iso8601_string) except ValueError: parser_mediator.ProduceExtractionWarning( 'invalid date time value: {0:s}'.format(iso8601_string)) return else: # TODO: add support for fractional seconds. month = self._GetValueFromStructure(structure, 'month') try: month = timelib.MONTH_DICT.get(month.lower(), 0) except AttributeError: parser_mediator.ProduceExtractionWarning( 'invalid month value: {0!s}'.format(month)) return if month != 0: self._UpdateYear(parser_mediator, month) day = self._GetValueFromStructure(structure, 'day') hours = self._GetValueFromStructure(structure, 'hour') minutes = self._GetValueFromStructure(structure, 'minute') seconds = self._GetValueFromStructure(structure, 'second') time_elements_tuple = (self._year_use, month, day, hours, minutes, seconds) try: date_time = dfdatetime_time_elements.TimeElements( time_elements_tuple=time_elements_tuple) date_time.is_local_time = True except ValueError: parser_mediator.ProduceExtractionWarning( 'invalid date time value: {0!s}'.format( time_elements_tuple)) return plugin = None if key == 'syslog_comment': event_data = SyslogCommentEventData() event_data.body = self._GetValueFromStructure(structure, 'body') # TODO: pass line number to offset or remove. event_data.offset = 0 else: event_data = SyslogLineEventData() event_data.body = self._GetValueFromStructure(structure, 'body') event_data.hostname = self._GetValueFromStructure( structure, 'hostname') # TODO: pass line number to offset or remove. event_data.offset = 0 event_data.pid = self._GetValueFromStructure(structure, 'pid') event_data.reporter = self._GetValueFromStructure( structure, 'reporter') event_data.severity = self._GetValueFromStructure( structure, 'severity') plugin = self._plugin_by_reporter.get(event_data.reporter, None) if plugin: attributes = { 'body': event_data.body, 'hostname': event_data.hostname, 'pid': event_data.pid, 'reporter': event_data.reporter, 'severity': event_data.severity } try: # TODO: pass event_data instead of attributes. plugin.Process(parser_mediator, date_time, attributes) except errors.WrongPlugin: plugin = None if not plugin: event = time_events.DateTimeValuesEvent( date_time, definitions.TIME_DESCRIPTION_WRITTEN, time_zone=parser_mediator.timezone) parser_mediator.ProduceEventWithEventData(event, event_data)
def _ParseContainerConfigJSON(self, parser_mediator, file_object): """Extracts events from a Docker container configuration file. The path of each container config file is: DOCKER_DIR/containers/<container_id>/config.json Args: parser_mediator (ParserMediator): mediates interactions between parsers and other components, such as storage and dfvfs. file_object (dfvfs.FileIO): a file-like object. Raises: UnableToParseFile: when the file is not a valid container config file. """ file_content = file_object.read() file_content = codecs.decode(file_content, self._ENCODING) json_dict = json.loads(file_content) if 'Driver' not in json_dict: raise errors.UnableToParseFile( 'not a valid Docker container configuration file, ' 'missing ' '\'Driver\' key.') container_id_from_path = self._GetIdentifierFromPath(parser_mediator) container_id_from_json = json_dict.get('ID', None) if not container_id_from_json: raise errors.UnableToParseFile( 'not a valid Docker layer configuration file, the \'ID\' key is ' 'missing from the JSON dict (should be {0:s})'.format( container_id_from_path)) if container_id_from_json != container_id_from_path: raise errors.UnableToParseFile( 'not a valid Docker container configuration file. The \'ID\' key of ' 'the JSON dict ({0:s}) is different from the layer ID taken from the' ' path to the file ({1:s}) JSON file.)'.format( container_id_from_json, container_id_from_path)) if 'Config' in json_dict and 'Hostname' in json_dict['Config']: container_name = json_dict['Config']['Hostname'] else: container_name = 'Unknown container name' event_data = DockerJSONContainerEventData() event_data.container_id = container_id_from_path event_data.container_name = container_name json_state = json_dict.get('State', None) if json_state is not None: time_string = json_state.get('StartedAt', None) if time_string is not None: event_data.action = 'Container Started' try: date_time = dfdatetime_time_elements.TimeElementsInMicroseconds( ) date_time.CopyFromStringISO8601(time_string) except ValueError as exception: parser_mediator.ProduceExtractionWarning(( 'Unable to parse container start time string: {0:s} with error: ' '{1!s}').format(time_string, exception)) date_time = dfdatetime_semantic_time.InvalidTime() event = time_events.DateTimeValuesEvent( date_time, definitions.TIME_DESCRIPTION_START) parser_mediator.ProduceEventWithEventData(event, event_data) time_string = json_state.get('FinishedAt', None) if time_string is not None: # If the timestamp is 0001-01-01T00:00:00Z, the container # is still running, so we don't generate a Finished event if time_string != '0001-01-01T00:00:00Z': event_data.action = 'Container Finished' try: date_time = dfdatetime_time_elements.TimeElementsInMicroseconds( ) date_time.CopyFromStringISO8601(time_string) except ValueError as exception: parser_mediator.ProduceExtractionWarning(( 'Unable to parse container finish time string: {0:s} with ' 'error: {1!s}').format(time_string, exception)) date_time = dfdatetime_semantic_time.InvalidTime() event = time_events.DateTimeValuesEvent( date_time, definitions.TIME_DESCRIPTION_END) parser_mediator.ProduceEventWithEventData( event, event_data) time_string = json_dict.get('Created', None) if time_string is not None: event_data.action = 'Container Created' try: date_time = dfdatetime_time_elements.TimeElementsInMicroseconds( ) date_time.CopyFromStringISO8601(time_string) except ValueError as exception: parser_mediator.ProduceExtractionWarning(( 'Unable to parse container created time string: {0:s} with error: ' '{1!s}').format(time_string, exception)) date_time = dfdatetime_semantic_time.InvalidTime() event = time_events.DateTimeValuesEvent( date_time, definitions.TIME_DESCRIPTION_ADDED) parser_mediator.ProduceEventWithEventData(event, event_data)
def GetEntries(self, parser_mediator, match=None, **unused_kwargs): """Extracts relevant BT entries. Args: parser_mediator (ParserMediator): mediates interactions between parsers and other components, such as storage and dfvfs. match (Optional[dict[str: object]]): keys extracted from PLIST_KEYS. """ device_cache = match.get('DeviceCache', {}) for device, value in device_cache.items(): name = value.get('Name', '') if name: name = ''.join(('Name:', name)) event_data = plist_event.PlistTimeEventData() event_data.root = '/DeviceCache' datetime_value = value.get('LastInquiryUpdate', None) if datetime_value: event_data.desc = ' '.join( filter(None, ('Bluetooth Discovery', name))) event_data.key = '{0:s}/LastInquiryUpdate'.format(device) date_time = dfdatetime_time_elements.TimeElementsInMicroseconds( ) date_time.CopyFromDatetime(datetime_value) event = time_events.DateTimeValuesEvent( date_time, definitions.TIME_DESCRIPTION_WRITTEN) parser_mediator.ProduceEventWithEventData(event, event_data) if device in match.get('PairedDevices', []): event_data.desc = 'Paired:True {0:s}'.format(name) event_data.key = device date_time = dfdatetime_time_elements.TimeElementsInMicroseconds( ) date_time.CopyFromDatetime(datetime_value) event = time_events.DateTimeValuesEvent( date_time, definitions.TIME_DESCRIPTION_WRITTEN) parser_mediator.ProduceEventWithEventData( event, event_data) datetime_value = value.get('LastNameUpdate', None) if datetime_value: event_data.desc = ' '.join( filter(None, ('Device Name Set', name))) event_data.key = '{0:s}/LastNameUpdate'.format(device) date_time = dfdatetime_time_elements.TimeElementsInMicroseconds( ) date_time.CopyFromDatetime(datetime_value) event = time_events.DateTimeValuesEvent( date_time, definitions.TIME_DESCRIPTION_WRITTEN) parser_mediator.ProduceEventWithEventData(event, event_data) datetime_value = value.get('LastServicesUpdate', None) if datetime_value: event_data.desc = ' '.join( filter(None, ('Services Updated', name))) event_data.key = '{0:s}/LastServicesUpdate'.format(device) date_time = dfdatetime_time_elements.TimeElementsInMicroseconds( ) date_time.CopyFromDatetime(datetime_value) event = time_events.DateTimeValuesEvent( date_time, definitions.TIME_DESCRIPTION_WRITTEN) parser_mediator.ProduceEventWithEventData(event, event_data)
def testConvertDateTimeValuesToJSON(self): """Test ConvertDateTimeValuesToJSON function.""" posix_time_object = posix_time.PosixTime(timestamp=1281643591) expected_json_dict = { '__class_name__': 'PosixTime', '__type__': 'DateTimeValues', 'timestamp': 1281643591 } json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( posix_time_object) self.assertEqual(json_dict, expected_json_dict) posix_time_object.is_local_time = True expected_json_dict = { '__class_name__': 'PosixTime', '__type__': 'DateTimeValues', 'is_local_time': True, 'timestamp': 1281643591 } json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( posix_time_object) self.assertEqual(json_dict, expected_json_dict) never_time_object = semantic_time.Never() expected_json_dict = { '__class_name__': 'Never', '__type__': 'DateTimeValues', 'string': 'Never' } json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( never_time_object) self.assertEqual(json_dict, expected_json_dict) fat_date_time_object = fat_date_time.FATDateTime( fat_date_time=0xa8d03d0c) expected_json_dict = { '__class_name__': 'FATDateTime', '__type__': 'DateTimeValues', 'fat_date_time': 2832219404 } json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( fat_date_time_object) self.assertEqual(json_dict, expected_json_dict) golang_timestamp = bytes.fromhex('01000000000000000200000003ffff') golang_time_object = golang_time.GolangTime( golang_timestamp=golang_timestamp) expected_json_dict = { '__class_name__': 'GolangTime', '__type__': 'DateTimeValues', 'golang_timestamp': (b'\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\xff\xff'), 'time_zone_offset': 0 } json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( golang_time_object) self.assertEqual(json_dict, expected_json_dict) rfc2579_date_time_object = rfc2579_date_time.RFC2579DateTime( rfc2579_date_time_tuple=(2010, 8, 12, 20, 6, 31, 6, '+', 2, 0)) expected_json_dict = { '__class_name__': 'RFC2579DateTime', '__type__': 'DateTimeValues', 'rfc2579_date_time_tuple': (2010, 8, 12, 20, 6, 31, 6), 'time_zone_offset': 120 } json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( rfc2579_date_time_object) self.assertEqual(json_dict, expected_json_dict) time_elements_object = time_elements.TimeElements( time_elements_tuple=(2010, 8, 12, 20, 6, 31)) expected_json_dict = { '__class_name__': 'TimeElements', '__type__': 'DateTimeValues', 'time_elements_tuple': (2010, 8, 12, 20, 6, 31) } json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( time_elements_object) self.assertEqual(json_dict, expected_json_dict) time_elements_object = time_elements.TimeElementsInMilliseconds( time_elements_tuple=(2010, 8, 12, 20, 6, 31, 546)) expected_json_dict = { '__class_name__': 'TimeElementsInMilliseconds', '__type__': 'DateTimeValues', 'time_elements_tuple': (2010, 8, 12, 20, 6, 31, 546) } json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( time_elements_object) self.assertEqual(json_dict, expected_json_dict) time_elements_object = time_elements.TimeElementsInMicroseconds( time_elements_tuple=(2010, 8, 12, 20, 6, 31, 429876)) expected_json_dict = { '__class_name__': 'TimeElementsInMicroseconds', '__type__': 'DateTimeValues', 'time_elements_tuple': (2010, 8, 12, 20, 6, 31, 429876) } json_dict = serializer.Serializer.ConvertDateTimeValuesToJSON( time_elements_object) self.assertEqual(json_dict, expected_json_dict)
def testCopyFromStringISO8601(self): """Tests the CopyFromStringISO8601 function.""" time_elements_object = time_elements.TimeElementsInMicroseconds() expected_time_elements_tuple = (2010, 8, 12, 0, 0, 0) expected_number_of_seconds = 1281571200 time_elements_object.CopyFromStringISO8601('2010-08-12') self.assertEqual(time_elements_object._time_elements_tuple, expected_time_elements_tuple) self.assertEqual(time_elements_object._number_of_seconds, expected_number_of_seconds) self.assertEqual(time_elements_object.microseconds, 0) expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) expected_number_of_seconds = 1281647191 time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31') self.assertEqual(time_elements_object._time_elements_tuple, expected_time_elements_tuple) self.assertEqual(time_elements_object._number_of_seconds, expected_number_of_seconds) self.assertEqual(time_elements_object.microseconds, 0) expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) expected_number_of_seconds = 1281647191 time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31Z') self.assertEqual(time_elements_object._time_elements_tuple, expected_time_elements_tuple) self.assertEqual(time_elements_object._number_of_seconds, expected_number_of_seconds) self.assertEqual(time_elements_object.microseconds, 0) expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) expected_number_of_seconds = 1281647191 time_elements_object.CopyFromStringISO8601('2010-08-12T21:06:31.5') self.assertEqual(time_elements_object._time_elements_tuple, expected_time_elements_tuple) self.assertEqual(time_elements_object._number_of_seconds, expected_number_of_seconds) self.assertEqual(time_elements_object.microseconds, 500000) expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) expected_number_of_seconds = 1281647191 time_elements_object.CopyFromStringISO8601( '2010-08-12T21:06:31.546875') self.assertEqual(time_elements_object._time_elements_tuple, expected_time_elements_tuple) self.assertEqual(time_elements_object._number_of_seconds, expected_number_of_seconds) self.assertEqual(time_elements_object.microseconds, 546875) expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) expected_number_of_seconds = 1281647191 time_elements_object.CopyFromStringISO8601( '2010-08-12T21:06:31,546875') self.assertEqual(time_elements_object._time_elements_tuple, expected_time_elements_tuple) self.assertEqual(time_elements_object._number_of_seconds, expected_number_of_seconds) self.assertEqual(time_elements_object.microseconds, 546875) expected_time_elements_tuple = (2012, 3, 5, 20, 40, 0) expected_number_of_seconds = 1330980000 time_elements_object.CopyFromStringISO8601( '2012-03-05T20:40:00.0000000Z') self.assertEqual(time_elements_object._time_elements_tuple, expected_time_elements_tuple) self.assertEqual(time_elements_object._number_of_seconds, expected_number_of_seconds) self.assertEqual(time_elements_object.microseconds, 0) expected_time_elements_tuple = (2010, 8, 12, 22, 6, 31) expected_number_of_seconds = 1281650791 time_elements_object.CopyFromStringISO8601( '2010-08-12T21:06:31.546875-01:00') self.assertEqual(time_elements_object._time_elements_tuple, expected_time_elements_tuple) self.assertEqual(time_elements_object._number_of_seconds, expected_number_of_seconds) self.assertEqual(time_elements_object.microseconds, 546875) expected_time_elements_tuple = (2010, 8, 12, 20, 6, 31) expected_number_of_seconds = 1281643591 time_elements_object.CopyFromStringISO8601( '2010-08-12T21:06:31.546875+01:00') self.assertEqual(time_elements_object._time_elements_tuple, expected_time_elements_tuple) self.assertEqual(time_elements_object._number_of_seconds, expected_number_of_seconds) self.assertEqual(time_elements_object.microseconds, 546875) with self.assertRaises(ValueError): time_elements_object.CopyFromStringISO8601(None) with self.assertRaises(ValueError): time_elements_object.CopyFromStringISO8601( '2010-08-12 21:06:31.546875+01:00') # Valid ISO 8601 notations currently not supported. with self.assertRaises(ValueError): time_elements_object.CopyFromStringISO8601('2016-W33') with self.assertRaises(ValueError): time_elements_object.CopyFromStringISO8601('2016-W33-3') with self.assertRaises(ValueError): time_elements_object.CopyFromStringISO8601('--08-17') with self.assertRaises(ValueError): time_elements_object.CopyFromStringISO8601('2016-230')
def testCopyFromDateTimeString(self): """Tests the CopyFromDateTimeString function.""" time_elements_object = time_elements.TimeElementsInMicroseconds() expected_time_elements_tuple = (2010, 8, 12, 0, 0, 0) expected_number_of_seconds = 1281571200 time_elements_object.CopyFromDateTimeString('2010-08-12') self.assertEqual(time_elements_object._time_elements_tuple, expected_time_elements_tuple) self.assertEqual(time_elements_object._number_of_seconds, expected_number_of_seconds) self.assertEqual(time_elements_object.microseconds, 0) expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) expected_number_of_seconds = 1281647191 time_elements_object.CopyFromDateTimeString('2010-08-12 21:06:31') self.assertEqual(time_elements_object._time_elements_tuple, expected_time_elements_tuple) self.assertEqual(time_elements_object._number_of_seconds, expected_number_of_seconds) self.assertEqual(time_elements_object.microseconds, 0) expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) expected_number_of_seconds = 1281647191 time_elements_object.CopyFromDateTimeString( '2010-08-12 21:06:31.546875') self.assertEqual(time_elements_object._time_elements_tuple, expected_time_elements_tuple) self.assertEqual(time_elements_object._number_of_seconds, expected_number_of_seconds) self.assertEqual(time_elements_object.microseconds, 546875) expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) expected_number_of_seconds = 1281650791 time_elements_object.CopyFromDateTimeString( '2010-08-12 21:06:31.546875-01:00') self.assertEqual(time_elements_object._time_elements_tuple, expected_time_elements_tuple) self.assertEqual(time_elements_object._number_of_seconds, expected_number_of_seconds) self.assertEqual(time_elements_object.microseconds, 546875) self.assertEqual(time_elements_object.time_zone_offset, -60) expected_time_elements_tuple = (2010, 8, 12, 21, 6, 31) expected_number_of_seconds = 1281643591 time_elements_object.CopyFromDateTimeString( '2010-08-12 21:06:31.546875+01:00') self.assertEqual(time_elements_object._time_elements_tuple, expected_time_elements_tuple) self.assertEqual(time_elements_object._number_of_seconds, expected_number_of_seconds) self.assertEqual(time_elements_object.microseconds, 546875) self.assertEqual(time_elements_object.time_zone_offset, 60) expected_time_elements_tuple = (1601, 1, 2, 0, 0, 0) expected_number_of_seconds = -11644387200 time_elements_object.CopyFromDateTimeString('1601-01-02 00:00:00') self.assertEqual(time_elements_object._time_elements_tuple, expected_time_elements_tuple) self.assertEqual(time_elements_object._number_of_seconds, expected_number_of_seconds) self.assertEqual(time_elements_object.microseconds, 0)