Merge pull request #1037 from safing/feature/add-debug-data

Add update versions debug data
This commit is contained in:
Daniel Hovie
2022-12-12 15:05:53 +01:00
committed by GitHub
11 changed files with 50 additions and 193 deletions

View File

@@ -146,6 +146,7 @@ func debugInfo(ar *api.Request) (data []byte, err error) {
compat.AddToDebugInfo(di)
di.AddLastReportedModuleError()
di.AddLastUnexpectedLogs()
updates.AddToDebugInfo(di)
di.AddGoroutineStack()
// Return data.

View File

@@ -169,7 +169,7 @@ var (
// SPNRulesHelp defines the help text for SPN related Hub selection rules.
SPNRulesHelp = strings.ReplaceAll(`Rules are checked from top to bottom, stopping after the first match. They can match the following attributes of SPN Nodes:
- Country (based on IPs): "US"
- Country (based on IPs): "US" (two-letter country codes according to ISO 3166-1 alpha-2)
- AS number: "AS123456"
- Address: "192.168.0.1"
- Network: "192.168.0.1/24"
@@ -250,7 +250,7 @@ func registerConfiguration() error { //nolint:maintidx
- Matching with a wildcard prefix: "*xample.com"
- Matching with a wildcard suffix: "example.*"
- Matching domains containing text: "*example*"
- By country (based on IP): "US"
- By country (based on IP): "US" (two-letter country codes according to ISO 3166-1 alpha-2)
- By AS number: "AS123456"
- By filter list - use the filterlist ID prefixed with "L:": "L:MAL"
- Match anything: "*"

View File

@@ -1,9 +0,0 @@
package profile
// Platform identifiers.
const (
PlatformLinux = "linux"
PlatformWindows = "windows"
PlatformMac = "macos"
PlatformOpenBSD = "openbsd"
)

View File

@@ -1,6 +0,0 @@
package profile
// OS Identifier.
const (
osIdentifier = PlatformMac
)

View File

@@ -1,6 +0,0 @@
package profile
// OS Identifier.
const (
osIdentifier = PlatformLinux
)

View File

@@ -1,6 +0,0 @@
package profile
// OS Identifier.
const (
osIdentifier = PlatformOpenBSD
)

View File

@@ -1,6 +0,0 @@
package profile
// OS Identifier.
const (
osIdentifier = PlatformWindows
)

View File

@@ -1,85 +0,0 @@
package profile
var fingerprintWeights = map[string]int{
"full_path": 2,
"partial_path": 1,
"md5_sum": 4,
"sha1_sum": 5,
"sha256_sum": 6,
}
// Fingerprint links processes to profiles.
type Fingerprint struct {
OS string
Type string
Value string
Comment string
LastUsed int64
}
// MatchesOS returns whether the Fingerprint is applicable for the current OS.
func (fp *Fingerprint) MatchesOS() bool {
return fp.OS == osIdentifier
}
// GetFingerprintWeight returns the weight of the given fingerprint type.
func GetFingerprintWeight(fpType string) (weight int) {
weight, ok := fingerprintWeights[fpType]
if ok {
return weight
}
return 0
}
// TODO: move to profile
/*
// AddFingerprint adds the given fingerprint to the profile.
func (profile *Profile) AddFingerprint(fp *Fingerprint) {
if fp.OS == "" {
fp.OS = osIdentifier
}
if fp.LastUsed == 0 {
fp.LastUsed = time.Now().Unix()
}
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
}
*/

View File

@@ -1,47 +0,0 @@
package profile
import (
"path/filepath"
"strings"
"github.com/safing/portbase/utils"
)
// GetPathIdentifier returns the identifier from the given path.
func GetPathIdentifier(path string) string {
// clean path
// TODO: is this necessary?
cleanedPath, err := filepath.EvalSymlinks(path)
if err == nil {
path = cleanedPath
} else {
path = filepath.Clean(path)
}
splittedPath := strings.Split(path, "/")
// strip sensitive data
switch {
case strings.HasPrefix(path, "/home/"):
splittedPath = splittedPath[3:]
case strings.HasPrefix(path, "/root/"):
splittedPath = splittedPath[2:]
}
// common directories with executable
if i := utils.IndexOfString(splittedPath, "bin"); i > 0 {
splittedPath = splittedPath[i:]
return strings.Join(splittedPath, "/")
}
if i := utils.IndexOfString(splittedPath, "sbin"); i > 0 {
splittedPath = splittedPath[i:]
return strings.Join(splittedPath, "/")
}
// shorten to max 3
if len(splittedPath) > 3 {
splittedPath = splittedPath[len(splittedPath)-3:]
}
return strings.Join(splittedPath, "/")
}

View File

@@ -1,26 +0,0 @@
package profile
import "testing"
func testPathID(t *testing.T, execPath, identifierPath string) {
t.Helper()
result := GetPathIdentifier(execPath)
if result != identifierPath {
t.Errorf("unexpected identifier path for %s: got %s, expected %s", execPath, result, identifierPath)
}
}
func TestGetPathIdentifier(t *testing.T) {
t.Parallel()
testPathID(t, "/bin/bash", "bin/bash")
testPathID(t, "/home/user/bin/bash", "bin/bash")
testPathID(t, "/home/user/project/main", "project/main")
testPathID(t, "/root/project/main", "project/main")
testPathID(t, "/tmp/a/b/c/d/install.sh", "c/d/install.sh")
testPathID(t, "/lib/systemd/systemd-udevd", "lib/systemd/systemd-udevd")
testPathID(t, "/bundle/ruby/2.4.0/bin/passenger", "bin/passenger")
testPathID(t, "/usr/sbin/cron", "sbin/cron")
testPathID(t, "/usr/local/bin/python", "bin/python")
}

View File

@@ -2,12 +2,16 @@ package updates
import (
"context"
"fmt"
"sort"
"strings"
"sync"
"github.com/safing/portbase/database/record"
"github.com/safing/portbase/info"
"github.com/safing/portbase/log"
"github.com/safing/portbase/updater"
"github.com/safing/portbase/utils/debug"
"github.com/safing/portmaster/updates/helper"
)
@@ -131,3 +135,46 @@ func export(_ context.Context, _ interface{}) error {
}
return GetSimpleVersions().save()
}
// AddToDebugInfo adds the update system status to the given debug.Info.
func AddToDebugInfo(di *debug.Info) {
// Get resources from registry.
resources := registry.Export()
platformPrefix := helper.PlatformIdentifier("")
// Collect data for debug info.
var active, selected []string
var activeCnt, totalCnt int
for id, r := range resources {
// Ignore resources for other platforms.
if !strings.HasPrefix(id, "all/") && !strings.HasPrefix(id, platformPrefix) {
continue
}
totalCnt++
if r.ActiveVersion != nil {
activeCnt++
active = append(active, fmt.Sprintf("%s: %s", id, r.ActiveVersion.VersionNumber))
}
if r.SelectedVersion != nil {
selected = append(selected, fmt.Sprintf("%s: %s", id, r.SelectedVersion.VersionNumber))
}
}
sort.Strings(active)
sort.Strings(selected)
// Compile to one list.
lines := make([]string, 0, len(active)+len(selected)+3)
lines = append(lines, "Active:")
lines = append(lines, active...)
lines = append(lines, "")
lines = append(lines, "Selected:")
lines = append(lines, selected...)
// Add section.
di.AddSection(
fmt.Sprintf("Updates: %s (%d/%d)", initialReleaseChannel, activeCnt, totalCnt),
debug.UseCodeSection|debug.AddContentLineBreaks,
lines...,
)
}