github.com/DataDog/datadog-agent/pkg/security/secl@v0.55.0-devel.0.20240517055856-10c4965fea94/compiler/eval/evaluators.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  // Package eval holds eval related files
     7  package eval
     8  
     9  import (
    10  	"net"
    11  
    12  	"github.com/DataDog/datadog-agent/pkg/security/secl/compiler/ast"
    13  )
    14  
    15  // Evaluator is the interface of an evaluator
    16  type Evaluator interface {
    17  	Eval(ctx *Context) interface{}
    18  	IsDeterministicFor(field Field) bool
    19  	GetField() string
    20  	IsStatic() bool
    21  }
    22  
    23  // BoolEvaluator returns a bool as result of the evaluation
    24  type BoolEvaluator struct {
    25  	EvalFnc     BoolEvalFnc
    26  	Field       Field
    27  	Value       bool
    28  	Weight      int
    29  	OpOverrides *OpOverrides
    30  
    31  	// used during compilation of partial
    32  	isDeterministic bool
    33  }
    34  
    35  // Eval returns the result of the evaluation
    36  func (b *BoolEvaluator) Eval(ctx *Context) interface{} {
    37  	return b.EvalFnc(ctx)
    38  }
    39  
    40  // IsDeterministicFor returns whether the evaluator is partial
    41  func (b *BoolEvaluator) IsDeterministicFor(field Field) bool {
    42  	return b.isDeterministic || (b.Field != "" && b.Field == field)
    43  }
    44  
    45  // GetField returns field name used by this evaluator
    46  func (b *BoolEvaluator) GetField() string {
    47  	return b.Field
    48  }
    49  
    50  // IsStatic returns whether the evaluator is a scalar
    51  func (b *BoolEvaluator) IsStatic() bool {
    52  	return b.EvalFnc == nil
    53  }
    54  
    55  // IntEvaluator returns an int as result of the evaluation
    56  type IntEvaluator struct {
    57  	EvalFnc     func(ctx *Context) int
    58  	Field       Field
    59  	Value       int
    60  	Weight      int
    61  	OpOverrides *OpOverrides
    62  
    63  	// used during compilation of partial
    64  	isDeterministic           bool
    65  	isDuration                bool
    66  	isFromArithmeticOperation bool
    67  }
    68  
    69  // Eval returns the result of the evaluation
    70  func (i *IntEvaluator) Eval(ctx *Context) interface{} {
    71  	return i.EvalFnc(ctx)
    72  }
    73  
    74  // IsDeterministicFor returns whether the evaluator is partial
    75  func (i *IntEvaluator) IsDeterministicFor(field Field) bool {
    76  	return i.isDeterministic || (i.Field != "" && i.Field == field)
    77  }
    78  
    79  // GetField returns field name used by this evaluator
    80  func (i *IntEvaluator) GetField() string {
    81  	return i.Field
    82  }
    83  
    84  // IsStatic returns whether the evaluator is a scalar
    85  func (i *IntEvaluator) IsStatic() bool {
    86  	return i.EvalFnc == nil
    87  }
    88  
    89  // StringEvaluator returns a string as result of the evaluation
    90  type StringEvaluator struct {
    91  	EvalFnc       func(ctx *Context) string
    92  	Field         Field
    93  	Value         string
    94  	Weight        int
    95  	OpOverrides   *OpOverrides
    96  	ValueType     FieldValueType
    97  	StringCmpOpts StringCmpOpts // only Field evaluator can set this value
    98  
    99  	// used during compilation of partial
   100  	isDeterministic bool
   101  }
   102  
   103  // Eval returns the result of the evaluation
   104  func (s *StringEvaluator) Eval(ctx *Context) interface{} {
   105  	return s.EvalFnc(ctx)
   106  }
   107  
   108  // IsDeterministicFor returns whether the evaluator is partial
   109  func (s *StringEvaluator) IsDeterministicFor(field Field) bool {
   110  	return s.isDeterministic || (s.Field != "" && s.Field == field)
   111  }
   112  
   113  // GetField returns field name used by this evaluator
   114  func (s *StringEvaluator) GetField() string {
   115  	return s.Field
   116  }
   117  
   118  // IsStatic returns whether the evaluator is a scalar
   119  func (s *StringEvaluator) IsStatic() bool {
   120  	return s.EvalFnc == nil
   121  }
   122  
   123  // GetValue returns the evaluator value
   124  func (s *StringEvaluator) GetValue(ctx *Context) string {
   125  	if s.EvalFnc == nil {
   126  		return s.Value
   127  	}
   128  	return s.EvalFnc(ctx)
   129  }
   130  
   131  // ToStringMatcher returns a StringMatcher of the evaluator
   132  func (s *StringEvaluator) ToStringMatcher(opts StringCmpOpts) (StringMatcher, error) {
   133  	if s.IsStatic() {
   134  		matcher, err := NewStringMatcher(s.ValueType, s.Value, opts)
   135  		if err != nil {
   136  			return nil, err
   137  		}
   138  		return matcher, nil
   139  	}
   140  
   141  	return nil, nil
   142  }
   143  
   144  // StringArrayEvaluator returns an array of strings
   145  type StringArrayEvaluator struct {
   146  	EvalFnc       func(ctx *Context) []string
   147  	Values        []string
   148  	Field         Field
   149  	Weight        int
   150  	OpOverrides   *OpOverrides
   151  	StringCmpOpts StringCmpOpts // only Field evaluator can set this value
   152  
   153  	// used during compilation of partial
   154  	isDeterministic bool
   155  }
   156  
   157  // Eval returns the result of the evaluation
   158  func (s *StringArrayEvaluator) Eval(ctx *Context) interface{} {
   159  	return s.EvalFnc(ctx)
   160  }
   161  
   162  // IsDeterministicFor returns whether the evaluator is partial
   163  func (s *StringArrayEvaluator) IsDeterministicFor(field Field) bool {
   164  	return s.isDeterministic || (s.Field != "" && s.Field == field)
   165  }
   166  
   167  // GetField returns field name used by this evaluator
   168  func (s *StringArrayEvaluator) GetField() string {
   169  	return s.Field
   170  }
   171  
   172  // IsStatic returns whether the evaluator is a scalar
   173  func (s *StringArrayEvaluator) IsStatic() bool {
   174  	return s.EvalFnc == nil
   175  }
   176  
   177  // AppendValue append the given value
   178  func (s *StringArrayEvaluator) AppendValue(value string) {
   179  	s.Values = append(s.Values, value)
   180  }
   181  
   182  // StringValuesEvaluator returns an array of strings
   183  type StringValuesEvaluator struct {
   184  	EvalFnc func(ctx *Context) *StringValues
   185  	Values  StringValues
   186  	Weight  int
   187  
   188  	// used during compilation of partial
   189  	isDeterministic bool
   190  }
   191  
   192  // Eval returns the result of the evaluation
   193  func (s *StringValuesEvaluator) Eval(ctx *Context) interface{} {
   194  	return s.EvalFnc(ctx)
   195  }
   196  
   197  // IsDeterministicFor returns whether the evaluator is partial
   198  func (s *StringValuesEvaluator) IsDeterministicFor(_ Field) bool {
   199  	return s.isDeterministic
   200  }
   201  
   202  // GetField returns field name used by this evaluator
   203  func (s *StringValuesEvaluator) GetField() string {
   204  	return ""
   205  }
   206  
   207  // IsStatic returns whether the evaluator is a scalar
   208  func (s *StringValuesEvaluator) IsStatic() bool {
   209  	return s.EvalFnc == nil
   210  }
   211  
   212  // Compile the underlying StringValues
   213  func (s *StringValuesEvaluator) Compile(opts StringCmpOpts) error {
   214  	return s.Values.Compile(opts)
   215  }
   216  
   217  // SetFieldValues apply field values
   218  func (s *StringValuesEvaluator) SetFieldValues(values ...FieldValue) error {
   219  	return s.Values.SetFieldValues(values...)
   220  }
   221  
   222  // AppendMembers add members to the evaluator
   223  func (s *StringValuesEvaluator) AppendMembers(members ...ast.StringMember) {
   224  	for _, member := range members {
   225  		var value FieldValue
   226  		if member.Pattern != nil {
   227  			value = FieldValue{
   228  				Value: *member.Pattern,
   229  				Type:  PatternValueType,
   230  			}
   231  		} else if member.Regexp != nil {
   232  			value = FieldValue{
   233  				Value: *member.Regexp,
   234  				Type:  RegexpValueType,
   235  			}
   236  		} else {
   237  			value = FieldValue{
   238  				Value: *member.String,
   239  				Type:  ScalarValueType,
   240  			}
   241  		}
   242  		s.Values.AppendFieldValue(value)
   243  	}
   244  }
   245  
   246  // IntArrayEvaluator returns an array of int
   247  type IntArrayEvaluator struct {
   248  	EvalFnc     func(ctx *Context) []int
   249  	Field       Field
   250  	Values      []int
   251  	Weight      int
   252  	OpOverrides *OpOverrides
   253  
   254  	// used during compilation of partial
   255  	isDeterministic bool
   256  }
   257  
   258  // Eval returns the result of the evaluation
   259  func (i *IntArrayEvaluator) Eval(ctx *Context) interface{} {
   260  	return i.EvalFnc(ctx)
   261  }
   262  
   263  // IsDeterministicFor returns whether the evaluator is partial
   264  func (i *IntArrayEvaluator) IsDeterministicFor(field Field) bool {
   265  	return i.isDeterministic || (i.Field != "" && i.Field == field)
   266  }
   267  
   268  // GetField returns field name used by this evaluator
   269  func (i *IntArrayEvaluator) GetField() string {
   270  	return i.Field
   271  }
   272  
   273  // IsStatic returns whether the evaluator is a scalar
   274  func (i *IntArrayEvaluator) IsStatic() bool {
   275  	return i.EvalFnc == nil
   276  }
   277  
   278  // AppendValues to the array evaluator
   279  func (i *IntArrayEvaluator) AppendValues(values ...int) {
   280  	i.Values = append(i.Values, values...)
   281  }
   282  
   283  // BoolArrayEvaluator returns an array of bool
   284  type BoolArrayEvaluator struct {
   285  	EvalFnc     func(ctx *Context) []bool
   286  	Field       Field
   287  	Values      []bool
   288  	Weight      int
   289  	OpOverrides *OpOverrides
   290  
   291  	// used during compilation of partial
   292  	isDeterministic bool
   293  }
   294  
   295  // Eval returns the result of the evaluation
   296  func (b *BoolArrayEvaluator) Eval(ctx *Context) interface{} {
   297  	return b.EvalFnc(ctx)
   298  }
   299  
   300  // IsDeterministicFor returns whether the evaluator is partial
   301  func (b *BoolArrayEvaluator) IsDeterministicFor(field Field) bool {
   302  	return b.isDeterministic || (b.Field != "" && b.Field == field)
   303  }
   304  
   305  // GetField returns field name used by this evaluator
   306  func (b *BoolArrayEvaluator) GetField() string {
   307  	return b.Field
   308  }
   309  
   310  // IsStatic returns whether the evaluator is a scalar
   311  func (b *BoolArrayEvaluator) IsStatic() bool {
   312  	return b.EvalFnc == nil
   313  }
   314  
   315  // CIDREvaluator returns a net.IP
   316  type CIDREvaluator struct {
   317  	EvalFnc     func(ctx *Context) net.IPNet
   318  	Field       Field
   319  	Value       net.IPNet
   320  	Weight      int
   321  	OpOverrides *OpOverrides
   322  	ValueType   FieldValueType
   323  
   324  	// used during compilation of partial
   325  	isDeterministic bool
   326  }
   327  
   328  // Eval returns the result of the evaluation
   329  func (s *CIDREvaluator) Eval(ctx *Context) interface{} {
   330  	return s.EvalFnc(ctx)
   331  }
   332  
   333  // IsDeterministicFor returns whether the evaluator is partial
   334  func (s *CIDREvaluator) IsDeterministicFor(field Field) bool {
   335  	return s.isDeterministic || (s.Field != "" && s.Field == field)
   336  }
   337  
   338  // GetField returns field name used by this evaluator
   339  func (s *CIDREvaluator) GetField() string {
   340  	return s.Field
   341  }
   342  
   343  // IsStatic returns whether the evaluator is a scalar
   344  func (s *CIDREvaluator) IsStatic() bool {
   345  	return s.EvalFnc == nil
   346  }
   347  
   348  // CIDRValuesEvaluator returns a net.IP
   349  type CIDRValuesEvaluator struct {
   350  	EvalFnc   func(ctx *Context) *CIDRValues
   351  	Value     CIDRValues
   352  	Weight    int
   353  	ValueType FieldValueType
   354  
   355  	// used during compilation of partial
   356  	isDeterministic bool
   357  }
   358  
   359  // Eval returns the result of the evaluation
   360  func (s *CIDRValuesEvaluator) Eval(ctx *Context) interface{} {
   361  	return s.EvalFnc(ctx)
   362  }
   363  
   364  // IsDeterministicFor returns whether the evaluator is partial
   365  func (s *CIDRValuesEvaluator) IsDeterministicFor(_ Field) bool {
   366  	return s.isDeterministic
   367  }
   368  
   369  // GetField returns field name used by this evaluator
   370  func (s *CIDRValuesEvaluator) GetField() string {
   371  	return ""
   372  }
   373  
   374  // IsStatic returns whether the evaluator is a scalar
   375  func (s *CIDRValuesEvaluator) IsStatic() bool {
   376  	return s.EvalFnc == nil
   377  }
   378  
   379  // CIDRArrayEvaluator returns an array of net.IPNet
   380  type CIDRArrayEvaluator struct {
   381  	EvalFnc     func(ctx *Context) []net.IPNet
   382  	Field       Field
   383  	Value       []net.IPNet
   384  	Weight      int
   385  	OpOverrides *OpOverrides
   386  	ValueType   FieldValueType
   387  
   388  	// used during compilation of partial
   389  	isDeterministic bool
   390  }
   391  
   392  // Eval returns the result of the evaluation
   393  func (s *CIDRArrayEvaluator) Eval(ctx *Context) interface{} {
   394  	return s.EvalFnc(ctx)
   395  }
   396  
   397  // IsDeterministicFor returns whether the evaluator is partial
   398  func (s *CIDRArrayEvaluator) IsDeterministicFor(field Field) bool {
   399  	return s.isDeterministic || (s.Field != "" && s.Field == field)
   400  }
   401  
   402  // GetField returns field name used by this evaluator
   403  func (s *CIDRArrayEvaluator) GetField() string {
   404  	return s.Field
   405  }
   406  
   407  // IsStatic returns whether the evaluator is a scalar
   408  func (s *CIDRArrayEvaluator) IsStatic() bool {
   409  	return s.EvalFnc == nil
   410  }