mirror of
https://github.com/safing/portmaster
synced 2025-04-21 11:29:09 +00:00
* Move portbase into monorepo * Add new simple module mgr * [WIP] Switch to new simple module mgr * Add StateMgr and more worker variants * [WIP] Switch more modules * [WIP] Switch more modules * [WIP] swtich more modules * [WIP] switch all SPN modules * [WIP] switch all service modules * [WIP] Convert all workers to the new module system * [WIP] add new task system to module manager * [WIP] Add second take for scheduling workers * [WIP] Add FIXME for bugs in new scheduler * [WIP] Add minor improvements to scheduler * [WIP] Add new worker scheduler * [WIP] Fix more bug related to new module system * [WIP] Fix start handing of the new module system * [WIP] Improve startup process * [WIP] Fix minor issues * [WIP] Fix missing subsystem in settings * [WIP] Initialize managers in constructor * [WIP] Move module event initialization to constrictors * [WIP] Fix setting for enabling and disabling the SPN module * [WIP] Move API registeration into module construction * [WIP] Update states mgr for all modules * [WIP] Add CmdLine operation support * Add state helper methods to module group and instance * Add notification and module status handling to status package * Fix starting issues * Remove pilot widget and update security lock to new status data * Remove debug logs * Improve http server shutdown * Add workaround for cleanly shutting down firewall+netquery * Improve logging * Add syncing states with notifications for new module system * Improve starting, stopping, shutdown; resolve FIXMEs/TODOs * [WIP] Fix most unit tests * Review new module system and fix minor issues * Push shutdown and restart events again via API * Set sleep mode via interface * Update example/template module * [WIP] Fix spn/cabin unit test * Remove deprecated UI elements * Make log output more similar for the logging transition phase * Switch spn hub and observer cmds to new module system * Fix log sources * Make worker mgr less error prone * Fix tests and minor issues * Fix observation hub * Improve shutdown and restart handling * Split up big connection.go source file * Move varint and dsd packages to structures repo * Improve expansion test * Fix linter warnings * Fix interception module on windows * Fix linter errors --------- Co-authored-by: Vladimir Stoilov <vladimir@safing.io>
222 lines
5.3 KiB
Go
222 lines
5.3 KiB
Go
package navigator
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
"golang.org/x/exp/slices"
|
|
|
|
"github.com/safing/portmaster/base/log"
|
|
"github.com/safing/portmaster/service/intel/geoip"
|
|
"github.com/safing/portmaster/service/profile/endpoints"
|
|
"github.com/safing/portmaster/spn/hub"
|
|
)
|
|
|
|
// UpdateIntel supplies the map with new intel data. The data is not copied, so
|
|
// it must not be modified after being supplied. If the map is empty, the
|
|
// bootstrap hubs will be added to the map.
|
|
func (m *Map) UpdateIntel(update *hub.Intel, trustNodes []string) error {
|
|
// Check if intel data is already parsed.
|
|
if update.Parsed() == nil {
|
|
return errors.New("intel data is not parsed")
|
|
}
|
|
|
|
m.Lock()
|
|
defer m.Unlock()
|
|
|
|
// Update the map's reference to the intel data.
|
|
m.intel = update
|
|
|
|
// Update pins with new intel data.
|
|
for _, pin := range m.all {
|
|
// Add/Update location data from IP addresses.
|
|
pin.updateLocationData()
|
|
|
|
// Override Pin Data.
|
|
m.updateInfoOverrides(pin)
|
|
|
|
// Update Trust and Advisory Statuses.
|
|
m.updateIntelStatuses(pin, trustNodes)
|
|
|
|
// Push changes.
|
|
// TODO: Only set when pin changed.
|
|
pin.pushChanges.Set()
|
|
}
|
|
|
|
// Configure the map's regions.
|
|
m.updateRegions(m.intel.Regions)
|
|
|
|
// Push pin changes.
|
|
m.PushPinChanges()
|
|
|
|
log.Infof("spn/navigator: updated intel on map %s", m.Name)
|
|
|
|
// Add bootstrap hubs if map is empty.
|
|
if m.isEmpty() {
|
|
return m.addBootstrapHubs(m.intel.BootstrapHubs)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetIntel returns the map's intel data.
|
|
func (m *Map) GetIntel() *hub.Intel {
|
|
m.RLock()
|
|
defer m.RUnlock()
|
|
|
|
return m.intel
|
|
}
|
|
|
|
func (m *Map) updateIntelStatuses(pin *Pin, trustNodes []string) {
|
|
// Reset all related states.
|
|
pin.removeStates(StateTrusted | StateUsageDiscouraged | StateUsageAsHomeDiscouraged | StateUsageAsDestinationDiscouraged)
|
|
|
|
// Check if Intel data is loaded.
|
|
if m.intel == nil {
|
|
return
|
|
}
|
|
|
|
// Check Hub Intel
|
|
hubIntel, ok := m.intel.Hubs[pin.Hub.ID]
|
|
if ok {
|
|
// Apply the verified owner, if any.
|
|
pin.VerifiedOwner = hubIntel.VerifiedOwner
|
|
|
|
// Check if Hub is discontinued.
|
|
if hubIntel.Discontinued {
|
|
// Reset state, set offline and return.
|
|
pin.State = StateNone
|
|
pin.addStates(StateOffline)
|
|
return
|
|
}
|
|
|
|
// Check if Hub is trusted.
|
|
if hubIntel.Trusted {
|
|
pin.addStates(StateTrusted)
|
|
}
|
|
}
|
|
|
|
// Check manual trust status.
|
|
switch {
|
|
case slices.Contains[[]string, string](trustNodes, pin.VerifiedOwner):
|
|
pin.addStates(StateTrusted)
|
|
case slices.Contains[[]string, string](trustNodes, pin.Hub.ID):
|
|
pin.addStates(StateTrusted)
|
|
}
|
|
|
|
// Check advisories.
|
|
// Check for UsageDiscouraged.
|
|
checkStatusList(
|
|
pin,
|
|
StateUsageDiscouraged,
|
|
m.intel.AdviseOnlyTrustedHubs,
|
|
m.intel.Parsed().HubAdvisory,
|
|
)
|
|
// Check for UsageAsHomeDiscouraged.
|
|
checkStatusList(
|
|
pin,
|
|
StateUsageAsHomeDiscouraged,
|
|
m.intel.AdviseOnlyTrustedHomeHubs,
|
|
m.intel.Parsed().HomeHubAdvisory,
|
|
)
|
|
// Check for UsageAsDestinationDiscouraged.
|
|
checkStatusList(
|
|
pin,
|
|
StateUsageAsDestinationDiscouraged,
|
|
m.intel.AdviseOnlyTrustedDestinationHubs,
|
|
m.intel.Parsed().DestinationHubAdvisory,
|
|
)
|
|
}
|
|
|
|
func checkStatusList(pin *Pin, state PinState, requireTrusted bool, endpointList endpoints.Endpoints) {
|
|
if requireTrusted && !pin.State.Has(StateTrusted) {
|
|
pin.addStates(state)
|
|
return
|
|
}
|
|
|
|
if pin.EntityV4 != nil {
|
|
result, _ := endpointList.Match(context.TODO(), pin.EntityV4)
|
|
if result == endpoints.Denied {
|
|
pin.addStates(state)
|
|
return
|
|
}
|
|
}
|
|
|
|
if pin.EntityV6 != nil {
|
|
result, _ := endpointList.Match(context.TODO(), pin.EntityV6)
|
|
if result == endpoints.Denied {
|
|
pin.addStates(state)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (m *Map) updateInfoOverrides(pin *Pin) {
|
|
// Check if Intel data is loaded and if there are any overrides.
|
|
if m.intel == nil {
|
|
return
|
|
}
|
|
|
|
// Get overrides for this pin.
|
|
hubIntel, ok := m.intel.Hubs[pin.Hub.ID]
|
|
if !ok || hubIntel.Override == nil {
|
|
return
|
|
}
|
|
overrides := hubIntel.Override
|
|
|
|
// Apply overrides
|
|
if overrides.CountryCode != "" {
|
|
if pin.LocationV4 != nil {
|
|
pin.LocationV4.Country = geoip.GetCountryInfo(overrides.CountryCode)
|
|
}
|
|
if pin.EntityV4 != nil {
|
|
pin.EntityV4.Country = overrides.CountryCode
|
|
}
|
|
if pin.LocationV6 != nil {
|
|
pin.LocationV6.Country = geoip.GetCountryInfo(overrides.CountryCode)
|
|
}
|
|
if pin.EntityV6 != nil {
|
|
pin.EntityV6.Country = overrides.CountryCode
|
|
}
|
|
}
|
|
if overrides.Coordinates != nil {
|
|
if pin.LocationV4 != nil {
|
|
pin.LocationV4.Coordinates = *overrides.Coordinates
|
|
}
|
|
if pin.EntityV4 != nil {
|
|
pin.EntityV4.Coordinates = overrides.Coordinates
|
|
}
|
|
if pin.LocationV6 != nil {
|
|
pin.LocationV6.Coordinates = *overrides.Coordinates
|
|
}
|
|
if pin.EntityV6 != nil {
|
|
pin.EntityV6.Coordinates = overrides.Coordinates
|
|
}
|
|
}
|
|
if overrides.ASN != 0 {
|
|
if pin.LocationV4 != nil {
|
|
pin.LocationV4.AutonomousSystemNumber = overrides.ASN
|
|
}
|
|
if pin.EntityV4 != nil {
|
|
pin.EntityV4.ASN = overrides.ASN
|
|
}
|
|
if pin.LocationV6 != nil {
|
|
pin.LocationV6.AutonomousSystemNumber = overrides.ASN
|
|
}
|
|
if pin.EntityV6 != nil {
|
|
pin.EntityV6.ASN = overrides.ASN
|
|
}
|
|
}
|
|
if overrides.ASOrg != "" {
|
|
if pin.LocationV4 != nil {
|
|
pin.LocationV4.AutonomousSystemOrganization = overrides.ASOrg
|
|
}
|
|
if pin.EntityV4 != nil {
|
|
pin.EntityV4.ASOrg = overrides.ASOrg
|
|
}
|
|
if pin.LocationV6 != nil {
|
|
pin.LocationV6.AutonomousSystemOrganization = overrides.ASOrg
|
|
}
|
|
if pin.EntityV6 != nil {
|
|
pin.EntityV6.ASOrg = overrides.ASOrg
|
|
}
|
|
}
|
|
}
|