forked from aquasecurity/tracee
-
Notifications
You must be signed in to change notification settings - Fork 0
/
output.go
106 lines (94 loc) · 2.85 KB
/
output.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
package main
import (
"bytes"
"errors"
"fmt"
"io"
"log"
"net/http"
"path/filepath"
"strings"
"text/template"
"github.com/Masterminds/sprig"
tracee "github.com/aquasecurity/tracee/tracee-ebpf/tracee/external"
"github.com/aquasecurity/tracee/tracee-rules/types"
)
const DefaultDetectionOutputTemplate string = `
*** Detection ***
Time: {{ dateInZone "2006-01-02T15:04:05Z" (now) "UTC" }}
Signature ID: {{ .SigMetadata.ID }}
Signature: {{ .SigMetadata.Name }}
Data: {{ .Data }}
Command: {{ .Context.ProcessName }}
Hostname: {{ .Context.HostName }}
`
func setupTemplate(inputTemplateFile string) (*template.Template, error) {
switch {
case inputTemplateFile != "":
return template.New(filepath.Base(inputTemplateFile)).
Funcs(sprig.TxtFuncMap()).
ParseFiles(inputTemplateFile)
default:
return template.New("default").
Funcs(sprig.TxtFuncMap()).
Parse(DefaultDetectionOutputTemplate)
}
}
func setupOutput(w io.Writer, webhook string, webhookTemplate string, contentType string, outputTemplate string) (chan types.Finding, error) {
out := make(chan types.Finding)
var err error
var tWebhook *template.Template
tWebhook, err = setupTemplate(webhookTemplate)
if err != nil && webhookTemplate != "" {
return nil, fmt.Errorf("error preparing webhook template: %v", err)
}
var tOutput *template.Template
tOutput, err = setupTemplate(outputTemplate)
if err != nil && outputTemplate != "" {
return nil, fmt.Errorf("error preparing output template: %v", err)
}
go func(w io.Writer, tWebhook, tOutput *template.Template) {
for res := range out {
switch res.Context.(type) {
case tracee.Event:
if err := tOutput.Execute(w, res); err != nil {
log.Println("error writing to output: ", err)
}
default:
log.Printf("unsupported event detected: %T\n", res.Context)
continue
}
if webhook != "" {
if err := sendToWebhook(tWebhook, res, webhook, webhookTemplate, contentType); err != nil {
log.Println(err)
}
}
}
}(w, tWebhook, tOutput)
return out, nil
}
func sendToWebhook(t *template.Template, res types.Finding, webhook string, webhookTemplate string, contentType string) error {
var payload string
switch {
case webhookTemplate != "":
if t == nil {
return fmt.Errorf("error writing to template: template not initialized")
}
if contentType == "" {
log.Println("content-type was not set for the custom template: ", webhookTemplate)
}
buf := bytes.Buffer{}
if err := t.Execute(&buf, res); err != nil {
return fmt.Errorf("error writing to the template: %v", err)
}
payload = buf.String()
default:
return errors.New("error sending to webhook: --webhook-template flag is required when using --webhook flag")
}
resp, err := http.Post(webhook, contentType, strings.NewReader(payload))
if err != nil {
return fmt.Errorf("error calling webhook %v", err)
}
_ = resp.Body.Close()
return nil
}