diff --git a/core/config.go b/core/config.go index 6c4f9574..0ee6921f 100644 --- a/core/config.go +++ b/core/config.go @@ -7,6 +7,7 @@ import ( "github.com/safing/portbase/log" ) +// Configuration Keys var ( CfgDevModeKey = "core/devMode" defaultDevMode bool diff --git a/core/core.go b/core/core.go index 7b3b4532..f15a2709 100644 --- a/core/core.go +++ b/core/core.go @@ -3,9 +3,14 @@ package core import ( "fmt" + "github.com/safing/portbase/modules" "github.com/safing/portbase/modules/subsystems" - "github.com/safing/portbase/modules" + // module dependencies + _ "github.com/safing/portbase/rng" + _ "github.com/safing/portmaster/status" + _ "github.com/safing/portmaster/ui" + _ "github.com/safing/portmaster/updates" ) var ( @@ -13,7 +18,9 @@ var ( ) func init() { - module = modules.Register("core", nil, start, nil, "database", "config", "api", "random", "notifications", "subsystems", "ui", "updates", "status") + modules.Register("base", nil, registerDatabases, nil, "database", "config", "random") + + module = modules.Register("core", nil, start, nil, "base", "subsystems", "status", "updates", "api", "notifications", "ui") subsystems.Register( "core", "Core", @@ -29,5 +36,5 @@ func start() error { return fmt.Errorf("failed to start plattform-specific components: %s", err) } - return registerDatabases() + return nil } diff --git a/core/databases.go b/core/databases.go index 65612e8c..941aa97a 100644 --- a/core/databases.go +++ b/core/databases.go @@ -10,6 +10,7 @@ import ( _ "github.com/safing/portbase/database/storage/bbolt" ) +// Default Values (changeable for testing) var ( DefaultDatabaseStorageType = "bbolt" ) diff --git a/core/global.go b/core/global.go index 13c6cfa9..d76bbaa5 100644 --- a/core/global.go +++ b/core/global.go @@ -12,7 +12,10 @@ import ( "github.com/safing/portbase/notifications" ) +// Default Values (changeable for testing) var ( + DefaultAPIListenAddress = "127.0.0.1:817" + dataDir string databaseDir string ) @@ -53,7 +56,7 @@ func globalPrep() error { } // set api listen address - api.SetDefaultAPIListenAddress("127.0.0.1:817") + api.SetDefaultAPIListenAddress(DefaultAPIListenAddress) // set notification persistence notifications.SetPersistenceBasePath("core:notifications") diff --git a/core/pmtesting/testing.go b/core/pmtesting/testing.go index fc5005b2..04779939 100644 --- a/core/pmtesting/testing.go +++ b/core/pmtesting/testing.go @@ -1,6 +1,18 @@ -// package coretest provides a simple unit test setup routine. +// Package pmtesting provides a simple unit test setup routine. // -// Just include `_ "github.com/safing/portmaster/core/pmtesting"` +// Usage: +// +// package name +// +// import ( +// "testing" +// +// "github.com/safing/portmaster/core/pmtesting" +// ) +// +// func TestMain(m *testing.M) { +// pmtesting.TestMain(m, module) +// } // package pmtesting @@ -29,10 +41,17 @@ func init() { flag.BoolVar(&printStackOnExit, "print-stack-on-exit", false, "prints the stack before of shutting down") } -func TestMain(m *testing.M) { +// TestMain provides a simple unit test setup routine. +func TestMain(m *testing.M, module *modules.Module) { + // enable module for testing + module.Enable() + // switch databases to memory only core.DefaultDatabaseStorageType = "hashmap" + // switch API to high port + core.DefaultAPIListenAddress = "127.0.0.1:10817" + // set log level log.SetLogLevel(log.TraceLevel) @@ -40,19 +59,22 @@ func TestMain(m *testing.M) { tmpDir := filepath.Join(os.TempDir(), "portmaster-testing") // initialize data dir err := dataroot.Initialize(tmpDir, 0755) - // start modules - if err == nil { - err = modules.Start() - } - // handle setup error if err != nil { - fmt.Fprintf(os.Stderr, "failed to setup test: %s\n", err) - printStack() + fmt.Fprintf(os.Stderr, "failed to initialize data root: %s\n", err) os.Exit(1) } - // run tests - exitCode := m.Run() + // start modules + var exitCode int + err = modules.Start() + if err != nil { + // starting failed + fmt.Fprintf(os.Stderr, "failed to setup test: %s\n", err) + exitCode = 1 + } else { + // run tests + exitCode = m.Run() + } // shutdown _ = modules.Shutdown() @@ -63,7 +85,14 @@ func TestMain(m *testing.M) { printStack() // clean up and exit - // keep! os.RemoveAll(tmpDir) + + // Important: Do not remove tmpDir, as it is used as a cache for updates. + // remove config + _ = os.Remove(filepath.Join(tmpDir, "config.json")) + // remove databases + _ = os.Remove(filepath.Join(tmpDir, "databases.json")) + _ = os.RemoveAll(filepath.Join(tmpDir, "databases")) + os.Exit(exitCode) } diff --git a/firewall/config.go b/firewall/config.go index 62f505ef..721d1382 100644 --- a/firewall/config.go +++ b/firewall/config.go @@ -4,6 +4,7 @@ import ( "github.com/safing/portbase/config" ) +// Configuration Keys var ( CfgOptionEnableFilterKey = "filter/enable" diff --git a/firewall/dialer.go b/firewall/dialer.go index bf158b65..270b3f9f 100644 --- a/firewall/dialer.go +++ b/firewall/dialer.go @@ -4,13 +4,13 @@ import ( "fmt" "net" - "github.com/safing/portmaster/network/environment" + "github.com/safing/portmaster/netenv" "github.com/safing/portmaster/resolver" ) func init() { resolver.SetLocalAddrFactory(PermittedAddr) - environment.SetLocalAddrFactory(PermittedAddr) + netenv.SetLocalAddrFactory(PermittedAddr) } // PermittedAddr returns an already permitted local address for the given network for reliable connectivity. diff --git a/firewall/firewall.go b/firewall/firewall.go index dc6231a7..0b32a9a0 100644 --- a/firewall/firewall.go +++ b/firewall/firewall.go @@ -44,7 +44,7 @@ var ( ) func init() { - module = modules.Register("firewall", prep, start, stop, "core", "network", "resolver", "intel", "processes") + module = modules.Register("filter", prep, start, stop, "core", "network", "nameserver", "intel") subsystems.Register( "filter", "Privacy Filter", diff --git a/intel/geoip/module_test.go b/intel/geoip/module_test.go index 1b32ad88..c1ae951b 100644 --- a/intel/geoip/module_test.go +++ b/intel/geoip/module_test.go @@ -7,5 +7,5 @@ import ( ) func TestMain(m *testing.M) { - pmtesting.TestMain(m) + pmtesting.TestMain(m, module) } diff --git a/intel/module.go b/intel/module.go index 99169de3..ea4d013f 100644 --- a/intel/module.go +++ b/intel/module.go @@ -4,6 +4,11 @@ import ( "github.com/safing/portbase/modules" ) +var ( + // Module of this package. Export needed for testing of the endpoints package. + Module *modules.Module +) + func init() { - modules.Register("intel", nil, nil, nil, "geoip") + Module = modules.Register("intel", nil, nil, nil, "geoip") } diff --git a/nameserver/nameserver.go b/nameserver/nameserver.go index ba7c6577..6c7a7601 100644 --- a/nameserver/nameserver.go +++ b/nameserver/nameserver.go @@ -11,8 +11,8 @@ import ( "github.com/safing/portbase/modules" "github.com/safing/portmaster/detection/dga" "github.com/safing/portmaster/firewall" + "github.com/safing/portmaster/netenv" "github.com/safing/portmaster/network" - "github.com/safing/portmaster/network/environment" "github.com/safing/portmaster/network/netutils" "github.com/safing/portmaster/resolver" @@ -30,7 +30,7 @@ var ( ) func init() { - module = modules.Register("nameserver", prep, start, stop, "core", "resolver", "network") + module = modules.Register("nameserver", prep, start, stop, "core", "resolver", "network", "netenv") subsystems.Register( "dns", "Secure DNS", @@ -108,9 +108,9 @@ func handleRequestAsMicroTask(w dns.ResponseWriter, query *dns.Msg) { } } -func handleRequest(ctx context.Context, w dns.ResponseWriter, query *dns.Msg) error { +func handleRequest(ctx context.Context, w dns.ResponseWriter, query *dns.Msg) error { //nolint:gocognit // TODO // return with server failure if offline - if environment.GetOnlineStatus() == environment.StatusOffline { + if netenv.GetOnlineStatus() == netenv.StatusOffline { returnServerFailure(w, query) return nil } diff --git a/nameserver/only/nameserver.go b/nameserver/only/nameserver.go index 24920477..feaa5ca5 100644 --- a/nameserver/only/nameserver.go +++ b/nameserver/only/nameserver.go @@ -5,15 +5,13 @@ import ( "net" "strings" - "github.com/safing/portmaster/network/environment" - - "github.com/miekg/dns" - "github.com/safing/portbase/log" "github.com/safing/portbase/modules" - - "github.com/safing/portmaster/intel" + "github.com/safing/portmaster/netenv" "github.com/safing/portmaster/network/netutils" + "github.com/safing/portmaster/resolver" + + "github.com/miekg/dns" ) var ( @@ -27,7 +25,7 @@ var ( ) func init() { - module = modules.Register("nameserver", initLocalhostRRs, start, stop, "core", "intel", "network") + module = modules.Register("nameserver", initLocalhostRRs, start, stop, "core", "resolver", "network", "netenv") } func initLocalhostRRs() error { @@ -53,7 +51,7 @@ func start() error { err := dnsServer.ListenAndServe() if err != nil { // check if we are shutting down - if module.ShutdownInProgress() { + if module.IsStopping() { return nil } } @@ -87,20 +85,20 @@ func handleRequestAsMicroTask(w dns.ResponseWriter, query *dns.Msg) { return handleRequest(ctx, w, query) }) if err != nil { - log.Warningf("intel: failed to handle dns request: %s", err) + log.Warningf("nameserver: failed to handle dns request: %s", err) } } func handleRequest(ctx context.Context, w dns.ResponseWriter, query *dns.Msg) error { // return with server failure if offline - if environment.GetOnlineStatus() == environment.StatusOffline { + if netenv.GetOnlineStatus() == netenv.StatusOffline { returnServerFailure(w, query) return nil } // only process first question, that's how everyone does it. question := query.Question[0] - q := &intel.Query{ + q := &resolver.Query{ FQDN: question.Name, QType: dns.Type(question.Qtype), } @@ -157,7 +155,7 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, query *dns.Msg) er // TODO: if there are 3 request for the same domain/type in a row, delete all caches of that domain // get intel and RRs - rrCache, err := intel.Resolve(ctx, q) + rrCache, err := resolver.Resolve(ctx, q) if err != nil { // TODO: analyze nxdomain requests, malware could be trying DGA-domains tracer.Warningf("nameserver: request for %s%s: %s", q.FQDN, q.QType, err) @@ -169,9 +167,9 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, query *dns.Msg) er for _, rr := range append(rrCache.Answer, rrCache.Extra...) { switch v := rr.(type) { case *dns.A: - ipInfo, err := intel.GetIPInfo(v.A.String()) + ipInfo, err := resolver.GetIPInfo(v.A.String()) if err != nil { - ipInfo = &intel.IPInfo{ + ipInfo = &resolver.IPInfo{ IP: v.A.String(), Domains: []string{q.FQDN}, } @@ -183,9 +181,9 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, query *dns.Msg) er } } case *dns.AAAA: - ipInfo, err := intel.GetIPInfo(v.AAAA.String()) + ipInfo, err := resolver.GetIPInfo(v.AAAA.String()) if err != nil { - ipInfo = &intel.IPInfo{ + ipInfo = &resolver.IPInfo{ IP: v.AAAA.String(), Domains: []string{q.FQDN}, } diff --git a/pmctl/main.go b/pmctl/main.go index 2c99fe2f..6cea5b6e 100644 --- a/pmctl/main.go +++ b/pmctl/main.go @@ -9,14 +9,12 @@ import ( "strings" "syscall" - "github.com/safing/portbase/updater" - - "github.com/safing/portmaster/core/structure" - - "github.com/safing/portbase/utils" - + "github.com/safing/portbase/dataroot" "github.com/safing/portbase/info" portlog "github.com/safing/portbase/log" + "github.com/safing/portbase/updater" + "github.com/safing/portbase/utils" + "github.com/spf13/cobra" ) @@ -158,15 +156,15 @@ func cmdSetup(cmd *cobra.Command, args []string) (err error) { // remove redundant escape characters and quotes dataDir = strings.Trim(dataDir, `\"`) - // initialize structure - err = structure.Initialize(dataDir, 0755) + // initialize dataroot + err = dataroot.Initialize(dataDir, 0755) if err != nil { return fmt.Errorf("failed to initialize data root: %s", err) } - dataRoot = structure.Root() + dataRoot = dataroot.Root() // initialize registry - err := registry.Initialize(structure.Root().ChildDir("updates", 0755)) + err := registry.Initialize(dataRoot.ChildDir("updates", 0755)) if err != nil { return err } @@ -187,7 +185,7 @@ func cmdSetup(cmd *cobra.Command, args []string) (err error) { // logs and warning if !showShortVersion && !showFullVersion && !strings.Contains(cmd.CommandPath(), " show ") { // set up logs root - logsRoot = structure.NewRootDir("logs", 0777) + logsRoot = dataRoot.ChildDir("logs", 0777) err = logsRoot.Ensure() if err != nil { return fmt.Errorf("failed to initialize logs root: %s", err) diff --git a/process/config.go b/process/config.go index 36722fe5..9329eddb 100644 --- a/process/config.go +++ b/process/config.go @@ -4,6 +4,7 @@ import ( "github.com/safing/portbase/config" ) +// Configuration Keys var ( CfgOptionEnableProcessDetectionKey = "core/enableProcessDetection" enableProcessDetection config.BoolOption diff --git a/process/module_test.go b/process/module_test.go new file mode 100644 index 00000000..fc33c7bd --- /dev/null +++ b/process/module_test.go @@ -0,0 +1,11 @@ +package process + +import ( + "testing" + + "github.com/safing/portmaster/core/pmtesting" +) + +func TestMain(m *testing.M) { + pmtesting.TestMain(m, module) +} diff --git a/profile/config.go b/profile/config.go index db03a9d1..49f64160 100644 --- a/profile/config.go +++ b/profile/config.go @@ -4,6 +4,7 @@ import ( "github.com/safing/portbase/config" ) +// Configuration Keys var ( cfgStringOptions = make(map[string]config.StringOption) cfgStringArrayOptions = make(map[string]config.StringArrayOption) diff --git a/profile/endpoints/endpoints_test.go b/profile/endpoints/endpoints_test.go index 147e6bf4..0eb4e2e1 100644 --- a/profile/endpoints/endpoints_test.go +++ b/profile/endpoints/endpoints_test.go @@ -10,7 +10,7 @@ import ( ) func TestMain(m *testing.M) { - pmtesting.TestMain(m) + pmtesting.TestMain(m, intel.Module) } func testEndpointMatch(t *testing.T, ep Endpoint, entity *intel.Entity, expectedResult EPResult) { diff --git a/profile/find.go b/profile/find.go index 51475bce..85ad5a7d 100644 --- a/profile/find.go +++ b/profile/find.go @@ -5,6 +5,7 @@ import ( "github.com/safing/portbase/log" ) +// FindOrCreateLocalProfileByPath returns an existing or new profile for the given application path. func FindOrCreateLocalProfileByPath(fullPath string) (profile *Profile, new bool, err error) { // find local profile it, err := profileDB.Query( diff --git a/profile/fingerprint/fingerprint.go b/profile/fingerprint/fingerprint.go index d049d42c..7d7d4bde 100644 --- a/profile/fingerprint/fingerprint.go +++ b/profile/fingerprint/fingerprint.go @@ -47,3 +47,41 @@ func (profile *Profile) AddFingerprint(fp *Fingerprint) { profile.Fingerprints = append(profile.Fingerprints, fp) } */ + +// TODO: matching +/* +//nolint:deadcode,unused // FIXME +func matchProfile(p *Process, prof *profile.Profile) (score int) { + for _, fp := range prof.Fingerprints { + score += matchFingerprint(p, fp) + } + return +} + +//nolint:deadcode,unused // FIXME +func matchFingerprint(p *Process, fp *profile.Fingerprint) (score int) { + if !fp.MatchesOS() { + return 0 + } + + switch fp.Type { + case "full_path": + if p.Path == fp.Value { + return profile.GetFingerprintWeight(fp.Type) + } + case "partial_path": + // FIXME: if full_path matches, do not match partial paths + return profile.GetFingerprintWeight(fp.Type) + case "md5_sum", "sha1_sum", "sha256_sum": + // FIXME: one sum is enough, check sums in a grouped form, start with the best + sum, err := p.GetExecHash(fp.Type) + if err != nil { + log.Errorf("process: failed to get hash of executable: %s", err) + } else if sum == fp.Value { + return profile.GetFingerprintWeight(fp.Type) + } + } + + return 0 +} +*/ diff --git a/profile/module_test.go b/profile/module_test.go new file mode 100644 index 00000000..55bd1876 --- /dev/null +++ b/profile/module_test.go @@ -0,0 +1,11 @@ +package profile + +import ( + "testing" + + "github.com/safing/portmaster/core/pmtesting" +) + +func TestMain(m *testing.M) { + pmtesting.TestMain(m, module) +} diff --git a/status/module.go b/status/module.go index f7ac9231..da3486e9 100644 --- a/status/module.go +++ b/status/module.go @@ -4,13 +4,10 @@ import ( "github.com/safing/portbase/database" "github.com/safing/portbase/log" "github.com/safing/portbase/modules" - - // module dependencies - _ "github.com/safing/portmaster/core" ) func init() { - modules.Register("status", nil, start, stop, "config", "database") + modules.Register("status", nil, start, stop, "base") } func start() error { diff --git a/ui/serve.go b/ui/serve.go index 96bb34b9..2dcd219d 100644 --- a/ui/serve.go +++ b/ui/serve.go @@ -115,8 +115,8 @@ func ServeFileFromBundle(w http.ResponseWriter, r *http.Request, bundleName stri } } - // set content security policy - // FIXME: this breaks the ui client + // TODO: Set content security policy + // For some reason, this breaks the ui client // w.Header().Set("Content-Security-Policy", "default-src 'self'") w.WriteHeader(http.StatusOK) diff --git a/updates/main.go b/updates/main.go index e7a550a7..31bc3065 100644 --- a/updates/main.go +++ b/updates/main.go @@ -29,7 +29,7 @@ var ( ) func init() { - module = modules.Register("updates", registerConfig, start, stop, "config", "database") + module = modules.Register("updates", registerConfig, start, stop, "base") module.RegisterEvent(eventVersionUpdate) module.RegisterEvent(eventResourceUpdate) }