78 lines
1.9 KiB
Go
78 lines
1.9 KiB
Go
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
package correlation
|
|
|
|
// LineageOf walks each starting PID through parentOf, excluding pid 0/init so
|
|
// unrelated process trees never correlate merely because they share init.
|
|
func LineageOf(pids []int, parentOf func(int) int, depth int) map[int]bool {
|
|
seen := make(map[int]bool)
|
|
for _, start := range pids {
|
|
current := start
|
|
steps := 0
|
|
for current != 0 && current != 1 && steps <= depth {
|
|
if seen[current] {
|
|
break
|
|
}
|
|
seen[current] = true
|
|
current = parentOf(current)
|
|
steps++
|
|
}
|
|
}
|
|
return seen
|
|
}
|
|
|
|
type IndexIncident struct {
|
|
ID string `json:"id"`
|
|
Host string `json:"host"`
|
|
LastTimestamp float64 `json:"last_ts"`
|
|
Lineage []int `json:"lineage"`
|
|
}
|
|
|
|
// Assign returns the most recently active incident compatible with this host
|
|
// and lineage. Empty-lineage evidence may join any open incident on the host,
|
|
// reproducing Python's fallback for FIM/package evidence without a live PID.
|
|
func Assign(index []IndexIncident, lineage map[int]bool, when float64, host string, window int) string {
|
|
best := ""
|
|
bestTimestamp := -1.0
|
|
for _, incident := range index {
|
|
if incident.Host != host || when-incident.LastTimestamp > float64(window) {
|
|
continue
|
|
}
|
|
if len(lineage) > 0 && !intersects(incident.Lineage, lineage) {
|
|
continue
|
|
}
|
|
if incident.LastTimestamp > bestTimestamp {
|
|
best, bestTimestamp = incident.ID, incident.LastTimestamp
|
|
}
|
|
}
|
|
return best
|
|
}
|
|
|
|
func MaxSeverity(left, right string) string {
|
|
if severityRank(left) >= severityRank(right) {
|
|
return left
|
|
}
|
|
return right
|
|
}
|
|
|
|
func severityRank(value string) int {
|
|
switch value {
|
|
case "MEDIUM":
|
|
return 1
|
|
case "HIGH":
|
|
return 2
|
|
case "CRITICAL":
|
|
return 3
|
|
default:
|
|
return 0
|
|
}
|
|
}
|
|
|
|
func intersects(values []int, wanted map[int]bool) bool {
|
|
for _, value := range values {
|
|
if wanted[value] {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|