mirror of
https://github.com/safing/portmaster
synced 2025-09-02 10:39:22 +00:00
Integrate special profiles into regular profile fetching for correct profile udpates
This commit is contained in:
parent
afa696bb48
commit
b9127d3f91
3 changed files with 46 additions and 109 deletions
|
@ -27,18 +27,10 @@ func (p *Process) GetProfile(ctx context.Context) (changed bool, err error) {
|
||||||
// If not, continue with loading the profile.
|
// If not, continue with loading the profile.
|
||||||
log.Tracer(ctx).Trace("process: loading profile")
|
log.Tracer(ctx).Trace("process: loading profile")
|
||||||
|
|
||||||
// Check if there is a special profile for this process.
|
// Get special or regular profile.
|
||||||
localProfile, err := p.loadSpecialProfile(ctx)
|
localProfile, err := profile.GetLocalProfile(p.getSpecialProfileID(), p.MatchingData(), p.CreateProfileCallback)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, fmt.Errorf("failed to load special profile: %w", err)
|
return false, fmt.Errorf("failed to find profile: %w", err)
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, find a regular profile for the process.
|
|
||||||
if localProfile == nil {
|
|
||||||
localProfile, err = profile.GetLocalProfile("", p.MatchingData(), p.CreateProfileCallback)
|
|
||||||
if err != nil {
|
|
||||||
return false, fmt.Errorf("failed to find profile: %w", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign profile to process.
|
// Assign profile to process.
|
||||||
|
@ -48,10 +40,9 @@ func (p *Process) GetProfile(ctx context.Context) (changed bool, err error) {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadSpecialProfile attempts to load a special profile.
|
// getSpecialProfileID returns the special profile ID for the process, if any.
|
||||||
func (p *Process) loadSpecialProfile(_ context.Context) (*profile.Profile, error) {
|
func (p *Process) getSpecialProfileID() (specialProfileID string) {
|
||||||
// Check if we need a special profile.
|
// Check if we need a special profile.
|
||||||
var specialProfileID string
|
|
||||||
switch p.Pid {
|
switch p.Pid {
|
||||||
case UnidentifiedProcessID:
|
case UnidentifiedProcessID:
|
||||||
specialProfileID = profile.UnidentifiedProfileID
|
specialProfileID = profile.UnidentifiedProfileID
|
||||||
|
@ -103,11 +94,5 @@ func (p *Process) loadSpecialProfile(_ context.Context) (*profile.Profile, error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if a special profile should be applied.
|
return specialProfileID
|
||||||
if specialProfileID == "" {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return special profile.
|
|
||||||
return profile.GetSpecialProfile(specialProfileID, p.Path)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/safing/portbase/database"
|
||||||
"github.com/safing/portbase/database/query"
|
"github.com/safing/portbase/database/query"
|
||||||
"github.com/safing/portbase/database/record"
|
"github.com/safing/portbase/database/record"
|
||||||
"github.com/safing/portbase/log"
|
"github.com/safing/portbase/log"
|
||||||
|
@ -50,6 +51,7 @@ func GetLocalProfile(id string, md MatchingData, createProfileCallback func() *P
|
||||||
|
|
||||||
// In some cases, we might need to get a profile directly, without matching data.
|
// In some cases, we might need to get a profile directly, without matching data.
|
||||||
// This could lead to inconsistent data - use with caution.
|
// This could lead to inconsistent data - use with caution.
|
||||||
|
// Example: Saving prompt results to profile should always be to the same ID!
|
||||||
if md == nil {
|
if md == nil {
|
||||||
if id == "" {
|
if id == "" {
|
||||||
return nil, errors.New("cannot get local profiles without ID and matching data")
|
return nil, errors.New("cannot get local profiles without ID and matching data")
|
||||||
|
@ -61,6 +63,26 @@ func GetLocalProfile(id string, md MatchingData, createProfileCallback func() *P
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if we are requesting a special profile.
|
||||||
|
var created, special bool
|
||||||
|
if id != "" && isSpecialProfileID(id) {
|
||||||
|
special = true
|
||||||
|
|
||||||
|
// Get special profile from DB.
|
||||||
|
if profile == nil {
|
||||||
|
profile, err = getProfile(makeScopedID(SourceLocal, id))
|
||||||
|
if err != nil && !errors.Is(err, database.ErrNotFound) {
|
||||||
|
log.Warningf("profile: failed to get special profile %s: %s", id, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create profile if not found or if it needs a reset.
|
||||||
|
if profile == nil || specialProfileNeedsReset(profile) {
|
||||||
|
profile = createSpecialProfile(id, md.Path())
|
||||||
|
created = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If we don't have a profile yet, find profile based on matching data.
|
// If we don't have a profile yet, find profile based on matching data.
|
||||||
if profile == nil {
|
if profile == nil {
|
||||||
profile, err = findProfile(SourceLocal, md)
|
profile, err = findProfile(SourceLocal, md)
|
||||||
|
@ -70,7 +92,6 @@ func GetLocalProfile(id string, md MatchingData, createProfileCallback func() *P
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we still don't have a profile, create a new one.
|
// If we still don't have a profile, create a new one.
|
||||||
var created bool
|
|
||||||
if profile == nil {
|
if profile == nil {
|
||||||
created = true
|
created = true
|
||||||
|
|
||||||
|
@ -105,7 +126,12 @@ func GetLocalProfile(id string, md MatchingData, createProfileCallback func() *P
|
||||||
// Initialize and update profile.
|
// Initialize and update profile.
|
||||||
|
|
||||||
// Update metadata.
|
// Update metadata.
|
||||||
changed := profile.updateMetadata(md.Path())
|
var changed bool
|
||||||
|
if special {
|
||||||
|
changed = updateSpecialProfileMetadata(profile, md.Path())
|
||||||
|
} else {
|
||||||
|
changed = profile.updateMetadata(md.Path())
|
||||||
|
}
|
||||||
|
|
||||||
// Save if created or changed.
|
// Save if created or changed.
|
||||||
if created || changed {
|
if created || changed {
|
||||||
|
@ -117,7 +143,7 @@ func GetLocalProfile(id string, md MatchingData, createProfileCallback func() *P
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trigger further metadata fetching from system if profile was created.
|
// Trigger further metadata fetching from system if profile was created.
|
||||||
if created && profile.UsePresentationPath {
|
if created && profile.UsePresentationPath && !special {
|
||||||
module.StartWorker("get profile metadata", profile.updateMetadataFromSystem)
|
module.StartWorker("get profile metadata", profile.updateMetadataFromSystem)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
package profile
|
package profile
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/safing/portbase/database"
|
|
||||||
"github.com/safing/portbase/log"
|
"github.com/safing/portbase/log"
|
||||||
"github.com/safing/portmaster/status"
|
"github.com/safing/portmaster/status"
|
||||||
)
|
)
|
||||||
|
@ -77,91 +75,19 @@ If you think you might have messed up the settings of the System DNS Client, jus
|
||||||
PortmasterNotifierProfileDescription = `This is the Portmaster UI Tray Notifier.`
|
PortmasterNotifierProfileDescription = `This is the Portmaster UI Tray Notifier.`
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetSpecialProfile fetches a special profile. This function ensures that the loaded profile
|
func isSpecialProfileID(id string) bool {
|
||||||
// is shared among all callers. Always provide all available data points.
|
switch id {
|
||||||
func GetSpecialProfile(id string, path string) ( //nolint:gocognit
|
case UnidentifiedProfileID,
|
||||||
profile *Profile,
|
UnsolicitedProfileID,
|
||||||
err error,
|
SystemProfileID,
|
||||||
) {
|
SystemResolverProfileID,
|
||||||
// Check if we have an ID.
|
PortmasterProfileID,
|
||||||
if id == "" {
|
PortmasterAppProfileID,
|
||||||
return nil, errors.New("cannot get special profile without ID")
|
PortmasterNotifierProfileID:
|
||||||
}
|
return true
|
||||||
scopedID := makeScopedID(SourceLocal, id)
|
|
||||||
|
|
||||||
// Globally lock getting a profile.
|
|
||||||
// This does not happen too often, and it ensures we really have integrity
|
|
||||||
// and no race conditions.
|
|
||||||
getProfileLock.Lock()
|
|
||||||
defer getProfileLock.Unlock()
|
|
||||||
|
|
||||||
// Check if there already is an active profile.
|
|
||||||
var previousVersion *Profile
|
|
||||||
profile = getActiveProfile(scopedID)
|
|
||||||
if profile != nil {
|
|
||||||
// Mark active and return if not outdated.
|
|
||||||
if profile.outdated.IsNotSet() {
|
|
||||||
profile.MarkStillActive()
|
|
||||||
return profile, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// If outdated, get from database.
|
|
||||||
previousVersion = profile
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get special profile from DB and check if it needs a reset.
|
|
||||||
var created bool
|
|
||||||
profile, err = getProfile(scopedID)
|
|
||||||
switch {
|
|
||||||
case err == nil:
|
|
||||||
// Reset profile if needed.
|
|
||||||
if specialProfileNeedsReset(profile) {
|
|
||||||
profile = createSpecialProfile(id, path)
|
|
||||||
created = true
|
|
||||||
}
|
|
||||||
case !errors.Is(err, database.ErrNotFound):
|
|
||||||
// Warn when fetching from DB fails, and create new profile as fallback.
|
|
||||||
log.Warningf("profile: failed to get special profile %s: %s", id, err)
|
|
||||||
fallthrough
|
|
||||||
default:
|
default:
|
||||||
// Create new profile if it does not exist (or failed to load).
|
return false
|
||||||
profile = createSpecialProfile(id, path)
|
|
||||||
created = true
|
|
||||||
}
|
}
|
||||||
// Check if creating the special profile was successful.
|
|
||||||
if profile == nil {
|
|
||||||
return nil, errors.New("given ID is not a special profile ID")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update metadata
|
|
||||||
changed := updateSpecialProfileMetadata(profile, path)
|
|
||||||
|
|
||||||
// Save if created or changed.
|
|
||||||
if created || changed {
|
|
||||||
err := profile.Save()
|
|
||||||
if err != nil {
|
|
||||||
log.Warningf("profile: failed to save special profile %s: %s", scopedID, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare profile for first use.
|
|
||||||
|
|
||||||
// If we are refetching, assign the layered profile from the previous version.
|
|
||||||
// The internal references will be updated when the layered profile checks for updates.
|
|
||||||
if previousVersion != nil && previousVersion.layeredProfile != nil {
|
|
||||||
profile.layeredProfile = previousVersion.layeredProfile
|
|
||||||
}
|
|
||||||
|
|
||||||
// Profiles must have a layered profile, create a new one if it
|
|
||||||
// does not yet exist.
|
|
||||||
if profile.layeredProfile == nil {
|
|
||||||
profile.layeredProfile = NewLayeredProfile(profile)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the profile to the currently active profiles.
|
|
||||||
addActiveProfile(profile)
|
|
||||||
|
|
||||||
return profile, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateSpecialProfileMetadata(profile *Profile, binaryPath string) (changed bool) {
|
func updateSpecialProfileMetadata(profile *Profile, binaryPath string) (changed bool) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue