Fix layered profiles not readable via the API

This commit is contained in:
Patrick Pacher 2020-10-30 16:43:49 +01:00
parent c0509042a0
commit fb6b34ebe5
4 changed files with 75 additions and 30 deletions

View file

@ -16,18 +16,26 @@ var (
activeProfilesLock sync.RWMutex
)
// getActiveProfile returns a cached copy of an active profile and nil if it isn't found.
// getActiveProfile returns a cached copy of an active profile and
// nil if it isn't found.
func getActiveProfile(scopedID string) *Profile {
activeProfilesLock.RLock()
defer activeProfilesLock.RUnlock()
activeProfile, ok := activeProfiles[scopedID]
if ok {
activeProfile.MarkStillActive()
return activeProfile
return activeProfiles[scopedID]
}
// getAllActiveProfiles returns a slice of active profiles.
func getAllActiveProfiles() []*Profile {
activeProfilesLock.RLock()
defer activeProfilesLock.RUnlock()
result := make([]*Profile, 0, len(activeProfiles))
for _, p := range activeProfiles {
result = append(result, p)
}
return nil
return result
}
// findActiveProfile searched for an active local profile using the linked path.

View file

@ -51,6 +51,8 @@ func GetProfile(source profileSource, id, linkedPath string) ( //nolint:gocognit
// Check if there already is an active and not outdated profile.
profile = getActiveProfile(scopedID)
if profile != nil {
profile.MarkStillActive()
if profile.outdated.IsSet() {
previousVersion = profile
} else {

View file

@ -5,11 +5,12 @@ import (
"strings"
"github.com/safing/portbase/database/record"
"github.com/safing/portbase/log"
"github.com/safing/portbase/runtime"
)
const (
revisionProviderPrefix = "runtime:layeredProfile/"
revisionProviderPrefix = "layeredProfile/"
)
var (
@ -18,24 +19,50 @@ var (
)
func registerRevisionProvider() error {
_, err := runtime.DefaultRegistry.Register(
_, err := runtime.Register(
revisionProviderPrefix,
runtime.SimpleValueGetterFunc(getRevision),
runtime.SimpleValueGetterFunc(getRevisions),
)
return err
}
func getRevision(key string) ([]record.Record, error) {
func getRevisions(key string) ([]record.Record, error) {
log.Warningf("loading for key " + key)
key = strings.TrimPrefix(key, revisionProviderPrefix)
var profiles []*Profile
if key == "" {
profiles = getAllActiveProfiles()
} else {
// Get active profile.
profile := getActiveProfile(key)
if profile == nil {
return nil, errProfileNotActive
}
}
records := make([]record.Record, 0, len(profiles))
for _, p := range profiles {
layered, err := getProfileRevision(p)
if err != nil {
log.Warningf("failed to get layered profile for %s: %s", p.ID, err)
continue
}
records = append(records, layered)
}
return records, nil
}
// getProfileRevision returns the layered profile for p.
// It also updates the layered profile if required.
func getProfileRevision(p *Profile) (*LayeredProfile, error) {
// Get layered profile.
layeredProfile := profile.LayeredProfile()
layeredProfile := p.LayeredProfile()
if layeredProfile == nil {
return nil, errNoLayeredProfile
}
@ -45,5 +72,5 @@ func getRevision(key string) ([]record.Record, error) {
layeredProfile.Update()
}
return []record.Record{layeredProfile}, nil
return layeredProfile, nil
}

View file

@ -7,6 +7,7 @@ import (
"github.com/safing/portbase/database/record"
"github.com/safing/portbase/log"
"github.com/safing/portbase/runtime"
"github.com/safing/portmaster/status"
@ -31,19 +32,24 @@ type LayeredProfile struct {
// These functions give layered access to configuration options and require
// the layered profile to be read locked.
DisableAutoPermit config.BoolOption
BlockScopeLocal config.BoolOption
BlockScopeLAN config.BoolOption
BlockScopeInternet config.BoolOption
BlockP2P config.BoolOption
BlockInbound config.BoolOption
RemoveOutOfScopeDNS config.BoolOption
RemoveBlockedDNS config.BoolOption
FilterSubDomains config.BoolOption
FilterCNAMEs config.BoolOption
PreventBypassing config.BoolOption
DomainHeuristics config.BoolOption
UseSPN config.BoolOption
// TODO(ppacher): we need JSON tags here so the layeredProfile can be exposed
// via the API. If we ever switch away from JSON to something else supported
// by DSD this WILL BREAK!
DisableAutoPermit config.BoolOption `json:"-"`
BlockScopeLocal config.BoolOption `json:"-"`
BlockScopeLAN config.BoolOption `json:"-"`
BlockScopeInternet config.BoolOption `json:"-"`
BlockP2P config.BoolOption `json:"-"`
BlockInbound config.BoolOption `json:"-"`
RemoveOutOfScopeDNS config.BoolOption `json:"-"`
RemoveBlockedDNS config.BoolOption `json:"-"`
FilterSubDomains config.BoolOption `json:"-"`
FilterCNAMEs config.BoolOption `json:"-"`
PreventBypassing config.BoolOption `json:"-"`
DomainHeuristics config.BoolOption `json:"-"`
UseSPN config.BoolOption `json:"-"`
}
// NewLayeredProfile returns a new layered profile based on the given local profile.
@ -118,7 +124,9 @@ func NewLayeredProfile(localProfile *Profile) *LayeredProfile {
new.updateCaches()
new.SetKey(revisionProviderPrefix + localProfile.ID)
new.CreateMeta()
new.SetKey(runtime.DefaultRegistry.DatabaseName() + ":" + revisionProviderPrefix + localProfile.ID)
return new
}