From a33808685c3c3ea7433b5239031b132cf6beb554 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 20 Apr 2020 13:57:07 +0200 Subject: [PATCH] Implement review suggestions --- firewall/firewall.go | 2 +- firewall/master.go | 4 ++-- network/connection.go | 2 +- network/dns.go | 14 ++++++++------ process/database.go | 15 +++++++-------- process/find.go | 4 ++-- process/iphelper/get.go | 26 +++++++++++++++----------- process/proc/gather.go | 8 ++++---- process/proc/get.go | 10 +++++++--- process/proc/processfinder.go | 2 +- process/proc/sockets.go | 6 +++--- process/process.go | 19 ++++++++++--------- process/special.go | 35 ++++++++++++++++++++++++++--------- profile/active.go | 2 +- profile/special.go | 2 ++ 15 files changed, 90 insertions(+), 61 deletions(-) diff --git a/firewall/firewall.go b/firewall/firewall.go index 5ccc8677..923e87f2 100644 --- a/firewall/firewall.go +++ b/firewall/firewall.go @@ -233,7 +233,7 @@ func initialHandler(conn *network.Connection, pkt packet.Packet) { if ps.isMe { // approve conn.Accept("internally approved") - conn.Hidden = true + conn.Internal = true // finish conn.StopFirewallHandler() issueVerdict(conn, pkt, 0, true) diff --git a/firewall/master.go b/firewall/master.go index 9cb55bc1..15f6edb8 100644 --- a/firewall/master.go +++ b/firewall/master.go @@ -50,7 +50,7 @@ func DecideOnConnection(conn *network.Connection, pkt packet.Packet) { //nolint: if conn.Process().Pid == os.Getpid() { log.Infof("filter: granting own connection %s", conn) conn.Verdict = network.VerdictAccept - conn.Hidden = true + conn.Internal = true return } @@ -76,7 +76,7 @@ func DecideOnConnection(conn *network.Connection, pkt packet.Packet) { //nolint: log.Warningf("filter: failed to find load local peer process with PID %d: %s", otherPid, err) } else if otherProcess.Pid == conn.Process().Pid { conn.Accept("connection to self") - conn.Hidden = true + conn.Internal = true return } } diff --git a/network/connection.go b/network/connection.go index 3b2c6a84..88b36e14 100644 --- a/network/connection.go +++ b/network/connection.go @@ -41,7 +41,7 @@ type Connection struct { //nolint:maligned // TODO: fix alignment VerdictPermanent bool Inspecting bool Encrypted bool // TODO - Hidden bool + Internal bool // Portmaster internal connections are marked in order to easily filter these out in the UI pktQueue chan packet.Packet firewallHandler FirewallHandler diff --git a/network/dns.go b/network/dns.go index 43c0efcf..b33fa99f 100644 --- a/network/dns.go +++ b/network/dns.go @@ -5,6 +5,8 @@ import ( "strconv" "sync" "time" + + "github.com/safing/portmaster/process" ) var ( @@ -16,6 +18,9 @@ var ( // duration after which DNS requests without a following connection are logged openDNSRequestLimit = 3 * time.Second + + // scope prefix + unidentifiedProcessScopePrefix = strconv.Itoa(process.UnidentifiedProcessID) + "/" ) func removeOpenDNSRequest(pid int, fqdn string) { @@ -26,12 +31,9 @@ func removeOpenDNSRequest(pid int, fqdn string) { _, ok := openDNSRequests[key] if ok { delete(openDNSRequests, key) - return - } - - // check if there is an open dns request from an unidentified process - if pid >= 0 { - delete(openDNSRequests, "-1/"+fqdn) + } else if pid != process.UnidentifiedProcessID { + // check if there is an open dns request from an unidentified process + delete(openDNSRequests, unidentifiedProcessScopePrefix+fqdn) } } diff --git a/process/database.go b/process/database.go index b4ce09b3..1ce5295d 100644 --- a/process/database.go +++ b/process/database.go @@ -53,16 +53,13 @@ func (p *Process) Save() { p.Lock() defer p.Unlock() + p.UpdateMeta() + if !p.KeyIsSet() { + // set key p.SetKey(fmt.Sprintf("%s/%d", processDatabaseNamespace, p.Pid)) - p.CreateMeta() - } - processesLock.RLock() - _, ok := processes[p.Pid] - processesLock.RUnlock() - - if !ok { + // save processesLock.Lock() processes[p.Pid] = p processesLock.Unlock() @@ -113,7 +110,9 @@ func CleanProcessStorage(activePIDs map[int]struct{}) { _, active := activePIDs[p.Pid] switch { - case p.Pid <= 0: + case p.Pid == UnidentifiedProcessID: + // internal + case p.Pid == SystemProcessID: // internal case active: // process in system process table or recently seen on the network diff --git a/process/find.go b/process/find.go index 0e609f52..30f93f2d 100644 --- a/process/find.go +++ b/process/find.go @@ -49,7 +49,7 @@ func GetPidByPacket(pkt packet.Packet) (pid int, direction bool, err error) { case pkt.Info().Protocol == packet.UDP && pkt.Info().Version == packet.IPv6: return getUDP6PacketInfo(localIP, localPort, remoteIP, remotePort, pkt.IsInbound()) default: - return -1, false, errors.New("unsupported protocol for finding process") + return UnidentifiedProcessID, false, errors.New("unsupported protocol for finding process") } } @@ -107,7 +107,7 @@ func GetPidByEndpoints(localIP net.IP, localPort uint16, remoteIP net.IP, remote case protocol == packet.UDP && ipVersion == packet.IPv6: return getUDP6PacketInfo(localIP, localPort, remoteIP, remotePort, false) default: - return -1, false, errors.New("unsupported protocol for finding process") + return UnidentifiedProcessID, false, errors.New("unsupported protocol for finding process") } } diff --git a/process/iphelper/get.go b/process/iphelper/get.go index 99c0f821..6487ea06 100644 --- a/process/iphelper/get.go +++ b/process/iphelper/get.go @@ -9,6 +9,10 @@ import ( "time" ) +const ( + unidentifiedProcessID = -1 +) + var ( tcp4Connections []*ConnectionEntry tcp4Listeners []*ConnectionEntry @@ -55,7 +59,7 @@ func GetTCP4PacketInfo(localIP net.IP, localPort uint16, remoteIP net.IP, remote } lock.Unlock() if err != nil { - return -1, pktDirection, err + return unidentifiedProcessID, pktDirection, err } // search @@ -67,7 +71,7 @@ func GetTCP4PacketInfo(localIP net.IP, localPort uint16, remoteIP net.IP, remote time.Sleep(waitTime) } - return -1, pktDirection, nil + return unidentifiedProcessID, pktDirection, nil } // GetTCP6PacketInfo returns the pid of the given IPv6/TCP connection. @@ -91,7 +95,7 @@ func GetTCP6PacketInfo(localIP net.IP, localPort uint16, remoteIP net.IP, remote } lock.Unlock() if err != nil { - return -1, pktDirection, err + return unidentifiedProcessID, pktDirection, err } // search @@ -103,7 +107,7 @@ func GetTCP6PacketInfo(localIP net.IP, localPort uint16, remoteIP net.IP, remote time.Sleep(waitTime) } - return -1, pktDirection, nil + return unidentifiedProcessID, pktDirection, nil } // GetUDP4PacketInfo returns the pid of the given IPv4/UDP connection. @@ -127,7 +131,7 @@ func GetUDP4PacketInfo(localIP net.IP, localPort uint16, remoteIP net.IP, remote } lock.Unlock() if err != nil { - return -1, pktDirection, err + return unidentifiedProcessID, pktDirection, err } // search @@ -139,7 +143,7 @@ func GetUDP4PacketInfo(localIP net.IP, localPort uint16, remoteIP net.IP, remote time.Sleep(waitTime) } - return -1, pktDirection, nil + return unidentifiedProcessID, pktDirection, nil } // GetUDP6PacketInfo returns the pid of the given IPv6/UDP connection. @@ -163,7 +167,7 @@ func GetUDP6PacketInfo(localIP net.IP, localPort uint16, remoteIP net.IP, remote } lock.Unlock() if err != nil { - return -1, pktDirection, err + return unidentifiedProcessID, pktDirection, err } // search @@ -175,7 +179,7 @@ func GetUDP6PacketInfo(localIP net.IP, localPort uint16, remoteIP net.IP, remote time.Sleep(waitTime) } - return -1, pktDirection, nil + return unidentifiedProcessID, pktDirection, nil } func search(connections, listeners []*ConnectionEntry, localIP, remoteIP net.IP, localPort, remotePort uint16, pktDirection bool) (pid int, direction bool) { //nolint:unparam // TODO: use direction, it may not be used because results caused problems, investigate. @@ -204,7 +208,7 @@ func search(connections, listeners []*ConnectionEntry, localIP, remoteIP net.IP, } } - return -1, pktDirection + return unidentifiedProcessID, pktDirection } func searchConnections(list []*ConnectionEntry, localIP, remoteIP net.IP, localPort, remotePort uint16) (pid int) { @@ -218,7 +222,7 @@ func searchConnections(list []*ConnectionEntry, localIP, remoteIP net.IP, localP } } - return -1 + return unidentifiedProcessID } func searchListeners(list []*ConnectionEntry, localIP net.IP, localPort uint16) (pid int) { @@ -231,7 +235,7 @@ func searchListeners(list []*ConnectionEntry, localIP net.IP, localPort uint16) } } - return -1 + return unidentifiedProcessID } // GetActiveConnectionIDs returns all currently active connection IDs. diff --git a/process/proc/gather.go b/process/proc/gather.go index 436b0bb2..1413b3c9 100644 --- a/process/proc/gather.go +++ b/process/proc/gather.go @@ -33,7 +33,7 @@ func GetPidOfConnection(localIP net.IP, localPort uint16, protocol uint8) (pid i } } if !ok { - return -1, NoSocket + return unidentifiedProcessID, NoSocket } } @@ -45,7 +45,7 @@ func GetPidOfConnection(localIP net.IP, localPort uint16, protocol uint8) (pid i pid, ok = GetPidOfInode(uid, inode) } if !ok { - return -1, NoProcess + return unidentifiedProcessID, NoProcess } return @@ -64,7 +64,7 @@ func GetPidOfIncomingConnection(localIP net.IP, localPort uint16, protocol uint8 } if !ok { - return -1, NoSocket + return unidentifiedProcessID, NoSocket } } @@ -76,7 +76,7 @@ func GetPidOfIncomingConnection(localIP net.IP, localPort uint16, protocol uint8 pid, ok = GetPidOfInode(uid, inode) } if !ok { - return -1, NoProcess + return unidentifiedProcessID, NoProcess } return diff --git a/process/proc/get.go b/process/proc/get.go index dec27e23..52974b3e 100644 --- a/process/proc/get.go +++ b/process/proc/get.go @@ -7,6 +7,10 @@ import ( "net" ) +const ( + unidentifiedProcessID = -1 +) + // GetTCP4PacketInfo searches the network state tables for a TCP4 connection func GetTCP4PacketInfo(localIP net.IP, localPort uint16, remoteIP net.IP, remotePort uint16, pktDirection bool) (pid int, direction bool, err error) { return search(TCP4, localIP, localPort, pktDirection) @@ -52,11 +56,11 @@ func search(protocol uint8, localIP net.IP, localPort uint16, pktDirection bool) switch status { case NoSocket: - return -1, direction, errors.New("could not find socket") + return unidentifiedProcessID, direction, errors.New("could not find socket") case NoProcess: - return -1, direction, errors.New("could not find PID") + return unidentifiedProcessID, direction, errors.New("could not find PID") default: - return -1, direction, nil + return unidentifiedProcessID, direction, nil } } diff --git a/process/proc/processfinder.go b/process/proc/processfinder.go index 5ee1bb4b..5e6ed7cc 100644 --- a/process/proc/processfinder.go +++ b/process/proc/processfinder.go @@ -77,7 +77,7 @@ func GetPidOfInode(uid, inode int) (int, bool) { //nolint:gocognit // TODO } } - return -1, false + return unidentifiedProcessID, false } func findSocketFromPid(pid, inode int) bool { diff --git a/process/proc/sockets.go b/process/proc/sockets.go index c82b078c..bcdd91d4 100644 --- a/process/proc/sockets.go +++ b/process/proc/sockets.go @@ -100,7 +100,7 @@ func getConnectionSocket(localIP net.IP, localPort uint16, protocol uint8) (int, socketData, err := os.Open(procFile) if err != nil { log.Warningf("process/proc: could not read %s: %s", procFile, err) - return -1, -1, false + return unidentifiedProcessID, unidentifiedProcessID, false } defer socketData.Close() @@ -146,7 +146,7 @@ func getConnectionSocket(localIP net.IP, localPort uint16, protocol uint8) (int, } - return -1, -1, false + return unidentifiedProcessID, unidentifiedProcessID, false } @@ -187,7 +187,7 @@ func getListeningSocket(localIP net.IP, localPort uint16, protocol uint8) (uid, return data[0], data[1], true } - return -1, -1, false + return unidentifiedProcessID, unidentifiedProcessID, false } func procDelimiter(c rune) bool { diff --git a/process/process.go b/process/process.go index acdadeb8..8ef1ad73 100644 --- a/process/process.go +++ b/process/process.go @@ -75,10 +75,10 @@ func (p *Process) String() string { func GetOrFindPrimaryProcess(ctx context.Context, pid int) (*Process, error) { log.Tracer(ctx).Tracef("process: getting primary process for PID %d", pid) - if pid <= -1 { + switch pid { + case UnidentifiedProcessID: return GetUnidentifiedProcess(ctx), nil - } - if pid == 0 { + case SystemProcessID: return GetSystemProcess(ctx), nil } @@ -121,10 +121,10 @@ func GetOrFindPrimaryProcess(ctx context.Context, pid int) (*Process, error) { func GetOrFindProcess(ctx context.Context, pid int) (*Process, error) { log.Tracer(ctx).Tracef("process: getting process for PID %d", pid) - if pid <= -1 { + switch pid { + case UnidentifiedProcessID: return GetUnidentifiedProcess(ctx), nil - } - if pid == 0 { + case SystemProcessID: return GetSystemProcess(ctx), nil } @@ -184,10 +184,11 @@ func deduplicateRequest(ctx context.Context, pid int) (finishRequest func()) { } func loadProcess(ctx context.Context, pid int) (*Process, error) { - if pid <= -1 { + + switch pid { + case UnidentifiedProcessID: return GetUnidentifiedProcess(ctx), nil - } - if pid == 0 { + case SystemProcessID: return GetSystemProcess(ctx), nil } diff --git a/process/special.go b/process/special.go index 8cbf6130..277d337b 100644 --- a/process/special.go +++ b/process/special.go @@ -8,35 +8,52 @@ import ( "github.com/safing/portmaster/profile" ) +// Special Process IDs +const ( + UnidentifiedProcessID = -1 + SystemProcessID = 0 +) + var ( // unidentifiedProcess is used when a process cannot be found. unidentifiedProcess = &Process{ - UserID: -1, + UserID: UnidentifiedProcessID, UserName: "Unknown", - Pid: -1, - ParentPid: -1, + Pid: UnidentifiedProcessID, + ParentPid: UnidentifiedProcessID, Name: "Unidentified Processes", } // systemProcess is used to represent the Kernel. systemProcess = &Process{ - UserID: 0, + UserID: SystemProcessID, UserName: "Kernel", - Pid: 0, - ParentPid: 0, + Pid: SystemProcessID, + ParentPid: SystemProcessID, Name: "Operating System", } ) +// GetUnidentifiedProcess returns the special process assigned to unidentified processes. func GetUnidentifiedProcess(ctx context.Context) *Process { - return getSpecialProcess(ctx, unidentifiedProcess, profile.GetUnidentifiedProfile) + return getSpecialProcess(ctx, UnidentifiedProcessID, unidentifiedProcess, profile.GetUnidentifiedProfile) } +// GetSystemProcess returns the special process used for the Kernel. func GetSystemProcess(ctx context.Context) *Process { - return getSpecialProcess(ctx, systemProcess, profile.GetSystemProfile) + return getSpecialProcess(ctx, SystemProcessID, systemProcess, profile.GetSystemProfile) } -func getSpecialProcess(ctx context.Context, p *Process, getProfile func() *profile.Profile) *Process { +func getSpecialProcess(ctx context.Context, pid int, template *Process, getProfile func() *profile.Profile) *Process { + // check storage + p, ok := GetProcessFromStorage(pid) + if ok { + return p + } + + // assign template + p = template + p.Lock() defer p.Unlock() diff --git a/profile/active.go b/profile/active.go index 3d45a727..ff6a71c8 100644 --- a/profile/active.go +++ b/profile/active.go @@ -50,7 +50,7 @@ func markActiveProfileAsOutdated(scopedID string) { } } -func cleanActiveProfiles(ctx context.Context) error { //nolint:param // need to conform to interface +func cleanActiveProfiles(ctx context.Context) error { for { select { case <-time.After(activeProfileCleanerTickDuration): diff --git a/profile/special.go b/profile/special.go index 13993337..6bce01d7 100644 --- a/profile/special.go +++ b/profile/special.go @@ -9,6 +9,7 @@ const ( systemProfileID = "_system" ) +// GetUnidentifiedProfile returns the special profile assigned to unidentified processes. func GetUnidentifiedProfile() *Profile { // get profile profile, err := GetProfile(SourceLocal, unidentifiedProfileID) @@ -31,6 +32,7 @@ func GetUnidentifiedProfile() *Profile { return profile } +// GetSystemProfile returns the special profile used for the Kernel. func GetSystemProfile() *Profile { // get profile profile, err := GetProfile(SourceLocal, systemProfileID)