Example #1
0
    def _ConvertToTimestamp(self, date, time, timezone):
        """Converts date and time values into a timestamp.

    The date and time are made up of two strings, the date and the time,
    separated by a tab. The time is in local time. The month and day can
    be either 1 or 2 characters long, e.g.: 7/30/2013\\t10:22:48 AM

    Args:
      date (str): date.
      time (str): time.
      timezone (pytz.timezone): timezone of the date and time.

    Returns:
      int: a timestamp integer containing the number of micro seconds since
          January 1, 1970, 00:00:00 UTC.

    Raises:
      TimestampError: if the timestamp is badly formed or unable to transfer
          the supplied date and time into a timestamp.
    """
        # TODO: check if this is correct, likely not date or not time
        # is more accurate.
        if not date and not time:
            raise errors.TimestampError(
                'Unable to extract timestamp from McAfee AV logline.')

        # TODO: Figure out how McAfee sets Day First and use that here.
        # The in-file time format is '07/30/2013\t10:22:48 AM'.
        try:
            time_string = '{0:s} {1:s}'.format(date, time)
        except UnicodeDecodeError:
            raise errors.TimestampError('Unable to form a timestamp string.')

        return timelib.Timestamp.FromTimeString(time_string, timezone=timezone)
Example #2
0
    def ParseLine(self, parser_mediator):
        """Return an event object extracted from the current line.

    Args:
      parser_mediator: a parser mediator object (instance of ParserMediator).

    Raises:
      TimestampError: if time is not defined or invalid.
    """
        if not self.attributes[u'time']:
            raise errors.TimestampError(
                u'Unable to parse log line: {0:s} - missing time.'.format(
                    self.PrintLine()))

        if not self.attributes[u'iyear']:
            raise errors.TimestampError(
                u'Unable to parse log line: {0:s} - missing year.'.format(
                    self.PrintLine()))

        times = self.attributes[u'time'].split(u':')
        if self.local_zone:
            timezone = parser_mediator.timezone
        else:
            timezone = pytz.UTC

        if len(times) < 3:
            raise errors.TimestampError(
                u'Unable to parse log line - unsupported format: {0:s}'.format(
                    self.PrintLine()))
        try:
            secs = times[2].split('.')
            if len(secs) == 2:
                sec, us = secs
            else:
                sec = times[2]
                us = 0

            timestamp = timelib.Timestamp.FromTimeParts(
                int(self.attributes[u'iyear']),
                self.attributes[u'imonth'],
                self.attributes[u'iday'],
                int(times[0]),
                int(times[1]),
                int(sec),
                microseconds=int(us),
                timezone=timezone)

        except ValueError as exception:
            raise errors.TimestampError(
                u'Unable to parse log line: {0:s} with error: {1:s}'.format(
                    self.PrintLine(), exception))

        event_object = self.CreateEvent(timestamp,
                                        getattr(self, u'entry_offset', 0),
                                        self.attributes)
        parser_mediator.ProduceEvent(event_object)
Example #3
0
    def ParseRecord(self, parser_mediator, key, structure):
        """Parse the record and return an SCCM log event object.

    Args:
      parser_mediator: A parser mediator object (instance of ParserMediator).
      key: An identification string indicating the name of the parsed
           structure.
      structure: A pyparsing.ParseResults object from a line in the
                 log file.

    Raises:
      TimestampError: when a non-int value for microseconds is encountered.
    """
        # Sometimes, SCCM logs will exhibit a seven-digit sub-second precision
        # (100 nanosecond intervals). Using six-digit precision because
        # timestamps are in microseconds.
        if len(structure.microsecond) > 6:
            structure.microsecond = structure.microsecond[0:6]

        try:
            microsecond = int(structure.microsecond, 10)
        except ValueError:
            raise errors.TimestampError(
                u'Unable to read number of microseconds value.')

        # 3-digit precision is milliseconds,
        # so multiply by 1000 to convert to microseconds
        if len(structure.microsecond) == 3:
            microsecond = microsecond * 1000

        timestamp = timelib.Timestamp.FromTimeParts(year=structure.year,
                                                    month=structure.month,
                                                    day=structure.day,
                                                    hour=structure.hour,
                                                    minutes=structure.minute,
                                                    seconds=structure.second,
                                                    microseconds=microsecond)

        # If an offset is given for the event, apply the offset to convert to UTC.
        if u'offset' in key:
            try:
                delta_microseconds = int(structure.utc_offset_minutes[1:], 10)
            except (IndexError, ValueError):
                raise errors.TimestampError(
                    u'Unable to parse minute offset from UTC.')

            delta_microseconds *= self._MICRO_SECONDS_PER_MINUTE
            if structure.utc_offset_minutes[0] == u'-':
                delta_microseconds = -delta_microseconds
            timestamp += delta_microseconds

        event_object = SCCMLogEvent(timestamp, 0, structure)
        parser_mediator.ProduceEvent(event_object)
Example #4
0
  def FromSystemtime(cls, systemtime):
    """Converts a SYSTEMTIME structure into a timestamp.

    The SYSTEMTIME structure is a 128-bit struct containing 8 little endian
    16-bit integers structured like so:
      struct {
        WORD year,
        WORD month,
        WORD day_of_week,
        WORD day,
        WORD hour,
        WORD minute,
        WORD second,
        WORD millisecond
      }

    Args:
      systemtime (bytes): 128-bit SYSTEMTIME timestamp value.

    Returns:
      int: timestamp, which contains the number of micro seconds since
          January 1, 1970, 00:00:00 UTC or 0 on error.
    """
    try:
      timestamp = cls.SYSTEMTIME_STRUCT.parse(systemtime)
    except construct.ConstructError as exception:
      raise errors.TimestampError(
          u'Unable to create timestamp from {0:s} with error: {1:s}'.format(
              systemtime, exception))
    return cls.FromTimeParts(
        year=timestamp.year, month=timestamp.month,
        day=timestamp.day, hour=timestamp.hour,
        minutes=timestamp.minutes, seconds=timestamp.seconds,
        microseconds=(
            timestamp.milliseconds * cls.MILLI_SECONDS_TO_MICRO_SECONDS))
Example #5
0
    def _GetTimestampFromEntry(self, structure):
        """Parses a timestamp from a TIME entry structure.

    Args:
      structure: TIME entry structure:
                 year: String with the number of the year.
                 month: String with the number of the month.
                 day: String with the number of the day.
                 hour: String with the number of the month.
                 minute: String with the number of the minute.
                 second: String with the number of the second.

    Returns:
      The timestamp which is an integer containing the number of micro seconds
      since January 1, 1970, 00:00:00 UTC.

    Raises:
      TimestampError: if the timestamp cannot be created from the date and
                      time values.
    """
        try:
            year = int(structure.year, 10)
            month = int(structure.month, 10)
            day = int(structure.day, 10)
            hours = int(structure.hour, 10)
            minutes = int(structure.minute, 10)
            seconds = int(structure.second, 10)
        except ValueError:
            raise errors.TimestampError(
                u'Invalid keychain time {0!s}'.format(structure))

        return timelib.Timestamp.FromTimeParts(year, month, day, hours,
                                               minutes, seconds)
Example #6
0
    def _ConvertToTimestamp(self, structure, timezone, year=0):
        """Converts date and time values into a timestamp.

    Args:
      structure: a log line structure (instance of pyparsing.ParseResults)
                 that contains the log header.
      timezone: The timezone object.
      year: Optional current year.

    Returns:
      The timestamp which is an integer containing the number of micro seconds
      since January 1, 1970, 00:00:00 UTC.

    Raises:
      TimestampError: if the timestamp cannot be created from the date and
                      time values.
    """
        month = timelib.MONTH_DICT.get(structure.month_name.lower(), None)
        if not month:
            raise errors.TimestampError(u'Unsupport month name: {0:s}'.format(
                structure.month_name))

        hour, minute, second = structure.time
        if not year:
            # This condition could happen when parsing the header line: if unable
            # to get a valid year, returns a '0' timestamp, thus preventing any
            # log line parsing (since xchat_year is unset to '0') until a new good
            # (it means supported) header with a valid year information is found.
            # TODO: reconsider this behaviour.
            year = structure.get(u'year', 0)
            if not year:
                raise errors.TimestampError(u'Missing year.')

            self._xchat_year = year

        day = structure.get(u'day', 0)
        return timelib.Timestamp.FromTimeParts(year,
                                               month,
                                               day,
                                               hour,
                                               minute,
                                               second,
                                               timezone=timezone)
Example #7
0
    def FromTimeString(cls,
                       time_string,
                       dayfirst=False,
                       gmt_as_timezone=True,
                       timezone=pytz.UTC):
        """Converts a string containing a date and time value into a timestamp.

    Args:
      time_string: String that contains a date and time value.
      dayfirst: An optional boolean argument. If set to true then the
                parser will change the precedence in which it parses timestamps
                from MM-DD-YYYY to DD-MM-YYYY (and YYYY-MM-DD will be
                YYYY-DD-MM, etc).
      gmt_as_timezone: Sometimes the dateutil parser will interpret GMT and UTC
                       the same way, that is not make a distinction. By default
                       this is set to true, that is GMT can be interpreted
                       differently than UTC. If that is not the expected result
                       this attribute can be set to false.
      timezone: Optional timezone object (instance of pytz.timezone) that
                the data and time value in the string represents. This value
                is used when the timezone cannot be determined from the string.

    Returns:
      The timestamp which is an integer containing the number of micro seconds
      since January 1, 1970, 00:00:00 UTC or 0 on error.

    Raises:
      TimestampError: if the time string could not be parsed.
    """
        if not gmt_as_timezone and time_string.endswith(' GMT'):
            time_string = '{0:s}UTC'.format(time_string[:-3])

        try:
            # TODO: deprecate the use of dateutil parser.
            datetime_object = dateutil.parser.parse(time_string,
                                                    dayfirst=dayfirst)

        except (TypeError, ValueError) as exception:
            raise errors.TimestampError((
                'Unable to convert time string: {0:s} in to a datetime object '
                'with error: {1!s}').format(time_string, exception))

        if datetime_object.tzinfo:
            datetime_object = datetime_object.astimezone(pytz.UTC)
        else:
            datetime_object = timezone.localize(datetime_object)

        posix_time = int(calendar.timegm(datetime_object.utctimetuple()))
        timestamp = posix_time * definitions.MICROSECONDS_PER_SECOND
        return timestamp + datetime_object.microsecond
Example #8
0
  def _GetTimestamp(self, date, time, timezone):
    """Determines a timestamp from the time string.

    The date and time are made up of two strings, the date and the time,
    separated by a tab. The time is in local time. The month and day can
    be either 1 or 2 characters long, e.g.: 7/30/2013\\t10:22:48 AM

    Args:
      date: the string representing the date.
      time: the string representing the time.
      timezone: timezone (instance of pytz.timezone) that the data and time
                values represent.

    Returns:
      The timestamp time value. The timestamp contains the number of
      microseconds since Jan 1, 1970 00:00:00 UTC or None if the time string
      could not be parsed.

    Raises:
      TimestampError: if the timestamp is badly formed or unable to transfer
                      the supplied date and time into a timestamp.
    """
    # TODO: check if this is correct, likely not date or not time
    # is more accurate.
    if not (date and time):
      raise errors.TimestampError(
          u'Unable to extract timestamp from McAfee AV logline.')

    # TODO: Figure out how McAfee sets Day First and use that here.
    # The in-file time format is '07/30/2013\t10:22:48 AM'.
    try:
      time_string = u'{0:s} {1:s}'.format(date, time)
    except UnicodeDecodeError:
      raise errors.TimestampError(u'Unable to form a timestamp string.')

    return timelib.Timestamp.FromTimeString(time_string, timezone=timezone)
Example #9
0
    def FromTimeParts(cls,
                      year,
                      month,
                      day,
                      hour,
                      minutes,
                      seconds,
                      microseconds=0,
                      timezone=pytz.UTC):
        """Converts a list of time entries to a timestamp.

    Args:
      year: An integer representing the year.
      month: An integer between 1 and 12.
      day: An integer representing the number of day in the month.
      hour: An integer representing the hour, 0 <= hour < 24.
      minutes: An integer, 0 <= minute < 60.
      seconds: An integer, 0 <= second < 60.
      microseconds: Optional number of microseconds ranging from:
                    0 <= microsecond < 1000000.
      timezone: Optional timezone (instance of pytz.timezone).

    Returns:
      The timestamp which is an integer containing the number of micro seconds
      since January 1, 1970, 00:00:00 UTC or 0 on error.

    Raises:
      TimestampError: if the timestamp cannot be created from the time parts.
    """
        try:
            date = datetime.datetime(year, month, day, hour, minutes, seconds,
                                     microseconds)
        except ValueError as exception:
            raise errors.TimestampError(
                (u'Unable to create timestamp from {0:04d}-{1:02d}-{2:02d} '
                 u'{3:02d}:{4:02d}:{5:02d}.{6:06d} with error: {7:s}').format(
                     year, month, day, hour, minutes, seconds, microseconds,
                     exception))

        if isinstance(timezone, py2to3.STRING_TYPES):
            timezone = pytz.timezone(timezone)

        date_use = timezone.localize(date)
        posix_time = int(calendar.timegm(date_use.utctimetuple()))

        return cls.FromPosixTime(posix_time) + microseconds
Example #10
0
  def ParseLine(self, parser_mediator):
    """Parse a single line from the SELinux audit file.

    This method extends the one from TextParser slightly, creating a
    SELinux event with the timestamp (UTC) taken from log entries.

    Args:
      parser_mediator: A parser mediator object (instance of ParserMediator).

    Raises:
      TimestampError: if timestamp is not defined.
    """
    if not self.timestamp:
      raise errors.TimestampError(
          u'Unable to parse log line - missing timestamp.')

    offset = getattr(self, u'entry_offset', 0)
    event_object = SELinuxLineEvent(self.timestamp, offset, self.attributes)
    parser_mediator.ProduceEvent(event_object)
    self.timestamp = 0
Example #11
0
  def _CreateDateTime(self, date_string, time_string):
    """Creates a date time value from the date time strings.

    The format stores the date and time as 2 separate strings separated by
    a tab. The time is in local time. The month and day can be either 1 or 2
    characters long, for example: "7/30/2013\\t10:22:48 AM"

    Args:
      date_string (str): date string.
      time_string (str): time string.

    Returns:
      dfdatetime.TimeElements: date time object.

    Raises:
      TimestampError: if the date or time string cannot be converted in
          a date time object.
    """
    if not date_string and not time_string:
      raise errors.TimestampError('Missing date or time string.')

    # TODO: Figure out how McAfee sets Day First and use that here.
    # The in-file time format is '07/30/2013\t10:22:48 AM'.

    try:
      month_string, day_of_month_string, year_string = date_string.split('/')
      year = int(year_string, 10)
      month = int(month_string, 10)
      day_of_month = int(day_of_month_string, 10)
    except (AttributeError, ValueError):
      raise errors.TimestampError('Unsupported date string: {0:s}'.format(
          date_string))

    try:
      time_value, time_suffix = time_string.split(' ')
      hours_string, minutes_string, seconds_string = time_value.split(':')
      hours = int(hours_string, 10)
      minutes = int(minutes_string, 10)
      seconds = int(seconds_string, 10)
    except (AttributeError, ValueError):
      raise errors.TimestampError('Unsupported time string: {0:s}'.format(
          time_string))

    if time_suffix == 'PM':
      hours += 12
    elif time_suffix != 'AM':
      raise errors.TimestampError('Unsupported time suffix: {0:s}.'.format(
          time_suffix))

    time_elements_tuple = (year, month, day_of_month, hours, minutes, seconds)

    try:
      date_time = dfdatetime_time_elements.TimeElements(
          time_elements_tuple=time_elements_tuple)

    except ValueError:
      raise errors.TimestampError(
          'Unsupported date and time strings: {0:s} {1:s}'.format(
              date_string, time_string))

    date_time.is_local_time = True
    return date_time
Example #12
0
    def ParseRecord(self, parser_mediator, key, structure):
        """Parse the record and return an SCCM log event object.

    Args:
      parser_mediator (ParserMediator): mediates interactions between parsers
          and other components, such as storage and dfvfs.
      file_object (dfvfs.FileIO): a file-like object.
      structure (pyparsing.ParseResults): structure of tokens derived from
          a line of a text file.

    Raises:
      ParseError: when the structure type is unknown.
      TimestampError: when a non-int value for microseconds is encountered.
    """
        if key not in (u'log_entry', u'log_entry_at_end', u'log_entry_offset',
                       u'log_entry_offset_at_end'):
            raise errors.ParseError(
                u'Unable to parse record, unknown structure: {0:s}'.format(
                    key))

        # Sometimes, SCCM logs will exhibit a seven-digit sub-second precision
        # (100 nanosecond intervals). Using six-digit precision because
        # timestamps are in microseconds.
        if len(structure.microsecond) > 6:
            structure.microsecond = structure.microsecond[0:6]

        try:
            microseconds = int(structure.microsecond, 10)
        except ValueError as exception:
            parser_mediator.ProduceExtractionError(
                u'unable to determine microseconds with error: {0:s}'.format(
                    exception))
            return

        # 3-digit precision is milliseconds,
        # so multiply by 1000 to convert to microseconds
        if len(structure.microsecond) == 3:
            microseconds *= 1000

        try:
            timestamp = timelib.Timestamp.FromTimeParts(
                structure.year, structure.month, structure.day, structure.hour,
                structure.minute, structure.second, microseconds)
        except errors.TimestampError as exception:
            timestamp = timelib.Timestamp.NONE_TIMESTAMP
            parser_mediator.ProduceExtractionError(
                u'unable to determine timestamp with error: {0:s}'.format(
                    exception))

        # If an offset is given for the event, apply the offset to convert to UTC.
        if timestamp and u'offset' in key:
            try:
                delta_microseconds = int(structure.utc_offset_minutes[1:], 10)
            except (IndexError, ValueError) as exception:
                raise errors.TimestampError(
                    u'Unable to parse minute offset from UTC with error: {0:s}.'
                    .format(exception))

            delta_microseconds *= self._MICRO_SECONDS_PER_MINUTE
            if structure.utc_offset_minutes[0] == u'-':
                delta_microseconds = -delta_microseconds
            timestamp += delta_microseconds

        event_data = SCCMLogEventData()
        event_data.component = structure.component
        # TODO: pass line number to offset or remove.
        event_data.offset = 0
        event_data.text = structure.text

        event = time_events.TimestampEvent(
            timestamp, definitions.TIME_DESCRIPTION_WRITTEN)
        parser_mediator.ProduceEventWithEventData(event, event_data)