Fix handling of connectivity / captive portal domains

Also, improve handling of queries during being captive.
This commit is contained in:
Daniel
2020-07-17 16:09:46 +02:00
parent a6e161e0a1
commit 68c2d23c1b
15 changed files with 223 additions and 63 deletions

View File

@@ -1,6 +1,6 @@
package status
// Definitions of Security and Status Levels
// Definitions of Security and Status Levels.
const (
SecurityLevelOff uint8 = 0

View File

@@ -1,6 +1,8 @@
package status
import (
"context"
"github.com/safing/portbase/database"
"github.com/safing/portbase/database/query"
"github.com/safing/portbase/database/record"
@@ -35,7 +37,10 @@ func (sh *statusHook) PrePut(r record.Record) (record.Record, error) {
// apply applicable settings
if SelectedSecurityLevel() != newStatus.SelectedSecurityLevel {
go setSelectedSecurityLevel(newStatus.SelectedSecurityLevel)
module.StartWorker("set selected security level", func(_ context.Context) error {
setSelectedSecurityLevel(newStatus.SelectedSecurityLevel)
return nil
})
}
// TODO: allow setting of Gate17 status (on/off)

View File

@@ -7,22 +7,16 @@ import (
var (
activeSecurityLevel *uint32
selectedSecurityLevel *uint32
portmasterStatus *uint32
gate17Status *uint32
)
func init() {
var (
activeSecurityLevelValue uint32
selectedSecurityLevelValue uint32
portmasterStatusValue uint32
gate17StatusValue uint32
)
activeSecurityLevel = &activeSecurityLevelValue
selectedSecurityLevel = &selectedSecurityLevelValue
portmasterStatus = &portmasterStatusValue
gate17Status = &gate17StatusValue
}
// ActiveSecurityLevel returns the current security level.
@@ -34,13 +28,3 @@ func ActiveSecurityLevel() uint8 {
func SelectedSecurityLevel() uint8 {
return uint8(atomic.LoadUint32(selectedSecurityLevel))
}
// PortmasterStatus returns the current Portmaster status.
func PortmasterStatus() uint8 {
return uint8(atomic.LoadUint32(portmasterStatus))
}
// Gate17Status returns the current Gate17 status.
func Gate17Status() uint8 {
return uint8(atomic.LoadUint32(gate17Status))
}

View File

@@ -8,8 +8,6 @@ func TestGet(t *testing.T) {
// TODO: write real tests
ActiveSecurityLevel()
SelectedSecurityLevel()
PortmasterStatus()
Gate17Status()
option := ConfigIsActive("invalid")
option(0)
option = ConfigIsActiveConcurrent("invalid")

View File

@@ -6,21 +6,40 @@ import (
"github.com/safing/portbase/modules"
)
var (
module *modules.Module
)
func init() {
modules.Register("status", nil, start, stop, "base")
module = modules.Register("status", nil, start, stop, "base")
}
func start() error {
var loadedStatus *SystemStatus
err := initSystemStatus()
if err != nil {
return err
}
err = startNetEnvHooking()
if err != nil {
return err
}
status.Save()
return initStatusHook()
}
func initSystemStatus() error {
// load status from database
r, err := statusDB.Get(statusDBKey)
switch err {
case nil:
loadedStatus, err = EnsureSystemStatus(r)
loadedStatus, err := EnsureSystemStatus(r)
if err != nil {
log.Criticalf("status: failed to unwrap system status: %s", err)
loadedStatus = nil
} else {
status = loadedStatus
}
case database.ErrNotFound:
// create new status
@@ -28,10 +47,6 @@ func start() error {
log.Criticalf("status: failed to load system status: %s", err)
}
// activate loaded status, if available
if loadedStatus != nil {
status = loadedStatus
}
status.Lock()
defer status.Unlock()
@@ -41,10 +56,9 @@ func start() error {
// update status
status.updateThreatMitigationLevel()
status.autopilot()
status.updateOnlineStatus()
go status.Save()
return initStatusHook()
return nil
}
func stop() error {

28
status/netenv.go Normal file
View File

@@ -0,0 +1,28 @@
package status
import (
"context"
"github.com/safing/portmaster/netenv"
)
// startNetEnvHooking starts the listener for online status changes.
func startNetEnvHooking() error {
return module.RegisterEventHook(
"netenv",
netenv.OnlineStatusChangedEvent,
"update online status in system status",
func(_ context.Context, _ interface{}) error {
status.Lock()
status.updateOnlineStatus()
status.Unlock()
status.Save()
return nil
},
)
}
func (s *SystemStatus) updateOnlineStatus() {
s.OnlineStatus = netenv.GetOnlineStatus()
s.CaptivePortal = netenv.GetCaptivePortal()
}

View File

@@ -6,7 +6,7 @@ import (
"github.com/safing/portbase/log"
)
// autopilot automatically adjusts the security level as needed
// autopilot automatically adjusts the security level as needed.
func (s *SystemStatus) autopilot() {
// check if users is overruling
if s.SelectedSecurityLevel > SecurityLevelOff {
@@ -33,19 +33,18 @@ func setSelectedSecurityLevel(level uint8) {
switch level {
case SecurityLevelOff, SecurityLevelNormal, SecurityLevelHigh, SecurityLevelExtreme:
status.Lock()
defer status.Unlock()
status.SelectedSecurityLevel = level
atomicUpdateSelectedSecurityLevel(level)
status.autopilot()
go status.Save()
status.Unlock()
status.Save()
default:
log.Errorf("status: tried to set selected security level to invalid value: %d", level)
}
}
// update functions for atomic stuff
func atomicUpdateActiveSecurityLevel(level uint8) {
atomic.StoreUint32(activeSecurityLevel, uint32(level))
}

View File

@@ -1,9 +1,12 @@
package status
import (
"context"
"fmt"
"sync"
"github.com/safing/portmaster/netenv"
"github.com/safing/portbase/database/record"
"github.com/safing/portbase/log"
)
@@ -28,11 +31,22 @@ type SystemStatus struct {
ActiveSecurityLevel uint8
SelectedSecurityLevel uint8
OnlineStatus netenv.OnlineStatus
CaptivePortal *netenv.CaptivePortal
ThreatMitigationLevel uint8
Threats map[string]*Threat
}
// Save saves the SystemStatus to the database
// SaveAsync saves the SystemStatus to the database asynchronously.
func (s *SystemStatus) SaveAsync() {
module.StartWorker("save system status", func(_ context.Context) error {
s.Save()
return nil
})
}
// Save saves the SystemStatus to the database.
func (s *SystemStatus) Save() {
err := statusDB.Put(s)
if err != nil {

View File

@@ -26,7 +26,7 @@ func AddOrUpdateThreat(new *Threat) {
status.updateThreatMitigationLevel()
status.autopilot()
go status.Save()
status.SaveAsync()
}
// DeleteThreat deletes a threat from the system status.
@@ -38,7 +38,7 @@ func DeleteThreat(id string) {
status.updateThreatMitigationLevel()
status.autopilot()
go status.Save()
status.SaveAsync()
}
// GetThreats returns all threats who's IDs are prefixed by the given string, and also a locker for editing them.