Skip to content

Commit

Permalink
tetra: Add IMA hashes in compact printing
Browse files Browse the repository at this point in the history
Signed-off-by: Andrei Fedotov <[email protected]>
  • Loading branch information
anfedotoff committed Sep 16, 2024
1 parent 2c1a144 commit 9998343
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 17 deletions.
8 changes: 5 additions & 3 deletions cmd/tetra/getevents/getevents.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,19 @@ type Opts struct {
Timestamps bool
TTYEncode string
StackTraces bool
ImaHash bool
PolicyNames []string
}

var Options Opts

// GetEncoder returns an encoder for an event stream based on configuration options.
var GetEncoder = func(w io.Writer, colorMode encoder.ColorMode, timestamps bool, compact bool, tty string, stackTraces bool) encoder.EventEncoder {
var GetEncoder = func(w io.Writer, colorMode encoder.ColorMode, timestamps bool, compact bool, tty string, stackTraces bool, imaHash bool) encoder.EventEncoder {
if tty != "" {
return encoder.NewTtyEncoder(w, tty)
}
if compact {
return encoder.NewCompactEncoder(w, colorMode, timestamps, stackTraces)
return encoder.NewCompactEncoder(w, colorMode, timestamps, stackTraces, imaHash)
}
return encoder.NewProtojsonEncoder(w)
}
Expand Down Expand Up @@ -121,7 +122,7 @@ func getEvents(ctx context.Context, client tetragon.FineGuidanceSensorsClient) e
if err != nil {
return fmt.Errorf("failed to call GetEvents: %w", err)
}
eventEncoder := GetEncoder(os.Stdout, encoder.ColorMode(Options.Color), Options.Timestamps, Options.Output == "compact", Options.TTYEncode, Options.StackTraces)
eventEncoder := GetEncoder(os.Stdout, encoder.ColorMode(Options.Color), Options.Timestamps, Options.Output == "compact", Options.TTYEncode, Options.StackTraces, Options.ImaHash)
for {
res, err := stream.Recv()
if err != nil {
Expand Down Expand Up @@ -219,6 +220,7 @@ redirection of events to the stdin. Examples:
flags.BoolVar(&Options.Timestamps, "timestamps", false, "Include timestamps in compact output")
flags.StringVarP(&Options.TTYEncode, "tty-encode", "t", "", "Encode terminal data by file path (all other events will be ignored)")
flags.BoolVar(&Options.StackTraces, "stack-traces", true, "Include stack traces in compact output")
flags.BoolVar(&Options.ImaHash, "ima-hash", true, "Include ima hashes in compact output")
flags.StringSliceVar(&Options.PolicyNames, "policy-names", nil, "Get events by tracing policy names")
return &cmd
}
32 changes: 31 additions & 1 deletion pkg/encoder/encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,17 @@ type CompactEncoder struct {
Colorer *Colorer
Timestamps bool
StackTraces bool
ImaHash bool
}

// NewCompactEncoder initializes and returns a pointer to CompactEncoder.
func NewCompactEncoder(w io.Writer, colorMode ColorMode, timestamps bool, stackTraces bool) *CompactEncoder {
func NewCompactEncoder(w io.Writer, colorMode ColorMode, timestamps bool, stackTraces bool, imaHash bool) *CompactEncoder {
return &CompactEncoder{
Writer: w,
Colorer: NewColorer(colorMode),
Timestamps: timestamps,
StackTraces: stackTraces,
ImaHash: imaHash,
}
}

Expand All @@ -123,6 +125,12 @@ func (p *CompactEncoder) Encode(v interface{}) error {
fmt.Fprint(p.Writer, st)
}

// print ima hash if available
if p.ImaHash {
st := HumanIMAHash(event, p.Colorer)
fmt.Fprint(p.Writer, st)
}

return nil
}

Expand Down Expand Up @@ -223,6 +231,28 @@ func HumanStackTrace(response *tetragon.GetEventsResponse, colorer *Colorer) str
}
return out.String()
}
func HumanIMAHash(response *tetragon.GetEventsResponse, colorer *Colorer) string {
out := new(strings.Builder)
if ev, ok := response.Event.(*tetragon.GetEventsResponse_ProcessLsm); ok {
if ev.ProcessLsm.ImaHash != "" {
var path string
switch ev.ProcessLsm.FunctionName {
case "file_open":
fallthrough
case "mmap_file":
path = ev.ProcessLsm.Args[0].GetFileArg().Path
case "bprm_check_security":
path = ev.ProcessLsm.Args[0].GetLinuxBinprmArg().Path
default:
}
if path != "" {
colorer.Green.Fprintf(out, " %s", path)
colorer.Blue.Fprintf(out, " %s\n", ev.ProcessLsm.ImaHash)
}
}
}
return out.String()
}

func (p *CompactEncoder) EventToString(response *tetragon.GetEventsResponse) (string, error) {
switch response.Event.(type) {
Expand Down
26 changes: 13 additions & 13 deletions pkg/encoder/encoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ import (
)

func TestCompactEncoder_InvalidEventToString(t *testing.T) {
p := NewCompactEncoder(os.Stdout, Never, false, false)
p := NewCompactEncoder(os.Stdout, Never, false, false, false)

// should fail if the event field is nil.
_, err := p.EventToString(&tetragon.GetEventsResponse{})
assert.Error(t, err)
}

func TestCompactEncoder_ExecEventToString(t *testing.T) {
p := NewCompactEncoder(os.Stdout, Never, false, false)
p := NewCompactEncoder(os.Stdout, Never, false, false, false)

// should fail if the process field is nil.
_, err := p.EventToString(&tetragon.GetEventsResponse{
Expand Down Expand Up @@ -74,7 +74,7 @@ func TestCompactEncoder_ExecEventToString(t *testing.T) {
}

func TestCompactEncoder_ExitEventToString(t *testing.T) {
p := NewCompactEncoder(os.Stdout, Never, false, false)
p := NewCompactEncoder(os.Stdout, Never, false, false, false)

// should fail if the process field is nil.
_, err := p.EventToString(&tetragon.GetEventsResponse{
Expand Down Expand Up @@ -124,7 +124,7 @@ func TestCompactEncoder_ExitEventToString(t *testing.T) {
}

func TestCompactEncoder_KprobeEventToString(t *testing.T) {
p := NewCompactEncoder(os.Stdout, Never, false, false)
p := NewCompactEncoder(os.Stdout, Never, false, false, false)

// should fail without process field
_, err := p.EventToString(&tetragon.GetEventsResponse{
Expand Down Expand Up @@ -157,7 +157,7 @@ func TestCompactEncoder_KprobeEventToString(t *testing.T) {
}

func TestCompactEncoder_KprobeOpenEventToString(t *testing.T) {
p := NewCompactEncoder(os.Stdout, Never, false, false)
p := NewCompactEncoder(os.Stdout, Never, false, false, false)

// open without args
result, err := p.EventToString(&tetragon.GetEventsResponse{
Expand Down Expand Up @@ -201,7 +201,7 @@ func TestCompactEncoder_KprobeOpenEventToString(t *testing.T) {
}

func TestCompactEncoder_KprobeWriteEventToString(t *testing.T) {
p := NewCompactEncoder(os.Stdout, Never, false, false)
p := NewCompactEncoder(os.Stdout, Never, false, false, false)

// write without args
result, err := p.EventToString(&tetragon.GetEventsResponse{
Expand Down Expand Up @@ -246,7 +246,7 @@ func TestCompactEncoder_KprobeWriteEventToString(t *testing.T) {
}

func TestCompactEncoder_KprobeCloseEventToString(t *testing.T) {
p := NewCompactEncoder(os.Stdout, Never, false, false)
p := NewCompactEncoder(os.Stdout, Never, false, false, false)

// open without args
result, err := p.EventToString(&tetragon.GetEventsResponse{
Expand Down Expand Up @@ -289,7 +289,7 @@ func TestCompactEncoder_KprobeCloseEventToString(t *testing.T) {
}

func TestCompactEncoder_KprobeBPFEventToString(t *testing.T) {
p := NewCompactEncoder(os.Stdout, Never, false, false)
p := NewCompactEncoder(os.Stdout, Never, false, false, false)

// bpf with no args
result, err := p.EventToString(&tetragon.GetEventsResponse{
Expand Down Expand Up @@ -337,7 +337,7 @@ func TestCompactEncoder_KprobeBPFEventToString(t *testing.T) {
}

func TestCompactEncoder_KprobePerfEventAllocEventToString(t *testing.T) {
p := NewCompactEncoder(os.Stdout, Never, false, false)
p := NewCompactEncoder(os.Stdout, Never, false, false, false)

// perf event alloc with no args
result, err := p.EventToString(&tetragon.GetEventsResponse{
Expand Down Expand Up @@ -384,7 +384,7 @@ func TestCompactEncoder_KprobePerfEventAllocEventToString(t *testing.T) {
}

func TestCompactEncoder_KprobeBPFMapAllocEventToString(t *testing.T) {
p := NewCompactEncoder(os.Stdout, Never, false, false)
p := NewCompactEncoder(os.Stdout, Never, false, false, false)

// bpf map with no args
result, err := p.EventToString(&tetragon.GetEventsResponse{
Expand Down Expand Up @@ -435,7 +435,7 @@ func TestCompactEncoder_KprobeBPFMapAllocEventToString(t *testing.T) {

func TestCompactEncoder_Encode(t *testing.T) {
var b bytes.Buffer
p := NewCompactEncoder(&b, Never, false, false)
p := NewCompactEncoder(&b, Never, false, false, false)

// invalid event
err := p.Encode(nil)
Expand Down Expand Up @@ -466,7 +466,7 @@ func TestCompactEncoder_Encode(t *testing.T) {

func TestCompactEncoder_EncodeWithTimestamp(t *testing.T) {
var b bytes.Buffer
p := NewCompactEncoder(&b, Never, true, false)
p := NewCompactEncoder(&b, Never, true, false, false)

// invalid event
err := p.Encode(nil)
Expand Down Expand Up @@ -579,7 +579,7 @@ func FuzzCompactEncoder(f *testing.F) {
}

var buf1 bytes.Buffer
compactEncoder := NewCompactEncoder(&buf1, cm, timestamps, stackTraces)
compactEncoder := NewCompactEncoder(&buf1, cm, timestamps, stackTraces, false)
err = compactEncoder.Encode(msg)
require.NoError(t, err)
})
Expand Down

0 comments on commit 9998343

Please sign in to comment.