github.com/DataDog/datadog-agent/pkg/security/secl@v0.55.0-devel.0.20240517055856-10c4965fea94/model/model_test.go (about)

     1  // Unless explicitly stated otherwise all files in this repository are licensed
     2  // under the Apache License Version 2.0.
     3  // This product includes software developed at Datadog (https://www.datadoghq.com/).
     4  // Copyright 2016-present Datadog, Inc.
     5  
     6  //go:build linux
     7  
     8  // Package model holds model related files
     9  package model
    10  
    11  import (
    12  	"errors"
    13  	"net"
    14  	"reflect"
    15  	"strings"
    16  	"testing"
    17  
    18  	"github.com/DataDog/datadog-agent/pkg/security/secl/compiler/eval"
    19  )
    20  
    21  func TestPathValidation(t *testing.T) {
    22  	mod := &Model{}
    23  
    24  	var maxDepthPath string
    25  	for i := 0; i <= MaxPathDepth; i++ {
    26  		maxDepthPath += "a/"
    27  	}
    28  
    29  	var maxSegmentPath string
    30  	for i := 0; i <= MaxSegmentLength; i++ {
    31  		maxSegmentPath += "a"
    32  	}
    33  
    34  	tests := []struct {
    35  		val            string
    36  		errMessage     string
    37  		fieldValueType eval.FieldValueType
    38  	}{
    39  		{
    40  			val: "/var/log/*",
    41  		},
    42  		{
    43  			val:        "~/apache/httpd.conf",
    44  			errMessage: ErrPathMustBeAbsolute,
    45  		},
    46  		{
    47  			val:        "../../../etc/apache/httpd.conf",
    48  			errMessage: ErrPathMustBeAbsolute,
    49  		},
    50  		{
    51  			val:        "/etc/apache/./httpd.conf",
    52  			errMessage: ErrPathMustBeAbsolute,
    53  		},
    54  		{
    55  			val:        "*/",
    56  			errMessage: ErrPathMustBeAbsolute,
    57  		},
    58  		{
    59  			val:        "~/",
    60  			errMessage: ErrPathMustBeAbsolute,
    61  		},
    62  		{
    63  			val:            "/run/..data",
    64  			fieldValueType: eval.PatternValueType,
    65  		},
    66  		{
    67  			val:            "./data",
    68  			fieldValueType: eval.PatternValueType,
    69  			errMessage:     ErrPathMustBeAbsolute,
    70  		},
    71  		{
    72  			val:            "../data",
    73  			fieldValueType: eval.PatternValueType,
    74  			errMessage:     ErrPathMustBeAbsolute,
    75  		},
    76  		{
    77  			val:            "/data/../a",
    78  			fieldValueType: eval.PatternValueType,
    79  			errMessage:     ErrPathMustBeAbsolute,
    80  		},
    81  		{
    82  			val:            "*/data",
    83  			fieldValueType: eval.PatternValueType,
    84  		},
    85  		{
    86  			val:            ".*",
    87  			fieldValueType: eval.RegexpValueType,
    88  			errMessage:     ErrPathMustBeAbsolute,
    89  		},
    90  		{
    91  			val:            "/etc/*",
    92  			fieldValueType: eval.PatternValueType,
    93  		},
    94  		{
    95  			val:            "*",
    96  			fieldValueType: eval.PatternValueType,
    97  			errMessage:     ErrPathMustBeAbsolute,
    98  		},
    99  		{
   100  			val:        maxDepthPath,
   101  			errMessage: ErrPathMustBeAbsolute,
   102  		},
   103  		{
   104  			val:        maxSegmentPath,
   105  			errMessage: ErrPathMustBeAbsolute,
   106  		},
   107  	}
   108  
   109  	for _, test := range tests {
   110  		err := mod.ValidateField("open.file.path", eval.FieldValue{Value: test.val})
   111  		if err != nil && test.errMessage == "" {
   112  			t.Errorf("shouldn't return an error: %s", err)
   113  		}
   114  		if err != nil && !strings.Contains(err.Error(), test.errMessage) {
   115  			t.Errorf("Error message is `%s`, wanted it to contain `%s`", err.Error(), test.errMessage)
   116  		}
   117  	}
   118  }
   119  
   120  func TestSetFieldValue(t *testing.T) {
   121  	var readOnlyError *eval.ErrFieldReadOnly
   122  	var fieldNotSupportedError *eval.ErrNotSupported
   123  
   124  	event := NewFakeEvent()
   125  	for _, field := range event.GetFields() {
   126  		kind, err := event.GetFieldType(field)
   127  		if err != nil {
   128  			t.Fatal(err)
   129  		}
   130  
   131  		switch kind {
   132  		case reflect.String:
   133  			err = event.SetFieldValue(field, "aaa")
   134  			if err != nil {
   135  				if errors.As(err, &readOnlyError) {
   136  					continue
   137  				}
   138  				t.Error(err)
   139  			}
   140  			value, err := event.GetFieldValue(field)
   141  			if err != nil {
   142  				if errors.As(err, &fieldNotSupportedError) {
   143  					continue
   144  				}
   145  				t.Errorf("unable to get the expected `%s` value: %v", field, err)
   146  			}
   147  			switch v := value.(type) {
   148  			case string:
   149  				if v != "aaa" {
   150  					t.Errorf("unable to get the expected `%s` value: %v", field, v)
   151  				}
   152  			case []string:
   153  				if v[0] != "aaa" {
   154  					t.Errorf("unable to get the expected `%s` value: %v", field, v)
   155  				}
   156  			default:
   157  				t.Errorf("unable to get the expected `%s` value: %v", field, v)
   158  			}
   159  		case reflect.Int:
   160  			err = event.SetFieldValue(field, 123)
   161  			if err != nil {
   162  				if errors.As(err, &readOnlyError) {
   163  					continue
   164  				}
   165  				t.Error(err)
   166  			}
   167  			value, err := event.GetFieldValue(field)
   168  			if err != nil {
   169  				if errors.As(err, &fieldNotSupportedError) {
   170  					continue
   171  				}
   172  				t.Errorf("unable to get the expected `%s` value: %v", field, err)
   173  			}
   174  			switch v := value.(type) {
   175  			case int:
   176  				if v != 123 {
   177  					t.Errorf("unable to get the expected `%s` value: %v", field, v)
   178  				}
   179  			case []int:
   180  				if v[0] != 123 {
   181  					t.Errorf("unable to get the expected `%s` value: %v", field, v)
   182  				}
   183  			default:
   184  				t.Errorf("unable to get the expected `%s` value: %v", field, v)
   185  			}
   186  		case reflect.Bool:
   187  			err = event.SetFieldValue(field, true)
   188  			if err != nil {
   189  				if errors.As(err, &readOnlyError) {
   190  					continue
   191  				}
   192  				t.Error(err)
   193  			}
   194  			value, err := event.GetFieldValue(field)
   195  			if err != nil {
   196  				if errors.As(err, &fieldNotSupportedError) {
   197  					continue
   198  				}
   199  				t.Errorf("unable to get the expected `%s` value: %v", field, err)
   200  			}
   201  			switch v := value.(type) {
   202  			case bool:
   203  				if !v {
   204  					t.Errorf("unable to get the expected `%s` value: %v", field, v)
   205  				}
   206  			case []bool:
   207  				if !v[0] {
   208  					t.Errorf("unable to get the expected `%s` value: %v", field, v)
   209  				}
   210  			default:
   211  				t.Errorf("unable to get the expected `%s` value: %v", field, v)
   212  			}
   213  		case reflect.Struct:
   214  			switch field {
   215  			case "network.destination.ip", "network.source.ip":
   216  				ip, ipnet, err := net.ParseCIDR("127.0.0.1/24")
   217  				if err != nil {
   218  					t.Error(err)
   219  				}
   220  
   221  				if err = event.SetFieldValue(field, *ipnet); err != nil {
   222  					t.Error(err)
   223  				}
   224  				if value, err := event.GetFieldValue(field); err != nil || value.(net.IPNet).IP.Equal(ip) {
   225  					t.Errorf("unable to get the expected value: %v", err)
   226  				}
   227  			}
   228  		default:
   229  			t.Errorf("type of field %s unknown: %v", field, kind)
   230  		}
   231  	}
   232  }