mirror of
https://github.com/safing/portmaster
synced 2025-09-02 10:39:22 +00:00
Fix deleting profiles
This commit is contained in:
parent
2cbaf126e9
commit
888b33918a
8 changed files with 89 additions and 32 deletions
|
@ -259,7 +259,7 @@ func saveResponse(p *profile.Profile, entity *intel.Entity, promptResponse strin
|
||||||
// Update the profile if necessary.
|
// Update the profile if necessary.
|
||||||
if p.IsOutdated() {
|
if p.IsOutdated() {
|
||||||
var err error
|
var err error
|
||||||
p, err = profile.GetProfile(p.Source, p.ID, p.LinkedPath)
|
p, err = profile.GetProfile(p.Source, p.ID, p.LinkedPath, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ func GetNetworkHost(ctx context.Context, remoteIP net.IP) (process *Process, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the (linked) local profile.
|
// Get the (linked) local profile.
|
||||||
networkHostProfile, err := profile.GetProfile(profile.SourceNetwork, remoteIP.String(), "")
|
networkHostProfile, err := profile.GetProfile(profile.SourceNetwork, remoteIP.String(), "", false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ func (p *Process) GetProfile(ctx context.Context) (changed bool, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the (linked) local profile.
|
// Get the (linked) local profile.
|
||||||
localProfile, err := profile.GetProfile(profile.SourceLocal, profileID, p.Path)
|
localProfile, err := profile.GetProfile(profile.SourceLocal, profileID, p.Path, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,25 +61,31 @@ func startProfileUpdateChecker() error {
|
||||||
// Get active profile.
|
// Get active profile.
|
||||||
activeProfile := getActiveProfile(strings.TrimPrefix(r.Key(), profilesDBPath))
|
activeProfile := getActiveProfile(strings.TrimPrefix(r.Key(), profilesDBPath))
|
||||||
if activeProfile == nil {
|
if activeProfile == nil {
|
||||||
|
// Don't do any additional actions if the profile is not active.
|
||||||
continue profileFeed
|
continue profileFeed
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the record is being deleted, but there is an active profile,
|
// If the record is being deleted, reset the profile.
|
||||||
// create an empty profile instead.
|
// create an empty profile instead.
|
||||||
if r.Meta().IsDeleted() {
|
if r.Meta().IsDeleted() {
|
||||||
newProfile := New(
|
newProfile, err := GetProfile(
|
||||||
activeProfile.Source,
|
activeProfile.Source,
|
||||||
activeProfile.ID,
|
activeProfile.ID,
|
||||||
activeProfile.LinkedPath,
|
activeProfile.LinkedPath,
|
||||||
nil,
|
true,
|
||||||
)
|
)
|
||||||
// Copy some metadata from the old profile.
|
|
||||||
newProfile.Name = activeProfile.Name
|
|
||||||
// Save the new profile.
|
|
||||||
err := newProfile.Save()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("profile: failed to save new profile for profile reset: %s", err)
|
log.Errorf("profile: failed to create new profile after reset: %s", err)
|
||||||
|
} else {
|
||||||
|
// Copy metadata from the old profile.
|
||||||
|
newProfile.copyMetadataFrom(activeProfile)
|
||||||
|
// Save the new profile.
|
||||||
|
err := newProfile.Save()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("profile: failed to save new profile after reset: %s", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set to outdated, so it is loaded in the layered profiles.
|
// Set to outdated, so it is loaded in the layered profiles.
|
||||||
activeProfile.outdated.Set()
|
activeProfile.outdated.Set()
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ var getProfileLock sync.Mutex
|
||||||
// linkedPath parameters whenever available. The linkedPath is used as the key
|
// linkedPath parameters whenever available. The linkedPath is used as the key
|
||||||
// for locking concurrent requests, so it must be supplied if available.
|
// for locking concurrent requests, so it must be supplied if available.
|
||||||
// If linkedPath is not supplied, source and id make up the key instead.
|
// If linkedPath is not supplied, source and id make up the key instead.
|
||||||
func GetProfile(source profileSource, id, linkedPath string) ( //nolint:gocognit
|
func GetProfile(source profileSource, id, linkedPath string, reset bool) ( //nolint:gocognit
|
||||||
profile *Profile,
|
profile *Profile,
|
||||||
err error,
|
err error,
|
||||||
) {
|
) {
|
||||||
|
@ -40,28 +40,23 @@ func GetProfile(source profileSource, id, linkedPath string) ( //nolint:gocognit
|
||||||
if profile != nil {
|
if profile != nil {
|
||||||
profile.MarkStillActive()
|
profile.MarkStillActive()
|
||||||
|
|
||||||
if profile.outdated.IsSet() {
|
if profile.outdated.IsSet() || reset {
|
||||||
previousVersion = profile
|
previousVersion = profile
|
||||||
} else {
|
} else {
|
||||||
return profile, nil
|
return profile, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get from database.
|
// Get from database.
|
||||||
profile, err = getProfile(scopedID)
|
if !reset {
|
||||||
|
profile, err = getProfile(scopedID)
|
||||||
// Check if the request is for a special profile that may need a reset.
|
// Check if the profile is special and needs a reset.
|
||||||
if err == nil && specialProfileNeedsReset(profile) {
|
if err == nil && specialProfileNeedsReset(profile) {
|
||||||
// Trigger creation of special profile.
|
profile = getSpecialProfile(id, linkedPath)
|
||||||
err = database.ErrNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we cannot find a profile, check if the request is for a special
|
|
||||||
// profile we can create.
|
|
||||||
if errors.Is(err, database.ErrNotFound) {
|
|
||||||
profile = getSpecialProfile(id, linkedPath)
|
|
||||||
if profile != nil {
|
|
||||||
err = nil
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Simulate missing profile to create new one.
|
||||||
|
err = database.ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
case linkedPath != "":
|
case linkedPath != "":
|
||||||
|
@ -70,23 +65,48 @@ func GetProfile(source profileSource, id, linkedPath string) ( //nolint:gocognit
|
||||||
// the linked path.
|
// the linked path.
|
||||||
profile = findActiveProfile(linkedPath)
|
profile = findActiveProfile(linkedPath)
|
||||||
if profile != nil {
|
if profile != nil {
|
||||||
if profile.outdated.IsSet() {
|
if profile.outdated.IsSet() || reset {
|
||||||
previousVersion = profile
|
previousVersion = profile
|
||||||
} else {
|
} else {
|
||||||
return profile, nil
|
return profile, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get from database.
|
// Get from database.
|
||||||
profile, err = findProfile(linkedPath)
|
if !reset {
|
||||||
|
profile, err = findProfile(linkedPath)
|
||||||
|
// Check if the profile is special and needs a reset.
|
||||||
|
if err == nil && specialProfileNeedsReset(profile) {
|
||||||
|
profile = getSpecialProfile(id, linkedPath)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Simulate missing profile to create new one.
|
||||||
|
err = database.ErrNotFound
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, errors.New("cannot fetch profile without ID or path")
|
return nil, errors.New("cannot fetch profile without ID or path")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create new profile if none was found.
|
||||||
|
if errors.Is(err, database.ErrNotFound) {
|
||||||
|
err = nil
|
||||||
|
|
||||||
|
// Check if there is a special profile for this ID.
|
||||||
|
profile = getSpecialProfile(id, linkedPath)
|
||||||
|
|
||||||
|
// If not, create a standard profile.
|
||||||
|
if profile == nil {
|
||||||
|
profile = New(SourceLocal, id, linkedPath, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there was a non-recoverable error, return here.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process profiles coming directly from the database.
|
// Process profiles are coming directly from the database or are new.
|
||||||
// As we don't use any caching, these will be new objects.
|
// As we don't use any caching, these will be new objects.
|
||||||
|
|
||||||
// Add a layeredProfile to local and network profiles.
|
// Add a layeredProfile to local and network profiles.
|
||||||
|
|
|
@ -239,9 +239,9 @@ func (lp *LayeredProfile) Update() (revisionCounter uint64) {
|
||||||
if layer.outdated.IsSet() {
|
if layer.outdated.IsSet() {
|
||||||
changed = true
|
changed = true
|
||||||
// update layer
|
// update layer
|
||||||
newLayer, err := GetProfile(layer.Source, layer.ID, layer.LinkedPath)
|
newLayer, err := GetProfile(layer.Source, layer.ID, layer.LinkedPath, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("profiles: failed to update profile %s", layer.ScopedID())
|
log.Errorf("profiles: failed to update profile %s: %s", layer.ScopedID(), err)
|
||||||
} else {
|
} else {
|
||||||
lp.layers[i] = newLayer
|
lp.layers[i] = newLayer
|
||||||
}
|
}
|
||||||
|
|
|
@ -445,6 +445,31 @@ func (profile *Profile) UpdateMetadata(binaryPath string) (changed bool) {
|
||||||
return changed
|
return changed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (profile *Profile) copyMetadataFrom(otherProfile *Profile) (changed bool) {
|
||||||
|
if profile.Name != otherProfile.Name {
|
||||||
|
profile.Name = otherProfile.Name
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
if profile.Description != otherProfile.Description {
|
||||||
|
profile.Description = otherProfile.Description
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
if profile.Homepage != otherProfile.Homepage {
|
||||||
|
profile.Homepage = otherProfile.Homepage
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
if profile.Icon != otherProfile.Icon {
|
||||||
|
profile.Icon = otherProfile.Icon
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
if profile.IconType != otherProfile.IconType {
|
||||||
|
profile.IconType = otherProfile.IconType
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// updateMetadataFromSystem updates the profile metadata with data from the
|
// updateMetadataFromSystem updates the profile metadata with data from the
|
||||||
// operating system and saves it afterwards.
|
// operating system and saves it afterwards.
|
||||||
func (profile *Profile) updateMetadataFromSystem(ctx context.Context) error {
|
func (profile *Profile) updateMetadataFromSystem(ctx context.Context) error {
|
||||||
|
|
|
@ -36,6 +36,8 @@ In order to respect the app settings of the actual application, DNS requests fro
|
||||||
- Outgoing Rules (without global rules)
|
- Outgoing Rules (without global rules)
|
||||||
- Block Bypassing
|
- Block Bypassing
|
||||||
- Filter Lists
|
- Filter Lists
|
||||||
|
|
||||||
|
If you think you might have messed up the settings of the System DNS Client, just delete the profile below to reset it to the defaults.
|
||||||
`
|
`
|
||||||
|
|
||||||
// PortmasterProfileID is the profile ID used for the Portmaster Core itself.
|
// PortmasterProfileID is the profile ID used for the Portmaster Core itself.
|
||||||
|
@ -193,6 +195,10 @@ func getSpecialProfile(profileID, linkedPath string) *Profile {
|
||||||
// check if the special profile has not been changed by the user and if not,
|
// check if the special profile has not been changed by the user and if not,
|
||||||
// check if the profile is outdated and can be upgraded.
|
// check if the profile is outdated and can be upgraded.
|
||||||
func specialProfileNeedsReset(profile *Profile) bool {
|
func specialProfileNeedsReset(profile *Profile) bool {
|
||||||
|
if profile == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case profile.Source != SourceLocal:
|
case profile.Source != SourceLocal:
|
||||||
// Special profiles live in the local scope only.
|
// Special profiles live in the local scope only.
|
||||||
|
|
Loading…
Add table
Reference in a new issue