diff options
author | Emiliano Ciavatta | 2020-04-15 17:08:03 +0000 |
---|---|---|
committer | Emiliano Ciavatta | 2020-04-15 17:08:03 +0000 |
commit | 819d8af4f57e78724a2de02707bd4883715763bc (patch) | |
tree | 4db8833a9c8f0a157e65dbefdedda188d536486c /rules_manager.go | |
parent | a32ff72dfe0c2aba3e51bd9536d5e11a30a9d73d (diff) |
Implement FillWithMatchedRules
Diffstat (limited to 'rules_manager.go')
-rw-r--r-- | rules_manager.go | 87 |
1 files changed, 80 insertions, 7 deletions
diff --git a/rules_manager.go b/rules_manager.go index 89b6153..fdd3eaa 100644 --- a/rules_manager.go +++ b/rules_manager.go @@ -25,17 +25,17 @@ type RegexFlags struct { } type Pattern struct { - Regex string `json:"regex" binding:"min=1" bson:"regex"` + Regex string `json:"regex" binding:"required,min=1" bson:"regex"` Flags RegexFlags `json:"flags" bson:"flags,omitempty"` MinOccurrences uint `json:"min_occurrences" bson:"min_occurrences,omitempty"` MaxOccurrences uint `json:"max_occurrences" binding:"omitempty,gtefield=MinOccurrences" bson:"max_occurrences,omitempty"` Direction uint8 `json:"direction" binding:"omitempty,max=2" bson:"direction,omitempty"` - internalID int + internalID uint } type Filter struct { ServicePort uint16 `json:"service_port" bson:"service_port,omitempty"` - ClientAddress string `json:"client_address" binding:"omitempty,ip_addr" bson:"client_address,omitempty"` + ClientAddress string `json:"client_address" binding:"omitempty,ip" bson:"client_address,omitempty"` ClientPort uint16 `json:"client_port" bson:"client_port,omitempty"` MinDuration uint `json:"min_duration" bson:"min_duration,omitempty"` MaxDuration uint `json:"max_duration" binding:"omitempty,gtefield=MinDuration" bson:"max_duration,omitempty"` @@ -66,6 +66,7 @@ type RulesManager interface { GetRule(id RowID) (Rule, bool) UpdateRule(context context.Context, id RowID, rule Rule) (bool, error) GetRules() []Rule + SetFlag(context context.Context, flagRegex string) error FillWithMatchedRules(connection *Connection, clientMatches map[uint][]PatternSlice, serverMatches map[uint][]PatternSlice) DatabaseUpdateChannel() chan RulesDatabase } @@ -75,7 +76,7 @@ type rulesManagerImpl struct { rules map[RowID]Rule rulesByName map[string]Rule patterns []*hyperscan.Pattern - patternsIds map[string]int + patternsIds map[string]uint mutex sync.Mutex databaseUpdated chan RulesDatabase validate *validator.Validate @@ -87,7 +88,7 @@ func NewRulesManager(storage Storage) RulesManager { rules: make(map[RowID]Rule), rulesByName: make(map[string]Rule), patterns: make([]*hyperscan.Pattern, 0), - patternsIds: make(map[string]int), + patternsIds: make(map[string]uint), mutex: sync.Mutex{}, databaseUpdated: make(chan RulesDatabase, 1), validate: validator.New(), @@ -194,6 +195,78 @@ func (rm *rulesManagerImpl) SetFlag(context context.Context, flagRegex string) e func (rm *rulesManagerImpl) FillWithMatchedRules(connection *Connection, clientMatches map[uint][]PatternSlice, serverMatches map[uint][]PatternSlice) { + rm.mutex.Lock() + + filterFunctions := []func (rule Rule)bool { + func(rule Rule) bool { + return rule.Filter.ClientAddress == "" || connection.SourceIP == rule.Filter.ClientAddress + }, + func(rule Rule) bool { + return rule.Filter.ClientPort == 0 || connection.SourcePort == rule.Filter.ClientPort + }, + func(rule Rule) bool { + return rule.Filter.ServicePort == 0 || connection.DestinationPort == rule.Filter.ServicePort + }, + func(rule Rule) bool { + return rule.Filter.MinDuration == 0 || uint(connection.ClosedAt.Sub(connection.StartedAt).Milliseconds()) >= + rule.Filter.MinDuration + }, + func(rule Rule) bool { + return rule.Filter.MaxDuration == 0 || uint(connection.ClosedAt.Sub(connection.StartedAt).Milliseconds()) <= + rule.Filter.MaxDuration + }, + func(rule Rule) bool { + return rule.Filter.MinBytes == 0 || uint(connection.ClientBytes + connection.ServerBytes) >= + rule.Filter.MinBytes + }, + func(rule Rule) bool { + return rule.Filter.MaxBytes == 0 || uint(connection.ClientBytes + connection.ServerBytes) <= + rule.Filter.MinBytes + }, + } + + connection.MatchedRules = make([]RowID, 0) + for _, rule := range rm.rules { + matching := true + for _, f := range filterFunctions { + if !f(rule) { + matching = false + break + } + } + + for _, p := range rule.Patterns { + checkOccurrences := func(occurrences []PatternSlice) bool { + return (p.MinOccurrences == 0 || uint(len(occurrences)) >= p.MinOccurrences) && + (p.MaxOccurrences == 0 || uint(len(occurrences)) <= p.MaxOccurrences) + } + clientOccurrences, clientPresent := clientMatches[p.internalID] + serverOccurrences, serverPresent := serverMatches[p.internalID] + + if p.Direction == DirectionToServer { + if !clientPresent || !checkOccurrences(clientOccurrences) { + matching = false + break + } + } else if p.Direction == DirectionToClient { + if !serverPresent || !checkOccurrences(serverOccurrences) { + matching = false + break + } + } else { + if !(clientPresent || serverPresent) || !checkOccurrences(append(clientOccurrences, serverOccurrences...)) { + matching = false + break + } + } + } + + if matching { + connection.MatchedRules = append(connection.MatchedRules, rule.ID) + } + } + + rm.mutex.Unlock() } func (rm *rulesManagerImpl) DatabaseUpdateChannel() chan RulesDatabase { @@ -226,7 +299,7 @@ func (rm *rulesManagerImpl) validateAndAddRuleLocal(rule *Rule) error { } id := len(rm.patternsIds) + len(newPatterns) - rule.Patterns[i].internalID = id + rule.Patterns[i].internalID = uint(id) compiledPattern.Id = id newPatterns = append(newPatterns, compiledPattern) duplicatePatterns[regex] = true @@ -235,7 +308,7 @@ 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()] = startId + id + rm.patternsIds[pattern.String()] = uint(startId + id) } rm.rules[rule.ID] = *rule |