safing-portmaster/status/threat.go
2019-08-20 12:02:09 +02:00

73 lines
2 KiB
Go

package status
import (
"strings"
"sync"
)
// Threat describes a detected threat.
type Threat struct {
ID string // A unique ID chosen by reporting module (eg. modulePrefix-incident) to periodically check threat existence
Name string // Descriptive (human readable) name for detected threat
Description string // Simple description
AdditionalData interface{} // Additional data a module wants to make available for the user
MitigationLevel uint8 // Recommended Security Level to switch to for mitigation
Started int64
Ended int64
// TODO: add locking
}
// AddOrUpdateThreat adds or updates a new threat in the system status.
func AddOrUpdateThreat(new *Threat) {
status.Lock()
defer status.Unlock()
status.Threats[new.ID] = new
status.updateThreatMitigationLevel()
status.autopilot()
go status.Save()
}
// DeleteThreat deletes a threat from the system status.
func DeleteThreat(id string) {
status.Lock()
defer status.Unlock()
delete(status.Threats, id)
status.updateThreatMitigationLevel()
status.autopilot()
go status.Save()
}
// GetThreats returns all threats who's IDs are prefixed by the given string, and also a locker for editing them.
func GetThreats(idPrefix string) ([]*Threat, sync.Locker) {
status.Lock()
defer status.Unlock()
var exportedThreats []*Threat
for id, threat := range status.Threats {
if strings.HasPrefix(id, idPrefix) {
exportedThreats = append(exportedThreats, threat)
}
}
return exportedThreats, &status.Mutex
}
func (s *SystemStatus) updateThreatMitigationLevel() {
// get highest mitigationLevel
var mitigationLevel uint8
for _, threat := range s.Threats {
switch threat.MitigationLevel {
case SecurityLevelDynamic, SecurityLevelSecure, SecurityLevelFortress:
if threat.MitigationLevel > mitigationLevel {
mitigationLevel = threat.MitigationLevel
}
}
}
// set new ThreatMitigationLevel
s.ThreatMitigationLevel = mitigationLevel
}