1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
|
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
}
|