Source code for winregrc.eventlog_providers

# -*- coding: utf-8 -*-
"""Windows Event Log providers collector."""

from winregrc import interface


[docs] class EventLogProvider(object): """Windows Event Log provider. Attributes: additional_identifier (str): additional identifier of the provider, contains a GUID. category_message_files (set[str]): paths of the category message files. event_message_files (set[str]): paths of the event message files. identifier (str): identifier of the provider, contains a GUID. log_sources (list[str]): names of the corresponding Event Log sources. log_types (list[str]): Windows Event Log types. name (str): name of the provider. parameter_message_files (set[str]): paths of the parameter message files. """
[docs] def __init__(self): """Initializes a Windows Event Log provider.""" super(EventLogProvider, self).__init__() self.additional_identifier = None self.category_message_files = set() self.event_message_files = set() self.identifier = None self.log_sources = [] self.log_types = [] self.name = None self.parameter_message_files = set()
[docs] class EventLogProvidersCollector(interface.WindowsRegistryKeyCollector): """Windows Event Log providers collector.""" _SERVICES_EVENTLOG_KEY_PATH = ( 'HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Services\\EventLog') _WINEVT_PUBLISHERS_KEY_PATH = ( 'HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\' 'WINEVT\\Publishers') def _CollectEventLogProviders( self, services_eventlog_key, winevt_publishers_key): """Collects Windows Event Log providers. Args: services_eventlog_key (dfwinreg.WinRegistryKey): a Services\\EventLog Windows Registry. winevt_publishers_key (dfwinreg.WinRegistryKey): a WINEVT\\Publishers Windows Registry. Yields: EventLogProvider: an Event Log provider. """ event_log_providers_per_identifier = {} event_log_providers_per_name = {} for event_log_provider in self._CollectEventLogProvidersFromPublishersKeys( winevt_publishers_key): provider_identifier = event_log_provider.identifier existing_event_log_provider = event_log_providers_per_identifier.get( provider_identifier, None) if existing_event_log_provider: self._MergeEventLogProviders( existing_event_log_provider, event_log_provider) else: event_log_providers_per_identifier[provider_identifier] = ( event_log_provider) if event_log_provider.name: event_log_providers_per_name[event_log_provider.name] = ( event_log_provider) event_log_providers_per_log_source = {} for event_log_provider in self._CollectEventLogProvidersFromServicesKey( services_eventlog_key): provider_identifier = event_log_provider.identifier if provider_identifier: existing_event_log_provider = event_log_providers_per_identifier.get( provider_identifier, None) if existing_event_log_provider: self._MergeEventLogProviders( existing_event_log_provider, event_log_provider) continue log_source = event_log_provider.log_sources[0] existing_event_log_provider = event_log_providers_per_name.get( log_source, None) if existing_event_log_provider: if (provider_identifier and provider_identifier != existing_event_log_provider.identifier): existing_event_log_provider.additional_identifier = ( provider_identifier) self._MergeEventLogProviders( existing_event_log_provider, event_log_provider) continue event_log_providers_per_log_source[log_source] = event_log_provider event_log_providers = list(event_log_providers_per_identifier.values()) event_log_providers.extend(event_log_providers_per_log_source.values()) for event_log_provider in sorted( event_log_providers, key=self._GetEventLogProviderSortedKey): event_log_provider.category_message_files = self._NormalizeMessageFiles( event_log_provider.category_message_files) event_log_provider.event_message_files = self._NormalizeMessageFiles( event_log_provider.event_message_files) event_log_provider.parameter_message_files = self._NormalizeMessageFiles( event_log_provider.parameter_message_files) yield event_log_provider def _CollectEventLogProvidersFromPublishersKeys(self, winevt_publishers_key): """Collects Windows Event Log providers from a WINEVT publishers key. Args: winevt_publishers_key (dfwinreg.WinRegistryKey): WINEVT publishers key. Yield: EventLogProvider: Event Log provider. """ if winevt_publishers_key: for guid_key in winevt_publishers_key.GetSubkeys(): event_log_provider = EventLogProvider() event_log_provider.identifier = guid_key.name.lower() event_log_provider.name = self._GetValueFromKey(guid_key, '') event_message_files = self._GetMessageFilePathsFromKey( guid_key, 'MessageFileName') event_log_provider.event_message_files = event_message_files # TODO: add support for ResourceFileName value # TODO: add support for ParameterFileName value yield event_log_provider def _CollectEventLogProvidersFromServicesKey(self, services_eventlog_key): """Collects Windows Event Log providers from a services Event Log key. Args: services_eventlog_key (dfwinreg.WinRegistryKey): services Event Log key. Yield: EventLogProvider: Event Log provider. """ if services_eventlog_key: for log_type_key in services_eventlog_key.GetSubkeys(): for provider_key in log_type_key.GetSubkeys(): provider_identifier = self._GetValueFromKey( provider_key, 'ProviderGuid', default_value='') provider_identifier = provider_identifier.lower() event_log_provider = EventLogProvider() event_log_provider.identifier = provider_identifier or None event_log_provider.log_sources = [provider_key.name] event_log_provider.log_types = [log_type_key.name] category_message_files = self._GetMessageFilePathsFromKey( provider_key, 'CategoryMessageFile') event_log_provider.category_message_files = category_message_files event_message_files = self._GetMessageFilePathsFromKey( provider_key, 'EventMessageFile') event_log_provider.event_message_files = event_message_files parameter_message_files = self._GetMessageFilePathsFromKey( provider_key, 'ParameterMessageFile') event_log_provider.parameter_message_files = parameter_message_files yield event_log_provider def _GetEventLogProviderSortedKey(self, event_log_provider): """Retrieves a key to sort Event Log providers on. Args: event_log_provider (EventLogProvider): Event Log provider. Returns: str: key to sort Event Log providers on. """ if not event_log_provider.log_sources: return event_log_provider.name or '' return event_log_provider.log_sources[0] def _GetMessageFilePathsFromKey(self, registry_key, value_name): """Retrieves a value as a list of message file paths. Args: registry_key (dfwinreg.WinRegistryKey): Windows Registry key. value_name (str): name of the value. Returns: set[str]: paths of message files. """ message_files = set() registry_value = registry_key.GetValueByName(value_name) if registry_value: value_string = registry_value.GetDataAsObject() for path in value_string.split(';'): path = path.strip() if path: message_files.add(path) return message_files def _MergeEventLogProviders( self, first_event_log_provider, second_event_log_provider): """Merges the information of the second Event Log provider into the first. Args: first_event_log_provider (EventLogProvider): first Event Log provider. second_event_log_provider (EventLogProvider): second Event Log provider. """ for log_source in second_event_log_provider.log_sources: if log_source not in first_event_log_provider.log_sources: first_event_log_provider.log_sources.append(log_source) for log_type in second_event_log_provider.log_types: if log_type not in first_event_log_provider.log_types: first_event_log_provider.log_types.append(log_type) first_event_log_provider.category_message_files.update( second_event_log_provider.category_message_files) first_event_log_provider.event_message_files.update( second_event_log_provider.event_message_files) first_event_log_provider.parameter_message_files.update( second_event_log_provider.parameter_message_files) def _NormalizeMessageFiles(self, message_files): """Normalizes the message files. Args: message_files (list[str]): paths of the message files. Returns: set[str]: normalized paths of the message files. """ normalized_message_files = set() paths_lower = set() for path in message_files: path_lower = path.lower() if path_lower not in paths_lower: paths_lower.add(path_lower) normalized_message_files.add(path) return normalized_message_files
[docs] def Collect(self, registry): """Collects Windows Event Log providers from a Windows Registry. Args: registry (dfwinreg.WinRegistry): Windows Registry. Returns: generator[EventLogProvider]: Event Log provider generator. """ # TODO: add support to collect Event Log providers from all control sets. services_eventlog_key = registry.GetKeyByPath( self._SERVICES_EVENTLOG_KEY_PATH) winevt_publishers_key = registry.GetKeyByPath( self._WINEVT_PUBLISHERS_KEY_PATH) return self._CollectEventLogProviders( services_eventlog_key, winevt_publishers_key)