func applyNormalization()

in aucoalesce/coalesce.go [455:609]


func applyNormalization(event *Event) {
	setHowDefaults(event)

	var syscallNorm *Normalization
	if syscall, ok := event.Data["syscall"]; ok {
		syscallNorm, ok = syscallNorms[syscall]
		if !ok {
			syscallNorm = syscallNorms["*"] // get the default to add some basic categorization
		}
	}

	var norm *Normalization
	if event.Type == auparse.AUDIT_SYSCALL {
		norm = syscallNorm
	} else {
		norms := recordTypeNorms[event.Type.String()]
		switch len(norms) {
		case 0:
			// No normalization found.
		case 1:
			norm = norms[0]
		default:
		nextNorm:
			for _, n := range norms {
				// Select normalization if all 'has_fields' are present.
				for _, f := range n.HasFields.Values {
					if _, found := event.Data[f]; !found {
						continue nextNorm
					}
				}
				norm = n
			}
		}
	}
	if norm == nil {
		event.Warnings = append(event.Warnings, errors.New("no normalization found for event"))
		return
	}

	event.ECS.Event.Kind = norm.ECS.Kind
	event.ECS.Event.Category = norm.ECS.Category.Values
	event.ECS.Event.Type = norm.ECS.Type.Values

	// we check to see if the non-AUDIT_SYSCALL event has an associated syscall
	// from another part of the auditd message log, if it does and we have normalizations
	// for that syscall, we merge the ECS categorization and type information so that
	// the event has both enrichment for the record type itself and for the syscall it
	// captures
	hasAdditionalNormalization := syscallNorm != nil && syscallNorm != norm
	if hasAdditionalNormalization {
		event.ECS.Event.Category = append(event.ECS.Event.Category, syscallNorm.ECS.Category.Values...)
		event.ECS.Event.Type = append(event.ECS.Event.Type, syscallNorm.ECS.Type.Values...)
		if event.Result == "fail" {
			event.ECS.Event.Outcome = "failure"
		}
	}

	event.Summary.Action = norm.Action

	switch norm.ObjectWhat {
	case "file", "filesystem":
		event.Summary.Object.Type = norm.ObjectWhat
		if len(event.Paths) > 0 {
			if err := setFileObject(event, norm.ObjectPathIndex); err != nil {
				event.Warnings = append(event.Warnings, fmt.Errorf("failed to set file object: %w", err))
			}
		}
	case "socket":
		event.Summary.Object.Type = norm.ObjectWhat
		setSocketObject(event)
	default:
		event.Summary.Object.Type = norm.ObjectWhat
	}

	if len(norm.SubjectPrimaryFieldName.Values) > 0 {
		var err error
		for _, subjKey := range norm.SubjectPrimaryFieldName.Values {
			if err = setSubjectPrimary(subjKey, event); err == nil {
				break
			}
		}
		if err != nil {
			event.Warnings = append(event.Warnings, fmt.Errorf("failed to set subject primary using keys=%v because they were not found", norm.SubjectPrimaryFieldName.Values))
		}
	}

	if len(norm.SubjectSecondaryFieldName.Values) > 0 {
		var err error
		for _, subjKey := range norm.SubjectSecondaryFieldName.Values {
			if err = setSubjectSecondary(subjKey, event); err == nil {
				break
			}
		}
		if err != nil {
			event.Warnings = append(event.Warnings, fmt.Errorf("failed to set subject secondary using keys=%v because they were not found", norm.SubjectSecondaryFieldName.Values))
		}
	}

	if len(norm.ObjectPrimaryFieldName.Values) > 0 {
		var err error
		for _, objKey := range norm.ObjectPrimaryFieldName.Values {
			if err = setObjectPrimary(objKey, event); err == nil {
				break
			}
		}
		if err != nil {
			event.Warnings = append(event.Warnings, fmt.Errorf("failed to set object primary using keys=%v because they were not found", norm.ObjectPrimaryFieldName.Values))
		}
	}

	if len(norm.ObjectSecondaryFieldName.Values) > 0 {
		var err error
		for _, objKey := range norm.ObjectSecondaryFieldName.Values {
			if err = setObjectSecondary(objKey, event); err == nil {
				break
			}
		}
		if err != nil {
			event.Warnings = append(event.Warnings, fmt.Errorf("failed to set object secondary using keys=%v because they were not found", norm.ObjectSecondaryFieldName.Values))
		}
	}

	if len(norm.How.Values) > 0 {
		var err error
		for _, howKey := range norm.How.Values {
			if err = setHow(howKey, event); err == nil {
				break
			}
		}
		if err != nil {
			event.Warnings = append(event.Warnings, fmt.Errorf("failed to set how using keys=%v because they were not found", norm.How.Values))
		}
	}

	if event.Source == nil && len(norm.SourceIP.Values) > 0 {
		var err error
		for _, sourceIPKey := range norm.SourceIP.Values {
			if err = setSourceIP(sourceIPKey, event); err == nil {
				break
			}
		}
		if err != nil {
			event.Warnings = append(event.Warnings, fmt.Errorf("failed to "+
				"set source IP using keys=%v because they were not found",
				norm.SourceIP.Values))
		}
	}

	// Populate ECS fields from `mappings` section.
	for _, mapping := range norm.ECS.Mappings {
		if mapping.To != nil && mapping.From != nil {
			mapping.To(event, mapping.From(event))
		}
	}
}