Work on portmaster restructuring

This commit is contained in:
Daniel
2018-11-27 16:39:06 +01:00
parent 99851166a0
commit 5bdb021c88
38 changed files with 605 additions and 332 deletions

69
process/database.go Normal file
View File

@@ -0,0 +1,69 @@
package process
import (
"fmt"
"sync"
"github.com/Safing/portbase/database"
"github.com/tevino/abool"
)
var (
processes = make(map[int]*Process)
processesLock sync.RWMutex
dbController *database.Controller
dbControllerFlag = abool.NewBool(false)
)
func makeProcessKey(pid int) string {
return fmt.Sprintf("network:tree/%d", pid)
}
// GetProcessFromStorage returns a process from the internal storage.
func GetProcessFromStorage(pid int) (*Process, bool) {
processesLock.RLock()
defer processesLock.RUnlock()
p, ok := processes[pid]
return p, ok
}
// All returns a copy of all process objects.
func All() []*Process {
processesLock.RLock()
defer processesLock.RUnlock()
all := make([]*Process, 0, len(processes))
for _, proc := range processes {
all = append(all, proc)
}
return all
}
// Save saves the process to the internal state and pushes an update.
func (p *Process) Save() {
p.Lock()
defer p.Unlock()
if p.DatabaseKey() == "" {
p.SetKey(makeProcessKey(p.Pid))
p.CreateMeta()
processesLock.Lock()
defer processesLock.Unlock()
processes[p.Pid] = p
}
if dbControllerFlag.IsSet() {
dbController.PushUpdate(p)
}
}
// SetDBController sets the database controller and allows the package to push database updates on a save. It must be set by the package that registers the "network" database.
func SetDBController(controller *database.Controller) {
dbController = controller
dbControllerFlag.Set()
}

View File

@@ -1,21 +1,7 @@
// Copyright Safing ICS Technologies GmbH. Use of this source code is governed by the AGPL license that can be found in the LICENSE file.
/*
Profiles
Profiles describe the network behaviour
Profiles are found in 3 different paths:
- /Me/Profiles/: Profiles used for this system
- /Data/Profiles/: Profiles supplied by Safing
- /Company/Profiles/: Profiles supplied by the company
When a program wants to use the network for the first time, Safing first searches for a Profile in the Company namespace, then in the Data namespace. If neither is found, it searches for a default profile in the same order.
Default profiles are profiles with a path ending with a "/". The default profile with the longest matching path is chosen.
Package process fetches process and socket information from the operating system.
It can find the process owning a network connection.
*/
package process

View File

@@ -7,11 +7,13 @@ import (
"github.com/Safing/portmaster/network/packet"
)
// Errors
var (
ErrConnectionNotFound = errors.New("could not find connection")
ErrProcessNotFound = errors.New("could not find process")
)
// GetPidByPacket returns the pid of the owner of the packet.
func GetPidByPacket(pkt packet.Packet) (pid int, direction bool, err error) {
var localIP net.IP
@@ -50,6 +52,7 @@ func GetPidByPacket(pkt packet.Packet) (pid int, direction bool, err error) {
}
// GetProcessByPacket returns the process that owns the given packet.
func GetProcessByPacket(pkt packet.Packet) (process *Process, direction bool, err error) {
var pid int
@@ -70,6 +73,7 @@ func GetProcessByPacket(pkt packet.Packet) (process *Process, direction bool, er
}
// GetPidByEndpoints returns the pid of the owner of the described link.
func GetPidByEndpoints(localIP net.IP, localPort uint16, remoteIP net.IP, remotePort uint16, protocol packet.IPProtocol) (pid int, direction bool, err error) {
ipVersion := packet.IPv4
@@ -92,6 +96,7 @@ func GetPidByEndpoints(localIP net.IP, localPort uint16, remoteIP net.IP, remote
}
// GetProcessByEndpoints returns the process that owns the described link.
func GetProcessByEndpoints(localIP net.IP, localPort uint16, remoteIP net.IP, remotePort uint16, protocol packet.IPProtocol) (process *Process, err error) {
var pid int
@@ -112,37 +117,7 @@ func GetProcessByEndpoints(localIP net.IP, localPort uint16, remoteIP net.IP, re
}
// GetActiveConnectionIDs returns a list of all active connection IDs.
func GetActiveConnectionIDs() []string {
return getActiveConnectionIDs()
}
// func GetProcessByPid(pid int) *Process {
// process, err := GetOrFindProcess(pid)
// if err != nil {
// log.Warningf("process: failed to get process %d: %s", pid, err)
// return nil
// }
// return process
// }
// func GetProcessOfConnection(localIP *net.IP, localPort uint16, protocol uint8) (process *Process, status uint8) {
// pid, status := GetPidOfConnection(localIP, localPort, protocol)
// if status == Success {
// process = GetProcessByPid(pid)
// if process == nil {
// return nil, NoProcessInfo
// }
// }
// return
// }
// func GetProcessByPacket(pkt packet.Packet) (process *Process, direction bool, status uint8) {
// pid, direction, status := GetPidByPacket(pkt)
// if status == Success {
// process = GetProcessByPid(pid)
// if process == nil {
// return nil, direction, NoProcessInfo
// }
// }
// return
// }

View File

@@ -1,6 +1,8 @@
package process
import "github.com/Safing/portmaster/process/proc"
import (
"github.com/Safing/portmaster/process/proc"
)
var (
getTCP4PacketInfo = proc.GetTCP4PacketInfo

Binary file not shown.

View File

@@ -3,10 +3,8 @@
package process
import (
"errors"
"fmt"
"runtime"
"strconv"
"sync"
processInfo "github.com/shirou/gopsutil/process"
@@ -36,11 +34,7 @@ type Process struct {
// Icon is a path to the icon and is either prefixed "f:" for filepath, "d:" for database cache path or "c:"/"a:" for a the icon key to fetch it from a company / authoritative node and cache it in its own cache.
}
// GetProcess fetches Process with the provided name from the default namespace.
func GetProcess(name string) (*Process, error) {
return nil, errors.New("NIY")
}
// Strings returns a string represenation of process
func (m *Process) String() string {
if m == nil {
return "?"
@@ -48,9 +42,10 @@ func (m *Process) String() string {
return fmt.Sprintf("%s:%s:%d", m.UserName, m.Path, m.Pid)
}
// GetOrFindProcess returns the process for the given PID.
func GetOrFindProcess(pid int) (*Process, error) {
process, err := GetProcess(strconv.Itoa(pid))
if err == nil {
process, ok := GetProcessFromStorage(pid)
if ok {
return process, nil
}
@@ -59,7 +54,7 @@ func GetOrFindProcess(pid int) (*Process, error) {
}
switch {
case (pid == 0 && runtime.GOOS == "linux") || (pid == 4 && runtime.GOOS == "windows"):
case new.IsKernel():
new.UserName = "Kernel"
new.Name = "Operating System"
default:
@@ -72,7 +67,8 @@ func GetOrFindProcess(pid int) (*Process, error) {
// UID
// net yet implemented for windows
if runtime.GOOS == "linux" {
uids, err := pInfo.Uids()
var uids []int32
uids, err = pInfo.Uids()
if err != nil {
log.Warningf("process: failed to get UID: %s", err)
} else {
@@ -203,8 +199,8 @@ func GetOrFindProcess(pid int) (*Process, error) {
}
// save to DB
// new.Save()
// save to storage
new.Save()
return new, nil
}

View File

@@ -1,13 +1,21 @@
package process
// IsUser returns whether the process is run by a normal user.
func (m *Process) IsUser() bool {
return m.UserID >= 1000
}
// IsAdmin returns whether the process is run by an admin user.
func (m *Process) IsAdmin() bool {
return m.UserID >= 0
}
// IsSystem returns whether the process is run by the operating system.
func (m *Process) IsSystem() bool {
return m.UserID == 0
}
// IsKernel returns whether the process is the Kernel.
func (m *Process) IsKernel() bool {
return m.Pid == 0
}

View File

@@ -2,15 +2,23 @@ package process
import "strings"
// IsUser returns whether the process is run by a normal user.
func (m *Process) IsUser() bool {
return m.Pid != 4 && // Kernel
!strings.HasPrefix(m.UserName, "NT-") // NT-Authority (localized!)
}
// IsAdmin returns whether the process is run by an admin user.
func (m *Process) IsAdmin() bool {
return strings.HasPrefix(m.UserName, "NT-") // NT-Authority (localized!)
}
// IsSystem returns whether the process is run by the operating system.
func (m *Process) IsSystem() bool {
return m.Pid == 4
}
// IsKernel returns whether the process is the Kernel.
func (m *Process) IsKernel() bool {
return m.Pid == 4
}

15
process/unknown.go Normal file
View File

@@ -0,0 +1,15 @@
package process
var (
UnknownProcess = &Process{
UserID: -1,
UserName: "Unknown",
Pid: -1,
ParentPid: -1,
Name: "Unknown Processes",
}
)
func init() {
UnknownProcess.Save()
}