Compile translates the operator type field to its callback counterpart
()
| 107 | |
| 108 | // Compile translates the operator type field to its callback counterpart |
| 109 | func (o *Operator) Compile() error { |
| 110 | if o.isCompiled { |
| 111 | return nil |
| 112 | } |
| 113 | |
| 114 | // The only operator Type that can have the Data field empty are: |
| 115 | // Simple, Regexp, List. |
| 116 | // For List, because it uses List field and not Data field. |
| 117 | // For Simple and Regexp, because it can be useful to match on some |
| 118 | // operands that can in practice be equal to an empty string. This is the |
| 119 | // case, for example, when a request has a "bare" IP instead of a domain |
| 120 | // name, therefore DstHost field will be empty. You can match empty string |
| 121 | // with simple comparison or the "^$" regexp pattern. |
| 122 | if !(o.Type == Simple || o.Type == Regexp || o.Type == List) && |
| 123 | o.Operand != OpTrue && o.Data == "" { |
| 124 | return fmt.Errorf("Operand %s cannot be empty (%s)", o.Operand, o.Type) |
| 125 | } |
| 126 | |
| 127 | if o.Type == Simple { |
| 128 | if o.Operand == OpUserName { |
| 129 | // TODO: allow regexps, take into account users from containers. |
| 130 | u, err := user.Lookup(o.Data) |
| 131 | if err != nil { |
| 132 | return fmt.Errorf("user.name Operand error: %s", err) |
| 133 | } |
| 134 | o.cb = o.simpleCmp |
| 135 | o.Data = u.Uid |
| 136 | return nil |
| 137 | } else if o.Operand == OpProcessHashMD5 || o.Operand == OpProcessHashSHA1 { |
| 138 | o.cb = o.hashCmp |
| 139 | return nil |
| 140 | } |
| 141 | |
| 142 | o.cb = o.simpleCmp |
| 143 | |
| 144 | } else if o.Type == Regexp { |
| 145 | o.cb = o.reCmp |
| 146 | if o.Sensitive == false { |
| 147 | o.Data = strings.ToLower(o.Data) |
| 148 | } |
| 149 | re, err := regexp.Compile(o.Data) |
| 150 | if err != nil { |
| 151 | return err |
| 152 | } |
| 153 | o.re = re |
| 154 | } else if o.Type == List { |
| 155 | o.Operand = OpList |
| 156 | } else if o.Type == Network { |
| 157 | // Check if the operator's data is an alias present in the cache |
| 158 | if ipNets, found := AliasIPCache[o.Data]; found { |
| 159 | o.cb = func(value interface{}) bool { |
| 160 | ip := value.(net.IP) |
| 161 | matchFound := false |
| 162 | |
| 163 | for _, ipNet := range ipNets { |
| 164 | if ipNet.Contains(ip) { |
| 165 | matchFound = true |
| 166 | break |