From e029a04123dc77499d5e953ca81d6b849aa39252 Mon Sep 17 00:00:00 2001 From: Emiliano Ciavatta Date: Wed, 28 Jul 2021 13:33:46 +0200 Subject: Fix error in rule pattern management after hyperscan update --- rules_manager.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'rules_manager.go') diff --git a/rules_manager.go b/rules_manager.go index 5d6cded..736d561 100644 --- a/rules_manager.go +++ b/rules_manager.go @@ -21,12 +21,14 @@ import ( "context" "errors" "fmt" - "github.com/flier/gohs/hyperscan" - "github.com/go-playground/validator/v10" - log "github.com/sirupsen/logrus" "sort" + "strings" "sync" "time" + + "github.com/flier/gohs/hyperscan" + "github.com/go-playground/validator/v10" + log "github.com/sirupsen/logrus" ) const DirectionBoth = 0 @@ -336,7 +338,8 @@ func (rm *rulesManagerImpl) validateAndAddRuleLocal(rule *Rule) error { startID := len(rm.patterns) for id, pattern := range newPatterns { rm.patterns = append(rm.patterns, pattern) - rm.patternsIds[pattern.String()] = uint(startID + id) + regex := pattern.String() + rm.patternsIds[regex[strings.IndexByte(regex, ':')+1:]] = uint(startID + id) } rm.rules[rule.ID] = *rule @@ -363,7 +366,11 @@ func (rm *rulesManagerImpl) generateDatabase(version RowID) error { } func (p *Pattern) BuildPattern() (*hyperscan.Pattern, error) { - hp, err := hyperscan.ParsePattern(fmt.Sprintf("/%s/", p.Regex)) + if !strings.HasPrefix(p.Regex, "/") || !strings.HasSuffix(p.Regex, "/") { + p.Regex = fmt.Sprintf("/%s/", p.Regex) + } + + hp, err := hyperscan.ParsePattern(p.Regex) if err != nil { return nil, err } -- cgit v1.2.3-70-g09d2 From 49f9a5f352d4b54fa6331fe096be8206d8daa79a Mon Sep 17 00:00:00 2001 From: Emiliano Ciavatta Date: Wed, 28 Jul 2021 14:37:48 +0200 Subject: Update regex patterns management --- CHANGELOG.md | 4 +++- rules_manager.go | 15 ++++++++++----- rules_manager_test.go | 47 ++++++++++++++++++++++++----------------------- 3 files changed, 37 insertions(+), 29 deletions(-) (limited to 'rules_manager.go') diff --git a/CHANGELOG.md b/CHANGELOG.md index f33137c..9388543 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ - Update backend and frontend dependencies +- Added a control to not wrap regex around slashes if the user add a pattern that already has slashes + ## 1.20.12 -- Reached a stable version \ No newline at end of file +- Reached a stable version diff --git a/rules_manager.go b/rules_manager.go index 736d561..ed1932d 100644 --- a/rules_manager.go +++ b/rules_manager.go @@ -315,11 +315,20 @@ func (rm *rulesManagerImpl) validateAndAddRuleLocal(rule *Rule) error { return err } + regex := pattern.Regex + if !strings.HasPrefix(regex, "/") { + regex = fmt.Sprintf("/%s", regex) + } + if !strings.HasSuffix(regex, "/") { + regex = fmt.Sprintf("%s/", regex) + } + rule.Patterns[i].Regex = regex + compiledPattern, err := pattern.BuildPattern() if err != nil { return err } - regex := compiledPattern.String() + regex = compiledPattern.String() if _, isPresent := duplicatePatterns[regex]; isPresent { return errors.New("duplicate pattern") } @@ -366,10 +375,6 @@ func (rm *rulesManagerImpl) generateDatabase(version RowID) error { } func (p *Pattern) BuildPattern() (*hyperscan.Pattern, error) { - if !strings.HasPrefix(p.Regex, "/") || !strings.HasSuffix(p.Regex, "/") { - p.Regex = fmt.Sprintf("/%s/", p.Regex) - } - hp, err := hyperscan.ParsePattern(p.Regex) if err != nil { return nil, err diff --git a/rules_manager_test.go b/rules_manager_test.go index 215e601..d3f6d20 100644 --- a/rules_manager_test.go +++ b/rules_manager_test.go @@ -18,10 +18,11 @@ package main import ( - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "testing" "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestAddAndGetAllRules(t *testing.T) { @@ -150,17 +151,17 @@ func TestLoadAndUpdateRules(t *testing.T) { expectedIds := []RowID{NewRowID(), NewRowID(), NewRowID(), NewRowID()} rules := []interface{}{ Rule{ID: expectedIds[0], Name: "rule1", Color: "#fff", Patterns: []Pattern{ - {Regex: "pattern1", Flags: RegexFlags{Caseless: true}, Direction: DirectionToClient, internalID: 0}, + {Regex: "/pattern1/", Flags: RegexFlags{Caseless: true}, Direction: DirectionToClient, internalID: 0}, }}, Rule{ID: expectedIds[1], Name: "rule2", Color: "#eee", Patterns: []Pattern{ - {Regex: "pattern2", MinOccurrences: 1, MaxOccurrences: 3, Direction: DirectionToServer, internalID: 1}, + {Regex: "/pattern2/", MinOccurrences: 1, MaxOccurrences: 3, Direction: DirectionToServer, internalID: 1}, }}, Rule{ID: expectedIds[2], Name: "rule3", Color: "#ddd", Patterns: []Pattern{ - {Regex: "pattern2", Direction: DirectionBoth, internalID: 1}, - {Regex: "pattern3", Flags: RegexFlags{MultiLine: true}, internalID: 2}, + {Regex: "/pattern2/", Direction: DirectionBoth, internalID: 1}, + {Regex: "/pattern3/", Flags: RegexFlags{MultiLine: true}, internalID: 2}, }}, Rule{ID: expectedIds[3], Name: "rule4", Color: "#ccc", Patterns: []Pattern{ - {Regex: "pattern3", internalID: 3}, + {Regex: "/pattern3/", internalID: 3}, }}, } ids, err := wrapper.Storage.Insert(Rules).Context(wrapper.Context).Many(rules) @@ -224,7 +225,7 @@ func TestFillWithMatchedRules(t *testing.T) { assert.ElementsMatch(t, []RowID{emptyRule}, conn.MatchedRules) filterRule, err := rulesManager.AddRule(wrapper.Context, Rule{ - Name: "filter", + Name: "filter", Color: "#fff", Filter: Filter{ ServicePort: 80, @@ -239,19 +240,19 @@ func TestFillWithMatchedRules(t *testing.T) { require.NoError(t, err) checkVersion(t, rulesManager, filterRule) conn = &Connection{ - SourceIP: "10.10.10.10", - SourcePort: 60000, + SourceIP: "10.10.10.10", + SourcePort: 60000, DestinationPort: 80, - ClientBytes: 32, - ServerBytes: 32, - StartedAt: time.Now(), - ClosedAt: time.Now().Add(3 * time.Second), + ClientBytes: 32, + ServerBytes: 32, + StartedAt: time.Now(), + ClosedAt: time.Now().Add(3 * time.Second), } rulesManager.FillWithMatchedRules(conn, map[uint][]PatternSlice{}, map[uint][]PatternSlice{}) assert.ElementsMatch(t, []RowID{emptyRule, filterRule}, conn.MatchedRules) patternRule, err := rulesManager.AddRule(wrapper.Context, Rule{ - Name: "pattern", + Name: "pattern", Color: "#fff", Patterns: []Pattern{ {Regex: "pattern1", Direction: DirectionToClient, MinOccurrences: 1}, @@ -262,28 +263,28 @@ func TestFillWithMatchedRules(t *testing.T) { require.NoError(t, err) checkVersion(t, rulesManager, patternRule) conn = &Connection{} - rulesManager.FillWithMatchedRules(conn, map[uint][]PatternSlice{2: {{0, 0},{0, 0}}, 3: {{0, 0}}}, + rulesManager.FillWithMatchedRules(conn, map[uint][]PatternSlice{2: {{0, 0}, {0, 0}}, 3: {{0, 0}}}, map[uint][]PatternSlice{1: {{0, 0}}, 3: {{0, 0}}}) assert.ElementsMatch(t, []RowID{emptyRule, patternRule}, conn.MatchedRules) - rulesManager.FillWithMatchedRules(conn, map[uint][]PatternSlice{2: {{0, 0},{0, 0}}}, - map[uint][]PatternSlice{1: {{0, 0}}, 3: {{0, 0},{0, 0}}}) + rulesManager.FillWithMatchedRules(conn, map[uint][]PatternSlice{2: {{0, 0}, {0, 0}}}, + map[uint][]PatternSlice{1: {{0, 0}}, 3: {{0, 0}, {0, 0}}}) assert.ElementsMatch(t, []RowID{emptyRule, patternRule}, conn.MatchedRules) - rulesManager.FillWithMatchedRules(conn, map[uint][]PatternSlice{2: {{0, 0},{0, 0}}, 3: {{0, 0},{0, 0}}}, + rulesManager.FillWithMatchedRules(conn, map[uint][]PatternSlice{2: {{0, 0}, {0, 0}}, 3: {{0, 0}, {0, 0}}}, map[uint][]PatternSlice{1: {{0, 0}}}) assert.ElementsMatch(t, []RowID{emptyRule, patternRule}, conn.MatchedRules) - rulesManager.FillWithMatchedRules(conn, map[uint][]PatternSlice{2: {{0, 0},{0, 0}}, 3: {{0, 0}}}, + rulesManager.FillWithMatchedRules(conn, map[uint][]PatternSlice{2: {{0, 0}, {0, 0}}, 3: {{0, 0}}}, map[uint][]PatternSlice{3: {{0, 0}}}) assert.ElementsMatch(t, []RowID{emptyRule}, conn.MatchedRules) - rulesManager.FillWithMatchedRules(conn, map[uint][]PatternSlice{2: {{0, 0},{0, 0},{0, 0}}, 3: {{0, 0}}}, + rulesManager.FillWithMatchedRules(conn, map[uint][]PatternSlice{2: {{0, 0}, {0, 0}, {0, 0}}, 3: {{0, 0}}}, map[uint][]PatternSlice{1: {{0, 0}}, 3: {{0, 0}}}) assert.ElementsMatch(t, []RowID{emptyRule}, conn.MatchedRules) - rulesManager.FillWithMatchedRules(conn, map[uint][]PatternSlice{2: {{0, 0},{0, 0}}, 3: {{0, 0}}}, - map[uint][]PatternSlice{1: {{0, 0}}, 3: {{0, 0},{0, 0}}}) + rulesManager.FillWithMatchedRules(conn, map[uint][]PatternSlice{2: {{0, 0}, {0, 0}}, 3: {{0, 0}}}, + map[uint][]PatternSlice{1: {{0, 0}}, 3: {{0, 0}, {0, 0}}}) assert.ElementsMatch(t, []RowID{emptyRule}, conn.MatchedRules) wrapper.Destroy(t) -- cgit v1.2.3-70-g09d2