feat(go): port process access detectors
This commit is contained in:
parent
f02509aab5
commit
fc9b5f0448
22 changed files with 554 additions and 40 deletions
|
|
@ -13,9 +13,24 @@ import (
|
|||
"codeberg.org/anassaeneroi/enodia-sentinal/go-agent/internal/model"
|
||||
)
|
||||
|
||||
// Paths makes host filesystem inputs injectable for parity and unit tests.
|
||||
type Paths struct {
|
||||
ProcRoot string
|
||||
LDPreloadPath string
|
||||
}
|
||||
|
||||
// Capture reads process state once from procRoot. Transient per-process read
|
||||
// failures degrade to empty fields, matching Python's fail-open Process view.
|
||||
func Capture(procRoot string) (model.State, error) {
|
||||
return CaptureWithPaths(Paths{
|
||||
ProcRoot: procRoot,
|
||||
LDPreloadPath: "/etc/ld.so.preload",
|
||||
})
|
||||
}
|
||||
|
||||
// CaptureWithPaths reads one process view and the global preload file.
|
||||
func CaptureWithPaths(paths Paths) (model.State, error) {
|
||||
procRoot := paths.ProcRoot
|
||||
if procRoot == "" {
|
||||
procRoot = "/proc"
|
||||
}
|
||||
|
|
@ -31,14 +46,52 @@ func Capture(procRoot string) (model.State, error) {
|
|||
}
|
||||
base := filepath.Join(procRoot, entry.Name())
|
||||
processes = append(processes, model.Process{
|
||||
PID: pid,
|
||||
Comm: strings.TrimSpace(readText(filepath.Join(base, "comm"))),
|
||||
Cmdline: strings.TrimSpace(strings.ReplaceAll(readText(filepath.Join(base, "cmdline")), "\x00", " ")),
|
||||
Exe: readLink(filepath.Join(base, "exe")),
|
||||
PID: pid,
|
||||
Comm: strings.TrimSpace(readText(filepath.Join(base, "comm"))),
|
||||
Cmdline: strings.TrimSpace(strings.ReplaceAll(readText(filepath.Join(base, "cmdline")), "\x00", " ")),
|
||||
Exe: readLink(filepath.Join(base, "exe")),
|
||||
Environ: parseEnviron(readText(filepath.Join(base, "environ"))),
|
||||
FDTargets: readFDTargets(filepath.Join(base, "fd")),
|
||||
})
|
||||
}
|
||||
sort.Slice(processes, func(i, j int) bool { return processes[i].PID < processes[j].PID })
|
||||
return model.State{Processes: processes}, nil
|
||||
return model.State{
|
||||
Processes: processes,
|
||||
LDPreload: strings.TrimSpace(readText(paths.LDPreloadPath)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func parseEnviron(raw string) map[string]string {
|
||||
result := make(map[string]string)
|
||||
for _, item := range strings.Split(raw, "\x00") {
|
||||
key, value, ok := strings.Cut(item, "=")
|
||||
if ok {
|
||||
result[key] = value
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func readFDTargets(path string) map[string]string {
|
||||
result := make(map[string]string)
|
||||
entries, err := os.ReadDir(path)
|
||||
if err != nil {
|
||||
return result
|
||||
}
|
||||
sort.Slice(entries, func(i, j int) bool {
|
||||
left, leftErr := strconv.Atoi(entries[i].Name())
|
||||
right, rightErr := strconv.Atoi(entries[j].Name())
|
||||
if leftErr == nil && rightErr == nil {
|
||||
return left < right
|
||||
}
|
||||
return entries[i].Name() < entries[j].Name()
|
||||
})
|
||||
for _, entry := range entries {
|
||||
if target := readLink(filepath.Join(path, entry.Name())); target != "" {
|
||||
result[entry.Name()] = target
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func readText(path string) string {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue