176 lines
4.3 KiB
Go
176 lines
4.3 KiB
Go
package filter
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
|
|
"github.com/ffuf/ffuf/v2/pkg/ffuf"
|
|
)
|
|
|
|
// MatcherManager handles both filters and matchers.
|
|
type MatcherManager struct {
|
|
IsCalibrated bool
|
|
Mutex sync.Mutex
|
|
Matchers map[string]ffuf.FilterProvider
|
|
Filters map[string]ffuf.FilterProvider
|
|
PerDomainFilters map[string]*PerDomainFilter
|
|
}
|
|
|
|
type PerDomainFilter struct {
|
|
IsCalibrated bool
|
|
Filters map[string]ffuf.FilterProvider
|
|
}
|
|
|
|
func NewPerDomainFilter(globfilters map[string]ffuf.FilterProvider) *PerDomainFilter {
|
|
return &PerDomainFilter{IsCalibrated: false, Filters: globfilters}
|
|
}
|
|
|
|
func (p *PerDomainFilter) SetCalibrated(value bool) {
|
|
p.IsCalibrated = value
|
|
}
|
|
|
|
func NewMatcherManager() ffuf.MatcherManager {
|
|
return &MatcherManager{
|
|
IsCalibrated: false,
|
|
Matchers: make(map[string]ffuf.FilterProvider),
|
|
Filters: make(map[string]ffuf.FilterProvider),
|
|
PerDomainFilters: make(map[string]*PerDomainFilter),
|
|
}
|
|
}
|
|
|
|
func (f *MatcherManager) SetCalibrated(value bool) {
|
|
f.IsCalibrated = value
|
|
}
|
|
|
|
func (f *MatcherManager) SetCalibratedForHost(host string, value bool) {
|
|
if f.PerDomainFilters[host] != nil {
|
|
f.PerDomainFilters[host].IsCalibrated = value
|
|
} else {
|
|
newFilter := NewPerDomainFilter(f.Filters)
|
|
newFilter.IsCalibrated = true
|
|
f.PerDomainFilters[host] = newFilter
|
|
}
|
|
}
|
|
|
|
func NewFilterByName(name string, value string) (ffuf.FilterProvider, error) {
|
|
if name == "status" {
|
|
return NewStatusFilter(value)
|
|
}
|
|
if name == "size" {
|
|
return NewSizeFilter(value)
|
|
}
|
|
if name == "word" {
|
|
return NewWordFilter(value)
|
|
}
|
|
if name == "line" {
|
|
return NewLineFilter(value)
|
|
}
|
|
if name == "regexp" {
|
|
return NewRegexpFilter(value)
|
|
}
|
|
if name == "time" {
|
|
return NewTimeFilter(value)
|
|
}
|
|
return nil, fmt.Errorf("Could not create filter with name %s", name)
|
|
}
|
|
|
|
//AddFilter adds a new filter to MatcherManager
|
|
func (f *MatcherManager) AddFilter(name string, option string, replace bool) error {
|
|
f.Mutex.Lock()
|
|
defer f.Mutex.Unlock()
|
|
newf, err := NewFilterByName(name, option)
|
|
if err == nil {
|
|
// valid filter create or append
|
|
if f.Filters[name] == nil || replace {
|
|
f.Filters[name] = newf
|
|
} else {
|
|
newoption := f.Filters[name].Repr() + "," + option
|
|
newerf, err := NewFilterByName(name, newoption)
|
|
if err == nil {
|
|
f.Filters[name] = newerf
|
|
}
|
|
}
|
|
}
|
|
return err
|
|
}
|
|
|
|
//AddPerDomainFilter adds a new filter to PerDomainFilter configuration
|
|
func (f *MatcherManager) AddPerDomainFilter(domain string, name string, option string) error {
|
|
f.Mutex.Lock()
|
|
defer f.Mutex.Unlock()
|
|
var pdFilters *PerDomainFilter
|
|
if filter, ok := f.PerDomainFilters[domain]; ok {
|
|
pdFilters = filter
|
|
} else {
|
|
pdFilters = NewPerDomainFilter(f.Filters)
|
|
}
|
|
newf, err := NewFilterByName(name, option)
|
|
if err == nil {
|
|
// valid filter create or append
|
|
if pdFilters.Filters[name] == nil {
|
|
pdFilters.Filters[name] = newf
|
|
} else {
|
|
newoption := pdFilters.Filters[name].Repr() + "," + option
|
|
newerf, err := NewFilterByName(name, newoption)
|
|
if err == nil {
|
|
pdFilters.Filters[name] = newerf
|
|
}
|
|
}
|
|
}
|
|
f.PerDomainFilters[domain] = pdFilters
|
|
return err
|
|
}
|
|
|
|
//RemoveFilter removes a filter of a given type
|
|
func (f *MatcherManager) RemoveFilter(name string) {
|
|
f.Mutex.Lock()
|
|
defer f.Mutex.Unlock()
|
|
delete(f.Filters, name)
|
|
}
|
|
|
|
//AddMatcher adds a new matcher to Config
|
|
func (f *MatcherManager) AddMatcher(name string, option string) error {
|
|
f.Mutex.Lock()
|
|
defer f.Mutex.Unlock()
|
|
newf, err := NewFilterByName(name, option)
|
|
if err == nil {
|
|
// valid filter create or append
|
|
if f.Matchers[name] == nil {
|
|
f.Matchers[name] = newf
|
|
} else {
|
|
newoption := f.Matchers[name].Repr() + "," + option
|
|
newerf, err := NewFilterByName(name, newoption)
|
|
if err == nil {
|
|
f.Matchers[name] = newerf
|
|
}
|
|
}
|
|
}
|
|
return err
|
|
}
|
|
|
|
func (f *MatcherManager) GetFilters() map[string]ffuf.FilterProvider {
|
|
return f.Filters
|
|
}
|
|
|
|
func (f *MatcherManager) GetMatchers() map[string]ffuf.FilterProvider {
|
|
return f.Matchers
|
|
}
|
|
|
|
func (f *MatcherManager) FiltersForDomain(domain string) map[string]ffuf.FilterProvider {
|
|
if f.PerDomainFilters[domain] == nil {
|
|
return f.Filters
|
|
}
|
|
return f.PerDomainFilters[domain].Filters
|
|
}
|
|
|
|
func (f *MatcherManager) CalibratedForDomain(domain string) bool {
|
|
if f.PerDomainFilters[domain] != nil {
|
|
return f.PerDomainFilters[domain].IsCalibrated
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (f *MatcherManager) Calibrated() bool {
|
|
return f.IsCalibrated
|
|
}
|