Added filterlist integration

This commit is contained in:
ppacher
2020-04-01 09:12:06 +02:00
committed by Patrick Pacher
parent 61d31d4426
commit f96f8d8d6e
20 changed files with 1898 additions and 58 deletions

View File

@@ -24,6 +24,9 @@ var (
CfgOptionServiceEndpointsKey = "filter/serviceEndpoints"
cfgOptionServiceEndpoints config.StringArrayOption
CfgOptionFilterListKey = "filter/lists"
cfgOptionFilterLists config.StringArrayOption
CfgOptionBlockScopeLocalKey = "filter/blockLocal"
cfgOptionBlockScopeLocal config.IntOption // security level option
@@ -135,6 +138,22 @@ Examples:
cfgOptionServiceEndpoints = config.Concurrent.GetAsStringArray(CfgOptionServiceEndpointsKey, []string{})
cfgStringArrayOptions[CfgOptionServiceEndpointsKey] = cfgOptionServiceEndpoints
// Filter list IDs
err = config.Register(&config.Option{
Name: "Filterlists",
Key: CfgOptionFilterListKey,
Description: "Filter connections by matching the endpoint against configured filterlists",
OptType: config.OptTypeStringArray,
DefaultValue: []string{},
ExternalOptType: "filter list",
ValidationRegex: `^[a-zA-Z0-9\-]+$`,
})
if err != nil {
return err
}
cfgOptionFilterLists = config.Concurrent.GetAsStringArray(CfgOptionFilterListKey, []string{})
cfgStringArrayOptions[CfgOptionFilterListKey] = cfgOptionFilterLists
// Block Scope Local
err = config.Register(&config.Option{
Name: "Block Scope Local",

View File

@@ -6,6 +6,7 @@ import (
"github.com/safing/portbase/log"
"github.com/safing/portmaster/intel/filterlist"
"github.com/safing/portmaster/status"
"github.com/tevino/abool"
@@ -94,7 +95,7 @@ func NewLayeredProfile(localProfile *Profile) *LayeredProfile {
cfgOptionRemoveBlockedDNS,
)
// TODO: load referenced profiles
// TODO: load linked profiles.
// FUTURE: load forced company profile
new.layers = append(new.layers, localProfile)
@@ -154,7 +155,7 @@ func (lp *LayeredProfile) Update() (revisionCounter uint64) {
func (lp *LayeredProfile) updateCaches() {
// update security level
var newLevel uint8 = 0
var newLevel uint8
for _, layer := range lp.layers {
if newLevel < layer.SecurityLevel {
newLevel = layer.SecurityLevel
@@ -217,6 +218,45 @@ func (lp *LayeredProfile) MatchServiceEndpoint(entity *intel.Entity) (result end
return cfgServiceEndpoints.Match(entity)
}
// MatchFilterLists matches the entity against the set of filter
// lists.
func (lp *LayeredProfile) MatchFilterLists(entity *intel.Entity) (result endpoints.EPResult, reason string) {
lookupMap, hasLists := entity.GetListsMap()
if !hasLists {
return endpoints.NoMatch, ""
}
log.Errorf("number of layers: %d", len(lp.layers))
for _, layer := range lp.layers {
if id := lookupMap.Match(layer.filterListIDs); id != "" {
return endpoints.Denied, id
}
// only check the first layer that has filter list
// IDs defined.
if len(layer.filterListIDs) > 0 {
return endpoints.NoMatch, ""
}
}
// TODO(ppacher): re-resolving global list IDs is a bit overkill,
// add some caching here.
cfgLock.RLock()
defer cfgLock.RUnlock()
globalIds, err := filterlist.ResolveListIDs(cfgOptionFilterLists())
if err != nil {
log.Errorf("filter: failed to get global filter list IDs: %s", err)
return endpoints.NoMatch, ""
}
if id := lookupMap.Match(globalIds); id != "" {
return endpoints.Denied, id
}
return endpoints.NoMatch, ""
}
// AddEndpoint adds an endpoint to the local endpoint list, saves the local profile and reloads the configuration.
func (lp *LayeredProfile) AddEndpoint(newEntry string) {
lp.localProfile.AddEndpoint(newEntry)

View File

@@ -14,6 +14,7 @@ import (
"github.com/safing/portbase/config"
"github.com/safing/portbase/database/record"
"github.com/safing/portmaster/intel/filterlist"
"github.com/safing/portmaster/profile/endpoints"
)
@@ -73,6 +74,7 @@ type Profile struct { //nolint:maligned // not worth the effort
defaultAction uint8
endpoints endpoints.Endpoints
serviceEndpoints endpoints.Endpoints
filterListIDs []string
// Lifecycle Management
oudated *abool.AtomicBool
@@ -140,6 +142,14 @@ func (profile *Profile) parseConfig() error {
}
}
list, ok = profile.configPerspective.GetAsStringArray(CfgOptionFilterListKey)
if ok {
profile.filterListIDs, err = filterlist.ResolveListIDs(list)
if err != nil {
lastErr = err
}
}
return lastErr
}