def GenResults(self, artifact_list, sources_list, parser_list=None): """Given a list of artifacts, sources and parsers, will RunChecks on them. Sample: (["Artifact1", "Artifact2"], [artifact1_data, artifact2_data], [config_file.artifact1_Parser(), config_file.artifact2_Parser()] artifact1_Parser().parse will run on artifact1_data & parsed results, along with raw and anomalies will be inserted into the host_data["Artifact1"]. artifact2_Parser().parse will run on artifact2_data & parsed results, along with raw and anomalies will be inserted into the host_data["Artifact2"]. Once artifacts added to host_data, loaded checks will be run against it. Args: artifact_list: list of artifacts to add to host_data for running checks sources_list: list of dictionaries containing file names and file data. If parser_list is empty then sources_list must contain a list of lists containing StatEntry or lists of other raw artifact data. parser_list: list of parsers to apply to file data from sources_list. This can be empty if no parser is to be applied. Returns: CheckResult containing any findings in sources_list against loaded checks. Raises: Error: When there are issues with the passed input. """ if parser_list is None: parser_list = [None] * len(artifact_list) # make sure all vars are lists if any( type(lst) != list for lst in [artifact_list, sources_list, parser_list]): raise test_lib.Error("All inputs are not lists.") # make sure all lists are of equal length if any( len(lst) != len(artifact_list) for lst in [sources_list, parser_list]): raise test_lib.Error("All lists are not of the same length.") host_data = self.SetKnowledgeBase() for artifact, sources, parser in zip(artifact_list, sources_list, parser_list): if parser is None: host_data[artifact] = self.SetArtifactData( raw=sources, results=host_data.get(artifact)) else: host_data = self._AddToHostData(host_data, artifact, sources, parser) return self.RunChecks(host_data)
def GenFileData(self, artifact, data, parser=None, modes=None, include=None): """Create a set of host_data results based on file parser results. Creates a host data result populated with a knowledge base, then processes each piece of host data as if it were file results using a parser. Specific stat values can be provided to the parser, if required, so that permissions, ownership and file types can be defined. Args: artifact: The artifact name that generated data will be mapped to. data: A dictionary of pathnames and data strings. The data strings are converted into file objects for the parser. parser: The FileParser that processes the data (and stats) modes: A dictionary of pathnames and stat values. Stat values are a dict of {st_uid: int, st_gid: int, st_mode: oct} entries. include: A list of pathnames to include in processing. If not provided, all paths are parsed. Returns: the host_data map populated with a knowledge base and artifact data. Raises: Error: When the handed parser was not initialized. """ host_data = self.SetKnowledgeBase() if not parser: raise test_lib.Error("Test method requires an initialized parser.") if not modes: modes = {} kb = host_data["KnowledgeBase"] files = [] rdfs = [] stats = [] for path in data: if include and path not in include: continue file_modes = modes.get(path, {}) stats, files = self._GenFileData([path], [data[path]], stats=stats, files=files, modes=file_modes) if parser.process_together: rdfs = list(parser.ParseMultiple(stats, files, kb)) else: for stat, file_obj in zip(stats, files): # Make sure the parser result is iterable. rslt = parser.Parse(stat, file_obj, kb) or [] rdfs.extend(rslt) anomaly = [a for a in rdfs if isinstance(a, rdf_anomaly.Anomaly)] parsed = [r for r in rdfs if not isinstance(r, rdf_anomaly.Anomaly)] host_data[artifact] = self.SetArtifactData(parsed=parsed, anomaly=anomaly, raw=stats) return host_data
def _AddToHostData(self, host_data, artifact, data, parser): """Parse raw data collected for an artifact into the host_data table.""" if type(data) != dict: raise test_lib.Error("Data for %s is not of type dictionary." % artifact) rdfs = [] stats = [] files = [] for path, lines in data.items(): stat = self.CreateStat(path) stats.append(stat) file_obj = StringIO.StringIO(lines) files.append(file_obj) if not parser.process_together: rdfs.extend(list(parser.Parse(stat, file_obj, None))) if parser.process_together: rdfs = list(parser.ParseMultiple(stats, files, None)) host_data[artifact] = self.SetArtifactData( anomaly=[a for a in rdfs if isinstance(a, rdf_anomaly.Anomaly)], parsed=[r for r in rdfs if not isinstance(r, rdf_anomaly.Anomaly)], raw=stats, results=host_data.get(artifact)) return host_data
def TestDataPath(self, file_name): """Generates a full path to the test data.""" path = os.path.join(config.CONFIG["Test.data_dir"], file_name) if not os.path.isfile(path): raise test_lib.Error("Missing test data: %s" % file_name) return path