safing-portmaster/service/process/profile.go
Daniel Hååvi 80664d1a27
Restructure modules ()
* Move portbase into monorepo

* Add new simple module mgr

* [WIP] Switch to new simple module mgr

* Add StateMgr and more worker variants

* [WIP] Switch more modules

* [WIP] Switch more modules

* [WIP] swtich more modules

* [WIP] switch all SPN modules

* [WIP] switch all service modules

* [WIP] Convert all workers to the new module system

* [WIP] add new task system to module manager

* [WIP] Add second take for scheduling workers

* [WIP] Add FIXME for bugs in new scheduler

* [WIP] Add minor improvements to scheduler

* [WIP] Add new worker scheduler

* [WIP] Fix more bug related to new module system

* [WIP] Fix start handing of the new module system

* [WIP] Improve startup process

* [WIP] Fix minor issues

* [WIP] Fix missing subsystem in settings

* [WIP] Initialize managers in constructor

* [WIP] Move module event initialization to constrictors

* [WIP] Fix setting for enabling and disabling the SPN module

* [WIP] Move API registeration into module construction

* [WIP] Update states mgr for all modules

* [WIP] Add CmdLine operation support

* Add state helper methods to module group and instance

* Add notification and module status handling to status package

* Fix starting issues

* Remove pilot widget and update security lock to new status data

* Remove debug logs

* Improve http server shutdown

* Add workaround for cleanly shutting down firewall+netquery

* Improve logging

* Add syncing states with notifications for new module system

* Improve starting, stopping, shutdown; resolve FIXMEs/TODOs

* [WIP] Fix most unit tests

* Review new module system and fix minor issues

* Push shutdown and restart events again via API

* Set sleep mode via interface

* Update example/template module

* [WIP] Fix spn/cabin unit test

* Remove deprecated UI elements

* Make log output more similar for the logging transition phase

* Switch spn hub and observer cmds to new module system

* Fix log sources

* Make worker mgr less error prone

* Fix tests and minor issues

* Fix observation hub

* Improve shutdown and restart handling

* Split up big connection.go source file

* Move varint and dsd packages to structures repo

* Improve expansion test

* Fix linter warnings

* Fix interception module on windows

* Fix linter errors

---------

Co-authored-by: Vladimir Stoilov <vladimir@safing.io>
2024-08-09 18:15:48 +03:00

116 lines
3.6 KiB
Go

package process
import (
"context"
"fmt"
"os"
"runtime"
"strings"
"github.com/safing/portmaster/base/log"
"github.com/safing/portmaster/service/profile"
)
var ownPID = os.Getpid()
// GetProfile finds and assigns a profile set to the process.
func (p *Process) GetProfile(ctx context.Context) (changed bool, err error) {
p.Lock()
defer p.Unlock()
// Check if profile is already loaded.
if p.profile != nil {
log.Tracer(ctx).Trace("process: profile already loaded")
return
}
// If not, continue with loading the profile.
log.Tracer(ctx).Trace("process: loading profile")
// Get special or regular profile.
localProfile, err := profile.GetLocalProfile(p.getSpecialProfileID(), p.MatchingData(), p.CreateProfileCallback)
if err != nil {
return false, fmt.Errorf("failed to find profile: %w", err)
}
// Assign profile to process.
p.PrimaryProfileID = localProfile.ScopedID()
p.profile = localProfile.LayeredProfile()
return true, nil
}
// RefetchProfile removes the profile and finds and assigns a new profile.
func (p *Process) RefetchProfile(ctx context.Context) error {
p.Lock()
defer p.Unlock()
// Get special or regular profile.
localProfile, err := profile.GetLocalProfile(p.getSpecialProfileID(), p.MatchingData(), p.CreateProfileCallback)
if err != nil {
return fmt.Errorf("failed to find profile: %w", err)
}
// Assign profile to process.
p.PrimaryProfileID = localProfile.ScopedID()
p.profile = localProfile.LayeredProfile()
return nil
}
// getSpecialProfileID returns the special profile ID for the process, if any.
func (p *Process) getSpecialProfileID() (specialProfileID string) {
// Check if we need a special profile.
switch p.Pid {
case UnidentifiedProcessID:
specialProfileID = profile.UnidentifiedProfileID
case UnsolicitedProcessID:
specialProfileID = profile.UnsolicitedProfileID
case SystemProcessID:
specialProfileID = profile.SystemProfileID
case ownPID:
specialProfileID = profile.PortmasterProfileID
default:
// Check if this is another Portmaster component.
if updatesPath != "" && strings.HasPrefix(p.Path, updatesPath) {
switch {
case strings.Contains(p.Path, "portmaster-app"):
specialProfileID = profile.PortmasterAppProfileID
case strings.Contains(p.Path, "portmaster-notifier"):
specialProfileID = profile.PortmasterNotifierProfileID
default:
// Unexpected binary from within the Portmaster updates directpry.
log.Warningf("process: unexpected binary in the updates directory: %s", p.Path)
// TODO: Assign a fully restricted profile in the future when we are
// sure that we won't kill any of our own things.
}
}
// Check if this is the system resolver.
switch runtime.GOOS {
case "windows":
// Depending on the OS version System32 may be capitalized or not.
if (p.Path == `C:\Windows\System32\svchost.exe` ||
p.Path == `C:\Windows\system32\svchost.exe`) &&
// This comes from the windows tasklist command and should be pretty consistent.
(profile.KeyAndValueInTags(p.Tags, "svchost", "Dnscache") ||
// As an alternative in case of failure, we try to match the svchost.exe service parameter.
strings.Contains(p.CmdLine, "-s Dnscache")) {
specialProfileID = profile.SystemResolverProfileID
}
case "linux":
switch p.Path {
case "/lib/systemd/systemd-resolved",
"/usr/lib/systemd/systemd-resolved",
"/lib64/systemd/systemd-resolved",
"/usr/lib64/systemd/systemd-resolved",
"/usr/bin/nscd",
"/usr/sbin/nscd",
"/usr/bin/dnsmasq",
"/usr/sbin/dnsmasq":
specialProfileID = profile.SystemResolverProfileID
}
}
}
return specialProfileID
}