Beispiel #1
0
  def Validate(self):
    """Check the source is well constructed."""
    # Catch common mistake of path vs paths.
    if self.attributes.GetItem("paths"):
      if not isinstance(self.attributes.GetItem("paths"), list):
        raise artifact_registry.ArtifactDefinitionError(
            "Arg 'paths' that is not a list.")

    if self.attributes.GetItem("path"):
      if not isinstance(self.attributes.GetItem("path"), basestring):
        raise artifact_registry.ArtifactDefinitionError(
            "Arg 'path' is not a string.")

    # Check all returned types.
    if self.returned_types:
      for rdf_type in self.returned_types:
        if rdf_type not in rdfvalue.RDFValue.classes:
          raise artifact_registry.ArtifactDefinitionError(
              "Invalid return type %s" % rdf_type)

    if str(self.type) not in TYPE_MAP:
      raise artifact_registry.ArtifactDefinitionError(
          "Invalid type %s." % self.type)

    src_type = TYPE_MAP[str(self.type)]
    required_attributes = src_type.get("required_attributes", [])
    missing_attributes = set(
        required_attributes).difference(self.attributes.keys())
    if missing_attributes:
      raise artifact_registry.ArtifactDefinitionError(
          "Missing required attributes: %s." % missing_attributes)
Beispiel #2
0
def ArtifactsFromYaml(yaml_content):
  """Get a list of Artifacts from json."""
  try:
    raw_list = list(yaml.safe_load_all(yaml_content))
  except (ValueError, yaml.YAMLError) as e:
    raise artifact_registry.ArtifactDefinitionError(
        "Invalid YAML for artifact: %s" % e)

  # Try to do the right thing with json/yaml formatted as a list.
  if (isinstance(raw_list, list) and len(raw_list) == 1 and
      isinstance(raw_list[0], list)):
    raw_list = raw_list[0]

  # Convert json into artifact and validate.
  valid_artifacts = []
  for artifact_dict in raw_list:
    # In this case we are feeding parameters directly from potentially
    # untrusted yaml/json to our RDFValue class. However, safe_load ensures
    # these are all primitive types as long as there is no other deserialization
    # involved, and we are passing these into protobuf primitive types.
    try:
      artifact_value = Artifact(**artifact_dict)
      valid_artifacts.append(artifact_value)
    except (TypeError, AttributeError) as e:
      raise artifact_registry.ArtifactDefinitionError(
          "Invalid artifact definition for %s: %s" %
          (artifact_dict.get("name"), e))

  return valid_artifacts
Beispiel #3
0
  def ValidateSyntax(self):
    """Validate artifact syntax.

    This method can be used to validate individual artifacts as they are loaded,
    without needing all artifacts to be loaded first, as for Validate().

    Raises:
      ArtifactDefinitionError: If artifact is invalid.
    """
    cls_name = self.name
    if not self.doc:
      raise artifact_registry.ArtifactDefinitionError(
          "Artifact %s has missing doc" % cls_name)

    for supp_os in self.supported_os:
      if supp_os not in SUPPORTED_OS_LIST:
        raise artifact_registry.ArtifactDefinitionError(
            "Artifact %s has invalid supported_os %s" % (cls_name, supp_os))

    for condition in self.conditions:
      try:
        of = objectfilter.Parser(condition).Parse()
        of.Compile(objectfilter.BaseFilterImplementation)
      except ConditionError as e:
        raise artifact_registry.ArtifactDefinitionError(
            "Artifact %s has invalid condition %s. %s" % (
                cls_name, condition, e))

    for label in self.labels:
      if label not in ARTIFACT_LABELS:
        raise artifact_registry.ArtifactDefinitionError(
            "Artifact %s has an invalid label %s. Please use one from "
            "ARTIFACT_LABELS." % (cls_name, label))

    # Anything listed in provides must be defined in the KnowledgeBase
    valid_provides = rdf_client.KnowledgeBase().GetKbFieldNames()
    for kb_var in self.provides:
      if kb_var not in valid_provides:
        raise artifact_registry.ArtifactDefinitionError(
            "Artifact %s has broken provides: '%s' not in KB fields: %s" % (
                cls_name, kb_var, valid_provides))

    # Any %%blah%% path dependencies must be defined in the KnowledgeBase
    for dep in self.GetArtifactPathDependencies():
      if dep not in valid_provides:
        raise artifact_registry.ArtifactDefinitionError(
            "Artifact %s has an invalid path dependency: '%s', not in KB "
            "fields: %s" % (cls_name, dep, valid_provides))

    for source in self.sources:
      try:
        source.Validate()
      except Error as e:
        raise artifact_registry.ArtifactDefinitionError(
            "Artifact %s has bad source. %s" % (cls_name, e))
Beispiel #4
0
  def testRDFMaps(self):
    """Validate the RDFMaps."""
    for rdf_name, dat in artifact.GRRArtifactMappings.rdf_map.items():
      # "info/software", "InstalledSoftwarePackages", "INSTALLED_PACKAGES",
      # "Append"
      _, aff4_type, aff4_attribute, operator = dat

      if operator not in ["Append", "Overwrite"]:
        raise artifact_registry.ArtifactDefinitionError(
            "Bad RDFMapping, unknown operator %s in %s" % (operator, rdf_name))

      if aff4_type not in aff4.AFF4Object.classes:
        raise artifact_registry.ArtifactDefinitionError(
            "Bad RDFMapping, invalid AFF4 Object %s in %s" % (aff4_type,
                                                              rdf_name))

      attr = getattr(aff4.AFF4Object.classes[aff4_type].SchemaCls,
                     aff4_attribute)()
      if not isinstance(attr, rdfvalue.RDFValue):
        raise artifact_registry.ArtifactDefinitionError(
            "Bad RDFMapping, bad attribute %s for %s" % (aff4_attribute,
                                                         rdf_name))
Beispiel #5
0
  def Validate(self):
    """Attempt to validate the artifact has been well defined.

    This is used to enforce Artifact rules. Since it checks all dependencies are
    present, this method can only be called once all artifacts have been loaded
    into the registry. Use ValidateSyntax to check syntax for each artifact on
    import.

    Raises:
      ArtifactDefinitionError: If artifact is invalid.
    """
    cls_name = self.name
    self.ValidateSyntax()

    # Check all artifact dependencies exist.
    for dependency in self.GetArtifactDependencies():
      if dependency not in artifact_registry.ArtifactRegistry.artifacts:
        raise artifact_registry.ArtifactDefinitionError(
            "Artifact %s has an invalid dependency %s . Could not find artifact"
            " definition." % (cls_name, dependency))