-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
Copy pathprocess_check.go
114 lines (97 loc) · 3.08 KB
/
process_check.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2016-present Datadog, Inc.
package checks
import (
"context"
"errors"
"fmt"
"strconv"
"time"
"github.com/DataDog/datadog-agent/pkg/compliance"
"github.com/DataDog/datadog-agent/pkg/compliance/checks/env"
"github.com/DataDog/datadog-agent/pkg/compliance/eval"
"github.com/DataDog/datadog-agent/pkg/util/log"
)
const (
cacheValidity time.Duration = 10 * time.Minute
)
var processReportedFields = []string{
compliance.ProcessFieldName,
compliance.ProcessFieldExe,
compliance.ProcessFieldCmdLine,
}
func resolveProcess(_ context.Context, e env.Env, id string, res compliance.ResourceCommon, rego bool) (resolved, error) {
if res.Process == nil {
return nil, fmt.Errorf("%s: expecting process resource in process check", id)
}
process := res.Process
log.Debugf("%s: running process check: %s", id, process.Name)
processes, err := getProcesses(cacheValidity)
if err != nil {
return nil, log.Errorf("%s: Unable to fetch processes: %v", id, err)
}
matchedProcesses := processes.findProcessesByName(process.Name)
var instances []resolvedInstance
for _, mp := range matchedProcesses {
flagValues := parseProcessCmdLine(mp.Cmdline)
instance := eval.NewInstance(
eval.VarMap{
compliance.ProcessFieldName: mp.Name,
compliance.ProcessFieldExe: mp.Exe,
compliance.ProcessFieldCmdLine: mp.Cmdline,
compliance.ProcessFieldFlags: flagValues,
},
eval.FunctionMap{
compliance.ProcessFuncFlag: processFlag(flagValues),
compliance.ProcessFuncHasFlag: processHasFlag(flagValues),
},
eval.RegoInputMap{
"name": mp.Name,
"exe": mp.Exe,
"cmdLine": mp.Cmdline,
"flags": flagValues,
},
)
instances = append(instances, newResolvedInstance(instance, strconv.Itoa(int(mp.Pid)), "process"))
}
if len(instances) == 0 && rego {
return nil, nil
}
// NOTE(safchain) workaround to allow fallback on all this resource if there is only one file
if len(instances) == 1 {
return instances[0].(*_resolvedInstance), nil
}
return newResolvedInstances(instances), nil
}
func processFlag(flagValues map[string]string) eval.Function {
return func(_ eval.Instance, args ...interface{}) (interface{}, error) {
flag, err := validateProcessFlagArg(args...)
if err != nil {
return nil, err
}
value := flagValues[flag]
return value, nil
}
}
func processHasFlag(flagValues map[string]string) eval.Function {
return func(_ eval.Instance, args ...interface{}) (interface{}, error) {
flag, err := validateProcessFlagArg(args...)
if err != nil {
return nil, err
}
_, has := flagValues[flag]
return has, nil
}
}
func validateProcessFlagArg(args ...interface{}) (string, error) {
if len(args) != 1 {
return "", fmt.Errorf(`invalid number of arguments, expecting 1 got %d`, len(args))
}
flag, ok := args[0].(string)
if !ok {
return "", errors.New(`expecting string value for flag argument`)
}
return flag, nil
}