Continue with the new profile integration

This commit is contained in:
Daniel
2020-04-01 17:15:33 +02:00
parent 5523fcf0bd
commit 200d9000f6
19 changed files with 509 additions and 557 deletions

View File

@@ -7,6 +7,8 @@ import (
"sync"
"time"
"github.com/safing/portmaster/intel"
"github.com/safing/portbase/database/record"
"github.com/safing/portbase/log"
"github.com/safing/portmaster/network/packet"
@@ -16,21 +18,22 @@ import (
type FirewallHandler func(pkt packet.Packet, link *Link)
// Link describes a distinct physical connection (e.g. TCP connection) - like an instance - of a Connection.
//nolint:maligned // TODO: fix alignment
type Link struct {
type Link struct { //nolint:maligned // TODO: fix alignment
record.Base
sync.Mutex
lock sync.Mutex
ID string
ID string
Entity *intel.Entity
Direction bool
Verdict Verdict
Reason string
ReasonID string // format source[:id[:id]]
Tunneled bool
VerdictPermanent bool
Inspect bool
Started int64
Ended int64
RemoteAddress string
pktQueue chan packet.Packet
firewallHandler FirewallHandler
@@ -41,70 +44,82 @@ type Link struct {
saveWhenFinished bool
}
// Lock locks the link and the link's Entity.
func (link *Link) Lock() {
link.lock.Lock()
link.Entity.Lock()
}
// Lock unlocks the link and the link's Entity.
func (link *Link) Unlock() {
link.Entity.Unlock()
link.lock.Unlock()
}
// Communication returns the Communication the Link is part of
func (link *Link) Communication() *Communication {
link.Lock()
defer link.Unlock()
link.lock.Lock()
defer link.lock.Unlock()
return link.comm
}
// GetVerdict returns the current verdict.
func (link *Link) GetVerdict() Verdict {
link.Lock()
defer link.Unlock()
link.lock.Lock()
defer link.lock.Unlock()
return link.Verdict
}
// FirewallHandlerIsSet returns whether a firewall handler is set or not
func (link *Link) FirewallHandlerIsSet() bool {
link.Lock()
defer link.Unlock()
link.lock.Lock()
defer link.lock.Unlock()
return link.firewallHandler != nil
}
// SetFirewallHandler sets the firewall handler for this link
func (link *Link) SetFirewallHandler(handler FirewallHandler) {
link.Lock()
defer link.Unlock()
link.lock.Lock()
defer link.lock.Unlock()
if link.firewallHandler == nil {
link.firewallHandler = handler
link.pktQueue = make(chan packet.Packet, 1000)
// start handling
module.StartWorker("", func(ctx context.Context) error {
module.StartWorker("packet handler", func(ctx context.Context) error {
link.packetHandler()
return nil
})
return
}
link.firewallHandler = handler
}
// StopFirewallHandler unsets the firewall handler
func (link *Link) StopFirewallHandler() {
link.Lock()
link.lock.Lock()
link.firewallHandler = nil
link.Unlock()
link.lock.Unlock()
link.pktQueue <- nil
}
// HandlePacket queues packet of Link for handling
func (link *Link) HandlePacket(pkt packet.Packet) {
link.Lock()
defer link.Unlock()
// get handler
link.lock.Lock()
handler := link.firewallHandler
link.lock.Unlock()
if link.firewallHandler != nil {
// send to queue
if handler != nil {
link.pktQueue <- pkt
return
}
// no handler!
log.Warningf("network: link %s does not have a firewallHandler, dropping packet", link)
err := pkt.Drop()
if err != nil {
log.Warningf("network: failed to drop packet %s: %s", pkt, err)
@@ -119,7 +134,7 @@ func (link *Link) Accept(reason string) {
// Deny blocks or drops the link depending on the connection direction and adds the given reason.
func (link *Link) Deny(reason string) {
if link.comm != nil && link.comm.Direction {
if link.Direction {
link.Drop(reason)
} else {
link.Block(reason)
@@ -151,8 +166,8 @@ func (link *Link) RerouteToTunnel(reason string) {
// UpdateVerdict sets a new verdict for this link, making sure it does not interfere with previous verdicts
func (link *Link) UpdateVerdict(newVerdict Verdict) {
link.Lock()
defer link.Unlock()
link.lock.Lock()
defer link.lock.Unlock()
if newVerdict > link.Verdict {
link.Verdict = newVerdict
@@ -166,8 +181,8 @@ func (link *Link) AddReason(reason string) {
return
}
link.Lock()
defer link.Unlock()
link.lock.Lock()
defer link.lock.Unlock()
if link.Reason != "" {
link.Reason += " | "
@@ -185,9 +200,9 @@ func (link *Link) packetHandler() {
return
}
// get handler
link.Lock()
link.lock.Lock()
handler := link.firewallHandler
link.Unlock()
link.lock.Unlock()
// execute handler or verdict
if handler != nil {
handler(pkt, link)
@@ -201,8 +216,8 @@ func (link *Link) packetHandler() {
// ApplyVerdict appies the link verdict to a packet.
func (link *Link) ApplyVerdict(pkt packet.Packet) {
link.Lock()
defer link.Unlock()
link.lock.Lock()
defer link.lock.Unlock()
var err error
@@ -251,12 +266,12 @@ func (link *Link) SaveWhenFinished() {
// SaveIfNeeded saves the Link if it is marked for saving when finished.
func (link *Link) SaveIfNeeded() {
link.Lock()
link.lock.Lock()
save := link.saveWhenFinished
if save {
link.saveWhenFinished = false
}
link.Unlock()
link.lock.Unlock()
if save {
link.saveAndLog()
@@ -274,18 +289,18 @@ func (link *Link) saveAndLog() {
// save saves the link object in the storage and propagates the change.
func (link *Link) save() error {
// update link
link.Lock()
link.lock.Lock()
if link.comm == nil {
link.Unlock()
link.lock.Unlock()
return errors.New("cannot save link without comms")
}
if !link.KeyIsSet() {
link.SetKey(fmt.Sprintf("network:tree/%d/%s/%s", link.comm.Process().Pid, link.comm.Domain, link.ID))
link.SetKey(fmt.Sprintf("network:tree/%d/%s/%s", link.comm.Process().Pid, link.comm.Scope, link.ID))
link.UpdateMeta()
}
link.saveWhenFinished = false
link.Unlock()
link.lock.Unlock()
// save link
linksLock.RLock()
@@ -306,8 +321,8 @@ func (link *Link) save() error {
func (link *Link) Delete() {
linksLock.Lock()
defer linksLock.Unlock()
link.Lock()
defer link.Unlock()
link.lock.Lock()
defer link.lock.Unlock()
delete(links, link.ID)
@@ -339,10 +354,15 @@ func GetOrCreateLinkByPacket(pkt packet.Packet) (*Link, bool) {
// CreateLinkFromPacket creates a new Link based on Packet.
func CreateLinkFromPacket(pkt packet.Packet) *Link {
link := &Link{
ID: pkt.GetLinkID(),
ID: pkt.GetLinkID(),
Entity: (&intel.Entity{
IP: pkt.Info().RemoteIP(),
Protocol: uint8(pkt.Info().Protocol),
Port: pkt.Info().RemotePort(),
}).Init(),
Direction: pkt.IsInbound(),
Verdict: VerdictUndecided,
Started: time.Now().Unix(),
RemoteAddress: pkt.FmtRemoteAddress(),
saveWhenFinished: true,
}
return link
@@ -350,59 +370,59 @@ func CreateLinkFromPacket(pkt packet.Packet) *Link {
// GetActiveInspectors returns the list of active inspectors.
func (link *Link) GetActiveInspectors() []bool {
link.Lock()
defer link.Unlock()
link.lock.Lock()
defer link.lock.Unlock()
return link.activeInspectors
}
// SetActiveInspectors sets the list of active inspectors.
func (link *Link) SetActiveInspectors(new []bool) {
link.Lock()
defer link.Unlock()
link.lock.Lock()
defer link.lock.Unlock()
link.activeInspectors = new
}
// GetInspectorData returns the list of inspector data.
func (link *Link) GetInspectorData() map[uint8]interface{} {
link.Lock()
defer link.Unlock()
link.lock.Lock()
defer link.lock.Unlock()
return link.inspectorData
}
// SetInspectorData set the list of inspector data.
func (link *Link) SetInspectorData(new map[uint8]interface{}) {
link.Lock()
defer link.Unlock()
link.lock.Lock()
defer link.lock.Unlock()
link.inspectorData = new
}
// String returns a string representation of Link.
func (link *Link) String() string {
link.Lock()
defer link.Unlock()
link.lock.Lock()
defer link.lock.Unlock()
if link.comm == nil {
return fmt.Sprintf("? <-> %s", link.RemoteAddress)
return fmt.Sprintf("? <-> %s", link.Entity.IP.String())
}
switch link.comm.Domain {
case "I":
switch link.comm.Scope {
case IncomingHost, IncomingLAN, IncomingInternet, IncomingInvalid:
if link.comm.process == nil {
return fmt.Sprintf("? <- %s", link.RemoteAddress)
return fmt.Sprintf("? <- %s", link.Entity.IP.String())
}
return fmt.Sprintf("%s <- %s", link.comm.process.String(), link.RemoteAddress)
case "D":
return fmt.Sprintf("%s <- %s", link.comm.process.String(), link.Entity.IP.String())
case PeerHost, PeerLAN, PeerInternet, PeerInvalid:
if link.comm.process == nil {
return fmt.Sprintf("? -> %s", link.RemoteAddress)
return fmt.Sprintf("? -> %s", link.Entity.IP.String())
}
return fmt.Sprintf("%s -> %s", link.comm.process.String(), link.RemoteAddress)
return fmt.Sprintf("%s -> %s", link.comm.process.String(), link.Entity.IP.String())
default:
if link.comm.process == nil {
return fmt.Sprintf("? -> %s (%s)", link.comm.Domain, link.RemoteAddress)
return fmt.Sprintf("? -> %s (%s)", link.comm.Scope, link.Entity.IP.String())
}
return fmt.Sprintf("%s to %s (%s)", link.comm.process.String(), link.comm.Domain, link.RemoteAddress)
return fmt.Sprintf("%s to %s (%s)", link.comm.process.String(), link.comm.Scope, link.Entity.IP.String())
}
}