mirror of
https://github.com/safing/portmaster
synced 2025-09-05 03:59:11 +00:00
Working on portmaster restructure
This commit is contained in:
parent
be8a1d1739
commit
3990790f17
26 changed files with 351 additions and 263 deletions
|
@ -11,17 +11,13 @@ import (
|
||||||
"github.com/Safing/portbase/modules"
|
"github.com/Safing/portbase/modules"
|
||||||
|
|
||||||
// include packages here
|
// include packages here
|
||||||
|
|
||||||
_ "github.com/Safing/portbase/database/dbmodule"
|
|
||||||
_ "github.com/Safing/portbase/database/storage/badger"
|
|
||||||
_ "github.com/Safing/portmaster/intel"
|
|
||||||
_ "github.com/Safing/portmaster/nameserver/only"
|
_ "github.com/Safing/portmaster/nameserver/only"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
// Set Info
|
// Set Info
|
||||||
info.Set("Portmaster (DNS only)", "0.0.1")
|
info.Set("Portmaster (DNS only)", "0.2.0")
|
||||||
|
|
||||||
// Start
|
// Start
|
||||||
err := modules.Start()
|
err := modules.Start()
|
||||||
|
|
|
@ -8,7 +8,7 @@ var (
|
||||||
permanentVerdicts config.BoolOption
|
permanentVerdicts config.BoolOption
|
||||||
)
|
)
|
||||||
|
|
||||||
func prep() error {
|
func registerConfig() error {
|
||||||
err := config.Register(&config.Option{
|
err := config.Register(&config.Option{
|
||||||
Name: "Permanent Verdicts",
|
Name: "Permanent Verdicts",
|
||||||
Key: "firewall/permanentVerdicts",
|
Key: "firewall/permanentVerdicts",
|
||||||
|
@ -20,5 +20,7 @@ func prep() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
configuredNameServers = config.Concurrent.GetAsBool("firewall/permanentVerdicts", true)
|
permanentVerdicts = config.Concurrent.GetAsBool("firewall/permanentVerdicts", true)
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,6 @@ var (
|
||||||
packetsBlocked *uint64
|
packetsBlocked *uint64
|
||||||
packetsDropped *uint64
|
packetsDropped *uint64
|
||||||
|
|
||||||
config = configuration.Get()
|
|
||||||
|
|
||||||
localNet4 *net.IPNet
|
localNet4 *net.IPNet
|
||||||
// Yes, this would normally be 127.0.0.0/8
|
// Yes, this would normally be 127.0.0.0/8
|
||||||
// TODO: figure out any side effects
|
// TODO: figure out any side effects
|
||||||
|
@ -40,11 +38,16 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
modules.Register("firewall", prep, start, stop, "database", "nameserver")
|
modules.Register("firewall", prep, start, stop, "global", "network", "nameserver")
|
||||||
}
|
}
|
||||||
|
|
||||||
func prep() (err error) {
|
func prep() (err error) {
|
||||||
|
|
||||||
|
err = registerConfig()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
_, localNet4, err = net.ParseCIDR("127.0.0.0/24")
|
_, localNet4, err = net.ParseCIDR("127.0.0.0/24")
|
||||||
// Yes, this would normally be 127.0.0.0/8
|
// Yes, this would normally be 127.0.0.0/8
|
||||||
// TODO: figure out any side effects
|
// TODO: figure out any side effects
|
||||||
|
@ -71,15 +74,18 @@ func prep() (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func start() {
|
func start() error {
|
||||||
// start interceptor
|
|
||||||
interception.Start()
|
|
||||||
|
|
||||||
go statLogger()
|
go statLogger()
|
||||||
go run()
|
go run()
|
||||||
// go run()
|
// go run()
|
||||||
// go run()
|
// go run()
|
||||||
// go run()
|
// go run()
|
||||||
|
|
||||||
|
return interception.Start()
|
||||||
|
}
|
||||||
|
|
||||||
|
func stop() error {
|
||||||
|
return interception.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
func handlePacket(pkt packet.Packet) {
|
func handlePacket(pkt packet.Packet) {
|
||||||
|
@ -119,16 +125,16 @@ func handlePacket(pkt packet.Packet) {
|
||||||
// defer log.Tracef("firewall: took %s to process packet %s", time.Now().Sub(timed).String(), pkt)
|
// defer log.Tracef("firewall: took %s to process packet %s", time.Now().Sub(timed).String(), pkt)
|
||||||
|
|
||||||
// check if packet is destined for tunnel
|
// check if packet is destined for tunnel
|
||||||
switch pkt.IPVersion() {
|
// switch pkt.IPVersion() {
|
||||||
case packet.IPv4:
|
// case packet.IPv4:
|
||||||
if TunnelNet4 != nil && TunnelNet4.Contains(pkt.GetIPHeader().Dst) {
|
// if TunnelNet4 != nil && TunnelNet4.Contains(pkt.GetIPHeader().Dst) {
|
||||||
tunnelHandler(pkt)
|
// tunnelHandler(pkt)
|
||||||
}
|
// }
|
||||||
case packet.IPv6:
|
// case packet.IPv6:
|
||||||
if TunnelNet6 != nil && TunnelNet6.Contains(pkt.GetIPHeader().Dst) {
|
// if TunnelNet6 != nil && TunnelNet6.Contains(pkt.GetIPHeader().Dst) {
|
||||||
tunnelHandler(pkt)
|
// tunnelHandler(pkt)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// associate packet to link and handle
|
// associate packet to link and handle
|
||||||
link, created := network.GetOrCreateLinkByPacket(pkt)
|
link, created := network.GetOrCreateLinkByPacket(pkt)
|
||||||
|
@ -175,11 +181,8 @@ func initialHandler(pkt packet.Packet, link *network.Link) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// persist connection
|
// add new Link to Connection (and save both)
|
||||||
connection.CreateInProcessNamespace()
|
connection.AddLink(link)
|
||||||
|
|
||||||
// add new Link to Connection
|
|
||||||
connection.AddLink(link, pkt)
|
|
||||||
|
|
||||||
// make a decision if not made already
|
// make a decision if not made already
|
||||||
if connection.Verdict == network.UNDECIDED {
|
if connection.Verdict == network.UNDECIDED {
|
||||||
|
|
|
@ -41,24 +41,28 @@ func RunInspectors(pkt packet.Packet, link *network.Link) (network.Verdict, bool
|
||||||
// inspectorsLock.Lock()
|
// inspectorsLock.Lock()
|
||||||
// defer inspectorsLock.Unlock()
|
// defer inspectorsLock.Unlock()
|
||||||
|
|
||||||
if link.ActiveInspectors == nil {
|
activeInspectors := link.GetActiveInspectors()
|
||||||
link.ActiveInspectors = make([]bool, len(inspectors), len(inspectors))
|
if activeInspectors == nil {
|
||||||
|
activeInspectors = make([]bool, len(inspectors), len(inspectors))
|
||||||
|
link.SetActiveInspectors(activeInspectors)
|
||||||
}
|
}
|
||||||
|
|
||||||
if link.InspectorData == nil {
|
inspectorData := link.GetInspectorData()
|
||||||
link.InspectorData = make(map[uint8]interface{})
|
if inspectorData == nil {
|
||||||
|
inspectorData = make(map[uint8]interface{})
|
||||||
|
link.SetInspectorData(inspectorData)
|
||||||
}
|
}
|
||||||
|
|
||||||
continueInspection := false
|
continueInspection := false
|
||||||
verdict := network.UNDECIDED
|
verdict := network.UNDECIDED
|
||||||
|
|
||||||
for key, skip := range link.ActiveInspectors {
|
for key, skip := range activeInspectors {
|
||||||
|
|
||||||
if skip {
|
if skip {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if link.Verdict > inspectVerdicts[key] {
|
if link.Verdict > inspectVerdicts[key] {
|
||||||
link.ActiveInspectors[key] = true
|
activeInspectors[key] = true
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,16 +83,16 @@ func RunInspectors(pkt packet.Packet, link *network.Link) (network.Verdict, bool
|
||||||
continueInspection = true
|
continueInspection = true
|
||||||
case BLOCK_LINK:
|
case BLOCK_LINK:
|
||||||
link.UpdateVerdict(network.BLOCK)
|
link.UpdateVerdict(network.BLOCK)
|
||||||
link.ActiveInspectors[key] = true
|
activeInspectors[key] = true
|
||||||
if verdict < network.BLOCK {
|
if verdict < network.BLOCK {
|
||||||
verdict = network.BLOCK
|
verdict = network.BLOCK
|
||||||
}
|
}
|
||||||
case DROP_LINK:
|
case DROP_LINK:
|
||||||
link.UpdateVerdict(network.DROP)
|
link.UpdateVerdict(network.DROP)
|
||||||
link.ActiveInspectors[key] = true
|
activeInspectors[key] = true
|
||||||
verdict = network.DROP
|
verdict = network.DROP
|
||||||
case STOP_INSPECTING:
|
case STOP_INSPECTING:
|
||||||
link.ActiveInspectors[key] = true
|
activeInspectors[key] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,5 +5,16 @@ package interception
|
||||||
import "github.com/Safing/portmaster/network/packet"
|
import "github.com/Safing/portmaster/network/packet"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// Packets channel for feeding the firewall.
|
||||||
Packets = make(chan packet.Packet, 1000)
|
Packets = make(chan packet.Packet, 1000)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Start starts the interception.
|
||||||
|
func Start() error {
|
||||||
|
return StartNfqueueInterception()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop starts the interception.
|
||||||
|
func Stop() error {
|
||||||
|
return StopNfqueueInterception()
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package interception
|
package interception
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/Safing/portbase/log"
|
"fmt"
|
||||||
"github.com/Safing/portbase/modules"
|
|
||||||
"github.com/Safing/portmaster/firewall/interception/windivert"
|
"github.com/Safing/portmaster/firewall/interception/windivert"
|
||||||
"github.com/Safing/portmaster/network/packet"
|
"github.com/Safing/portmaster/network/packet"
|
||||||
)
|
)
|
||||||
|
@ -10,20 +10,22 @@ import (
|
||||||
var Packets chan packet.Packet
|
var Packets chan packet.Packet
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
// Packets channel for feeding the firewall.
|
||||||
Packets = make(chan packet.Packet, 1000)
|
Packets = make(chan packet.Packet, 1000)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Start() {
|
// Start starts the interception.
|
||||||
|
func Start() error {
|
||||||
windivertModule := modules.Register("Firewall:Interception:WinDivert", 192)
|
|
||||||
|
|
||||||
wd, err := windivert.New("/WinDivert.dll", "")
|
wd, err := windivert.New("/WinDivert.dll", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Criticalf("firewall/interception: could not init windivert: %s", err)
|
return fmt.Errorf("firewall/interception: could not init windivert: %s", err)
|
||||||
} else {
|
|
||||||
wd.Packets(Packets)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<-windivertModule.Stop
|
return wd.Packets(Packets)
|
||||||
windivertModule.StopComplete()
|
}
|
||||||
|
|
||||||
|
// Stop starts the interception.
|
||||||
|
func Stop() error {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
// Copyright Safing ICS Technologies GmbH. Use of this source code is governed by the AGPL license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build linux
|
|
||||||
|
|
||||||
package interception
|
package interception
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -106,8 +102,8 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reverse because we'd like to insert in a loop
|
// Reverse because we'd like to insert in a loop
|
||||||
sort.Reverse(sort.StringSlice(v4once))
|
_ = sort.Reverse(sort.StringSlice(v4once)) // silence vet (sort is used just like in the docs)
|
||||||
sort.Reverse(sort.StringSlice(v6once))
|
_ = sort.Reverse(sort.StringSlice(v6once)) // silence vet (sort is used just like in the docs)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,9 +129,10 @@ func activateNfqueueFirewall() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ok bool
|
||||||
for _, rule := range v4once {
|
for _, rule := range v4once {
|
||||||
splittedRule := strings.Split(rule, " ")
|
splittedRule := strings.Split(rule, " ")
|
||||||
ok, err := ip4tables.Exists(splittedRule[0], splittedRule[1], splittedRule[2:]...)
|
ok, err = ip4tables.Exists(splittedRule[0], splittedRule[1], splittedRule[2:]...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -189,9 +186,10 @@ func deactivateNfqueueFirewall() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ok bool
|
||||||
for _, rule := range v4once {
|
for _, rule := range v4once {
|
||||||
splittedRule := strings.Split(rule, " ")
|
splittedRule := strings.Split(rule, " ")
|
||||||
ok, err := ip4tables.Exists(splittedRule[0], splittedRule[1], splittedRule[2:]...)
|
ok, err = ip4tables.Exists(splittedRule[0], splittedRule[1], splittedRule[2:]...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -204,10 +202,10 @@ func deactivateNfqueueFirewall() error {
|
||||||
|
|
||||||
for _, chain := range v4chains {
|
for _, chain := range v4chains {
|
||||||
splittedRule := strings.Split(chain, " ")
|
splittedRule := strings.Split(chain, " ")
|
||||||
if err := ip4tables.ClearChain(splittedRule[0], splittedRule[1]); err != nil {
|
if err = ip4tables.ClearChain(splittedRule[0], splittedRule[1]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := ip4tables.DeleteChain(splittedRule[0], splittedRule[1]); err != nil {
|
if err = ip4tables.DeleteChain(splittedRule[0], splittedRule[1]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -244,8 +242,8 @@ func deactivateNfqueueFirewall() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start starts the nfqueue interception.
|
// StartNfqueueInterception starts the nfqueue interception.
|
||||||
func Start() (err error) {
|
func StartNfqueueInterception() (err error) {
|
||||||
|
|
||||||
err = activateNfqueueFirewall()
|
err = activateNfqueueFirewall()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -278,8 +276,8 @@ func Start() (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop stops the nfqueue interception.
|
// StopNfqueueInterception stops the nfqueue interception.
|
||||||
func Stop() error {
|
func StopNfqueueInterception() error {
|
||||||
defer close(shutdownSignal)
|
defer close(shutdownSignal)
|
||||||
|
|
||||||
if out4Queue != nil {
|
if out4Queue != nil {
|
|
@ -1,19 +0,0 @@
|
||||||
package firewall
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/Safing/portbase/modules"
|
|
||||||
|
|
||||||
_ "github.com/Safing/portmaster/network"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
modules.Register("firewall", nil, start, stop, "network")
|
|
||||||
}
|
|
||||||
|
|
||||||
func start() error {
|
|
||||||
return registerAsDatabase()
|
|
||||||
}
|
|
||||||
|
|
||||||
func stop() error {
|
|
||||||
|
|
||||||
}
|
|
48
global/databases.go
Normal file
48
global/databases.go
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
package global
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Safing/portbase/database"
|
||||||
|
"github.com/Safing/portbase/modules"
|
||||||
|
|
||||||
|
// module dependencies
|
||||||
|
_ "github.com/Safing/portbase/database/dbmodule"
|
||||||
|
_ "github.com/Safing/portbase/database/storage/badger"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
modules.Register("global", nil, start, nil, "database")
|
||||||
|
}
|
||||||
|
|
||||||
|
func start() error {
|
||||||
|
_, err := database.Register(&database.Database{
|
||||||
|
Name: "core",
|
||||||
|
Description: "Holds core data, such as settings and profiles",
|
||||||
|
StorageType: "badger",
|
||||||
|
PrimaryAPI: "",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = database.Register(&database.Database{
|
||||||
|
Name: "cache",
|
||||||
|
Description: "Cached data, such as Intelligence and DNS Records",
|
||||||
|
StorageType: "badger",
|
||||||
|
PrimaryAPI: "",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// _, err = database.Register(&database.Database{
|
||||||
|
// Name: "history",
|
||||||
|
// Description: "Historic event data",
|
||||||
|
// StorageType: "badger",
|
||||||
|
// PrimaryAPI: "",
|
||||||
|
// })
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -25,7 +25,7 @@ type Intel struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeIntelKey(domain string) string {
|
func makeIntelKey(domain string) string {
|
||||||
return fmt.Sprintf("intel:Intel/%s", domain)
|
return fmt.Sprintf("cache:intel/domain/%s", domain)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetIntelFromDB gets an Intel record from the database.
|
// GetIntelFromDB gets an Intel record from the database.
|
||||||
|
|
|
@ -26,7 +26,7 @@ type IPInfo struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeIPInfoKey(ip string) string {
|
func makeIPInfoKey(ip string) string {
|
||||||
return fmt.Sprintf("intel:IPInfo/%s", ip)
|
return fmt.Sprintf("cache:intel/ipInfo/%s", ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetIPInfo gets an IPInfo record from the database.
|
// GetIPInfo gets an IPInfo record from the database.
|
||||||
|
|
|
@ -3,26 +3,18 @@ package intel
|
||||||
import (
|
import (
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
|
|
||||||
"github.com/Safing/portbase/database"
|
|
||||||
"github.com/Safing/portbase/log"
|
"github.com/Safing/portbase/log"
|
||||||
"github.com/Safing/portbase/modules"
|
"github.com/Safing/portbase/modules"
|
||||||
|
|
||||||
|
// module dependencies
|
||||||
|
_ "github.com/Safing/portmaster/global"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
modules.Register("intel", prep, start, nil, "database")
|
modules.Register("intel", prep, start, nil, "global")
|
||||||
}
|
}
|
||||||
|
|
||||||
func start() error {
|
func start() error {
|
||||||
_, err := database.Register(&database.Database{
|
|
||||||
Name: "intel",
|
|
||||||
Description: "Intelligence and DNS Data",
|
|
||||||
StorageType: "badger",
|
|
||||||
PrimaryAPI: "",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// load resolvers from config and environment
|
// load resolvers from config and environment
|
||||||
loadResolvers(false)
|
loadResolvers(false)
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ type NameRecord struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeNameRecordKey(domain string, question string) string {
|
func makeNameRecordKey(domain string, question string) string {
|
||||||
return fmt.Sprintf("intel:NameRecords/%s%s", domain, question)
|
return fmt.Sprintf("cache:intel/nameRecord/%s%s", domain, question)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNameRecord gets a NameRecord from the database.
|
// GetNameRecord gets a NameRecord from the database.
|
||||||
|
|
6
main.go
6
main.go
|
@ -14,15 +14,13 @@ import (
|
||||||
|
|
||||||
_ "github.com/Safing/portbase/database/dbmodule"
|
_ "github.com/Safing/portbase/database/dbmodule"
|
||||||
_ "github.com/Safing/portbase/database/storage/badger"
|
_ "github.com/Safing/portbase/database/storage/badger"
|
||||||
_ "github.com/Safing/portmaster/intel"
|
_ "github.com/Safing/portmaster/firewall"
|
||||||
_ "github.com/Safing/portmaster/nameserver/only"
|
|
||||||
_ "github.com/Safing/portmaster/nameserver/only"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
// Set Info
|
// Set Info
|
||||||
info.Set("Portmaster", "0.0.1")
|
info.Set("Portmaster", "0.2.0")
|
||||||
|
|
||||||
// Start
|
// Start
|
||||||
err := modules.Start()
|
err := modules.Start()
|
||||||
|
|
|
@ -9,20 +9,17 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
deadLinksTimeout = 5 * time.Minute
|
cleanerTickDuration = 1 * time.Minute
|
||||||
thresholdDuration = 1 * time.Minute
|
deadLinksTimeout = 5 * time.Minute
|
||||||
|
thresholdDuration = 1 * time.Minute
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
|
||||||
go cleaner()
|
|
||||||
}
|
|
||||||
|
|
||||||
func cleaner() {
|
func cleaner() {
|
||||||
time.Sleep(15 * time.Second)
|
|
||||||
for {
|
for {
|
||||||
markDeadLinks()
|
time.Sleep(cleanerTickDuration)
|
||||||
purgeDeadFor(5 * time.Minute)
|
cleanLinks()
|
||||||
time.Sleep(15 * time.Second)
|
cleanConnections()
|
||||||
|
cleanProcesses()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -234,7 +234,7 @@ func (conn *Connection) AddLink(link *Link) {
|
||||||
conn.LinkCount++
|
conn.LinkCount++
|
||||||
conn.LastLinkEstablished = time.Now().Unix()
|
conn.LastLinkEstablished = time.Now().Unix()
|
||||||
if conn.FirstLinkEstablished == 0 {
|
if conn.FirstLinkEstablished == 0 {
|
||||||
conn.FirstLinkEstablished = conn.FirstLinkEstablished
|
conn.FirstLinkEstablished = conn.LastLinkEstablished
|
||||||
}
|
}
|
||||||
conn.Save()
|
conn.Save()
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,8 +38,11 @@ func (s *StorageInterface) Get(key string) (record.Record, error) {
|
||||||
switch len(splitted) {
|
switch len(splitted) {
|
||||||
case 2:
|
case 2:
|
||||||
pid, err := strconv.Atoi(splitted[1])
|
pid, err := strconv.Atoi(splitted[1])
|
||||||
if err != nil {
|
if err == nil {
|
||||||
return process.GetProcessByPID(pid)
|
proc, ok := process.GetProcessFromStorage(pid)
|
||||||
|
if ok {
|
||||||
|
return proc, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case 3:
|
case 3:
|
||||||
conn, ok := connections[splitted[2]]
|
conn, ok := connections[splitted[2]]
|
||||||
|
@ -69,7 +72,7 @@ func (s *StorageInterface) Query(q *query.Query, local, internal bool) (*iterato
|
||||||
func (s *StorageInterface) processQuery(q *query.Query, it *iterator.Iterator) {
|
func (s *StorageInterface) processQuery(q *query.Query, it *iterator.Iterator) {
|
||||||
// processes
|
// processes
|
||||||
for _, proc := range process.All() {
|
for _, proc := range process.All() {
|
||||||
if strings.HasPrefix(proc.Meta().DatabaseKey, q.DatabaseKeyPrefix()) {
|
if strings.HasPrefix(proc.DatabaseKey(), q.DatabaseKeyPrefix()) {
|
||||||
it.Next <- proc
|
it.Next <- proc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,14 +82,14 @@ func (s *StorageInterface) processQuery(q *query.Query, it *iterator.Iterator) {
|
||||||
|
|
||||||
// connections
|
// connections
|
||||||
for _, conn := range connections {
|
for _, conn := range connections {
|
||||||
if strings.HasPrefix(conn.Meta().DatabaseKey, q.DatabaseKeyPrefix()) {
|
if strings.HasPrefix(conn.DatabaseKey(), q.DatabaseKeyPrefix()) {
|
||||||
it.Next <- conn
|
it.Next <- conn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// links
|
// links
|
||||||
for _, link := range links {
|
for _, link := range links {
|
||||||
if strings.HasPrefix(opt.Meta().DatabaseKey, q.DatabaseKeyPrefix()) {
|
if strings.HasPrefix(link.DatabaseKey(), q.DatabaseKeyPrefix()) {
|
||||||
it.Next <- link
|
it.Next <- link
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,7 +108,7 @@ func registerAsDatabase() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
controller, err := database.InjectDatabase("network", &ConfigStorageInterface{})
|
controller, err := database.InjectDatabase("network", &StorageInterface{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,6 +177,34 @@ func CreateLinkFromPacket(pkt packet.Packet) *Link {
|
||||||
return link
|
return link
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetActiveInspectors returns the list of active inspectors.
|
||||||
|
func (link *Link) GetActiveInspectors() []bool {
|
||||||
|
link.Lock()
|
||||||
|
defer link.Unlock()
|
||||||
|
return link.activeInspectors
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetActiveInspectors sets the list of active inspectors.
|
||||||
|
func (link *Link) SetActiveInspectors(new []bool) {
|
||||||
|
link.Lock()
|
||||||
|
defer link.Unlock()
|
||||||
|
link.activeInspectors = new
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInspectorData returns the list of inspector data.
|
||||||
|
func (link *Link) GetInspectorData() map[uint8]interface{} {
|
||||||
|
link.Lock()
|
||||||
|
defer link.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.inspectorData = new
|
||||||
|
}
|
||||||
|
|
||||||
// String returns a string representation of Link.
|
// String returns a string representation of Link.
|
||||||
func (link *Link) String() string {
|
func (link *Link) String() string {
|
||||||
if link.connection == nil {
|
if link.connection == nil {
|
||||||
|
|
|
@ -5,9 +5,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
modules.Register("network", prep, start, nil, "database")
|
modules.Register("network", nil, start, nil, "database")
|
||||||
}
|
}
|
||||||
|
|
||||||
func start() error {
|
func start() error {
|
||||||
|
go cleaner()
|
||||||
return registerAsDatabase()
|
return registerAsDatabase()
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
|
|
||||||
"github.com/Safing/portbase/database/record"
|
"github.com/Safing/portbase/database/record"
|
||||||
"github.com/Safing/portbase/log"
|
"github.com/Safing/portbase/log"
|
||||||
|
"github.com/Safing/portmaster/profile"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A Process represents a process running on the operating system
|
// A Process represents a process running on the operating system
|
||||||
|
@ -19,17 +20,18 @@ type Process struct {
|
||||||
record.Base
|
record.Base
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
|
|
||||||
UserID int
|
UserID int
|
||||||
UserName string
|
UserName string
|
||||||
UserHome string
|
UserHome string
|
||||||
Pid int
|
Pid int
|
||||||
ParentPid int
|
ParentPid int
|
||||||
Path string
|
Path string
|
||||||
Cwd string
|
Cwd string
|
||||||
FileInfo *FileInfo
|
FileInfo *FileInfo
|
||||||
CmdLine string
|
CmdLine string
|
||||||
FirstArg string
|
FirstArg string
|
||||||
ProfileKey string
|
|
||||||
|
profileSet *profile.Set
|
||||||
Name string
|
Name string
|
||||||
Icon string
|
Icon string
|
||||||
// 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.
|
// 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.
|
||||||
|
@ -39,7 +41,12 @@ type Process struct {
|
||||||
ConnectionCount uint
|
ConnectionCount uint
|
||||||
}
|
}
|
||||||
|
|
||||||
// Strings returns a string represenation of process
|
// ProfileSet returns the assigned profile set.
|
||||||
|
func (p *Process) ProfileSet() *profile.Set {
|
||||||
|
return p.profileSet
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strings returns a string represenation of process.
|
||||||
func (p *Process) String() string {
|
func (p *Process) String() string {
|
||||||
if p == nil {
|
if p == nil {
|
||||||
return "?"
|
return "?"
|
||||||
|
|
|
@ -20,8 +20,8 @@ func (d Domains) IsSet() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckStatus checks if the given domain is governed in the list of domains and returns whether it is permitted.
|
// Check checks if the given domain is governed in the list of domains and returns whether it is permitted.
|
||||||
func (d Domains) CheckStatus(domain string) (permit, ok bool) {
|
func (d Domains) Check(domain string) (permit, ok bool) {
|
||||||
// check for exact domain
|
// check for exact domain
|
||||||
dd, ok := d[domain]
|
dd, ok := d[domain]
|
||||||
if ok {
|
if ok {
|
||||||
|
|
|
@ -7,8 +7,8 @@ import (
|
||||||
"github.com/Safing/portmaster/status"
|
"github.com/Safing/portmaster/status"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ProfileFlags are used to quickly add common attributes to profiles
|
// Flags are used to quickly add common attributes to profiles
|
||||||
type ProfileFlags map[uint8]uint8
|
type Flags map[uint8]uint8
|
||||||
|
|
||||||
// Profile Flags
|
// Profile Flags
|
||||||
const (
|
const (
|
||||||
|
@ -31,8 +31,8 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// ErrProfileFlagsParseFailed is returned if a an invalid flag is encountered while parsing
|
// ErrFlagsParseFailed is returned if a an invalid flag is encountered while parsing
|
||||||
ErrProfileFlagsParseFailed = errors.New("profiles: failed to parse flags")
|
ErrFlagsParseFailed = errors.New("profiles: failed to parse flags")
|
||||||
|
|
||||||
sortedFlags = []uint8{
|
sortedFlags = []uint8{
|
||||||
Prompt,
|
Prompt,
|
||||||
|
@ -77,34 +77,33 @@ var (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// FlagsFromNames creates ProfileFlags from a comma seperated list of flagnames (e.g. "System,Strict,Secure")
|
// FlagsFromNames creates Flags from a comma seperated list of flagnames (e.g. "System,Strict,Secure")
|
||||||
// func FlagsFromNames(words []string) (*ProfileFlags, error) {
|
// func FlagsFromNames(words []string) (*Flags, error) {
|
||||||
// var flags ProfileFlags
|
// var flags Flags
|
||||||
// for _, entry := range words {
|
// for _, entry := range words {
|
||||||
// flag, ok := flagIDs[entry]
|
// flag, ok := flagIDs[entry]
|
||||||
// if !ok {
|
// if !ok {
|
||||||
// return nil, ErrProfileFlagsParseFailed
|
// return nil, ErrFlagsParseFailed
|
||||||
// }
|
// }
|
||||||
// flags = append(flags, flag)
|
// flags = append(flags, flag)
|
||||||
// }
|
// }
|
||||||
// return &flags, nil
|
// return &flags, nil
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// IsSet returns whether the ProfileFlags object is "set".
|
// Check checks if a flag is set at all and if it's active in the given security level.
|
||||||
func (pf ProfileFlags) IsSet() bool {
|
func (flags Flags) Check(flag, level uint8) (active bool, ok bool) {
|
||||||
if pf != nil {
|
if flags == nil {
|
||||||
return true
|
return false, false
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Has checks if a ProfileFlags object has a flag set in the given security level
|
setting, ok := flags[flag]
|
||||||
func (pf ProfileFlags) Has(flag, level uint8) bool {
|
if ok {
|
||||||
setting, ok := pf[flag]
|
if setting&level > 0 {
|
||||||
if ok && setting&level > 0 {
|
return true, true
|
||||||
return true
|
}
|
||||||
|
return false, true
|
||||||
}
|
}
|
||||||
return false
|
return false, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func getLevelMarker(levels, level uint8) string {
|
func getLevelMarker(levels, level uint8) string {
|
||||||
|
@ -114,11 +113,11 @@ func getLevelMarker(levels, level uint8) string {
|
||||||
return "-"
|
return "-"
|
||||||
}
|
}
|
||||||
|
|
||||||
// String return a string representation of ProfileFlags
|
// String return a string representation of Flags
|
||||||
func (pf ProfileFlags) String() string {
|
func (flags Flags) String() string {
|
||||||
var namedFlags []string
|
var markedFlags []string
|
||||||
for _, flag := range sortedFlags {
|
for _, flag := range sortedFlags {
|
||||||
levels, ok := pf[flag]
|
levels, ok := flags[flag]
|
||||||
if ok {
|
if ok {
|
||||||
s := flagNames[flag]
|
s := flagNames[flag]
|
||||||
if levels != status.SecurityLevelsAll {
|
if levels != status.SecurityLevelsAll {
|
||||||
|
@ -126,20 +125,18 @@ func (pf ProfileFlags) String() string {
|
||||||
s += getLevelMarker(levels, status.SecurityLevelSecure)
|
s += getLevelMarker(levels, status.SecurityLevelSecure)
|
||||||
s += getLevelMarker(levels, status.SecurityLevelFortress)
|
s += getLevelMarker(levels, status.SecurityLevelFortress)
|
||||||
}
|
}
|
||||||
|
markedFlags = append(markedFlags, s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, flag := range pf {
|
return strings.Join(markedFlags, ", ")
|
||||||
namedFlags = append(namedFlags, flagNames[flag])
|
|
||||||
}
|
|
||||||
return strings.Join(namedFlags, ", ")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add adds a flag to the Flags with the given level.
|
// Add adds a flag to the Flags with the given level.
|
||||||
func (pf ProfileFlags) Add(flag, levels uint8) {
|
func (flags Flags) Add(flag, levels uint8) {
|
||||||
pf[flag] = levels
|
flags[flag] = levels
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove removes a flag from the Flags.
|
// Remove removes a flag from the Flags.
|
||||||
func (pf ProfileFlags) Remove(flag uint8) {
|
func (flags Flags) Remove(flag uint8) {
|
||||||
delete(pf, flag)
|
delete(flags, flag)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@ package profile
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/Safing/portmaster/status"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestProfileFlags(t *testing.T) {
|
func TestProfileFlags(t *testing.T) {
|
||||||
|
@ -20,6 +22,19 @@ func TestProfileFlags(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testFlags := Flags{
|
||||||
|
Prompt: status.SecurityLevelsAll,
|
||||||
|
Internet: status.SecurityLevelsDynamicAndSecure,
|
||||||
|
LAN: status.SecurityLevelsDynamicAndSecure,
|
||||||
|
Localhost: status.SecurityLevelsAll,
|
||||||
|
Related: status.SecurityLevelDynamic,
|
||||||
|
RequireGate17: status.SecurityLevelsSecureAndFortress,
|
||||||
|
}
|
||||||
|
|
||||||
|
if testFlags.String() != "Prompt, Internet++-, LAN++-, Localhost, Related+--, RequireGate17-++" {
|
||||||
|
t.Errorf("unexpected output: %s", testFlags.String())
|
||||||
|
}
|
||||||
|
|
||||||
// // check Has
|
// // check Has
|
||||||
// emptyFlags := ProfileFlags{}
|
// emptyFlags := ProfileFlags{}
|
||||||
// for flag, name := range flagNames {
|
// for flag, name := range flagNames {
|
||||||
|
|
|
@ -9,19 +9,12 @@ import (
|
||||||
// Ports is a list of permitted or denied ports
|
// Ports is a list of permitted or denied ports
|
||||||
type Ports map[string][]*Port
|
type Ports map[string][]*Port
|
||||||
|
|
||||||
// IsSet returns whether the Ports object is "set".
|
// Check returns whether listening/connecting to a certain port is allowed, if set.
|
||||||
func (p Ports) IsSet() bool {
|
func (p Ports) Check(listen bool, protocol string, port uint16) (permit, ok bool) {
|
||||||
if p != nil {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// CheckStatus returns whether listening/connecting to a certain port is allowed, and if this option is even set.
|
|
||||||
func (p Ports) CheckStatus(listen bool, protocol string, port uint16) (permit, ok bool) {
|
|
||||||
if p == nil {
|
if p == nil {
|
||||||
return false, false
|
return false, false
|
||||||
}
|
}
|
||||||
|
|
||||||
if listen {
|
if listen {
|
||||||
protocol = "<" + protocol
|
protocol = "<" + protocol
|
||||||
}
|
}
|
||||||
|
@ -33,7 +26,7 @@ func (p Ports) CheckStatus(listen bool, protocol string, port uint16) (permit, o
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false, true
|
return false, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Ports) String() string {
|
func (p Ports) String() string {
|
||||||
|
|
|
@ -29,7 +29,7 @@ type Profile struct {
|
||||||
|
|
||||||
// The mininum security level to apply to connections made with this profile
|
// The mininum security level to apply to connections made with this profile
|
||||||
SecurityLevel uint8
|
SecurityLevel uint8
|
||||||
Flags ProfileFlags
|
Flags Flags
|
||||||
Domains Domains
|
Domains Domains
|
||||||
Ports Ports
|
Ports Ports
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@ type Profile struct {
|
||||||
ApproxLastUsed int64
|
ApproxLastUsed int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// New returns a new Profile.
|
||||||
func New() *Profile {
|
func New() *Profile {
|
||||||
return &Profile{}
|
return &Profile{}
|
||||||
}
|
}
|
||||||
|
@ -49,12 +50,10 @@ func New() *Profile {
|
||||||
// Save saves the profile to the database
|
// Save saves the profile to the database
|
||||||
func (profile *Profile) Save(namespace string) error {
|
func (profile *Profile) Save(namespace string) error {
|
||||||
if profile.ID == "" {
|
if profile.ID == "" {
|
||||||
// FIXME: this is weird, the docs says that it also returns an error
|
u, err := uuid.NewV4()
|
||||||
u := uuid.NewV4()
|
if err != nil {
|
||||||
// u, err := uuid.NewV4()
|
return err
|
||||||
// if err != nil {
|
}
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
profile.ID = u.String()
|
profile.ID = u.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,119 +1,132 @@
|
||||||
package profile
|
package profile
|
||||||
|
|
||||||
|
import "github.com/Safing/portmaster/status"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
emptyFlags = ProfileFlags{}
|
emptyFlags = Flags{}
|
||||||
emptyPorts = Ports{}
|
emptyPorts = Ports{}
|
||||||
)
|
)
|
||||||
|
|
||||||
// ProfileSet handles Profile chaining.
|
// Set handles Profile chaining.
|
||||||
type ProfileSet struct {
|
type Set struct {
|
||||||
Profiles [4]*Profile
|
profiles [4]*Profile
|
||||||
// Application
|
// Application
|
||||||
// Global
|
// Global
|
||||||
// Stamp
|
// Stamp
|
||||||
// Default
|
// Default
|
||||||
|
|
||||||
Independent bool
|
securityLevel uint8
|
||||||
|
independent bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSet returns a new profile set with given the profiles.
|
// NewSet returns a new profile set with given the profiles.
|
||||||
func NewSet(user, stamp *Profile) *ProfileSet {
|
func NewSet(user, stamp *Profile) *Set {
|
||||||
new := &ProfileSet{
|
new := &Set{
|
||||||
Profiles: [4]*Profile{
|
profiles: [4]*Profile{
|
||||||
user, // Application
|
user, // Application
|
||||||
nil, // Global
|
nil, // Global
|
||||||
stamp, // Stamp
|
stamp, // Stamp
|
||||||
nil, // Default
|
nil, // Default
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
new.Update()
|
new.Update(status.SecurityLevelFortress)
|
||||||
return new
|
return new
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update gets the new global and default profile and updates the independence status. It must be called when reusing a profile set for a series of calls.
|
// Update gets the new global and default profile and updates the independence status. It must be called when reusing a profile set for a series of calls.
|
||||||
func (ps *ProfileSet) Update() {
|
func (set *Set) Update(securityLevel uint8) {
|
||||||
specialProfileLock.RLock()
|
specialProfileLock.RLock()
|
||||||
defer specialProfileLock.RUnlock()
|
defer specialProfileLock.RUnlock()
|
||||||
|
|
||||||
// update profiles
|
// update profiles
|
||||||
ps.Profiles[1] = globalProfile
|
set.profiles[1] = globalProfile
|
||||||
ps.Profiles[3] = defaultProfile
|
set.profiles[3] = defaultProfile
|
||||||
|
|
||||||
// update independence
|
// update security level
|
||||||
if ps.Flags().Has(Independent, ps.SecurityLevel()) {
|
profileSecurityLevel := set.getProfileSecurityLevel()
|
||||||
// Stamp profiles do not have the Independent flag
|
if profileSecurityLevel > securityLevel {
|
||||||
ps.Independent = true
|
set.securityLevel = profileSecurityLevel
|
||||||
} else {
|
} else {
|
||||||
ps.Independent = false
|
set.securityLevel = securityLevel
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flags returns the highest prioritized ProfileFlags configuration.
|
|
||||||
func (ps *ProfileSet) Flags() ProfileFlags {
|
|
||||||
|
|
||||||
for _, profile := range ps.Profiles {
|
|
||||||
if profile != nil {
|
|
||||||
if profile.Flags.IsSet() {
|
|
||||||
return profile.Flags
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return emptyFlags
|
// update independence
|
||||||
|
if active, ok := set.CheckFlag(Independent); active && ok {
|
||||||
|
set.independent = true
|
||||||
|
} else {
|
||||||
|
set.independent = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckDomainStatus checks if the given domain is governed in any the lists of domains and returns whether it is permitted.
|
// CheckFlag returns whether a given flag is set.
|
||||||
func (ps *ProfileSet) CheckDomainStatus(domain string) (permit, ok bool) {
|
func (set *Set) CheckFlag(flag) (active bool) {
|
||||||
|
|
||||||
for i, profile := range ps.Profiles {
|
for i, profile := range set.profiles {
|
||||||
if i == 2 && ps.Independent {
|
if i == 2 && set.independent {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if profile != nil {
|
if profile != nil {
|
||||||
if profile.Domains.IsSet() {
|
active, ok := profile.Flags.Check(flag, set.securityLevel)
|
||||||
permit, ok = profile.Domains.CheckStatus(domain)
|
if ok {
|
||||||
if ok {
|
return active
|
||||||
return
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckDomain checks if the given domain is governed in any the lists of domains and returns whether it is permitted.
|
||||||
|
func (set *Set) CheckDomain(domain string) (permit, ok bool) {
|
||||||
|
|
||||||
|
for i, profile := range set.profiles {
|
||||||
|
if i == 2 && set.independent {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if profile != nil {
|
||||||
|
permit, ok = profile.Domains.Check(domain)
|
||||||
|
if ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ports returns the highest prioritized Ports configuration.
|
||||||
|
func (set *Set) CheckPort() (permit, ok bool) {
|
||||||
|
|
||||||
|
for i, profile := range set.profiles {
|
||||||
|
if i == 2 && set.independent {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if profile != nil {
|
||||||
|
if profile.Ports.Check() {
|
||||||
|
return profile.Ports
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false, false
|
return false, false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ports returns the highest prioritized Ports configuration.
|
|
||||||
func (ps *ProfileSet) Ports() Ports {
|
|
||||||
|
|
||||||
for i, profile := range ps.Profiles {
|
|
||||||
if i == 2 && ps.Independent {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if profile != nil {
|
|
||||||
if profile.Ports.IsSet() {
|
|
||||||
return profile.Ports
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return emptyPorts
|
|
||||||
}
|
|
||||||
|
|
||||||
// SecurityLevel returns the highest prioritized security level.
|
// SecurityLevel returns the highest prioritized security level.
|
||||||
func (ps *ProfileSet) SecurityLevel() uint8 {
|
func (set *Set) getProfileSecurityLevel() uint8 {
|
||||||
|
|
||||||
for i, profile := range ps.Profiles {
|
for i, profile := range set.profiles {
|
||||||
if i == 2 {
|
if i == 2 {
|
||||||
// Stamp profiles do not have the SecurityLevel setting
|
// Stamp profiles do not have the SecurityLevel setting
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if profile != nil {
|
if profile != nil {
|
||||||
if profile.SecurityLevel > 0 {
|
if profile.SecurityLevel > 0 {
|
||||||
return profile.SecurityLevel
|
return profile.SecurityLevel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue