crowdsec/pkg/exprhelpers/exprlib.go

144 lines
3.3 KiB
Go
Raw Normal View History

2020-05-15 09:39:16 +00:00
package exprhelpers
import (
2020-05-27 14:31:08 +00:00
"bufio"
2020-05-28 08:59:43 +00:00
"fmt"
"net"
2020-05-27 14:31:08 +00:00
"os"
"path"
"regexp"
2020-05-15 09:39:16 +00:00
"strconv"
2020-05-22 11:55:48 +00:00
"strings"
"time"
2020-05-15 09:39:16 +00:00
"github.com/davecgh/go-spew/spew"
2020-05-15 09:39:16 +00:00
log "github.com/sirupsen/logrus"
)
2020-05-27 14:31:08 +00:00
var dataFile map[string][]string
var dataFileRegex map[string][]*regexp.Regexp
2020-05-15 09:39:16 +00:00
func Atof(x string) float64 {
log.Debugf("debug atof %s", x)
ret, err := strconv.ParseFloat(x, 64)
if err != nil {
log.Warningf("Atof : can't convert float '%s' : %v", x, err)
}
return ret
}
func Upper(s string) string {
return strings.ToUpper(s)
2020-05-22 11:55:48 +00:00
}
2020-05-15 09:39:16 +00:00
func GetExprEnv(ctx map[string]interface{}) map[string]interface{} {
var ExprLib = map[string]interface{}{
"Atof": Atof,
"JsonExtract": JsonExtract,
"JsonExtractUnescape": JsonExtractUnescape,
"JsonExtractLib": JsonExtractLib,
"File": File,
"RegexpInFile": RegexpInFile,
"Upper": Upper,
"IpInRange": IpInRange,
"TimeNow": TimeNow,
}
2020-05-15 09:39:16 +00:00
for k, v := range ctx {
ExprLib[k] = v
}
return ExprLib
}
2020-05-27 14:31:08 +00:00
func Init() error {
dataFile = make(map[string][]string)
dataFileRegex = make(map[string][]*regexp.Regexp)
return nil
}
func FileInit(fileFolder string, filename string, fileType string) error {
2020-07-03 16:26:23 +00:00
log.Debugf("init (folder:%s) (file:%s) (type:%s)", fileFolder, filename, fileType)
2020-05-27 14:31:08 +00:00
filepath := path.Join(fileFolder, filename)
file, err := os.Open(filepath)
if err != nil {
2020-05-27 15:56:52 +00:00
return err
2020-05-27 14:31:08 +00:00
}
defer file.Close()
if fileType == "" {
log.Debugf("ignored file %s%s because no type specified", fileFolder, filename)
return nil
}
2020-05-27 14:31:08 +00:00
if _, ok := dataFile[filename]; !ok {
dataFile[filename] = []string{}
}
scanner := bufio.NewScanner(file)
for scanner.Scan() {
if strings.HasPrefix(scanner.Text(), "#") { // allow comments
continue
}
if len(scanner.Text()) == 0 { //skip empty lines
continue
}
2020-05-27 14:31:08 +00:00
switch fileType {
2020-05-27 15:56:52 +00:00
case "regex", "regexp":
2020-05-27 14:31:08 +00:00
dataFileRegex[filename] = append(dataFileRegex[filename], regexp.MustCompile(scanner.Text()))
case "string":
dataFile[filename] = append(dataFile[filename], scanner.Text())
default:
2020-05-28 08:59:43 +00:00
return fmt.Errorf("unknown data type '%s' for : '%s'", fileType, filename)
2020-05-27 14:31:08 +00:00
}
}
if err := scanner.Err(); err != nil {
2020-05-27 15:56:52 +00:00
return err
2020-05-27 14:31:08 +00:00
}
return nil
}
func File(filename string) []string {
if _, ok := dataFile[filename]; ok {
return dataFile[filename]
}
log.Errorf("file '%s' (type:string) not found in expr library", filename)
log.Errorf("expr library : %s", spew.Sdump(dataFile))
2020-05-27 14:31:08 +00:00
return []string{}
}
func RegexpInFile(data string, filename string) bool {
if _, ok := dataFileRegex[filename]; ok {
for _, re := range dataFileRegex[filename] {
if re.Match([]byte(data)) {
return true
}
}
} else {
log.Errorf("file '%s' (type:regexp) not found in expr library", filename)
log.Errorf("expr library : %s", spew.Sdump(dataFileRegex))
2020-05-27 14:31:08 +00:00
}
return false
}
func IpInRange(ip string, ipRange string) bool {
var err error
var ipParsed net.IP
var ipRangeParsed *net.IPNet
ipParsed = net.ParseIP(ip)
if ipParsed == nil {
log.Debugf("'%s' is not a valid IP", ip)
return false
}
if _, ipRangeParsed, err = net.ParseCIDR(ipRange); err != nil {
log.Debugf("'%s' is not a valid IP Range", ipRange)
return false
}
if ipRangeParsed.Contains(ipParsed) {
return true
}
return false
}
func TimeNow() string {
return time.Now().Format(time.RFC3339)
}