89 lines
2.9 KiB
Go
89 lines
2.9 KiB
Go
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
package incident
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"codeberg.org/anassaeneroi/enodia-sentinal/go-agent/internal/correlation"
|
|
"codeberg.org/anassaeneroi/enodia-sentinal/go-agent/internal/model"
|
|
)
|
|
|
|
func TestRecordAlertGroupsLineageAndPersistsCorrelation(t *testing.T) {
|
|
directory := t.TempDir()
|
|
store, err := New(directory, true, 1800, 8)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
firstTime := time.Unix(1000, 0).UTC()
|
|
first, err := store.RecordAlert("alert-1.log", model.Alert{
|
|
SID: 100003, Severity: "HIGH", Signature: "exec_rule.web-rce", PIDs: []int{4242},
|
|
}, map[int]bool{4242: true, 999: true}, firstTime, "host-a", "")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
second, err := store.RecordAlert("alert-2.log", model.Alert{
|
|
SID: 100067, Severity: "HIGH", Signature: "host_rule.suspicious-egress", PIDs: []int{4243},
|
|
}, map[int]bool{4243: true, 999: true}, firstTime.Add(50*time.Second), "host-a", "")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if first == "" || second != first {
|
|
t.Fatalf("incident ids first=%q second=%q", first, second)
|
|
}
|
|
index, err := LoadIndex(directory)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
item := index[first]
|
|
if len(index) != 1 || item == nil || item.Schema != Schema || item.AlertCount != 2 ||
|
|
item.Severity != "CRITICAL" || len(item.Snapshots) != 2 ||
|
|
len(item.Correlations) != 1 || item.Correlations[0].SID != correlation.SIDMultiStageIntrusion {
|
|
t.Fatalf("index=%#v", index)
|
|
}
|
|
if info, err := os.Stat(filepath.Join(directory, IndexName)); err != nil || info.Mode().Perm() != 0o600 {
|
|
t.Fatalf("incident index mode info=%v err=%v", info, err)
|
|
}
|
|
}
|
|
|
|
func TestPreferredIncidentMakesSnapshotAppendIdempotent(t *testing.T) {
|
|
store, err := New(t.TempDir(), true, 1800, 8)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
when := time.Unix(1000, 0).UTC()
|
|
id, err := store.RecordAlert("alert-1.log", model.Alert{
|
|
SID: 1, Severity: "HIGH", Signature: "one", PIDs: []int{10},
|
|
}, map[int]bool{10: true}, when, "host-a", "")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := store.RecordAlert("alert-1.log", model.Alert{
|
|
SID: 2, Severity: "CRITICAL", Signature: "two", PIDs: []int{20},
|
|
}, map[int]bool{20: true}, when.Add(500*time.Millisecond), "host-a", id); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
index, _ := LoadIndex(store.Dir)
|
|
item := index[id]
|
|
if len(item.Snapshots) != 1 || item.AlertCount != 2 || len(item.PIDs) != 2 || item.Severity != "CRITICAL" {
|
|
t.Fatalf("incident=%#v", item)
|
|
}
|
|
}
|
|
|
|
func TestDisabledStoreDoesNotWriteIndex(t *testing.T) {
|
|
directory := t.TempDir()
|
|
store, err := New(directory, false, 1800, 8)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
id, err := store.RecordAlert("alert.log", model.Alert{SID: 1, Severity: "HIGH", Signature: "test"}, nil, time.Now(), "host-a", "")
|
|
if err != nil || id != "" {
|
|
t.Fatalf("id=%q err=%v", id, err)
|
|
}
|
|
if _, err := os.Stat(filepath.Join(directory, IndexName)); !os.IsNotExist(err) {
|
|
t.Fatalf("disabled index exists: %v", err)
|
|
}
|
|
}
|