diff --git a/go.mod b/go.mod index f0499d830..21c4d6f80 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/mitchellh/go-server-timing v1.0.1 github.com/oschwald/maxminddb-golang v1.12.0 github.com/safing/jess v0.3.2 - github.com/safing/portbase v0.18.5 + github.com/safing/portbase v0.18.6 github.com/safing/portmaster-android/go v0.0.0-20230830120134-3226ceac3bec github.com/safing/spn v0.7.4 github.com/shirou/gopsutil v3.21.11+incompatible @@ -33,16 +33,16 @@ require ( github.com/tevino/abool v1.2.0 github.com/umahmood/haversine v0.0.0-20151105152445-808ab04add26 github.com/vincent-petithory/dataurl v1.0.0 - golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa - golang.org/x/net v0.18.0 + golang.org/x/exp v0.0.0-20231127185646-65229373498e + golang.org/x/net v0.19.0 golang.org/x/sync v0.5.0 - golang.org/x/sys v0.14.1-0.20231108175955-e4099bfacb8c + golang.org/x/sys v0.15.0 gopkg.in/yaml.v3 v3.0.1 zombiezen.com/go/sqlite v0.13.1 ) require ( - github.com/VictoriaMetrics/metrics v1.24.0 // indirect + github.com/VictoriaMetrics/metrics v1.25.3 // indirect github.com/aead/ecdh v0.2.0 // indirect github.com/aead/serpent v0.0.0-20160714141033-fba169763ea6 // indirect github.com/alessio/shellescape v1.4.2 // indirect @@ -94,14 +94,14 @@ require ( github.com/yusufpapurcu/wmi v1.2.3 // indirect github.com/zalando/go-keyring v0.2.3 // indirect go.etcd.io/bbolt v1.3.8 // indirect - golang.org/x/crypto v0.15.0 // indirect + golang.org/x/crypto v0.16.0 // indirect golang.org/x/mod v0.14.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/time v0.4.0 // indirect - golang.org/x/tools v0.15.0 // indirect + golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.16.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - gvisor.dev/gvisor v0.0.0-20231122063954-e54bfde79278 // indirect - modernc.org/libc v1.34.9 // indirect + gvisor.dev/gvisor v0.0.0-20231130223849-479d60c2258b // indirect + modernc.org/libc v1.34.11 // indirect modernc.org/mathutil v1.6.0 // indirect modernc.org/memory v1.7.2 // indirect modernc.org/sqlite v1.27.0 // indirect diff --git a/go.sum b/go.sum index f454a755e..c121a3528 100644 --- a/go.sum +++ b/go.sum @@ -3,8 +3,8 @@ github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIo github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/VictoriaMetrics/metrics v1.24.0 h1:ILavebReOjYctAGY5QU2F9X0MYvkcrG3aEn2RKa1Zkw= -github.com/VictoriaMetrics/metrics v1.24.0/go.mod h1:eFT25kvsTidQFHb6U0oa0rTrDRdz4xTYjpL8+UPohys= +github.com/VictoriaMetrics/metrics v1.25.3 h1:Zcxyj8JbAB6CQU51Er3D7RBRupcP55DevVQi9cFqo2Q= +github.com/VictoriaMetrics/metrics v1.25.3/go.mod h1:ZKmlI+QN6b9LUC0OiHNp2LiGQGlBy4U1re6Slooln1o= github.com/Xuanwo/go-locale v1.1.0 h1:51gUxhxl66oXAjI9uPGb2O0qwPECpriKQb2hl35mQkg= github.com/Xuanwo/go-locale v1.1.0/go.mod h1:UKrHoZB3FPIk9wIG2/tVSobnHgNnceGSH3Y8DY5cASs= github.com/aead/ecdh v0.2.0 h1:pYop54xVaq/CEREFEcukHRZfTdjiWvYIsZDXXrBapQQ= @@ -199,8 +199,8 @@ github.com/rot256/pblind v0.0.0-20231024115251-cd3f239f28c1/go.mod h1:2x8fbm9T+u github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/safing/jess v0.3.2 h1:d21+sautJlfTKcwgm6/TohUf0F8DL27Lug2XHBOBqvY= github.com/safing/jess v0.3.2/go.mod h1:N1Qiw9YBDHSVilocPEWHoGIEi+DvtmGds76rUhAyctU= -github.com/safing/portbase v0.18.5 h1:BgIBpreSNOnyHqx6Ovx3xJMkX2yOa3A2uLpfVBbfJPM= -github.com/safing/portbase v0.18.5/go.mod h1:qhhLjrr5iEGU9r7RZ6hJdtulOeycJ0d0jq95ZxGJ9Hs= +github.com/safing/portbase v0.18.6 h1:uMZOG4C0K61QJE7I4fI+55r1I/eV42TJdI1xA02U1yo= +github.com/safing/portbase v0.18.6/go.mod h1:qhhLjrr5iEGU9r7RZ6hJdtulOeycJ0d0jq95ZxGJ9Hs= github.com/safing/portmaster-android/go v0.0.0-20230830120134-3226ceac3bec h1:oSJY1seobofPwpMoJRkCgXnTwfiQWNfGMCPDfqgAEfg= github.com/safing/portmaster-android/go v0.0.0-20230830120134-3226ceac3bec/go.mod h1:abwyAQrZGemWbSh/aCD9nnkp0SvFFf/mGWkAbOwPnFE= github.com/safing/spn v0.7.4 h1:wAE17yWOgL/lEwluRXRj1gM08bhyg1f7GQHKuP3aNSw= @@ -280,10 +280,10 @@ golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA= -golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= -golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= -golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= +golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= +golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No= +golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -312,8 +312,8 @@ golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220107192237-5cfca573fb4d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg= -golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20170912212905-13449ad91cb2/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20170517211232-f52d1811a629/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -355,8 +355,8 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.14.1-0.20231108175955-e4099bfacb8c h1:3kC/TjQ+xzIblQv39bCOyRk8fbEeJcDHwbyxPUU2BpA= -golang.org/x/sys v0.14.1-0.20231108175955-e4099bfacb8c/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -367,16 +367,16 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.4.0 h1:Z81tqI5ddIoXDPvVQ7/7CC9TnLM7ubaFG2qXYd5BbYY= -golang.org/x/time v0.4.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= -golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8= -golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= +golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= +golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -396,12 +396,12 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gvisor.dev/gvisor v0.0.0-20231122063954-e54bfde79278 h1:iGsqvBE4llcqJv6k9WrA8SoooCNSNhYSSrwxLPVDPlc= -gvisor.dev/gvisor v0.0.0-20231122063954-e54bfde79278/go.mod h1:10sU+Uh5KKNv1+2x2A0Gvzt8FjD3ASIhorV3YsauXhk= +gvisor.dev/gvisor v0.0.0-20231130223849-479d60c2258b h1:fXhcWD4N2isj89cdDWZ6WttbixEyEaKisztUbShdhkw= +gvisor.dev/gvisor v0.0.0-20231130223849-479d60c2258b/go.mod h1:10sU+Uh5KKNv1+2x2A0Gvzt8FjD3ASIhorV3YsauXhk= honnef.co/go/tools v0.2.1/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY= honnef.co/go/tools v0.2.2/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY= -modernc.org/libc v1.34.9 h1:yhQGs5jsWHJIU7jY6nCe8GJw27j+z6xYi0eorwPpGgI= -modernc.org/libc v1.34.9/go.mod h1:YAXkAZ8ktnkCKaN9sw/UDeUVkGYJ/YquGO4FTi5nmHE= +modernc.org/libc v1.34.11 h1:hQDcIUlSG4QAOkXCIQKkaAOV5ptXvkOx4ddbXzgW2JU= +modernc.org/libc v1.34.11/go.mod h1:YAXkAZ8ktnkCKaN9sw/UDeUVkGYJ/YquGO4FTi5nmHE= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= diff --git a/intel/entity.go b/intel/entity.go index b890b1aec..d89be9f64 100644 --- a/intel/entity.go +++ b/intel/entity.go @@ -14,7 +14,6 @@ import ( "github.com/safing/portmaster/intel/filterlists" "github.com/safing/portmaster/intel/geoip" "github.com/safing/portmaster/network/netutils" - "github.com/safing/portmaster/status" ) // Entity describes a remote endpoint in many different ways. @@ -205,7 +204,7 @@ func (e *Entity) reverseResolve(ctx context.Context) { return } // TODO: security level - domain, err := reverseResolver(ctx, e.IP.String(), status.SecurityLevelNormal) + domain, err := reverseResolver(ctx, e.IP.String()) if err != nil { log.Tracer(ctx).Warningf("intel: failed to resolve IP %s: %s", e.IP, err) return diff --git a/intel/resolver.go b/intel/resolver.go index 359db36a2..264153ce8 100644 --- a/intel/resolver.go +++ b/intel/resolver.go @@ -4,10 +4,10 @@ import ( "context" ) -var reverseResolver func(ctx context.Context, ip string, securityLevel uint8) (domain string, err error) +var reverseResolver func(ctx context.Context, ip string) (domain string, err error) // SetReverseResolver allows the resolver module to register a function to allow reverse resolving IPs to domains. -func SetReverseResolver(fn func(ctx context.Context, ip string, securityLevel uint8) (domain string, err error)) { +func SetReverseResolver(fn func(ctx context.Context, ip string) (domain string, err error)) { if reverseResolver == nil { reverseResolver = fn } diff --git a/nameserver/nameserver.go b/nameserver/nameserver.go index 493c88ad3..5243f8c4b 100644 --- a/nameserver/nameserver.go +++ b/nameserver/nameserver.go @@ -256,9 +256,6 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg) return reply(conn, conn) } - // Save security level to query, so that the resolver can react to configuration. - q.SecurityLevel = conn.Process().Profile().SecurityLevel() - // Resolve request. rrCache, err = resolver.Resolve(ctx, q) // Handle error. diff --git a/profile/config.go b/profile/config.go index fdfcd3300..632e3869c 100644 --- a/profile/config.go +++ b/profile/config.go @@ -34,25 +34,25 @@ var ( // Network Scopes. CfgOptionBlockScopeInternetKey = "filter/blockInternet" - cfgOptionBlockScopeInternet config.IntOption // security level option + cfgOptionBlockScopeInternet config.BoolOption cfgOptionBlockScopeInternetOrder = 16 CfgOptionBlockScopeLANKey = "filter/blockLAN" - cfgOptionBlockScopeLAN config.IntOption // security level option + cfgOptionBlockScopeLAN config.BoolOption cfgOptionBlockScopeLANOrder = 17 CfgOptionBlockScopeLocalKey = "filter/blockLocal" - cfgOptionBlockScopeLocal config.IntOption // security level option + cfgOptionBlockScopeLocal config.BoolOption cfgOptionBlockScopeLocalOrder = 18 // Connection Types. CfgOptionBlockP2PKey = "filter/blockP2P" - cfgOptionBlockP2P config.IntOption // security level option + cfgOptionBlockP2P config.BoolOption cfgOptionBlockP2POrder = 19 CfgOptionBlockInboundKey = "filter/blockInbound" - cfgOptionBlockInbound config.IntOption // security level option + cfgOptionBlockInbound config.BoolOption cfgOptionBlockInboundOrder = 20 // Rules. @@ -72,35 +72,35 @@ var ( // Setting "Custom Filter List" at order 35. CfgOptionFilterSubDomainsKey = "filter/includeSubdomains" - cfgOptionFilterSubDomains config.IntOption // security level option + cfgOptionFilterSubDomains config.BoolOption cfgOptionFilterSubDomainsOrder = 36 // DNS Filtering. CfgOptionFilterCNAMEKey = "filter/includeCNAMEs" - cfgOptionFilterCNAME config.IntOption // security level option + cfgOptionFilterCNAME config.BoolOption cfgOptionFilterCNAMEOrder = 48 CfgOptionRemoveOutOfScopeDNSKey = "filter/removeOutOfScopeDNS" - cfgOptionRemoveOutOfScopeDNS config.IntOption // security level option + cfgOptionRemoveOutOfScopeDNS config.BoolOption cfgOptionRemoveOutOfScopeDNSOrder = 49 CfgOptionRemoveBlockedDNSKey = "filter/removeBlockedDNS" - cfgOptionRemoveBlockedDNS config.IntOption // security level option + cfgOptionRemoveBlockedDNS config.BoolOption cfgOptionRemoveBlockedDNSOrder = 50 CfgOptionDomainHeuristicsKey = "filter/domainHeuristics" - cfgOptionDomainHeuristics config.IntOption // security level option + cfgOptionDomainHeuristics config.BoolOption cfgOptionDomainHeuristicsOrder = 51 // Advanced. CfgOptionPreventBypassingKey = "filter/preventBypassing" - cfgOptionPreventBypassing config.IntOption // security level option + cfgOptionPreventBypassing config.BoolOption cfgOptionPreventBypassingOrder = 64 CfgOptionDisableAutoPermitKey = "filter/disableAutoPermit" - cfgOptionDisableAutoPermit config.IntOption // security level option + cfgOptionDisableAutoPermit config.BoolOption cfgOptionDisableAutoPermitOrder = 65 // Setting "Permanent Verdicts" at order 80. @@ -143,22 +143,6 @@ var ( // Setting "DNS Exit Node Rules" at order 148. ) -// A list of all security level settings. -var securityLevelSettings = []string{ - CfgOptionBlockScopeInternetKey, - CfgOptionBlockScopeLANKey, - CfgOptionBlockScopeLocalKey, - CfgOptionBlockP2PKey, - CfgOptionBlockInboundKey, - CfgOptionFilterSubDomainsKey, - CfgOptionFilterCNAMEKey, - CfgOptionRemoveOutOfScopeDNSKey, - CfgOptionRemoveBlockedDNSKey, - CfgOptionDomainHeuristicsKey, - CfgOptionPreventBypassingKey, - CfgOptionDisableAutoPermitKey, -} - var ( // SPNRulesQuickSettings are now generated automatically shorty after start. SPNRulesQuickSettings = []config.QuickSetting{ @@ -229,22 +213,22 @@ func registerConfiguration() error { //nolint:maintidx Name: "Disable Auto Allow", Key: CfgOptionDisableAutoPermitKey, Description: `Auto Allow searches for a relation between an app and the destination of a connection - if there is a correlation, the connection will be allowed.`, - OptType: config.OptTypeInt, + OptType: config.OptTypeBool, ReleaseLevel: config.ReleaseLevelBeta, - DefaultValue: status.SecurityLevelsAll, + DefaultValue: true, Annotations: config.Annotations{ config.SettablePerAppAnnotation: true, config.DisplayOrderAnnotation: cfgOptionDisableAutoPermitOrder, config.DisplayHintAnnotation: status.DisplayHintSecurityLevel, config.CategoryAnnotation: "Advanced", }, - PossibleValues: status.AllSecurityLevelValues, + Migrations: []config.MigrationFunc{status.MigrateSecurityLevelToBoolean}, }) if err != nil { return err } - cfgOptionDisableAutoPermit = config.Concurrent.GetAsInt(CfgOptionDisableAutoPermitKey, int64(status.SecurityLevelsAll)) - cfgIntOptions[CfgOptionDisableAutoPermitKey] = cfgOptionDisableAutoPermit + cfgOptionDisableAutoPermit = config.Concurrent.GetAsBool(CfgOptionDisableAutoPermitKey, true) + cfgBoolOptions[CfgOptionDisableAutoPermitKey] = cfgOptionDisableAutoPermit // Enable History err = config.Register(&config.Option{ @@ -450,8 +434,8 @@ Pro Tip: You can use "#" to add a comment to a rule. Name: "Block Domain Aliases", Key: CfgOptionFilterCNAMEKey, Description: "Block a domain if a resolved CNAME (alias) is blocked by a rule or filter list.", - OptType: config.OptTypeInt, - DefaultValue: status.SecurityLevelsAll, + OptType: config.OptTypeBool, + DefaultValue: true, ExpertiseLevel: config.ExpertiseLevelExpert, Annotations: config.Annotations{ config.SettablePerAppAnnotation: true, @@ -459,206 +443,206 @@ Pro Tip: You can use "#" to add a comment to a rule. config.DisplayOrderAnnotation: cfgOptionFilterCNAMEOrder, config.CategoryAnnotation: "DNS Filtering", }, - PossibleValues: status.AllSecurityLevelValues, + Migrations: []config.MigrationFunc{status.MigrateSecurityLevelToBoolean}, }) if err != nil { return err } - cfgOptionFilterCNAME = config.Concurrent.GetAsInt(CfgOptionFilterCNAMEKey, int64(status.SecurityLevelsAll)) - cfgIntOptions[CfgOptionFilterCNAMEKey] = cfgOptionFilterCNAME + cfgOptionFilterCNAME = config.Concurrent.GetAsBool(CfgOptionFilterCNAMEKey, true) + cfgBoolOptions[CfgOptionFilterCNAMEKey] = cfgOptionFilterCNAME // Include subdomains err = config.Register(&config.Option{ - Name: "Block Subdomains of Filter List Entries", - Key: CfgOptionFilterSubDomainsKey, - Description: "Additionally block all subdomains of entries in selected filter lists.", - OptType: config.OptTypeInt, - DefaultValue: status.SecurityLevelsAll, - PossibleValues: status.AllSecurityLevelValues, + Name: "Block Subdomains of Filter List Entries", + Key: CfgOptionFilterSubDomainsKey, + Description: "Additionally block all subdomains of entries in selected filter lists.", + OptType: config.OptTypeBool, + DefaultValue: true, Annotations: config.Annotations{ config.SettablePerAppAnnotation: true, config.DisplayHintAnnotation: status.DisplayHintSecurityLevel, config.DisplayOrderAnnotation: cfgOptionFilterSubDomainsOrder, config.CategoryAnnotation: "Filter Lists", }, + Migrations: []config.MigrationFunc{status.MigrateSecurityLevelToBoolean}, }) if err != nil { return err } - cfgOptionFilterSubDomains = config.Concurrent.GetAsInt(CfgOptionFilterSubDomainsKey, int64(status.SecurityLevelsAll)) - cfgIntOptions[CfgOptionFilterSubDomainsKey] = cfgOptionFilterSubDomains + cfgOptionFilterSubDomains = config.Concurrent.GetAsBool(CfgOptionFilterSubDomainsKey, true) + cfgBoolOptions[CfgOptionFilterSubDomainsKey] = cfgOptionFilterSubDomains // Block Scope Local err = config.Register(&config.Option{ Name: "Force Block Device-Local Connections", Key: CfgOptionBlockScopeLocalKey, Description: "Force Block all internal connections on your own device, ie. localhost. Is stronger than Rules (see below).", - OptType: config.OptTypeInt, + OptType: config.OptTypeBool, ExpertiseLevel: config.ExpertiseLevelExpert, - DefaultValue: status.SecurityLevelOff, - PossibleValues: status.AllSecurityLevelValues, + DefaultValue: false, Annotations: config.Annotations{ config.SettablePerAppAnnotation: true, config.DisplayHintAnnotation: status.DisplayHintSecurityLevel, config.DisplayOrderAnnotation: cfgOptionBlockScopeLocalOrder, config.CategoryAnnotation: "Network Scope", }, + Migrations: []config.MigrationFunc{status.MigrateSecurityLevelToBoolean}, }) if err != nil { return err } - cfgOptionBlockScopeLocal = config.Concurrent.GetAsInt(CfgOptionBlockScopeLocalKey, int64(status.SecurityLevelOff)) - cfgIntOptions[CfgOptionBlockScopeLocalKey] = cfgOptionBlockScopeLocal + cfgOptionBlockScopeLocal = config.Concurrent.GetAsBool(CfgOptionBlockScopeLocalKey, false) + cfgBoolOptions[CfgOptionBlockScopeLocalKey] = cfgOptionBlockScopeLocal // Block Scope LAN err = config.Register(&config.Option{ - Name: "Force Block LAN", - Key: CfgOptionBlockScopeLANKey, - Description: "Force Block all connections from and to the Local Area Network. Is stronger than Rules (see below).", - OptType: config.OptTypeInt, - DefaultValue: status.SecurityLevelOff, - PossibleValues: status.AllSecurityLevelValues, + Name: "Force Block LAN", + Key: CfgOptionBlockScopeLANKey, + Description: "Force Block all connections from and to the Local Area Network. Is stronger than Rules (see below).", + OptType: config.OptTypeBool, + DefaultValue: false, Annotations: config.Annotations{ config.SettablePerAppAnnotation: true, config.DisplayHintAnnotation: status.DisplayHintSecurityLevel, config.DisplayOrderAnnotation: cfgOptionBlockScopeLANOrder, config.CategoryAnnotation: "Network Scope", }, + Migrations: []config.MigrationFunc{status.MigrateSecurityLevelToBoolean}, }) if err != nil { return err } - cfgOptionBlockScopeLAN = config.Concurrent.GetAsInt(CfgOptionBlockScopeLANKey, int64(status.SecurityLevelOff)) - cfgIntOptions[CfgOptionBlockScopeLANKey] = cfgOptionBlockScopeLAN + cfgOptionBlockScopeLAN = config.Concurrent.GetAsBool(CfgOptionBlockScopeLANKey, false) + cfgBoolOptions[CfgOptionBlockScopeLANKey] = cfgOptionBlockScopeLAN // Block Scope Internet err = config.Register(&config.Option{ - Name: "Force Block Internet Access", - Key: CfgOptionBlockScopeInternetKey, - Description: "Force Block connections from and to the Internet. Is stronger than Rules (see below).", - OptType: config.OptTypeInt, - DefaultValue: status.SecurityLevelOff, - PossibleValues: status.AllSecurityLevelValues, + Name: "Force Block Internet Access", + Key: CfgOptionBlockScopeInternetKey, + Description: "Force Block connections from and to the Internet. Is stronger than Rules (see below).", + OptType: config.OptTypeBool, + DefaultValue: false, Annotations: config.Annotations{ config.SettablePerAppAnnotation: true, config.DisplayHintAnnotation: status.DisplayHintSecurityLevel, config.DisplayOrderAnnotation: cfgOptionBlockScopeInternetOrder, config.CategoryAnnotation: "Network Scope", }, + Migrations: []config.MigrationFunc{status.MigrateSecurityLevelToBoolean}, }) if err != nil { return err } - cfgOptionBlockScopeInternet = config.Concurrent.GetAsInt(CfgOptionBlockScopeInternetKey, int64(status.SecurityLevelOff)) - cfgIntOptions[CfgOptionBlockScopeInternetKey] = cfgOptionBlockScopeInternet + cfgOptionBlockScopeInternet = config.Concurrent.GetAsBool(CfgOptionBlockScopeInternetKey, false) + cfgBoolOptions[CfgOptionBlockScopeInternetKey] = cfgOptionBlockScopeInternet // Block Peer to Peer Connections err = config.Register(&config.Option{ - Name: "Force Block P2P/Direct Connections", - Key: CfgOptionBlockP2PKey, - Description: "These are connections that are established directly to an IP address or peer on the Internet without resolving a domain name via DNS first. Is stronger than Rules (see below).", - OptType: config.OptTypeInt, - DefaultValue: status.SecurityLevelOff, - PossibleValues: status.AllSecurityLevelValues, + Name: "Force Block P2P/Direct Connections", + Key: CfgOptionBlockP2PKey, + Description: "These are connections that are established directly to an IP address or peer on the Internet without resolving a domain name via DNS first. Is stronger than Rules (see below).", + OptType: config.OptTypeBool, + DefaultValue: false, Annotations: config.Annotations{ config.SettablePerAppAnnotation: true, config.DisplayHintAnnotation: status.DisplayHintSecurityLevel, config.DisplayOrderAnnotation: cfgOptionBlockP2POrder, config.CategoryAnnotation: "Connection Types", }, + Migrations: []config.MigrationFunc{status.MigrateSecurityLevelToBoolean}, }) if err != nil { return err } - cfgOptionBlockP2P = config.Concurrent.GetAsInt(CfgOptionBlockP2PKey, int64(status.SecurityLevelOff)) - cfgIntOptions[CfgOptionBlockP2PKey] = cfgOptionBlockP2P + cfgOptionBlockP2P = config.Concurrent.GetAsBool(CfgOptionBlockP2PKey, false) + cfgBoolOptions[CfgOptionBlockP2PKey] = cfgOptionBlockP2P // Block Inbound Connections err = config.Register(&config.Option{ - Name: "Force Block Incoming Connections", - Key: CfgOptionBlockInboundKey, - Description: "Connections initiated towards your device from the LAN or Internet. This will usually only be the case if you are running a network service or are using peer to peer software. Is stronger than Rules (see below).", - OptType: config.OptTypeInt, - DefaultValue: status.SecurityLevelsAll, - PossibleValues: status.AllSecurityLevelValues, + Name: "Force Block Incoming Connections", + Key: CfgOptionBlockInboundKey, + Description: "Connections initiated towards your device from the LAN or Internet. This will usually only be the case if you are running a network service or are using peer to peer software. Is stronger than Rules (see below).", + OptType: config.OptTypeBool, + DefaultValue: true, Annotations: config.Annotations{ config.SettablePerAppAnnotation: true, config.DisplayHintAnnotation: status.DisplayHintSecurityLevel, config.DisplayOrderAnnotation: cfgOptionBlockInboundOrder, config.CategoryAnnotation: "Connection Types", }, + Migrations: []config.MigrationFunc{status.MigrateSecurityLevelToBoolean}, }) if err != nil { return err } - cfgOptionBlockInbound = config.Concurrent.GetAsInt(CfgOptionBlockInboundKey, int64(status.SecurityLevelOff)) - cfgIntOptions[CfgOptionBlockInboundKey] = cfgOptionBlockInbound + cfgOptionBlockInbound = config.Concurrent.GetAsBool(CfgOptionBlockInboundKey, false) + cfgBoolOptions[CfgOptionBlockInboundKey] = cfgOptionBlockInbound // Filter Out-of-Scope DNS Records err = config.Register(&config.Option{ Name: "Enforce Global/Private Split-View", Key: CfgOptionRemoveOutOfScopeDNSKey, Description: "Reject private IP addresses (RFC1918 et al.) from public DNS responses. If the system resolver is in use, the resulting connection will be blocked instead of the DNS request.", - OptType: config.OptTypeInt, + OptType: config.OptTypeBool, ExpertiseLevel: config.ExpertiseLevelDeveloper, - DefaultValue: status.SecurityLevelsAll, - PossibleValues: status.AllSecurityLevelValues, + DefaultValue: true, Annotations: config.Annotations{ config.SettablePerAppAnnotation: true, config.DisplayHintAnnotation: status.DisplayHintSecurityLevel, config.DisplayOrderAnnotation: cfgOptionRemoveOutOfScopeDNSOrder, config.CategoryAnnotation: "DNS Filtering", }, + Migrations: []config.MigrationFunc{status.MigrateSecurityLevelToBoolean}, }) if err != nil { return err } - cfgOptionRemoveOutOfScopeDNS = config.Concurrent.GetAsInt(CfgOptionRemoveOutOfScopeDNSKey, int64(status.SecurityLevelsAll)) - cfgIntOptions[CfgOptionRemoveOutOfScopeDNSKey] = cfgOptionRemoveOutOfScopeDNS + cfgOptionRemoveOutOfScopeDNS = config.Concurrent.GetAsBool(CfgOptionRemoveOutOfScopeDNSKey, true) + cfgBoolOptions[CfgOptionRemoveOutOfScopeDNSKey] = cfgOptionRemoveOutOfScopeDNS // Filter DNS Records that would be blocked err = config.Register(&config.Option{ Name: "Reject Blocked IPs", Key: CfgOptionRemoveBlockedDNSKey, Description: "Reject blocked IP addresses directly from the DNS response instead of handing them over to the app and blocking a resulting connection. This settings does not affect privacy and only takes effect when the system resolver is not in use.", - OptType: config.OptTypeInt, + OptType: config.OptTypeBool, ExpertiseLevel: config.ExpertiseLevelDeveloper, - DefaultValue: status.SecurityLevelsAll, - PossibleValues: status.AllSecurityLevelValues, + DefaultValue: true, Annotations: config.Annotations{ config.SettablePerAppAnnotation: true, config.DisplayHintAnnotation: status.DisplayHintSecurityLevel, config.DisplayOrderAnnotation: cfgOptionRemoveBlockedDNSOrder, config.CategoryAnnotation: "DNS Filtering", }, + Migrations: []config.MigrationFunc{status.MigrateSecurityLevelToBoolean}, }) if err != nil { return err } - cfgOptionRemoveBlockedDNS = config.Concurrent.GetAsInt(CfgOptionRemoveBlockedDNSKey, int64(status.SecurityLevelsAll)) - cfgIntOptions[CfgOptionRemoveBlockedDNSKey] = cfgOptionRemoveBlockedDNS + cfgOptionRemoveBlockedDNS = config.Concurrent.GetAsBool(CfgOptionRemoveBlockedDNSKey, true) + cfgBoolOptions[CfgOptionRemoveBlockedDNSKey] = cfgOptionRemoveBlockedDNS // Domain heuristics err = config.Register(&config.Option{ Name: "Enable Domain Heuristics", Key: CfgOptionDomainHeuristicsKey, Description: "Checks for suspicious domain names and blocks them. This option currently targets domain names generated by malware and DNS data exfiltration channels.", - OptType: config.OptTypeInt, + OptType: config.OptTypeBool, ExpertiseLevel: config.ExpertiseLevelExpert, - DefaultValue: status.SecurityLevelsAll, - PossibleValues: status.AllSecurityLevelValues, + DefaultValue: true, Annotations: config.Annotations{ config.SettablePerAppAnnotation: true, config.DisplayHintAnnotation: status.DisplayHintSecurityLevel, config.DisplayOrderAnnotation: cfgOptionDomainHeuristicsOrder, config.CategoryAnnotation: "DNS Filtering", }, + Migrations: []config.MigrationFunc{status.MigrateSecurityLevelToBoolean}, }) if err != nil { return err } - cfgOptionDomainHeuristics = config.Concurrent.GetAsInt(CfgOptionDomainHeuristicsKey, int64(status.SecurityLevelsAll)) - cfgIntOptions[CfgOptionDomainHeuristicsKey] = cfgOptionDomainHeuristics + cfgOptionDomainHeuristics = config.Concurrent.GetAsBool(CfgOptionDomainHeuristicsKey, true) + cfgBoolOptions[CfgOptionDomainHeuristicsKey] = cfgOptionDomainHeuristics // Bypass prevention err = config.Register(&config.Option{ @@ -673,23 +657,23 @@ Current Features: - Block direct access to public DNS resolvers Please note that DNS bypass attempts might be additionally blocked in the System DNS Client App.`, - OptType: config.OptTypeInt, + OptType: config.OptTypeBool, ExpertiseLevel: config.ExpertiseLevelUser, ReleaseLevel: config.ReleaseLevelStable, - DefaultValue: status.SecurityLevelsAll, - PossibleValues: status.AllSecurityLevelValues, + DefaultValue: true, Annotations: config.Annotations{ config.SettablePerAppAnnotation: true, config.DisplayHintAnnotation: status.DisplayHintSecurityLevel, config.DisplayOrderAnnotation: cfgOptionPreventBypassingOrder, config.CategoryAnnotation: "Advanced", }, + Migrations: []config.MigrationFunc{status.MigrateSecurityLevelToBoolean}, }) if err != nil { return err } - cfgOptionPreventBypassing = config.Concurrent.GetAsInt((CfgOptionPreventBypassingKey), int64(status.SecurityLevelsAll)) - cfgIntOptions[CfgOptionPreventBypassingKey] = cfgOptionPreventBypassing + cfgOptionPreventBypassing = config.Concurrent.GetAsBool(CfgOptionPreventBypassingKey, true) + cfgBoolOptions[CfgOptionPreventBypassingKey] = cfgOptionPreventBypassing // Use SPN err = config.Register(&config.Option{ diff --git a/profile/migrations.go b/profile/migrations.go index 7d1f29792..eca9d8df3 100644 --- a/profile/migrations.go +++ b/profile/migrations.go @@ -7,21 +7,14 @@ import ( "github.com/hashicorp/go-version" - "github.com/safing/portbase/config" "github.com/safing/portbase/database" "github.com/safing/portbase/database/migration" "github.com/safing/portbase/database/query" "github.com/safing/portbase/log" - "github.com/safing/portmaster/status" ) func registerMigrations() error { return migrations.Add( - migration.Migration{ - Description: "Migrate to configurable network rating system", - Version: "v0.7.19", - MigrateFunc: migrateNetworkRatingSystem, - }, migration.Migration{ Description: "Migrate from LinkedPath to Fingerprints and PresentationPath", Version: "v0.9.9", @@ -40,35 +33,6 @@ func registerMigrations() error { ) } -func migrateNetworkRatingSystem(ctx context.Context, _, to *version.Version, db *database.Interface) error { - // determine the default value for the network rating system by searching for - // a global security level setting that is not set to the default. - networkRatingEnabled := false - for _, cfgkey := range securityLevelSettings { - def, err := config.GetOption(cfgkey) - if err != nil { - return err - } - - intValue := config.Concurrent.GetAsInt(cfgkey, 0)() - defaultValue, ok := def.DefaultValue.(uint8) - if ok && defaultValue != uint8(intValue) { - log.Tracer(ctx).Infof("found global security level setting with changed value. 0x%2x (default) != 0x%2x (current)", def.DefaultValue, intValue) - networkRatingEnabled = true - break - } - } - - if networkRatingEnabled { - err := status.SetNetworkRating(networkRatingEnabled) - if err != nil { - log.Warningf("profile: migration to %s failed to set network rating level to %v", to, networkRatingEnabled) - } - } - - return nil -} - func migrateLinkedPath(ctx context.Context, _, to *version.Version, db *database.Interface) error { // Get iterator over all profiles. it, err := db.Query(query.New(ProfilesDBPath)) diff --git a/profile/profile-layered.go b/profile/profile-layered.go index 6ed2ad925..4b89abdaa 100644 --- a/profile/profile-layered.go +++ b/profile/profile-layered.go @@ -11,7 +11,6 @@ import ( "github.com/safing/portbase/runtime" "github.com/safing/portmaster/intel" "github.com/safing/portmaster/profile/endpoints" - "github.com/safing/portmaster/status" ) // LayeredProfile combines multiple Profiles. @@ -66,51 +65,51 @@ func NewLayeredProfile(localProfile *Profile) *LayeredProfile { securityLevel: &securityLevelVal, } - lp.DisableAutoPermit = lp.wrapSecurityLevelOption( + lp.DisableAutoPermit = lp.wrapBoolOption( CfgOptionDisableAutoPermitKey, cfgOptionDisableAutoPermit, ) - lp.BlockScopeLocal = lp.wrapSecurityLevelOption( + lp.BlockScopeLocal = lp.wrapBoolOption( CfgOptionBlockScopeLocalKey, cfgOptionBlockScopeLocal, ) - lp.BlockScopeLAN = lp.wrapSecurityLevelOption( + lp.BlockScopeLAN = lp.wrapBoolOption( CfgOptionBlockScopeLANKey, cfgOptionBlockScopeLAN, ) - lp.BlockScopeInternet = lp.wrapSecurityLevelOption( + lp.BlockScopeInternet = lp.wrapBoolOption( CfgOptionBlockScopeInternetKey, cfgOptionBlockScopeInternet, ) - lp.BlockP2P = lp.wrapSecurityLevelOption( + lp.BlockP2P = lp.wrapBoolOption( CfgOptionBlockP2PKey, cfgOptionBlockP2P, ) - lp.BlockInbound = lp.wrapSecurityLevelOption( + lp.BlockInbound = lp.wrapBoolOption( CfgOptionBlockInboundKey, cfgOptionBlockInbound, ) - lp.RemoveOutOfScopeDNS = lp.wrapSecurityLevelOption( + lp.RemoveOutOfScopeDNS = lp.wrapBoolOption( CfgOptionRemoveOutOfScopeDNSKey, cfgOptionRemoveOutOfScopeDNS, ) - lp.RemoveBlockedDNS = lp.wrapSecurityLevelOption( + lp.RemoveBlockedDNS = lp.wrapBoolOption( CfgOptionRemoveBlockedDNSKey, cfgOptionRemoveBlockedDNS, ) - lp.FilterSubDomains = lp.wrapSecurityLevelOption( + lp.FilterSubDomains = lp.wrapBoolOption( CfgOptionFilterSubDomainsKey, cfgOptionFilterSubDomains, ) - lp.FilterCNAMEs = lp.wrapSecurityLevelOption( + lp.FilterCNAMEs = lp.wrapBoolOption( CfgOptionFilterCNAMEKey, cfgOptionFilterCNAME, ) - lp.PreventBypassing = lp.wrapSecurityLevelOption( + lp.PreventBypassing = lp.wrapBoolOption( CfgOptionPreventBypassingKey, cfgOptionPreventBypassing, ) - lp.DomainHeuristics = lp.wrapSecurityLevelOption( + lp.DomainHeuristics = lp.wrapBoolOption( CfgOptionDomainHeuristicsKey, cfgOptionDomainHeuristics, ) @@ -444,17 +443,6 @@ func (lp *LayeredProfile) MatchFilterLists(ctx context.Context, entity *intel.En return endpoints.NoMatch, nil } -func (lp *LayeredProfile) wrapSecurityLevelOption(configKey string, globalConfig config.IntOption) config.BoolOption { - activeAtLevels := lp.wrapIntOption(configKey, globalConfig) - - return func() bool { - return uint8(activeAtLevels())&max( - lp.SecurityLevel(), // layered profile security level - status.ActiveSecurityLevel(), // global security level - ) > 0 - } -} - func (lp *LayeredProfile) wrapBoolOption(configKey string, globalConfig config.BoolOption) config.BoolOption { var revCnt uint64 = 0 var value bool @@ -564,10 +552,3 @@ func (lp *LayeredProfile) wrapStringOption(configKey string, globalConfig config return value } } - -func max(a, b uint8) uint8 { - if a > b { - return a - } - return b -} diff --git a/profile/special.go b/profile/special.go index 1a97261e1..6e95e2789 100644 --- a/profile/special.go +++ b/profile/special.go @@ -4,7 +4,6 @@ import ( "time" "github.com/safing/portbase/log" - "github.com/safing/portmaster/status" ) const ( @@ -43,14 +42,15 @@ These connections - the "network noise" - can be found in this app.` // SystemResolverProfileName is the name used for the system's DNS resolver. SystemResolverProfileName = "System DNS Client" // SystemResolverProfileDescription is the description used for the system's DNS resolver. - SystemResolverProfileDescription = `The System DNS Client is a system service that requires special handling. For regular network connections, the configured settings will apply as usual, but DNS requests coming from the System DNS Client are handled in a special way, as they could actually be coming from any other application on the system. + SystemResolverProfileDescription = `The System DNS Client is a system service that requires special handling. -In order to respect the app settings of the actual application, DNS requests from the System DNS Client are only subject to the following settings: +For regular network connections, the configured settings will apply as usual. -- Outgoing Rules (without global rules) -- Filter Lists +DNS Requests coming from the System DNS Client, however, could actually be coming from any other application on the system: The System DNS Client resolves domain names on behalf of other applications. -If you think you might have messed up the settings of the System DNS Client, just delete the profile below to reset it to the defaults. +In order to correctly handle these, DNS Requests (not regular connections), do not take the globally configured Outgoing Rules into account. + +Additionally, the settings for the System DNS Client are specially pre-configured. If you are having issues or want to revert to the default settings, please delete this profile below. It will be automatically recreated with the default settings. ` // PortmasterProfileID is the profile ID used for the Portmaster Core itself. @@ -176,11 +176,11 @@ func createSpecialProfile(profileID string, path string) *Profile { // would see two connection prompts for the same domain. CfgOptionDefaultActionKey: DefaultActionPermitValue, // Disable force blockers. - CfgOptionBlockScopeInternetKey: status.SecurityLevelOff, - CfgOptionBlockScopeLANKey: status.SecurityLevelOff, - CfgOptionBlockScopeLocalKey: status.SecurityLevelOff, - CfgOptionBlockP2PKey: status.SecurityLevelOff, - CfgOptionBlockInboundKey: status.SecurityLevelOff, + CfgOptionBlockScopeInternetKey: false, + CfgOptionBlockScopeLANKey: false, + CfgOptionBlockScopeLocalKey: false, + CfgOptionBlockP2PKey: false, + CfgOptionBlockInboundKey: false, // Explicitly allow localhost and answers to multicast protocols that // are commonly used by system resolvers. // TODO: When the Portmaster gains the ability to attribute multicast @@ -214,11 +214,11 @@ func createSpecialProfile(profileID string, path string) *Profile { // reset in the OS integration and might show up in the connection // handling if a packet in the other direction hits the firewall first. CfgOptionDefaultActionKey: DefaultActionPermitValue, - CfgOptionBlockScopeInternetKey: status.SecurityLevelOff, - CfgOptionBlockScopeLANKey: status.SecurityLevelOff, - CfgOptionBlockScopeLocalKey: status.SecurityLevelOff, - CfgOptionBlockP2PKey: status.SecurityLevelOff, - CfgOptionBlockInboundKey: status.SecurityLevelOff, + CfgOptionBlockScopeInternetKey: false, + CfgOptionBlockScopeLANKey: false, + CfgOptionBlockScopeLocalKey: false, + CfgOptionBlockP2PKey: false, + CfgOptionBlockInboundKey: false, CfgOptionEndpointsKey: []string{ "+ *", }, @@ -238,11 +238,11 @@ func createSpecialProfile(profileID string, path string) *Profile { PresentationPath: path, Config: map[string]interface{}{ CfgOptionDefaultActionKey: DefaultActionBlockValue, - CfgOptionBlockScopeInternetKey: status.SecurityLevelOff, - CfgOptionBlockScopeLANKey: status.SecurityLevelOff, - CfgOptionBlockScopeLocalKey: status.SecurityLevelOff, - CfgOptionBlockP2PKey: status.SecurityLevelOff, - CfgOptionBlockInboundKey: status.SecurityLevelsAll, + CfgOptionBlockScopeInternetKey: false, + CfgOptionBlockScopeLANKey: false, + CfgOptionBlockScopeLocalKey: false, + CfgOptionBlockP2PKey: false, + CfgOptionBlockInboundKey: true, CfgOptionEndpointsKey: []string{ "+ Localhost", "+ .safing.io", @@ -258,11 +258,11 @@ func createSpecialProfile(profileID string, path string) *Profile { PresentationPath: path, Config: map[string]interface{}{ CfgOptionDefaultActionKey: DefaultActionBlockValue, - CfgOptionBlockScopeInternetKey: status.SecurityLevelOff, - CfgOptionBlockScopeLANKey: status.SecurityLevelOff, - CfgOptionBlockScopeLocalKey: status.SecurityLevelOff, - CfgOptionBlockP2PKey: status.SecurityLevelOff, - CfgOptionBlockInboundKey: status.SecurityLevelsAll, + CfgOptionBlockScopeInternetKey: false, + CfgOptionBlockScopeLANKey: false, + CfgOptionBlockScopeLocalKey: false, + CfgOptionBlockP2PKey: false, + CfgOptionBlockInboundKey: true, CfgOptionEndpointsKey: []string{ "+ Localhost", }, diff --git a/resolver/config.go b/resolver/config.go index 6d1cdc92a..135c7c27b 100644 --- a/resolver/config.go +++ b/resolver/config.go @@ -58,7 +58,7 @@ var ( cfgOptionNameServersOrder = 0 CfgOptionNoAssignedNameserversKey = "dns/noAssignedNameservers" - noAssignedNameservers status.SecurityLevelOptionFunc + noAssignedNameservers config.BoolOption cfgOptionNoAssignedNameserversOrder = 1 CfgOptionUseStaleCacheKey = "dns/useStaleCache" @@ -67,15 +67,15 @@ var ( cfgOptionUseStaleCacheOrder = 2 CfgOptionNoMulticastDNSKey = "dns/noMulticastDNS" - noMulticastDNS status.SecurityLevelOptionFunc + noMulticastDNS config.BoolOption cfgOptionNoMulticastDNSOrder = 3 CfgOptionNoInsecureProtocolsKey = "dns/noInsecureProtocols" - noInsecureProtocols status.SecurityLevelOptionFunc + noInsecureProtocols config.BoolOption cfgOptionNoInsecureProtocolsOrder = 4 CfgOptionDontResolveSpecialDomainsKey = "dns/dontResolveSpecialDomains" - dontResolveSpecialDomains status.SecurityLevelOptionFunc + dontResolveSpecialDomains config.BoolOption cfgOptionDontResolveSpecialDomainsOrder = 16 CfgOptionNameserverRetryRateKey = "dns/nameserverRetryRate" @@ -201,22 +201,22 @@ When referring to the DNS server using a domain name, as with DoH, it is highly Name: "Ignore System/Network Servers", Key: CfgOptionNoAssignedNameserversKey, Description: "Ignore DNS servers configured in your system or network. This may break domains from your local network.", - OptType: config.OptTypeInt, + OptType: config.OptTypeBool, ExpertiseLevel: config.ExpertiseLevelExpert, ReleaseLevel: config.ReleaseLevelStable, - DefaultValue: status.SecurityLevelsHighAndExtreme, - PossibleValues: status.SecurityLevelValues, + DefaultValue: false, Annotations: config.Annotations{ config.DisplayOrderAnnotation: cfgOptionNoAssignedNameserversOrder, config.DisplayHintAnnotation: status.DisplayHintSecurityLevel, config.CategoryAnnotation: "Servers", "self:detail:specialUseDomains": specialUseDomains, }, + Migrations: []config.MigrationFunc{status.MigrateSecurityLevelToBoolean}, }) if err != nil { return err } - noAssignedNameservers = status.SecurityLevelOption(CfgOptionNoAssignedNameserversKey) + noAssignedNameservers = config.Concurrent.GetAsBool(CfgOptionNoAssignedNameserversKey, false) useStaleCacheConfigOption = &config.Option{ Name: "Always Use DNS Cache", @@ -241,42 +241,42 @@ When referring to the DNS server using a domain name, as with DoH, it is highly Name: "Ignore Multicast DNS", Key: CfgOptionNoMulticastDNSKey, Description: "Do not resolve using Multicast DNS. This may break certain Plug and Play devices and services.", - OptType: config.OptTypeInt, + OptType: config.OptTypeBool, ExpertiseLevel: config.ExpertiseLevelExpert, ReleaseLevel: config.ReleaseLevelStable, - DefaultValue: status.SecurityLevelsHighAndExtreme, - PossibleValues: status.SecurityLevelValues, + DefaultValue: false, Annotations: config.Annotations{ config.DisplayOrderAnnotation: cfgOptionNoMulticastDNSOrder, config.DisplayHintAnnotation: status.DisplayHintSecurityLevel, config.CategoryAnnotation: "Resolving", "self:detail:multicastDomains": multicastDomains, }, + Migrations: []config.MigrationFunc{status.MigrateSecurityLevelToBoolean}, }) if err != nil { return err } - noMulticastDNS = status.SecurityLevelOption(CfgOptionNoMulticastDNSKey) + noMulticastDNS = config.Concurrent.GetAsBool(CfgOptionNoMulticastDNSKey, false) err = config.Register(&config.Option{ Name: "Use Secure Protocols Only", Key: CfgOptionNoInsecureProtocolsKey, Description: "Never resolve using insecure protocols, ie. plain DNS. This may break certain local DNS services, which always use plain DNS.", - OptType: config.OptTypeInt, + OptType: config.OptTypeBool, ExpertiseLevel: config.ExpertiseLevelExpert, ReleaseLevel: config.ReleaseLevelStable, - DefaultValue: status.SecurityLevelsHighAndExtreme, - PossibleValues: status.SecurityLevelValues, + DefaultValue: false, Annotations: config.Annotations{ config.DisplayOrderAnnotation: cfgOptionNoInsecureProtocolsOrder, config.DisplayHintAnnotation: status.DisplayHintSecurityLevel, config.CategoryAnnotation: "Resolving", }, + Migrations: []config.MigrationFunc{status.MigrateSecurityLevelToBoolean}, }) if err != nil { return err } - noInsecureProtocols = status.SecurityLevelOption(CfgOptionNoInsecureProtocolsKey) + noInsecureProtocols = config.Concurrent.GetAsBool(CfgOptionNoInsecureProtocolsKey, false) err = config.Register(&config.Option{ Name: "Block Unofficial TLDs", @@ -285,22 +285,22 @@ When referring to the DNS server using a domain name, as with DoH, it is highly "Block %s. Unofficial domains may pose a security risk. This setting does not affect .onion domains in the Tor Browser.", formatScopeList(specialServiceDomains), ), - OptType: config.OptTypeInt, + OptType: config.OptTypeBool, ExpertiseLevel: config.ExpertiseLevelExpert, ReleaseLevel: config.ReleaseLevelStable, - DefaultValue: status.SecurityLevelsAll, - PossibleValues: status.AllSecurityLevelValues, + DefaultValue: true, Annotations: config.Annotations{ config.DisplayOrderAnnotation: cfgOptionDontResolveSpecialDomainsOrder, config.DisplayHintAnnotation: status.DisplayHintSecurityLevel, config.CategoryAnnotation: "Resolving", "self:detail:specialServiceDomains": specialServiceDomains, }, + Migrations: []config.MigrationFunc{status.MigrateSecurityLevelToBoolean}, }) if err != nil { return err } - dontResolveSpecialDomains = status.SecurityLevelOption(CfgOptionDontResolveSpecialDomainsKey) + dontResolveSpecialDomains = config.Concurrent.GetAsBool(CfgOptionDontResolveSpecialDomainsKey, false) return nil } diff --git a/resolver/resolve.go b/resolver/resolve.go index bed30a56d..b9feb0a91 100644 --- a/resolver/resolve.go +++ b/resolver/resolve.go @@ -87,7 +87,6 @@ func (blocked *BlockedUpstreamError) Unwrap() error { type Query struct { FQDN string QType dns.Type - SecurityLevel uint8 NoCaching bool IgnoreFailing bool LocalResolversOnly bool diff --git a/resolver/reverse.go b/resolver/reverse.go index d6ded14dd..f8abb9623 100644 --- a/resolver/reverse.go +++ b/resolver/reverse.go @@ -11,7 +11,7 @@ import ( ) // ResolveIPAndValidate finds (reverse DNS), validates (forward DNS) and returns the domain name assigned to the given IP. -func ResolveIPAndValidate(ctx context.Context, ip string, securityLevel uint8) (domain string, err error) { +func ResolveIPAndValidate(ctx context.Context, ip string) (domain string, err error) { // get reversed DNS address reverseIP, err := dns.ReverseAddr(ip) if err != nil { @@ -21,9 +21,8 @@ func ResolveIPAndValidate(ctx context.Context, ip string, securityLevel uint8) ( // get PTR record q := &Query{ - FQDN: reverseIP, - QType: dns.Type(dns.TypePTR), - SecurityLevel: securityLevel, + FQDN: reverseIP, + QType: dns.Type(dns.TypePTR), } rrCache, err := Resolve(ctx, q) if err != nil || rrCache == nil { @@ -47,8 +46,7 @@ func ResolveIPAndValidate(ctx context.Context, ip string, securityLevel uint8) ( // get forward record q = &Query{ - FQDN: ptrName, - SecurityLevel: securityLevel, + FQDN: ptrName, } // IPv4/6 switch if strings.Contains(ip, ":") { diff --git a/resolver/reverse_test.go b/resolver/reverse_test.go index c6b05e71e..421df6725 100644 --- a/resolver/reverse_test.go +++ b/resolver/reverse_test.go @@ -13,7 +13,7 @@ func testReverse(t *testing.T, ip, result, expectedErr string) { ctx, tracer := log.AddTracer(context.Background()) defer tracer.Submit() - domain, err := ResolveIPAndValidate(ctx, ip, 0) + domain, err := ResolveIPAndValidate(ctx, ip) if err != nil { tracer.Warning(err.Error()) if expectedErr == "" || err.Error() != expectedErr { diff --git a/resolver/scopes.go b/resolver/scopes.go index 67195f1db..044b83fc5 100644 --- a/resolver/scopes.go +++ b/resolver/scopes.go @@ -259,7 +259,7 @@ func (q *Query) checkCompliance() error { } // special TLDs - if dontResolveSpecialDomains(q.SecurityLevel) && + if dontResolveSpecialDomains() && domainInScope(q.dotPrefixedFQDN, specialServiceDomains) { return ErrSpecialDomainsDisabled } @@ -268,7 +268,7 @@ func (q *Query) checkCompliance() error { } func (resolver *Resolver) checkCompliance(_ context.Context, q *Query) error { - if noInsecureProtocols(q.SecurityLevel) { + if noInsecureProtocols() { switch resolver.Info.Type { case ServerTypeDNS: return errInsecureProtocol @@ -285,13 +285,13 @@ func (resolver *Resolver) checkCompliance(_ context.Context, q *Query) error { } } - if noAssignedNameservers(q.SecurityLevel) { + if noAssignedNameservers() { if resolver.Info.Source == ServerSourceOperatingSystem { return errAssignedServer } } - if noMulticastDNS(q.SecurityLevel) { + if noMulticastDNS() { if resolver.Info.Source == ServerSourceMDNS { return errMulticastDNS } diff --git a/status/autopilot.go b/status/autopilot.go deleted file mode 100644 index 8f411dc7e..000000000 --- a/status/autopilot.go +++ /dev/null @@ -1,36 +0,0 @@ -package status - -import "context" - -var runAutoPilot = make(chan struct{}, 1) - -func triggerAutopilot() { - select { - case runAutoPilot <- struct{}{}: - default: - } -} - -func autoPilot(ctx context.Context) error { - for { - select { - case <-ctx.Done(): - return nil - case <-runAutoPilot: - } - - selected := SelectedSecurityLevel() - mitigation := getHighestMitigationLevel() - - active := SecurityLevelNormal - if selected != SecurityLevelOff { - active = selected - } else if mitigation != SecurityLevelOff { - active = mitigation - } - - setActiveLevel(active) - - pushSystemStatus() - } -} diff --git a/status/config.go b/status/config.go deleted file mode 100644 index ac49b7f2c..000000000 --- a/status/config.go +++ /dev/null @@ -1,42 +0,0 @@ -package status - -import "github.com/safing/portbase/config" - -// Configuration Keys. -var ( - CfgEnableNetworkRatingSystemKey = "core/enableNetworkRating" - cfgEnableNetworkRatingSystem config.BoolOption -) - -func registerConfig() error { - if err := config.Register(&config.Option{ - Name: "Enable Network Rating System", - Key: CfgEnableNetworkRatingSystemKey, - Description: `Enable the Network Rating System, which allows you to configure settings to be active in one environment but not in the other, like allowing sensitive connections at home but not at the public library. - -Please note that this feature will be replaced by a superior and easier to understand system in the future.`, - OptType: config.OptTypeBool, - ExpertiseLevel: config.ExpertiseLevelExpert, - ReleaseLevel: config.ReleaseLevelStable, - DefaultValue: false, - Annotations: config.Annotations{ - config.DisplayOrderAnnotation: 514, - config.CategoryAnnotation: "User Interface", - }, - }); err != nil { - return err - } - cfgEnableNetworkRatingSystem = config.Concurrent.GetAsBool(CfgEnableNetworkRatingSystemKey, false) - - return nil -} - -// NetworkRatingEnabled returns true if the network rating system has been enabled. -func NetworkRatingEnabled() bool { - return cfgEnableNetworkRatingSystem() -} - -// SetNetworkRating enables or disables the network rating system. -func SetNetworkRating(enabled bool) error { - return config.SetConfigOption(CfgEnableNetworkRatingSystemKey, enabled) -} diff --git a/status/mitigation.go b/status/mitigation.go deleted file mode 100644 index 8157c18f1..000000000 --- a/status/mitigation.go +++ /dev/null @@ -1,60 +0,0 @@ -package status - -import ( - "sync" - - "github.com/safing/portbase/log" -) - -type knownThreats struct { - sync.RWMutex - // active threats and their recommended mitigation level - list map[string]uint8 -} - -var threats = &knownThreats{ - list: make(map[string]uint8), -} - -// SetMitigationLevel sets the mitigation level for id -// to mitigation. If mitigation is SecurityLevelOff the -// mitigation record will be removed. If mitigation is -// an invalid level the call to SetMitigationLevel is a -// no-op. -func SetMitigationLevel(id string, mitigation uint8) { - if !IsValidSecurityLevel(mitigation) { - log.Warningf("tried to set invalid mitigation level %d for threat %s", mitigation, id) - return - } - - defer triggerAutopilot() - - threats.Lock() - defer threats.Unlock() - if mitigation == 0 { - delete(threats.list, id) - } else { - threats.list[id] = mitigation - } -} - -// DeleteMitigationLevel deletes the mitigation level for id. -func DeleteMitigationLevel(id string) { - SetMitigationLevel(id, SecurityLevelOff) -} - -// getHighestMitigationLevel returns the highest mitigation -// level set on a threat. -func getHighestMitigationLevel() uint8 { - threats.RLock() - defer threats.RUnlock() - - level := SecurityLevelNormal - for _, lvl := range threats.list { - if lvl > level { - level = lvl - } - } - - return level -} diff --git a/status/module.go b/status/module.go index 28adeb411..bc8238328 100644 --- a/status/module.go +++ b/status/module.go @@ -12,7 +12,7 @@ import ( var module *modules.Module func init() { - module = modules.Register("status", prepare, start, nil, "base", "config") + module = modules.Register("status", nil, start, nil, "base", "config") } func start() error { @@ -20,57 +20,26 @@ func start() error { return err } - module.StartWorker("auto-pilot", autoPilot) - - triggerAutopilot() - if err := module.RegisterEventHook( netenv.ModuleName, netenv.OnlineStatusChangedEvent, "update online status in system status", func(_ context.Context, _ interface{}) error { - triggerAutopilot() - return nil - }, - ); err != nil { - return err - } - - if err := module.RegisterEventHook( - "config", - "config change", - "Update network rating system", - func(_ context.Context, _ interface{}) error { - if !NetworkRatingEnabled() && ActiveSecurityLevel() != SecurityLevelNormal { - setSelectedLevel(SecurityLevelNormal) - triggerAutopilot() - } + pushSystemStatus() return nil }, ); err != nil { return err } - - return nil -} - -func prepare() error { - if err := registerConfig(); err != nil { - return err - } - return nil } // AddToDebugInfo adds the system status to the given debug.Info. func AddToDebugInfo(di *debug.Info) { di.AddSection( - fmt.Sprintf("Status: %s", SecurityLevelString(ActiveSecurityLevel())), + fmt.Sprintf("Status: %s", netenv.GetOnlineStatus()), debug.UseCodeSection|debug.AddContentLineBreaks, - fmt.Sprintf("ActiveSecurityLevel: %s", SecurityLevelString(ActiveSecurityLevel())), - fmt.Sprintf("SelectedSecurityLevel: %s", SecurityLevelString(SelectedSecurityLevel())), - fmt.Sprintf("ThreatMitigationLevel: %s", SecurityLevelString(getHighestMitigationLevel())), - fmt.Sprintf("CaptivePortal: %s", netenv.GetCaptivePortal().URL), fmt.Sprintf("OnlineStatus: %s", netenv.GetOnlineStatus()), + fmt.Sprintf("CaptivePortal: %s", netenv.GetCaptivePortal().URL), ) } diff --git a/status/provider.go b/status/provider.go index 43abb0c51..fbe8d84f8 100644 --- a/status/provider.go +++ b/status/provider.go @@ -1,8 +1,6 @@ package status import ( - "fmt" - "github.com/safing/portbase/database/record" "github.com/safing/portbase/runtime" "github.com/safing/portmaster/netenv" @@ -12,7 +10,6 @@ var pushUpdate runtime.PushFunc func setupRuntimeProvider() (err error) { // register the system status getter - // statusProvider := runtime.SimpleValueGetterFunc(func(_ string) ([]record.Record, error) { return []record.Record{buildSystemStatus()}, nil }) @@ -21,63 +18,14 @@ func setupRuntimeProvider() (err error) { return err } - // register the selected security level setter - // - levelProvider := runtime.SimpleValueSetterFunc(setSelectedSecurityLevel) - _, err = runtime.Register("system/security-level", levelProvider) - if err != nil { - return err - } - return nil } -// setSelectedSecurityLevel updates the selected security level. -func setSelectedSecurityLevel(r record.Record) (record.Record, error) { - var upd *SelectedSecurityLevelRecord - if r.IsWrapped() { - upd = new(SelectedSecurityLevelRecord) - if err := record.Unwrap(r, upd); err != nil { - return nil, err - } - } else { - // TODO(ppacher): this can actually never happen - // as we're write-only and ValueProvider.Set() should - // only ever be called from the HTTP API (so r must be wrapped). - // Though, make sure we handle the case as well ... - var ok bool - upd, ok = r.(*SelectedSecurityLevelRecord) - if !ok { - return nil, fmt.Errorf("expected *SelectedSecurityLevelRecord but got %T", r) - } - } - - // if the network rating system is not used at all we always force the security - // level to trusted. - if !NetworkRatingEnabled() { - upd.SelectedSecurityLevel = SecurityLevelNormal - } - - if !IsValidSecurityLevel(upd.SelectedSecurityLevel) { - return nil, fmt.Errorf("invalid security level: %d", upd.SelectedSecurityLevel) - } - - if SelectedSecurityLevel() != upd.SelectedSecurityLevel { - setSelectedLevel(upd.SelectedSecurityLevel) - triggerAutopilot() - } - - return r, nil -} - // buildSystemStatus build a new system status record. func buildSystemStatus() *SystemStatusRecord { status := &SystemStatusRecord{ - ActiveSecurityLevel: ActiveSecurityLevel(), - SelectedSecurityLevel: SelectedSecurityLevel(), - ThreatMitigationLevel: getHighestMitigationLevel(), - CaptivePortal: netenv.GetCaptivePortal(), - OnlineStatus: netenv.GetOnlineStatus(), + CaptivePortal: netenv.GetCaptivePortal(), + OnlineStatus: netenv.GetOnlineStatus(), } status.CreateMeta() diff --git a/status/records.go b/status/records.go index 7f2c39b4c..63f3f9fd5 100644 --- a/status/records.go +++ b/status/records.go @@ -13,15 +13,6 @@ type SystemStatusRecord struct { record.Base sync.Mutex - // ActiveSecurityLevel holds the currently - // active security level. - ActiveSecurityLevel uint8 - // SelectedSecurityLevel holds the security level - // as selected by the user. - SelectedSecurityLevel uint8 - // ThreatMitigationLevel holds the security level - // as selected by the auto-pilot. - ThreatMitigationLevel uint8 // OnlineStatus holds the current online status as // seen by the netenv package. OnlineStatus netenv.OnlineStatus @@ -30,13 +21,3 @@ type SystemStatusRecord struct { // connected to, if any. CaptivePortal *netenv.CaptivePortal } - -// SelectedSecurityLevelRecord is used as a dummy record.Record -// to provide a simply runtime-configuration for the user. -// It is write-only and exposed at "runtime:system/security-level". -type SelectedSecurityLevelRecord struct { - record.Base - sync.Mutex - - SelectedSecurityLevel uint8 -} diff --git a/status/security_level.go b/status/security_level.go index f4770f5db..46641fc2f 100644 --- a/status/security_level.go +++ b/status/security_level.go @@ -2,14 +2,50 @@ package status import "github.com/safing/portbase/config" -type ( - // SecurityLevelOptionFunc can be called with a minimum security level - // and returns whether or not a given security option is enabled or - // not. - // Use SecurityLevelOption() to get a SecurityLevelOptionFunc for a - // specific option. - SecurityLevelOptionFunc func(minSecurityLevel uint8) bool -) +// MigrateSecurityLevelToBoolean migrates a security level (int) option value to a boolean option value. +func MigrateSecurityLevelToBoolean(option *config.Option, value any) any { + // Check new (target) option type. + if option.OptType != config.OptTypeBool { + // This migration converts to boolean. + // Thus, conversion is not applicable. + return value + } + + // Convert value to uint8. + var nVal uint8 + switch v := value.(type) { + case int: + nVal = uint8(v) + case int8: + nVal = uint8(v) + case int16: + nVal = uint8(v) + case int32: + nVal = uint8(v) + case int64: + nVal = uint8(v) + case uint: + nVal = uint8(v) + case uint8: + nVal = v + case uint16: + nVal = uint8(v) + case uint32: + nVal = uint8(v) + case uint64: + nVal = uint8(v) + case float32: + nVal = uint8(v) + case float64: + nVal = uint8(v) + default: + // Input type not compatible. + return value + } + + // Convert to boolean. + return nVal&SecurityLevelNormal > 0 +} // DisplayHintSecurityLevel is an external option hint for security levels. // It's meant to be used as a value for config.DisplayHintAnnotation. @@ -21,98 +57,4 @@ const ( SecurityLevelNormal uint8 = 1 SecurityLevelHigh uint8 = 2 SecurityLevelExtreme uint8 = 4 - - SecurityLevelsNormalAndHigh uint8 = SecurityLevelNormal | SecurityLevelHigh - SecurityLevelsNormalAndExtreme uint8 = SecurityLevelNormal | SecurityLevelExtreme - SecurityLevelsHighAndExtreme uint8 = SecurityLevelHigh | SecurityLevelExtreme - SecurityLevelsAll uint8 = SecurityLevelNormal | SecurityLevelHigh | SecurityLevelExtreme -) - -// SecurityLevelValues defines all possible security levels. -var SecurityLevelValues = []config.PossibleValue{ - { - Name: "Trusted / Home Network", - Value: SecurityLevelsAll, - Description: "Setting is always enabled.", - }, - { - Name: "Untrusted / Public Network", - Value: SecurityLevelsHighAndExtreme, - Description: "Setting is enabled in untrusted and dangerous networks.", - }, - { - Name: "Danger / Hacked Network", - Value: SecurityLevelExtreme, - Description: "Setting is enabled only in dangerous networks.", - }, -} - -// AllSecurityLevelValues is like SecurityLevelValues but also includes Off. -var AllSecurityLevelValues = append([]config.PossibleValue{ - { - Name: "Off", - Value: SecurityLevelOff, - Description: "Setting is always disabled.", - }, -}, - SecurityLevelValues..., ) - -// IsValidSecurityLevel returns true if level is a valid, -// single security level. Level is also invalid if it's a -// bitmask with more that one security level set. -func IsValidSecurityLevel(level uint8) bool { - return level == SecurityLevelOff || - level == SecurityLevelNormal || - level == SecurityLevelHigh || - level == SecurityLevelExtreme -} - -// IsValidSecurityLevelMask returns true if level is a valid -// security level mask. It's like IsValidSecurityLevel but -// also allows bitmask combinations. -func IsValidSecurityLevelMask(level uint8) bool { - return level <= 7 -} - -func max(a, b uint8) uint8 { - if a > b { - return a - } - return b -} - -// SecurityLevelOption returns a function to check if the option -// identified by name is active at a given minimum security level. -// The returned function is safe for concurrent use with configuration -// updates. -func SecurityLevelOption(name string) SecurityLevelOptionFunc { - activeAtLevel := config.Concurrent.GetAsInt(name, int64(SecurityLevelsAll)) - return func(minSecurityLevel uint8) bool { - return uint8(activeAtLevel())&max(ActiveSecurityLevel(), minSecurityLevel) > 0 - } -} - -// SecurityLevelString returns the given security level as a string. -func SecurityLevelString(level uint8) string { - switch level { - case SecurityLevelOff: - return "Off" - case SecurityLevelNormal: - return "Trusted" - case SecurityLevelHigh: - return "Untrusted" - case SecurityLevelExtreme: - return "Danger" - case SecurityLevelsNormalAndHigh: - return "Trusted and Untrusted" - case SecurityLevelsNormalAndExtreme: - return "Trusted and Danger" - case SecurityLevelsHighAndExtreme: - return "Untrusted and Danger" - case SecurityLevelsAll: - return "Trusted, Untrusted and Danger" - default: - return "INVALID" - } -} diff --git a/status/state.go b/status/state.go deleted file mode 100644 index a3fb079a7..000000000 --- a/status/state.go +++ /dev/null @@ -1,30 +0,0 @@ -package status - -import ( - "sync/atomic" -) - -var ( - activeLevel = new(uint32) - selectedLevel = new(uint32) -) - -func setActiveLevel(lvl uint8) { - atomic.StoreUint32(activeLevel, uint32(lvl)) -} - -func setSelectedLevel(lvl uint8) { - atomic.StoreUint32(selectedLevel, uint32(lvl)) -} - -// ActiveSecurityLevel returns the currently active security -// level. -func ActiveSecurityLevel() uint8 { - return uint8(atomic.LoadUint32(activeLevel)) -} - -// SelectedSecurityLevel returns the security level as selected -// by the user. -func SelectedSecurityLevel() uint8 { - return uint8(atomic.LoadUint32(selectedLevel)) -} diff --git a/status/threat.go b/status/threat.go deleted file mode 100644 index c7592858f..000000000 --- a/status/threat.go +++ /dev/null @@ -1,132 +0,0 @@ -package status - -import ( - "time" - - "github.com/safing/portbase/log" - "github.com/safing/portbase/notifications" -) - -// Threat represents a threat to the system. -// A threat is basically a notification with strong -// typed EventData. Use the methods expored on Threat -// to manipulate the EventData field and push updates -// of the notification. -// Do not use EventData directly! -type Threat struct { - *notifications.Notification -} - -// ThreatPayload holds threat related information. -type ThreatPayload struct { - // MitigationLevel holds the recommended security - // level to mitigate the threat. - MitigationLevel uint8 - // Started holds the UNIX epoch timestamp in seconds - // at which the threat has been detected the first time. - Started int64 - // Ended holds the UNIX epoch timestamp in seconds - // at which the threat has been detected the last time. - Ended int64 - // Data may holds threat-specific data. - Data interface{} -} - -// NewThreat returns a new threat. Note that the -// threat only gets published once Publish is called. -// -// Example: -// -// threat := NewThreat("portscan", "Someone is scanning you"). -// SetData(portscanResult). -// SetMitigationLevel(SecurityLevelExtreme). -// Publish() -// -// Once you're done, delete the threat -// threat.Delete().Publish() -func NewThreat(id, title, msg string) *Threat { - t := &Threat{ - Notification: ¬ifications.Notification{ - EventID: id, - Type: notifications.Warning, - Title: title, - Category: "Threat", - Message: msg, - }, - } - - t.threatData().Started = time.Now().Unix() - - return t -} - -// SetData sets the data member of the threat payload. -func (t *Threat) SetData(data interface{}) *Threat { - t.Lock() - defer t.Unlock() - - t.threatData().Data = data - return t -} - -// SetMitigationLevel sets the mitigation level of the -// threat data. -func (t *Threat) SetMitigationLevel(lvl uint8) *Threat { - t.Lock() - defer t.Unlock() - - t.threatData().MitigationLevel = lvl - return t -} - -// Delete sets the ended timestamp of the threat. -func (t *Threat) Delete() *Threat { - t.Lock() - defer t.Unlock() - - t.threatData().Ended = time.Now().Unix() - - return t -} - -// Payload returns a copy of the threat payload. -func (t *Threat) Payload() ThreatPayload { - t.Lock() - defer t.Unlock() - - return *t.threatData() // creates a copy -} - -// Publish publishes the current threat. -// Publish should always be called when changes to -// the threat are recorded. -func (t *Threat) Publish() *Threat { - data := t.Payload() - if data.Ended > 0 { - DeleteMitigationLevel(t.EventID) - } else { - SetMitigationLevel(t.EventID, data.MitigationLevel) - } - - t.Save() - - return t -} - -// threatData returns the threat payload associated with this -// threat. If not data has been created yet a new ThreatPayload -// is attached to t and returned. The caller must make sure to -// hold appropriate locks when working with the returned payload. -func (t *Threat) threatData() *ThreatPayload { - if t.EventData == nil { - t.EventData = new(ThreatPayload) - } - - payload, ok := t.EventData.(*ThreatPayload) - if !ok { - log.Warningf("unexpected type %T in thread notification payload", t.EventData) - return new(ThreatPayload) - } - - return payload -}