wip: migrate to mono-repo. SPN has already been moved to spn/

This commit is contained in:
Patrick Pacher 2024-03-15 11:55:13 +01:00
parent b30fd00ccf
commit 8579430db9
No known key found for this signature in database
GPG key ID: E8CD2DA160925A6D
577 changed files with 35981 additions and 818 deletions

View file

@ -1,22 +0,0 @@
#!/bin/sh
DEP_FILE="Gopkg.toml"
# remove ignored internal deps
sed -i '/ignored = \["github.com\/safing\//d' $DEP_FILE
# portbase
PORTBASE_BRANCH="develop"
git branch | grep "* master" >/dev/null
if [ $? -eq 0 ]; then
PORTBASE_BRANCH="master"
fi
echo "
[[constraint]]
name = \"github.com/safing/portbase\"
branch = \"${PORTBASE_BRANCH}\"
[[constraint]]
name = \"github.com/safing/spn\"
branch = \"${PORTBASE_BRANCH}\"
" >> $DEP_FILE

405
Gopkg.lock generated
View file

@ -1,405 +0,0 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
digest = "1:6146fda730c18186631e91e818d995e759e7cbe27644d6871ccd469f6865c686"
name = "github.com/StackExchange/wmi"
packages = ["."]
pruneopts = ""
revision = "cbe66965904dbe8a6cd589e2298e5d8b986bd7dd"
version = "1.1.0"
[[projects]]
digest = "1:e010d6b45ee6c721df761eae89961c634ceb55feff166a48d15504729309f267"
name = "github.com/TheTannerRyan/ring"
packages = ["."]
pruneopts = ""
revision = "7b27005873e31b5d5a035e166636a09e03aaf40e"
version = "v1.1.1"
[[projects]]
digest = "1:21caed545a1c7ef7a2627bbb45989f689872ff6d5087d49c31340ce74c36de59"
name = "github.com/agext/levenshtein"
packages = ["."]
pruneopts = ""
revision = "52c14c47d03211d8ac1834e94601635e07c5a6ef"
version = "v1.2.3"
[[projects]]
branch = "v2.1"
digest = "1:3fc5d0d9cb474736e8e6c2f2292e0763b5132c6e7d8cbedf7bde404a470c8c3b"
name = "github.com/cookieo9/resources-go"
packages = ["."]
pruneopts = ""
revision = "d27c04069d0d5dfe11c202dacbf745ae8d1ab181"
[[projects]]
digest = "1:f384a8b6f89c502229e9013aa4f89ce5b5b56f09f9a4d601d7f1f026d3564fbf"
name = "github.com/coreos/go-iptables"
packages = ["iptables"]
pruneopts = ""
revision = "f901d6c2a4f2a4df092b98c33366dfba1f93d7a0"
version = "v0.4.5"
[[projects]]
digest = "1:0deddd908b6b4b768cfc272c16ee61e7088a60f7fe2f06c547bd3d8e1f8b8e77"
name = "github.com/davecgh/go-spew"
packages = ["spew"]
pruneopts = ""
revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73"
version = "v1.1.1"
[[projects]]
branch = "master"
digest = "1:c8098f53cd182561cfb128c9a5ba70e41ad2364b763f33f05c6bd54003ae6495"
name = "github.com/florianl/go-nfqueue"
packages = [
".",
"internal/unix",
]
pruneopts = ""
revision = "a2f196e98ab0ffdcb8b5252e7cbba98e45dea204"
[[projects]]
digest = "1:b6581f9180e0f2d5549280d71819ab951db9d511478c87daca95669589d505c0"
name = "github.com/go-ole/go-ole"
packages = [
".",
"oleutil",
]
pruneopts = ""
revision = "97b6244175ae18ea6eef668034fd6565847501c9"
version = "v1.2.4"
[[projects]]
digest = "1:f63933986e63230fc32512ed00bc18ea4dbb0f57b5da18561314928fd20c2ff0"
name = "github.com/godbus/dbus"
packages = ["."]
pruneopts = ""
revision = "37bf87eef99d69c4f1d3528bd66e3a87dc201472"
version = "v5.0.3"
[[projects]]
digest = "1:c18de9c9afca0ab336a29cf356d566abbdc29dd4948547557ed62c0da30d3be3"
name = "github.com/google/gopacket"
packages = [
".",
"layers",
"tcpassembly",
]
pruneopts = ""
revision = "558173e197d46ae52f0f7c58313c96296ee16a9c"
version = "v1.1.18"
[[projects]]
digest = "1:20dc576ad8f98fe64777c62f090a9b37dd67c62b23fe42b429c2c41936aa8a9c"
name = "github.com/google/renameio"
packages = ["."]
pruneopts = ""
revision = "f0e32980c006571efd537032e5f9cd8c1a92819e"
version = "v0.1.0"
[[projects]]
digest = "1:8e3bd93036b4a925fe2250d3e4f38f21cadb8ef623561cd80c3c50c114b13201"
name = "github.com/hashicorp/errwrap"
packages = ["."]
pruneopts = ""
revision = "8a6fb523712970c966eefc6b39ed2c5e74880354"
version = "v1.0.0"
[[projects]]
digest = "1:c6e569ffa34fcd24febd3562bff0520a104d15d1a600199cb3141debf2e58c89"
name = "github.com/hashicorp/go-multierror"
packages = ["."]
pruneopts = ""
revision = "2004d9dba6b07a5b8d133209244f376680f9d472"
version = "v1.1.0"
[[projects]]
digest = "1:ebffb4b4c8ddcf66bb549464183ea2ddbac6c58a803658f67249f83395d17455"
name = "github.com/hashicorp/go-version"
packages = ["."]
pruneopts = ""
revision = "59da58cfd357de719a4d16dac30481391a56c002"
version = "v1.2.1"
[[projects]]
digest = "1:870d441fe217b8e689d7949fef6e43efbc787e50f200cb1e70dbca9204a1d6be"
name = "github.com/inconshreveable/mousetrap"
packages = ["."]
pruneopts = ""
revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75"
version = "v1.0"
[[projects]]
branch = "master"
digest = "1:e71cc6b377264002aec0d9c235087e51ad7a3c1fb341bb4baa84709308b94fe8"
name = "github.com/kardianos/osext"
packages = ["."]
pruneopts = ""
revision = "2bc1f35cddc0cc527b4bc3dce8578fc2a6c11384"
[[projects]]
digest = "1:711ec17a2d8edd94cff8e2e4339d847e46acc1bb6b49ec29dcc1db78b666378b"
name = "github.com/mdlayher/netlink"
packages = [
".",
"nlenc",
]
pruneopts = ""
revision = "2a4e26491f1ba4eae173a7733ac11744cfed82b5"
version = "v1.2.0"
[[projects]]
digest = "1:508f444b8e00a569a40899aaf5740348b44c305d36f36d4f002b277677deef95"
name = "github.com/miekg/dns"
packages = ["."]
pruneopts = ""
revision = "10e0aeedbee54849adab780611454192a9980443"
version = "v1.1.33"
[[projects]]
digest = "1:3282ac9a9ddf5c2c0eda96693364d34fe0f8d10a0748259082a5c9fbd3e1f7e4"
name = "github.com/oschwald/maxminddb-golang"
packages = ["."]
pruneopts = ""
revision = "2e4624cc0c4105b1df1d0643ac3aadb53824dc7d"
version = "v1.7.0"
[[projects]]
digest = "1:c45802472e0c06928cd997661f2af610accd85217023b1d5f6331bebce0671d3"
name = "github.com/pkg/errors"
packages = ["."]
pruneopts = ""
revision = "614d223910a179a466c1767a985424175c39b465"
version = "v0.9.1"
[[projects]]
digest = "1:256484dbbcd271f9ecebc6795b2df8cad4c458dd0f5fd82a8c2fa0c29f233411"
name = "github.com/pmezard/go-difflib"
packages = ["difflib"]
pruneopts = ""
revision = "792786c7400a136282c1664665ae0a8db921c6c2"
version = "v1.0.0"
[[projects]]
digest = "1:70e15b4090e254d1eada6ef156773c0888cf707c43078479114d814761b902c5"
name = "github.com/shirou/gopsutil"
packages = [
"cpu",
"internal/common",
"mem",
"net",
"process",
]
pruneopts = ""
revision = "7e94bb8bcde053b6d6c98bda5145e9742c913c39"
version = "v2.20.7"
[[projects]]
digest = "1:bff75d4f1a2d2c4b8f4b46ff5ac230b80b5fa49276f615900cba09fe4c97e66e"
name = "github.com/spf13/cobra"
packages = ["."]
pruneopts = ""
revision = "a684a6d7f5e37385d954dd3b5a14fc6912c6ab9d"
version = "v1.0.0"
[[projects]]
digest = "1:688428eeb1ca80d92599eb3254bdf91b51d7e232fead3a73844c1f201a281e51"
name = "github.com/spf13/pflag"
packages = ["."]
pruneopts = ""
revision = "2e9d26c8c37aae03e3f9d4e90b7116f5accb7cab"
version = "v1.0.5"
[[projects]]
digest = "1:83fd2513b9f6ae0997bf646db6b74e9e00131e31002116fda597175f25add42d"
name = "github.com/stretchr/testify"
packages = ["assert"]
pruneopts = ""
revision = "f654a9112bbeac49ca2cd45bfbe11533c4666cf8"
version = "v1.6.1"
[[projects]]
digest = "1:1f11a269b089908c141f78c060991ff7bcd16545e95ee48d557e638fa846bde2"
name = "github.com/tevino/abool"
packages = ["."]
pruneopts = ""
revision = "8ae5c93531aabf12924a5b78e6dee1216bfff2f8"
version = "v1.2.0"
[[projects]]
branch = "master"
digest = "1:21097653bd7914de1262f2429e277933507442f892815a791ce1c0dbf0a8dc20"
name = "github.com/umahmood/haversine"
packages = ["."]
pruneopts = ""
revision = "808ab04add26660fd241ddb7973886c6dd6669e8"
[[projects]]
branch = "master"
digest = "1:df4642a605244e62c69ae335ac3c3cfa1c2b7ec971c3de398e1909592a961923"
name = "golang.org/x/crypto"
packages = [
"ed25519",
"ed25519/internal/edwards25519",
]
pruneopts = ""
revision = "123391ffb6de907695e1066dc40c1ff09322aeb6"
[[projects]]
digest = "1:ba49944a3238ae8f163c85b6d01d2db51cd5b09807105a3cfaacbd414744ca82"
name = "golang.org/x/mod"
packages = ["semver"]
pruneopts = ""
revision = "859b3ef565e237f9f1a0fb6b55385c497545680d"
version = "v0.3.0"
[[projects]]
branch = "master"
digest = "1:9ee0e6bc20d85d179d19be321443639dc501a8c0ba1bac173261b57768063e79"
name = "golang.org/x/net"
packages = [
"bpf",
"icmp",
"idna",
"internal/iana",
"internal/socket",
"ipv4",
"ipv6",
"publicsuffix",
]
pruneopts = ""
revision = "3edf25e44fccea9e11b919341e952fca722ef460"
[[projects]]
branch = "master"
digest = "1:ae1578a64c2b241c13ab243739d05936d83825d2b6e9ff043ea3c7105666493d"
name = "golang.org/x/sync"
packages = [
"errgroup",
"singleflight",
]
pruneopts = ""
revision = "6e8e738ad208923de99951fe0b48239bfd864f28"
[[projects]]
branch = "master"
digest = "1:ecfcd51736bf55de713770df4580026a43f01a94c9c077b0ab10239e8a93a589"
name = "golang.org/x/sys"
packages = [
"internal/unsafeheader",
"unix",
"windows",
"windows/registry",
"windows/svc",
"windows/svc/debug",
"windows/svc/eventlog",
"windows/svc/mgr",
]
pruneopts = ""
revision = "3ff754bf58a9922e2b8a1a0bd199be6c9a806123"
[[projects]]
digest = "1:fccda34e4c58111b1908d8d69bf8d57c41c8e2542bc18ec8cd38c4fa21057f71"
name = "golang.org/x/text"
packages = [
"collate",
"collate/build",
"internal/colltab",
"internal/gen",
"internal/language",
"internal/language/compact",
"internal/tag",
"internal/triegen",
"internal/ucd",
"language",
"secure/bidirule",
"transform",
"unicode/bidi",
"unicode/cldr",
"unicode/norm",
"unicode/rangetable",
]
pruneopts = ""
revision = "23ae387dee1f90d29a23c0e87ee0b46038fbed0e"
version = "v0.3.3"
[[projects]]
branch = "master"
digest = "1:1f61b0af124800c576e5ccc355d0634413e0b71fe6fbc77694b18bd30d9aa56e"
name = "golang.org/x/tools"
packages = [
"go/ast/astutil",
"go/gcexportdata",
"go/internal/gcimporter",
"go/internal/packagesdriver",
"go/packages",
"go/types/typeutil",
"internal/event",
"internal/event/core",
"internal/event/keys",
"internal/event/label",
"internal/gocommand",
"internal/packagesinternal",
"internal/typesinternal",
]
pruneopts = ""
revision = "d00afeaade8f1e68fb815705aa42d704c1b6df35"
[[projects]]
branch = "master"
digest = "1:a5a7a1a9560c0eb1f8b32c40da2e71bd2a05b9ff9e1ea294461c7dbe0d24c6bc"
name = "golang.org/x/xerrors"
packages = [
".",
"internal",
]
pruneopts = ""
revision = "5ec99f83aff198f5fbd629d6c8d8eb38a04218ca"
[[projects]]
branch = "v3"
digest = "1:2e9c4d6def1d36dcd17730e00c06b49a2e97ea5e1e639bcd24fa60fa43e33ad6"
name = "gopkg.in/yaml.v3"
packages = ["."]
pruneopts = ""
revision = "eeeca48fe7764f320e4870d231902bf9c1be2c08"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
input-imports = [
"github.com/TheTannerRyan/ring",
"github.com/agext/levenshtein",
"github.com/cookieo9/resources-go",
"github.com/coreos/go-iptables/iptables",
"github.com/florianl/go-nfqueue",
"github.com/godbus/dbus",
"github.com/google/gopacket",
"github.com/google/gopacket/layers",
"github.com/google/gopacket/tcpassembly",
"github.com/google/renameio",
"github.com/hashicorp/go-multierror",
"github.com/hashicorp/go-version",
"github.com/miekg/dns",
"github.com/oschwald/maxminddb-golang",
"github.com/shirou/gopsutil/process",
"github.com/spf13/cobra",
"github.com/stretchr/testify/assert",
"github.com/tevino/abool",
"github.com/umahmood/haversine",
"golang.org/x/net/icmp",
"golang.org/x/net/ipv4",
"golang.org/x/net/publicsuffix",
"golang.org/x/sync/errgroup",
"golang.org/x/sync/singleflight",
"golang.org/x/sys/unix",
"golang.org/x/sys/windows",
"golang.org/x/sys/windows/svc",
"golang.org/x/sys/windows/svc/debug",
"golang.org/x/sys/windows/svc/eventlog",
"golang.org/x/sys/windows/svc/mgr",
]
solver-name = "gps-cdcl"
solver-version = 1

View file

@ -1,35 +0,0 @@
# Gopkg.toml example
#
# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
# for detailed Gopkg.toml documentation.
#
# required = ["github.com/user/thing/cmd/thing"]
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
#
# [[constraint]]
# name = "github.com/user/project"
# version = "1.0.0"
#
# [[constraint]]
# name = "github.com/user/project2"
# branch = "dev"
# source = "github.com/myfork/project2"
#
# [[override]]
# name = "github.com/x/y"
# version = "2.4.0"
#
# [prune]
# non-go = false
# go-tests = true
# unused-packages = true
ignored = ["github.com/safing/portbase/*", "github.com/safing/spn/*"]
[[constraint]]
name = "github.com/florianl/go-nfqueue"
branch = "master" # switch back once we migrate to go.mod
[[override]]
name = "github.com/mdlayher/netlink"
version = "1.2.0" # remove when github.com/florianl/go-nfqueue has updated to v1.2.0

0
assets/.gitkeep Normal file
View file

3
cmds/hub/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
# Compiled binaries
hub
hub.exe

60
cmds/hub/build Executable file
View file

@ -0,0 +1,60 @@
#!/bin/bash
# get build data
if [[ "$BUILD_COMMIT" == "" ]]; then
BUILD_COMMIT=$(git describe --all --long --abbrev=99 --dirty 2>/dev/null)
fi
if [[ "$BUILD_USER" == "" ]]; then
BUILD_USER=$(id -un)
fi
if [[ "$BUILD_HOST" == "" ]]; then
BUILD_HOST=$(hostname -f)
fi
if [[ "$BUILD_DATE" == "" ]]; then
BUILD_DATE=$(date +%d.%m.%Y)
fi
if [[ "$BUILD_SOURCE" == "" ]]; then
BUILD_SOURCE=$(git remote -v | grep origin | cut -f2 | cut -d" " -f1 | head -n 1)
fi
if [[ "$BUILD_SOURCE" == "" ]]; then
BUILD_SOURCE=$(git remote -v | cut -f2 | cut -d" " -f1 | head -n 1)
fi
BUILD_BUILDOPTIONS=$(echo $* | sed "s/ /§/g")
# check
if [[ "$BUILD_COMMIT" == "" ]]; then
echo "could not automatically determine BUILD_COMMIT, please supply manually as environment variable."
exit 1
fi
if [[ "$BUILD_USER" == "" ]]; then
echo "could not automatically determine BUILD_USER, please supply manually as environment variable."
exit 1
fi
if [[ "$BUILD_HOST" == "" ]]; then
echo "could not automatically determine BUILD_HOST, please supply manually as environment variable."
exit 1
fi
if [[ "$BUILD_DATE" == "" ]]; then
echo "could not automatically determine BUILD_DATE, please supply manually as environment variable."
exit 1
fi
if [[ "$BUILD_SOURCE" == "" ]]; then
echo "could not automatically determine BUILD_SOURCE, please supply manually as environment variable."
exit 1
fi
# set build options
export CGO_ENABLED=0
if [[ $1 == "dev" ]]; then
shift
export CGO_ENABLED=1
DEV="-race"
fi
echo "Please notice, that this build script includes metadata into the build."
echo "This information is useful for debugging and license compliance."
echo "Run the compiled binary with the -version flag to see the information included."
# build
BUILD_PATH="github.com/safing/portbase/info"
go build $DEV -ldflags "-X ${BUILD_PATH}.commit=${BUILD_COMMIT} -X ${BUILD_PATH}.buildOptions=${BUILD_BUILDOPTIONS} -X ${BUILD_PATH}.buildUser=${BUILD_USER} -X ${BUILD_PATH}.buildHost=${BUILD_HOST} -X ${BUILD_PATH}.buildDate=${BUILD_DATE} -X ${BUILD_PATH}.buildSource=${BUILD_SOURCE}" $*

66
cmds/hub/main.go Normal file
View file

@ -0,0 +1,66 @@
package main
import (
"flag"
"fmt"
"os"
"runtime"
"github.com/safing/portbase/info"
"github.com/safing/portbase/metrics"
"github.com/safing/portbase/modules"
"github.com/safing/portbase/run"
_ "github.com/safing/portmaster/service/core/base"
_ "github.com/safing/portmaster/service/ui"
"github.com/safing/portmaster/service/updates"
"github.com/safing/portmaster/service/updates/helper"
_ "github.com/safing/portmaster/spn/captain"
"github.com/safing/portmaster/spn/conf"
)
func init() {
flag.BoolVar(&updates.RebootOnRestart, "reboot-on-restart", false, "reboot server on auto-upgrade")
}
func main() {
info.Set("SPN Hub", "0.7.6", "AGPLv3", true)
// Configure metrics.
_ = metrics.SetNamespace("hub")
// Configure updating.
updates.UserAgent = fmt.Sprintf("SPN Hub (%s %s)", runtime.GOOS, runtime.GOARCH)
helper.IntelOnly()
// Configure SPN mode.
conf.EnablePublicHub(true)
conf.EnableClient(false)
// Disable module management, as we want to start all modules.
modules.DisableModuleManagement()
// Configure microtask threshold.
// Scale with CPU/GOMAXPROCS count, but keep a baseline and minimum:
// CPUs -> MicroTasks
// 0 -> 8 (increased to minimum)
// 1 -> 8 (increased to minimum)
// 2 -> 8
// 3 -> 10
// 4 -> 12
// 8 -> 20
// 16 -> 36
//
// Start with number of GOMAXPROCS.
microTasksThreshold := runtime.GOMAXPROCS(0) * 2
// Use at least 4 microtasks based on GOMAXPROCS.
if microTasksThreshold < 4 {
microTasksThreshold = 4
}
// Add a 4 microtask baseline.
microTasksThreshold += 4
// Set threshold.
modules.SetMaxConcurrentMicroTasks(microTasksThreshold)
// Start.
os.Exit(run.Run())
}

123
cmds/hub/pack Executable file
View file

@ -0,0 +1,123 @@
#!/bin/bash
baseDir="$( cd "$(dirname "$0")" && pwd )"
cd "$baseDir"
COL_OFF="\033[0m"
COL_BOLD="\033[01;01m"
COL_RED="\033[31m"
COL_GREEN="\033[32m"
COL_YELLOW="\033[33m"
destDirPart1="../../dist"
destDirPart2="hub"
function prep {
# output
output="main"
# get version
version=$(grep "info.Set" main.go | cut -d'"' -f4)
# build versioned file name
filename="spn-hub_v${version//./-}"
# platform
platform="${GOOS}_${GOARCH}"
if [[ $GOOS == "windows" ]]; then
filename="${filename}.exe"
output="${output}.exe"
fi
# build destination path
destPath=${destDirPart1}/${platform}/${destDirPart2}/$filename
}
function check {
prep
# check if file exists
if [[ -f $destPath ]]; then
echo "[hub] $platform v$version already built"
else
echo -e "${COL_BOLD}[hub] $platform v$version${COL_OFF}"
fi
}
function build {
prep
# check if file exists
if [[ -f $destPath ]]; then
echo "[hub] $platform already built in v$version, skipping..."
return
fi
# build
./build main.go
if [[ $? -ne 0 ]]; then
echo -e "\n${COL_BOLD}[hub] $platform v$version: ${COL_RED}BUILD FAILED.${COL_OFF}"
exit 1
fi
mkdir -p $(dirname $destPath)
cp $output $destPath
echo -e "\n${COL_BOLD}[hub] $platform v$version: ${COL_GREEN}successfully built.${COL_OFF}"
}
function reset {
prep
# delete if file exists
if [[ -f $destPath ]]; then
rm $destPath
echo "[hub] $platform v$version deleted."
fi
}
function check_all {
GOOS=linux GOARCH=amd64 check
GOOS=windows GOARCH=amd64 check
GOOS=darwin GOARCH=amd64 check
GOOS=linux GOARCH=arm64 check
GOOS=windows GOARCH=arm64 check
GOOS=darwin GOARCH=arm64 check
}
function build_all {
GOOS=linux GOARCH=amd64 build
GOOS=windows GOARCH=amd64 build
GOOS=darwin GOARCH=amd64 build
GOOS=linux GOARCH=arm64 build
GOOS=windows GOARCH=arm64 build
GOOS=darwin GOARCH=arm64 build
}
function reset_all {
GOOS=linux GOARCH=amd64 reset
GOOS=windows GOARCH=amd64 reset
GOOS=darwin GOARCH=amd64 reset
GOOS=linux GOARCH=arm64 reset
GOOS=windows GOARCH=arm64 reset
GOOS=darwin GOARCH=arm64 reset
}
case $1 in
"check" )
check_all
;;
"build" )
build_all
;;
"reset" )
reset_all
;;
* )
echo ""
echo "build list:"
echo ""
check_all
echo ""
read -p "press [Enter] to start building" x
echo ""
build_all
echo ""
echo "finished building."
echo ""
;;
esac

View file

@ -7,9 +7,9 @@ import (
processInfo "github.com/shirou/gopsutil/process"
"github.com/spf13/cobra"
"github.com/safing/portmaster/network/packet"
"github.com/safing/portmaster/network/socket"
"github.com/safing/portmaster/network/state"
"github.com/safing/portmaster/service/network/packet"
"github.com/safing/portmaster/service/network/socket"
"github.com/safing/portmaster/service/network/state"
)
func init() {

3
cmds/observation-hub/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
# Compiled binaries
observation-hub
observation-hub.exe

View file

@ -0,0 +1,38 @@
# Docker Image for Observation Hub
# Important:
# You need to build this from the repo root!
# Run: docker build -f cmds/observation-hub/Dockerfile -t safing/observation-hub:latest .
# Check With: docker run -ti --rm safing/observation-hub:latest --help
# golang 1.21 linux/amd64 on debian bookworm
# https://github.com/docker-library/golang/blob/master/1.21/bookworm/Dockerfile
FROM golang:1.21-bookworm as builder
# Ensure ca-certficates are up to date
RUN update-ca-certificates
# Install dependencies
WORKDIR $GOPATH/src/github.com/safing/portmaster/spn
COPY go.mod .
COPY go.sum .
ENV GO111MODULE=on
RUN go mod download
RUN go mod verify
# Copy source code
COPY . .
# Build the static binary
RUN cd cmds/observation-hub && \
CGO_ENABLED=0 ./build -o /go/bin/observation-hub
# Use static image
# https://github.com/GoogleContainerTools/distroless
FROM gcr.io/distroless/static-debian12
# Copy our static executable
COPY --from=builder --chmod=0755 /go/bin/observation-hub /go/bin/observation-hub
# Run the observation-hub binary.
ENTRYPOINT ["/go/bin/observation-hub"]

View file

@ -0,0 +1,257 @@
package main
import (
"bytes"
"crypto/tls"
_ "embed"
"errors"
"flag"
"fmt"
"net/http"
"strings"
"text/template"
"time"
"github.com/safing/portbase/apprise"
"github.com/safing/portbase/log"
"github.com/safing/portbase/modules"
"github.com/safing/portmaster/service/intel/geoip"
)
var (
appriseModule *modules.Module
appriseNotifier *apprise.Notifier
appriseURL string
appriseTag string
appriseClientCert string
appriseClientKey string
appriseGreet bool
)
func init() {
appriseModule = modules.Register("apprise", nil, startApprise, nil)
flag.StringVar(&appriseURL, "apprise-url", "", "set the apprise URL to enable notifications via apprise")
flag.StringVar(&appriseTag, "apprise-tag", "", "set the apprise tag(s) according to their docs")
flag.StringVar(&appriseClientCert, "apprise-client-cert", "", "set the apprise client certificate")
flag.StringVar(&appriseClientKey, "apprise-client-key", "", "set the apprise client key")
flag.BoolVar(&appriseGreet, "apprise-greet", false, "send a greeting message to apprise on start")
}
func startApprise() error {
// Check if apprise should be configured.
if appriseURL == "" {
return nil
}
// Check if there is a tag.
if appriseTag == "" {
return errors.New("an apprise tag is required")
}
// Create notifier.
appriseNotifier = &apprise.Notifier{
URL: appriseURL,
DefaultType: apprise.TypeInfo,
DefaultTag: appriseTag,
DefaultFormat: apprise.FormatMarkdown,
AllowUntagged: false,
}
if appriseClientCert != "" || appriseClientKey != "" {
// Load client cert from disk.
cert, err := tls.LoadX509KeyPair(appriseClientCert, appriseClientKey)
if err != nil {
return fmt.Errorf("failed to load client cert/key: %w", err)
}
// Set client cert in http client.
appriseNotifier.SetClient(&http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
MinVersion: tls.VersionTLS12,
Certificates: []tls.Certificate{cert},
},
},
Timeout: 10 * time.Second,
})
}
if appriseGreet {
err := appriseNotifier.Send(appriseModule.Ctx, &apprise.Message{
Title: "👋 Observation Hub Reporting In",
Body: "I am the Observation Hub. I am connected to the SPN and watch out for it. I will report notable changes to the network here.",
})
if err != nil {
log.Warningf("apprise: failed to send test message: %s", err)
} else {
log.Info("apprise: sent greeting message")
}
}
return nil
}
func reportToApprise(change *observedChange) (errs error) {
// Check if configured.
if appriseNotifier == nil {
return nil
}
handleTag:
for _, tag := range strings.Split(appriseNotifier.DefaultTag, ",") {
// Check if we are shutting down.
if appriseModule.IsStopping() {
return nil
}
// Render notification based on tag / destination.
buf := &bytes.Buffer{}
switch {
case strings.HasPrefix(tag, "matrix-"):
if err := templates.ExecuteTemplate(buf, "matrix-notification", change); err != nil {
return fmt.Errorf("failed to render notification: %w", err)
}
case strings.HasPrefix(tag, "discord-"):
if err := templates.ExecuteTemplate(buf, "discord-notification", change); err != nil {
return fmt.Errorf("failed to render notification: %w", err)
}
default:
// Use matrix notification template as default for now.
if err := templates.ExecuteTemplate(buf, "matrix-notification", change); err != nil {
return fmt.Errorf("failed to render notification: %w", err)
}
}
// Send notification to apprise.
var err error
for i := 0; i < 3; i++ {
// Try three times.
err = appriseNotifier.Send(appriseModule.Ctx, &apprise.Message{
Body: buf.String(),
Tag: tag,
})
if err == nil {
continue handleTag
}
// Wait for 5 seconds, then try again.
time.Sleep(5 * time.Second)
}
// Add error to errors.
if err != nil {
errs = errors.Join(errs, fmt.Errorf("| failed to send: %w", err))
}
}
return errs
}
// var (
// entityTemplate = template.Must(template.New("entity").Parse(
// `Entity: {{ . }}
// {{ .IP }} [{{ .ASN }} - {{ .ASOrg }}]
// `,
// ))
// // {{ with .GetCountryInfo -}}
// // {{ .Name }} ({{ .Code }})
// // {{- end }}
// matrixTemplate = template.Must(template.New("matrix observer notification").Parse(
// `{{ .Title }}
// {{ if .Summary }}
// Details:
// {{ .Summary }}
// Note: Changes were registered at {{ .UpdateTime }} and were possibly merged.
// {{ end }}
// {{ template "entity" .UpdatedPin.EntityV4 }}
// Hub Info:
// Test: {{ .UpdatedPin.EntityV4 }}
// {{ template "entity" .UpdatedPin.EntityV4 }}
// {{ template "entity" .UpdatedPin.EntityV6 }}
// `,
// ))
// discordTemplate = template.Must(template.New("discord observer notification").Parse(
// ``,
// ))
// defaultTemplate = template.Must(template.New("default observer notification").Parse(
// ``,
// ))
// )
var (
//go:embed notifications.tmpl
templateFile string
templates = template.Must(template.New("notifications").Funcs(
template.FuncMap{
"joinStrings": joinStrings,
"textBlock": textBlock,
"getCountryInfo": getCountryInfo,
},
).Parse(templateFile))
)
func joinStrings(slice []string, sep string) string {
return strings.Join(slice, sep)
}
func textBlock(block, addPrefix, addSuffix string) string {
// Trim whitespaces.
block = strings.TrimSpace(block)
// Prepend and append string for every line.
lines := strings.Split(block, "\n")
for i, line := range lines {
lines[i] = addPrefix + line + addSuffix
}
// Return as block.
return strings.Join(lines, "\n")
}
func getCountryInfo(code string) geoip.CountryInfo {
// Get the country info directly instead of via the entity location,
// so it also works in test without the geoip module.
return geoip.GetCountryInfo(code)
}
// func init() {
// templates = template.Must(template.New(templateFile).Parse(templateFile))
// nt, err := templates.New("entity").Parse(
// `Entity: {{ . }}
// {{ .IP }} [{{ .ASN }} - {{ .ASOrg }}]
// `,
// )
// if err != nil {
// panic(err)
// }
// templates.AddParseTree(nt.Tree)
// if _, err := templates.New("matrix-notification").Parse(
// `{{ .Title }}
// {{ if .Summary }}
// Details:
// {{ .Summary }}
// Note: Changes were registered at {{ .UpdateTime }} and were possibly merged.
// {{ end }}
// {{ template "entity" .UpdatedPin.EntityV4 }}
// Hub Info:
// Test: {{ .UpdatedPin.EntityV4 }}
// {{ template "entity" .UpdatedPin.EntityV4 }}
// {{ template "entity" .UpdatedPin.EntityV6 }}
// `,
// ); err != nil {
// panic(err)
// }
// }

View file

@ -0,0 +1,84 @@
package main
import (
"bytes"
"fmt"
"net"
"testing"
"time"
"github.com/safing/portmaster/service/intel"
"github.com/safing/portmaster/service/network/netutils"
"github.com/safing/portmaster/spn/hub"
"github.com/safing/portmaster/spn/navigator"
)
var observedTestChange = &observedChange{
Title: "Hub Changed: fogos (8uLe-zUkC)",
Summary: `ConnectedTo.ZwqBAzGqifBAFKFW1GQijNM18pi7BnWH34GyKBF7KB5fC5.HubID removed ZwqBAzGqifBAFKFW1GQijNM18pi7BnWH34GyKBF7KB5fC5
ConnectedTo.ZwqBAzGqifBAFKFW1GQijNM18pi7BnWH34GyKBF7KB5fC5.Capacity removed 3403661
ConnectedTo.ZwqBAzGqifBAFKFW1GQijNM18pi7BnWH34GyKBF7KB5fC5.Latency removed 252.350006ms`,
UpdatedPin: &navigator.PinExport{
ID: "Zwtb8EKMatnMRkW1VaLh8CPV3QswD9iuRU4Sda8uLezUkC",
Name: "fogos",
Map: "main",
FirstSeen: time.Now(),
EntityV4: &intel.Entity{
IP: net.IPv4(138, 201, 140, 70),
IPScope: netutils.Global,
Country: "DE",
ASN: 24940,
ASOrg: "Hetzner Online GmbH",
},
States: []string{"HasRequiredInfo", "Reachable", "Active", "Trusted"},
VerifiedOwner: "Safing",
HopDistance: 3,
SessionActive: false,
Info: &hub.Announcement{
ID: "Zwtb8EKMatnMRkW1VaLh8CPV3QswD9iuRU4Sda8uLezUkC",
Timestamp: 1677682008,
Name: "fogos",
Group: "Safing",
ContactAddress: "abuse@safing.io",
ContactService: "email",
Hosters: []string{"Hetzner"},
Datacenter: "DE-Hetzner-FSN",
IPv4: net.IPv4(138, 201, 140, 70),
IPv6: net.ParseIP("2a01:4f8:172:3753::2"),
Transports: []string{"tcp:17", "tcp:17017"},
Entry: []string{},
Exit: []string{"- * TCP/25"},
},
Status: &hub.Status{
Timestamp: 1694180778,
Version: "0.6.19 ",
},
},
UpdateTime: time.Now(),
}
func TestNotificationTemplate(t *testing.T) {
t.Parallel()
fmt.Println("==========\nFound templates:")
for _, tpl := range templates.Templates() {
fmt.Println(tpl.Name())
}
fmt.Println("")
fmt.Println("\n\n==========\nMatrix template:")
matrixOutput := &bytes.Buffer{}
err := templates.ExecuteTemplate(matrixOutput, "matrix-notification", observedTestChange)
if err != nil {
t.Errorf("failed to render matrix template: %s", err)
}
fmt.Println(matrixOutput.String())
fmt.Println("\n\n==========\nDiscord template:")
discordOutput := &bytes.Buffer{}
err = templates.ExecuteTemplate(discordOutput, "discord-notification", observedTestChange)
if err != nil {
t.Errorf("failed to render discord template: %s", err)
}
fmt.Println(discordOutput.String())
}

60
cmds/observation-hub/build Executable file
View file

@ -0,0 +1,60 @@
#!/bin/bash
# get build data
if [[ "$BUILD_COMMIT" == "" ]]; then
BUILD_COMMIT=$(git describe --all --long --abbrev=99 --dirty 2>/dev/null)
fi
if [[ "$BUILD_USER" == "" ]]; then
BUILD_USER=$(id -un)
fi
if [[ "$BUILD_HOST" == "" ]]; then
BUILD_HOST=$(hostname -f)
fi
if [[ "$BUILD_DATE" == "" ]]; then
BUILD_DATE=$(date +%d.%m.%Y)
fi
if [[ "$BUILD_SOURCE" == "" ]]; then
BUILD_SOURCE=$(git remote -v | grep origin | cut -f2 | cut -d" " -f1 | head -n 1)
fi
if [[ "$BUILD_SOURCE" == "" ]]; then
BUILD_SOURCE=$(git remote -v | cut -f2 | cut -d" " -f1 | head -n 1)
fi
BUILD_BUILDOPTIONS=$(echo $* | sed "s/ /§/g")
# check
if [[ "$BUILD_COMMIT" == "" ]]; then
echo "could not automatically determine BUILD_COMMIT, please supply manually as environment variable."
exit 1
fi
if [[ "$BUILD_USER" == "" ]]; then
echo "could not automatically determine BUILD_USER, please supply manually as environment variable."
exit 1
fi
if [[ "$BUILD_HOST" == "" ]]; then
echo "could not automatically determine BUILD_HOST, please supply manually as environment variable."
exit 1
fi
if [[ "$BUILD_DATE" == "" ]]; then
echo "could not automatically determine BUILD_DATE, please supply manually as environment variable."
exit 1
fi
if [[ "$BUILD_SOURCE" == "" ]]; then
echo "could not automatically determine BUILD_SOURCE, please supply manually as environment variable."
exit 1
fi
# set build options
export CGO_ENABLED=0
if [[ $1 == "dev" ]]; then
shift
export CGO_ENABLED=1
DEV="-race"
fi
echo "Please notice, that this build script includes metadata into the build."
echo "This information is useful for debugging and license compliance."
echo "Run the compiled binary with the -version flag to see the information included."
# build
BUILD_PATH="github.com/safing/portbase/info"
go build $DEV -ldflags "-X ${BUILD_PATH}.commit=${BUILD_COMMIT} -X ${BUILD_PATH}.buildOptions=${BUILD_BUILDOPTIONS} -X ${BUILD_PATH}.buildUser=${BUILD_USER} -X ${BUILD_PATH}.buildHost=${BUILD_HOST} -X ${BUILD_PATH}.buildDate=${BUILD_DATE} -X ${BUILD_PATH}.buildSource=${BUILD_SOURCE}" $*

View file

@ -0,0 +1,44 @@
package main
import (
"fmt"
"os"
"runtime"
"github.com/safing/portbase/api"
"github.com/safing/portbase/info"
"github.com/safing/portbase/metrics"
"github.com/safing/portbase/modules"
"github.com/safing/portbase/run"
"github.com/safing/portmaster/service/updates"
"github.com/safing/portmaster/service/updates/helper"
"github.com/safing/portmaster/spn/captain"
"github.com/safing/portmaster/spn/conf"
"github.com/safing/portmaster/spn/sluice"
)
func main() {
info.Set("SPN Observation Hub", "0.7.1", "AGPLv3", true)
// Configure metrics.
_ = metrics.SetNamespace("observer")
// Configure user agent.
updates.UserAgent = fmt.Sprintf("SPN Observation Hub (%s %s)", runtime.GOOS, runtime.GOARCH)
helper.IntelOnly()
// Configure SPN mode.
conf.EnableClient(true)
conf.EnablePublicHub(false)
captain.DisableAccount = true
// Disable unneeded listeners.
sluice.EnableListener = false
api.EnableServer = false
// Disable module management, as we want to start all modules.
modules.DisableModuleManagement()
// Start.
os.Exit(run.Run())
}

View file

@ -0,0 +1,75 @@
{{ define "entity" -}}
{{ .IP }} [AS{{ .ASN }} - {{ .ASOrg }}] in {{ if .Country }}
{{- with getCountryInfo .Country -}}
{{ .Name }} ({{ .Code }}; Region {{ .Continent.Region }})
{{- end }}
{{- end }}
{{- end }}
{{ define "matrix-notification" -}}
### 🌍 {{ .Title }}{{ if .Summary }}
{{ textBlock .Summary "" " " }}
{{ end }}
> Note: Changes were registered at {{ .UpdateTime.UTC.Format "15:04:05 02.01.2006 MST" }} and were possibly merged.
##### Hub Info
> Name: {{ .UpdatedPin.Name }}
> ID: {{ .UpdatedPin.ID }}
> IPv4: {{ if .UpdatedPin.EntityV4 }}{{ template "entity" .UpdatedPin.EntityV4 }}{{ end }}
> IPv6: {{ if .UpdatedPin.EntityV6 }}{{ template "entity" .UpdatedPin.EntityV6 }}{{ end }}
> Version: {{ .UpdatedPin.Status.Version }}
> States: {{ joinStrings .UpdatedPin.States ", " }}
> Status: {{ len .UpdatedPin.Status.Lanes }} Lanes, {{ len .UpdatedPin.Status.Keys }} Keys, {{ .UpdatedPin.Status.Load }} Load
> Verified Owner: {{ .UpdatedPin.VerifiedOwner }}
> Transports: {{ joinStrings .UpdatedPin.Info.Transports ", " }}
> Entry: {{ joinStrings .UpdatedPin.Info.Entry ", " }}
> Exit: {{ joinStrings .UpdatedPin.Info.Exit ", " }}
> Relations: {{ if .UpdatedPin.Info.Group -}}
Group={{ .UpdatedPin.Info.Group }} {{ end }}
{{- if .UpdatedPin.Info.Datacenter -}}
Datacenter={{ .UpdatedPin.Info.Datacenter }} {{ end }}
{{- if .UpdatedPin.Info.Hosters -}}
Hosters={{ joinStrings .UpdatedPin.Info.Hosters ";" }} {{ end }}
{{- if .UpdatedPin.Info.ContactAddress -}}
Contact= {{ .UpdatedPin.Info.ContactAddress }}{{ if .UpdatedPin.Info.ContactService }} via {{ .UpdatedPin.Info.ContactService }}{{ end }}{{ end }}
{{- end }}
{{ define "discord-notification" -}}
# 🌍 {{ .Title }}{{ if .Summary }}
{{ .Summary }}
{{- end }}
##### Note: Changes were registered at {{ .UpdateTime.UTC.Format "15:04:05 02.01.2006 MST" }} and were possibly merged. - Hub Info:
Name: {{ .UpdatedPin.Name }}
ID: {{ .UpdatedPin.ID }}
IPv4: {{ if .UpdatedPin.EntityV4 }}{{ template "entity" .UpdatedPin.EntityV4 }}{{ end }}
IPv6: {{ if .UpdatedPin.EntityV6 }}{{ template "entity" .UpdatedPin.EntityV6 }}{{ end }}
Version: {{ .UpdatedPin.Status.Version }}
States: {{ joinStrings .UpdatedPin.States ", " }}
Status: {{ len .UpdatedPin.Status.Lanes }} Lanes, {{ len .UpdatedPin.Status.Keys }} Keys, {{ .UpdatedPin.Status.Load }} Load
Verified Owner: {{ .UpdatedPin.VerifiedOwner }}
Transports: {{ joinStrings .UpdatedPin.Info.Transports ", " }}
Entry: {{ joinStrings .UpdatedPin.Info.Entry ", " }}
Exit: {{ joinStrings .UpdatedPin.Info.Exit ", " }}
Relations: {{ if .UpdatedPin.Info.Group -}}
Group={{ .UpdatedPin.Info.Group }} {{ end }}
{{- if .UpdatedPin.Info.Datacenter -}}
Datacenter={{ .UpdatedPin.Info.Datacenter }} {{ end }}
{{- if .UpdatedPin.Info.Hosters -}}
Hosters={{ joinStrings .UpdatedPin.Info.Hosters ";" }} {{ end }}
{{- if .UpdatedPin.Info.ContactAddress -}}
Contact= {{ .UpdatedPin.Info.ContactAddress }}{{ if .UpdatedPin.Info.ContactService }} via {{ .UpdatedPin.Info.ContactService }}{{ end }}{{ end }}
{{- end }}

View file

@ -0,0 +1,407 @@
package main
import (
"context"
"errors"
"flag"
"fmt"
"path"
"strings"
"time"
diff "github.com/r3labs/diff/v3"
"golang.org/x/exp/slices"
"github.com/safing/portbase/database"
"github.com/safing/portbase/database/query"
"github.com/safing/portbase/log"
"github.com/safing/portbase/modules"
"github.com/safing/portmaster/spn/captain"
"github.com/safing/portmaster/spn/navigator"
)
var (
observerModule *modules.Module
db = database.NewInterface(&database.Options{
Local: true,
Internal: true,
})
reportAllChanges bool
errNoChanges = errors.New("no changes")
reportingDelayFlag string
reportingDelay = 10 * time.Minute
)
func init() {
observerModule = modules.Register("observer", prepObserver, startObserver, nil, "captain", "apprise")
flag.BoolVar(&reportAllChanges, "report-all-changes", false, "report all changes, no just interesting ones")
flag.StringVar(&reportingDelayFlag, "reporting-delay", "10m", "delay reports to summarize changes")
}
func prepObserver() error {
if reportingDelayFlag != "" {
duration, err := time.ParseDuration(reportingDelayFlag)
if err != nil {
return fmt.Errorf("failed to parse reporting-delay: %w", err)
}
reportingDelay = duration
}
return nil
}
func startObserver() error {
observerModule.StartServiceWorker("observer", 0, observerWorker)
return nil
}
type observedPin struct {
previous *navigator.PinExport
latest *navigator.PinExport
lastUpdate time.Time
lastUpdateReported bool
}
type observedChange struct {
Title string
Summary string
UpdatedPin *navigator.PinExport
UpdateTime time.Time
SPNStatus *captain.SPNStatus
}
func observerWorker(ctx context.Context) error {
log.Info("observer: starting")
defer log.Info("observer: stopped")
// Subscribe to SPN status.
statusSub, err := db.Subscribe(query.New("runtime:spn/status"))
if err != nil {
return fmt.Errorf("failed to subscribe to spn status: %w", err)
}
defer statusSub.Cancel() //nolint:errcheck
// Get latest status.
latestStatus := captain.GetSPNStatus()
// Step 1: Wait for SPN to connect, if needed.
if latestStatus.Status != captain.StatusConnected {
log.Info("observer: waiting for SPN to connect")
waitForConnect:
for {
select {
case r := <-statusSub.Feed:
if r == nil {
return errors.New("status feed ended")
}
statusUpdate, ok := r.(*captain.SPNStatus)
switch {
case !ok:
log.Warningf("observer: received invalid SPN status: %s", r)
case statusUpdate.Status == captain.StatusFailed:
log.Warningf("observer: SPN failed to connect")
case statusUpdate.Status == captain.StatusConnected:
break waitForConnect
}
case <-ctx.Done():
return nil
}
}
}
// Wait for one second for the navigator to settle things.
log.Info("observer: connected to network, waiting for navigator")
time.Sleep(1 * time.Second)
// Step 2: Get current state.
mapQuery := query.New("map:main/")
q, err := db.Query(mapQuery)
if err != nil {
return fmt.Errorf("failed to start map query: %w", err)
}
defer q.Cancel()
// Put all current pins in a map.
observedPins := make(map[string]*observedPin)
query:
for {
select {
case r := <-q.Next:
// Check if we are done.
if r == nil {
break query
}
// Add all pins to seen pins.
if pin, ok := r.(*navigator.PinExport); ok {
observedPins[pin.ID] = &observedPin{
previous: pin,
latest: pin,
}
} else {
log.Warningf("observer: received invalid pin export: %s", r)
}
case <-ctx.Done():
return nil
}
}
if q.Err() != nil {
return fmt.Errorf("failed to finish map query: %w", q.Err())
}
// Step 3: Monitor for changes.
sub, err := db.Subscribe(mapQuery)
if err != nil {
return fmt.Errorf("failed to start map sub: %w", err)
}
defer sub.Cancel() //nolint:errcheck
// Start ticker for checking for changes.
reportChangesTicker := time.NewTicker(10 * time.Second)
defer reportChangesTicker.Stop()
log.Info("observer: listening for hub changes")
for {
select {
case <-ctx.Done():
return nil
case r := <-statusSub.Feed:
// Keep SPN connection status up to date.
if r == nil {
return errors.New("status feed ended")
}
if statusUpdate, ok := r.(*captain.SPNStatus); ok {
latestStatus = statusUpdate
log.Infof("observer: SPN status is now %s", statusUpdate.Status)
} else {
log.Warningf("observer: received invalid pin export: %s", r)
}
case r := <-sub.Feed:
// Save all observed pins.
switch {
case r == nil:
return errors.New("pin feed ended")
case r.Meta().IsDeleted():
delete(observedPins, path.Base(r.DatabaseKey()))
default:
if pin, ok := r.(*navigator.PinExport); ok {
existingObservedPin, ok := observedPins[pin.ID]
if ok {
// Update previously observed Hub.
existingObservedPin.latest = pin
existingObservedPin.lastUpdate = time.Now()
existingObservedPin.lastUpdateReported = false
} else {
// Add new Hub.
observedPins[pin.ID] = &observedPin{
latest: pin,
lastUpdate: time.Now(),
}
}
} else {
log.Warningf("observer: received invalid pin export: %s", r)
}
}
case <-reportChangesTicker.C:
// Report changed pins.
for _, observedPin := range observedPins {
// Check if context was canceled.
select {
case <-ctx.Done():
return nil
default:
}
switch {
case observedPin.lastUpdateReported:
// Change already reported.
case time.Since(observedPin.lastUpdate) < reportingDelay:
// Only report changes if older than the configured delay.
default:
// Format and report.
title, changes, err := formatPinChanges(observedPin.previous, observedPin.latest)
if err != nil {
if !errors.Is(err, errNoChanges) {
log.Warningf("observer: failed to format pin changes: %s", err)
}
} else {
// Report changes.
reportChanges(&observedChange{
Title: title,
Summary: changes,
UpdatedPin: observedPin.latest,
UpdateTime: observedPin.lastUpdate,
SPNStatus: latestStatus,
})
}
// Update observed pin.
observedPin.previous = observedPin.latest
observedPin.lastUpdateReported = true
}
}
}
}
}
func reportChanges(change *observedChange) {
// Log changes.
log.Infof("observer:\n%s\n%s", change.Title, change.Summary)
// Report via Apprise.
err := reportToApprise(change)
if err != nil {
log.Warningf("observer: failed to report changes to apprise: %s", err)
}
}
var (
ignoreChangesIn = []string{
"ConnectedTo",
"HopDistance",
"Info.entryPolicy", // Alternatively, ignore "Info.Entry"
"Info.exitPolicy", // Alternatively, ignore "Info.Exit"
"Info.parsedTransports",
"Info.Timestamp",
"SessionActive",
"Status.Keys",
"Status.Lanes",
"Status.Load",
"Status.Timestamp",
}
ignoreStates = []string{
"IsHomeHub",
"Failing",
}
)
func ignoreChange(path string) bool {
if reportAllChanges {
return false
}
for _, pathPrefix := range ignoreChangesIn {
if strings.HasPrefix(path, pathPrefix) {
return true
}
}
return false
}
func formatPinChanges(from, to *navigator.PinExport) (title, changes string, err error) {
// Return immediately if pin is new.
if from == nil {
return fmt.Sprintf("New Hub: %s", makeHubName(to.Name, to.ID)), "", nil
}
// Find notable changes.
changelog, err := diff.Diff(from, to)
if err != nil {
return "", "", fmt.Errorf("failed to diff: %w", err)
}
if len(changelog) > 0 {
// Build changelog message.
changes := make([]string, 0, len(changelog))
for _, change := range changelog {
// Create path to changed field.
fullPath := strings.Join(change.Path, ".")
// Check if this path should be ignored.
if ignoreChange(fullPath) {
continue
}
// Add to reportable changes.
changeMsg := formatChange(change, fullPath)
if changeMsg != "" {
changes = append(changes, changeMsg)
}
}
// Log the changes, if there are any left.
if len(changes) > 0 {
return fmt.Sprintf("Hub Changed: %s", makeHubName(to.Name, to.ID)),
strings.Join(changes, "\n"),
nil
}
}
return "", "", errNoChanges
}
func formatChange(change diff.Change, fullPath string) string {
switch {
case strings.HasPrefix(fullPath, "States"):
switch change.Type {
case diff.CREATE:
return formatState(fmt.Sprintf("%v", change.To), true)
case diff.UPDATE:
a := formatState(fmt.Sprintf("%v", change.To), true)
b := formatState(fmt.Sprintf("%v", change.From), false)
switch {
case a != "" && b != "":
return a + "\n" + b
case a != "":
return a
case b != "":
return b
}
case diff.DELETE:
return formatState(fmt.Sprintf("%v", change.From), false)
}
default:
switch change.Type {
case diff.CREATE:
return fmt.Sprintf("%s added %v", fullPath, change.To)
case diff.UPDATE:
return fmt.Sprintf("%s changed from %v to %v", fullPath, change.From, change.To)
case diff.DELETE:
return fmt.Sprintf("%s removed %v", fullPath, change.From)
}
}
return ""
}
func formatState(name string, isSet bool) string {
// Check if state should be ignored.
if !reportAllChanges && slices.Contains[[]string, string](ignoreStates, name) {
return ""
}
if isSet {
return fmt.Sprintf("State is %v", name)
}
return fmt.Sprintf("State is NOT %v", name)
}
func makeHubName(name, id string) string {
shortenedID := id[len(id)-8:len(id)-4] +
"-" +
id[len(id)-4:]
// Be more careful, as the Hub name is user input.
switch {
case name == "":
return shortenedID
case len(name) > 16:
return fmt.Sprintf("%s (%s)", name[:16], shortenedID)
default:
return fmt.Sprintf("%s (%s)", name, shortenedID)
}
}

View file

@ -10,16 +10,16 @@ import (
"github.com/safing/portbase/log"
"github.com/safing/portbase/metrics"
"github.com/safing/portbase/run"
"github.com/safing/portmaster/updates"
"github.com/safing/spn/conf"
"github.com/safing/portmaster/service/updates"
"github.com/safing/portmaster/spn/conf"
// Include packages here.
_ "github.com/safing/portbase/modules/subsystems"
_ "github.com/safing/portmaster/core"
_ "github.com/safing/portmaster/firewall"
_ "github.com/safing/portmaster/nameserver"
_ "github.com/safing/portmaster/ui"
_ "github.com/safing/spn/captain"
_ "github.com/safing/portmaster/service/core"
_ "github.com/safing/portmaster/service/firewall"
_ "github.com/safing/portmaster/service/nameserver"
_ "github.com/safing/portmaster/service/ui"
_ "github.com/safing/portmaster/spn/captain"
)
func main() {

View file

@ -20,7 +20,7 @@ import (
portlog "github.com/safing/portbase/log"
"github.com/safing/portbase/updater"
"github.com/safing/portbase/utils"
"github.com/safing/portmaster/updates/helper"
"github.com/safing/portmaster/service/updates/helper"
)
var (

View file

@ -9,7 +9,7 @@ import (
"github.com/hashicorp/go-multierror"
"github.com/spf13/cobra"
"github.com/safing/portmaster/firewall/interception"
"github.com/safing/portmaster/service/firewall/interception"
)
var recoverIPTablesCmd = &cobra.Command{

View file

@ -16,7 +16,7 @@ import (
"github.com/spf13/cobra"
"github.com/tevino/abool"
"github.com/safing/portmaster/updates/helper"
"github.com/safing/portmaster/service/updates/helper"
)
const (

View file

@ -6,7 +6,7 @@ import (
"github.com/spf13/cobra"
"github.com/safing/portmaster/updates/helper"
"github.com/safing/portmaster/service/updates/helper"
)
func init() {

View file

@ -10,7 +10,7 @@ import (
portlog "github.com/safing/portbase/log"
"github.com/safing/portbase/updater"
"github.com/safing/portmaster/updates/helper"
"github.com/safing/portmaster/service/updates/helper"
)
var (

View file

@ -15,7 +15,7 @@ import (
"github.com/safing/jess/filesig"
portlog "github.com/safing/portbase/log"
"github.com/safing/portbase/updater"
"github.com/safing/portmaster/updates/helper"
"github.com/safing/portmaster/service/updates/helper"
)
var (

3
cmds/testsuite/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
# Compiled binaries
testsuite
testsuite.exe

33
cmds/testsuite/db.go Normal file
View file

@ -0,0 +1,33 @@
package main
import (
"github.com/safing/portbase/database"
_ "github.com/safing/portbase/database/storage/hashmap"
)
func setupDatabases(path string) error {
err := database.InitializeWithPath(path)
if err != nil {
return err
}
_, err = database.Register(&database.Database{
Name: "core",
Description: "Holds core data, such as settings and profiles",
StorageType: "hashmap",
})
if err != nil {
return err
}
_, err = database.Register(&database.Database{
Name: "cache",
Description: "Cached data, such as Intelligence and DNS Records",
StorageType: "hashmap",
})
if err != nil {
return err
}
return nil
}

125
cmds/testsuite/login.go Normal file
View file

@ -0,0 +1,125 @@
package main
import (
"errors"
"fmt"
"log"
"github.com/spf13/cobra"
"github.com/safing/portmaster/spn/access"
"github.com/safing/portmaster/spn/access/account"
)
var (
loginCmd = &cobra.Command{
Use: "login",
Short: "Test login and token issuing",
RunE: runTestCommand(testLogin),
}
loginUsername string
loginPassword string
loginDeviceID string
)
func init() {
rootCmd.AddCommand(loginCmd)
// Add flags for login options.
flags := loginCmd.Flags()
flags.StringVar(&loginUsername, "username", "", "set username to use for the login test")
flags.StringVar(&loginPassword, "password", "", "set password to use for the login test")
flags.StringVar(&loginDeviceID, "device-id", "", "set device ID to use for the login test")
// Mark all as required.
_ = loginCmd.MarkFlagRequired("username")
_ = loginCmd.MarkFlagRequired("password")
_ = loginCmd.MarkFlagRequired("device-id")
}
func testLogin(cmd *cobra.Command, args []string) (err error) {
// Init token zones.
err = access.InitializeZones()
if err != nil {
return fmt.Errorf("failed to initialize token zones: %w", err)
}
// Set initial user object in order to set the device ID that should be used for login.
initialUser := &access.UserRecord{
User: &account.User{
Username: loginUsername,
Device: &account.Device{
ID: loginDeviceID,
},
},
}
err = initialUser.Save()
if err != nil {
return fmt.Errorf("failed to save initial user with device ID: %w", err)
}
// Login.
_, _, err = access.Login(loginUsername, loginPassword)
if err != nil {
return fmt.Errorf("login failed: %w", err)
}
// Check user.
user, err := access.GetUser()
if err != nil {
return fmt.Errorf("failed to get user after login: %w", err)
}
if verbose {
log.Printf("user (from login): %+v", user.User)
log.Printf("device (from login): %+v", user.User.Device)
}
// Check if the device ID is unchanged.
if user.Device.ID != loginDeviceID {
return errors.New("device ID changed")
}
// Check Auth Token.
authToken, err := access.GetAuthToken()
if err != nil {
return fmt.Errorf("failed to get auth token after login: %w", err)
}
if verbose {
log.Printf("auth token (from login): %+v", authToken.Token)
}
firstAuthToken := authToken.Token.Token
// Update User.
_, _, err = access.UpdateUser()
if err != nil {
return fmt.Errorf("failed to update user: %w", err)
}
// Check if we received a new Auth Token.
authToken, err = access.GetAuthToken()
if err != nil {
return fmt.Errorf("failed to get auth token after user update: %w", err)
}
if verbose {
log.Printf("auth token (from update): %+v", authToken.Token)
}
if authToken.Token.Token == firstAuthToken {
return errors.New("auth token did not change after update")
}
// Get Tokens.
err = access.UpdateTokens()
if err != nil {
return fmt.Errorf("failed to update tokens: %w", err)
}
regular, fallback := access.GetTokenAmount(access.ExpandAndConnectZones)
if verbose {
log.Printf("received tokens: %d regular, %d fallback", regular, fallback)
}
if regular == 0 || fallback == 0 {
return fmt.Errorf("not enough tokens after fetching: %d regular, %d fallback", regular, fallback)
}
return nil
}

69
cmds/testsuite/main.go Normal file
View file

@ -0,0 +1,69 @@
package main
import (
"fmt"
"log"
"os"
"github.com/spf13/cobra"
)
var (
rootCmd = &cobra.Command{
Use: "testsuite",
Short: "An integration and end-to-end test tool for the SPN",
}
verbose bool
)
func runTestCommand(cmdFunc func(cmd *cobra.Command, args []string) error) func(cmd *cobra.Command, args []string) error {
return func(cmd *cobra.Command, args []string) error {
// Setup
dbDir, err := os.MkdirTemp("", "spn-testsuite-")
if err != nil {
makeReports(cmd, fmt.Errorf("internal test error: failed to setup datbases: %w", err))
return err
}
if err = setupDatabases(dbDir); err != nil {
makeReports(cmd, fmt.Errorf("internal test error: failed to setup datbases: %w", err))
return err
}
// Run Test
err = cmdFunc(cmd, args)
if err != nil {
log.Printf("test failed: %s", err)
}
// Report
makeReports(cmd, err)
// Cleanup and return more important error.
cleanUpErr := os.RemoveAll(dbDir)
if cleanUpErr != nil {
// Only log if the test failed, so we can return the more important error
if err == nil {
return cleanUpErr
}
log.Printf("cleanup failed: %s", err)
}
return err
}
}
func makeReports(cmd *cobra.Command, err error) {
reportToHealthCheckIfEnabled(cmd, err)
}
func init() {
flags := rootCmd.PersistentFlags()
flags.BoolVarP(&verbose, "verbose", "v", false, "enable verbose logging")
}
func main() {
if err := rootCmd.Execute(); err != nil {
os.Exit(1)
}
}

View file

@ -0,0 +1,51 @@
package main
import (
"log"
"net/http"
"strings"
"github.com/spf13/cobra"
)
var healthCheckReportURL string
func init() {
flags := rootCmd.PersistentFlags()
flags.StringVar(&healthCheckReportURL, "report-to-healthcheck", "", "report to the given healthchecks URL")
}
func reportToHealthCheckIfEnabled(_ *cobra.Command, failureErr error) {
if healthCheckReportURL == "" {
return
}
if failureErr != nil {
// Report failure.
resp, err := http.Post(
healthCheckReportURL+"/fail",
"text/plain; utf-8",
strings.NewReader(failureErr.Error()),
)
if err != nil {
log.Printf("failed to report failure to healthcheck at %q: %s", healthCheckReportURL, err)
return
}
_ = resp.Body.Close()
// Always log that we've report the error.
log.Printf("reported failure to healthcheck at %q", healthCheckReportURL)
} else {
// Report success.
resp, err := http.Get(healthCheckReportURL) //nolint:gosec
if err != nil {
log.Printf("failed to report success to healthcheck at %q: %s", healthCheckReportURL, err)
return
}
_ = resp.Body.Close()
if verbose {
log.Printf("reported success to healthcheck at %q", healthCheckReportURL)
}
}
}

View file

@ -1,3 +1,4 @@
//go:build windows
// +build windows
package main
@ -11,8 +12,8 @@ import (
"syscall"
"github.com/safing/portbase/log"
"github.com/safing/portmaster/firewall/interception/windowskext"
"github.com/safing/portmaster/network/packet"
"github.com/safing/portmaster/service/firewall/interception/windowskext"
"github.com/safing/portmaster/service/network/packet"
)
var (

0
desktop/angular/.gitkeep Normal file
View file

0
desktop/tauri/.gitkeep Normal file
View file

9
go.mod
View file

@ -10,6 +10,7 @@ replace github.com/tc-hib/winres => github.com/dhaavi/winres v0.2.2
require (
github.com/Xuanwo/go-locale v1.1.0
github.com/agext/levenshtein v1.2.3
github.com/awalterschulze/gographviz v2.0.3+incompatible
github.com/cilium/ebpf v0.12.3
github.com/coreos/go-iptables v0.7.0
github.com/florianl/go-conntrack v0.4.0
@ -25,11 +26,13 @@ require (
github.com/mat/besticon v3.12.0+incompatible
github.com/miekg/dns v1.1.57
github.com/mitchellh/go-server-timing v1.0.1
github.com/mr-tron/base58 v1.2.0
github.com/oschwald/maxminddb-golang v1.12.0
github.com/r3labs/diff/v3 v3.0.1
github.com/rot256/pblind v0.0.0-20231024115251-cd3f239f28c1
github.com/safing/jess v0.3.3
github.com/safing/portbase v0.18.9
github.com/safing/portmaster-android/go v0.0.0-20230830120134-3226ceac3bec
github.com/safing/spn v0.7.5
github.com/shirou/gopsutil v3.21.11+incompatible
github.com/spf13/cobra v1.8.0
github.com/spkg/zipfs v0.7.1
@ -53,8 +56,8 @@ require (
github.com/aead/serpent v0.0.0-20160714141033-fba169763ea6 // indirect
github.com/alessio/shellescape v1.4.2 // indirect
github.com/armon/go-radix v1.0.0 // indirect
github.com/awalterschulze/gographviz v2.0.3+incompatible // indirect
github.com/bluele/gcache v0.0.2 // indirect
github.com/brianvoe/gofakeit v3.18.0+incompatible // indirect
github.com/danieljoos/wincred v1.2.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
@ -79,12 +82,10 @@ require (
github.com/mdlayher/socket v0.5.0 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/mr-tron/base58 v1.2.0 // indirect
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rot256/pblind v0.0.0-20231024115251-cd3f239f28c1 // indirect
github.com/satori/go.uuid v1.2.0 // indirect
github.com/seehuhn/fortuna v1.0.1 // indirect
github.com/seehuhn/sha256d v1.0.0 // indirect

4
go.sum
View file

@ -203,6 +203,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/r3labs/diff/v3 v3.0.1 h1:CBKqf3XmNRHXKmdU7mZP1w7TV0pDyVCis1AUHtA4Xtg=
github.com/r3labs/diff/v3 v3.0.1/go.mod h1:f1S9bourRbiM66NskseyUdo0fTmEE0qKrikYJX63dgo=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
@ -246,6 +248,7 @@ github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
@ -275,6 +278,7 @@ github.com/valyala/histogram v1.2.0 h1:wyYGAZZt3CpwUiIb9AU/Zbllg1llXyrtApRS815OL
github.com/valyala/histogram v1.2.0/go.mod h1:Hb4kBwb4UxsaNbbbh+RRz8ZR6pdodR57tzWUS3BUzXY=
github.com/vincent-petithory/dataurl v1.0.0 h1:cXw+kPto8NLuJtlMsI152irrVw9fRDX8AbShPRpg2CI=
github.com/vincent-petithory/dataurl v1.0.0/go.mod h1:FHafX5vmDzyP+1CQATJn7WFKc9CvnvxyvZy6I1MrG/U=
github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=

3
pack
View file

@ -24,16 +24,19 @@ function safe_execute {
function check {
./cmds/portmaster-core/pack check
./cmds/portmaster-start/pack check
./cmds/hub/pack check
}
function build {
safe_execute ./cmds/portmaster-core/pack build
safe_execute ./cmds/portmaster-start/pack build
safe_execute ./cmds/hub/pack build
}
function reset {
./cmds/portmaster-core/pack reset
./cmds/portmaster-start/pack reset
./cmds/hub/pack resset
}
case $1 in

0
packaging/linux/.gitkeep Normal file
View file

View file

1
runtime/.gitkeep Normal file
View file

@ -0,0 +1 @@
The new portbase should land here.

View file

@ -5,12 +5,12 @@ import (
"time"
"github.com/safing/portbase/config"
"github.com/safing/portmaster/intel/geoip"
"github.com/safing/portmaster/netenv"
"github.com/safing/portmaster/updates"
"github.com/safing/spn/access"
"github.com/safing/spn/access/account"
"github.com/safing/spn/captain"
"github.com/safing/portmaster/service/intel/geoip"
"github.com/safing/portmaster/service/netenv"
"github.com/safing/portmaster/service/updates"
"github.com/safing/portmaster/spn/access"
"github.com/safing/portmaster/spn/access/account"
"github.com/safing/portmaster/spn/captain"
)
var portmasterStarted = time.Now()

View file

@ -18,7 +18,7 @@ import (
"github.com/safing/portbase/log"
"github.com/safing/portbase/modules"
"github.com/safing/portbase/notifications"
"github.com/safing/portmaster/updates"
"github.com/safing/portmaster/service/updates"
)
const (

View file

@ -3,8 +3,8 @@ package compat
import (
"net"
"github.com/safing/portmaster/network/packet"
"github.com/safing/portmaster/process"
"github.com/safing/portmaster/service/network/packet"
"github.com/safing/portmaster/service/process"
)
// SubmitSystemIntegrationCheckPacket submit a packet for the system integrity check.

View file

@ -9,8 +9,8 @@ import (
"github.com/safing/portbase/log"
"github.com/safing/portbase/modules"
"github.com/safing/portmaster/netenv"
"github.com/safing/portmaster/resolver"
"github.com/safing/portmaster/service/netenv"
"github.com/safing/portmaster/service/resolver"
)
var (

View file

@ -12,8 +12,8 @@ import (
"github.com/safing/portbase/log"
"github.com/safing/portbase/modules"
"github.com/safing/portbase/notifications"
"github.com/safing/portmaster/process"
"github.com/safing/portmaster/profile"
"github.com/safing/portmaster/service/process"
"github.com/safing/portmaster/service/profile"
)
type baseIssue struct {

View file

@ -12,9 +12,9 @@ import (
"github.com/safing/portbase/log"
"github.com/safing/portbase/rng"
"github.com/safing/portmaster/netenv"
"github.com/safing/portmaster/network/packet"
"github.com/safing/portmaster/resolver"
"github.com/safing/portmaster/service/netenv"
"github.com/safing/portmaster/service/network/packet"
"github.com/safing/portmaster/service/resolver"
)
var (

View file

@ -15,12 +15,12 @@ import (
"github.com/safing/portbase/notifications"
"github.com/safing/portbase/rng"
"github.com/safing/portbase/utils/debug"
"github.com/safing/portmaster/compat"
"github.com/safing/portmaster/process"
"github.com/safing/portmaster/resolver"
"github.com/safing/portmaster/status"
"github.com/safing/portmaster/updates"
"github.com/safing/spn/captain"
"github.com/safing/portmaster/service/compat"
"github.com/safing/portmaster/service/process"
"github.com/safing/portmaster/service/resolver"
"github.com/safing/portmaster/service/status"
"github.com/safing/portmaster/service/updates"
"github.com/safing/portmaster/spn/captain"
)
func registerAPIEndpoints() error {

View file

@ -9,13 +9,13 @@ import (
"github.com/safing/portbase/metrics"
"github.com/safing/portbase/modules"
"github.com/safing/portbase/modules/subsystems"
_ "github.com/safing/portmaster/broadcasts"
_ "github.com/safing/portmaster/netenv"
_ "github.com/safing/portmaster/netquery"
_ "github.com/safing/portmaster/status"
_ "github.com/safing/portmaster/sync"
_ "github.com/safing/portmaster/ui"
"github.com/safing/portmaster/updates"
_ "github.com/safing/portmaster/service/broadcasts"
_ "github.com/safing/portmaster/service/netenv"
_ "github.com/safing/portmaster/service/netquery"
_ "github.com/safing/portmaster/service/status"
_ "github.com/safing/portmaster/service/sync"
_ "github.com/safing/portmaster/service/ui"
"github.com/safing/portmaster/service/updates"
)
const (

View file

@ -7,7 +7,7 @@
// import (
// "testing"
//
// "github.com/safing/portmaster/core/pmtesting"
// "github.com/safing/portmaster/service/core/pmtesting"
// )
//
// func TestMain(m *testing.M) {
@ -27,7 +27,7 @@ import (
"github.com/safing/portbase/dataroot"
"github.com/safing/portbase/log"
"github.com/safing/portbase/modules"
"github.com/safing/portmaster/core/base"
"github.com/safing/portmaster/service/core/base"
)
var printStackOnExit bool

View file

@ -13,11 +13,11 @@ import (
"github.com/safing/portbase/dataroot"
"github.com/safing/portbase/log"
"github.com/safing/portbase/utils"
"github.com/safing/portmaster/netenv"
"github.com/safing/portmaster/network/netutils"
"github.com/safing/portmaster/network/packet"
"github.com/safing/portmaster/process"
"github.com/safing/portmaster/updates"
"github.com/safing/portmaster/service/netenv"
"github.com/safing/portmaster/service/network/netutils"
"github.com/safing/portmaster/service/network/packet"
"github.com/safing/portmaster/service/process"
"github.com/safing/portmaster/service/updates"
)
const (

View file

@ -4,11 +4,11 @@ import (
"context"
"strings"
"github.com/safing/portmaster/compat"
"github.com/safing/portmaster/nameserver/nsutil"
"github.com/safing/portmaster/network"
"github.com/safing/portmaster/network/packet"
"github.com/safing/portmaster/profile/endpoints"
"github.com/safing/portmaster/service/compat"
"github.com/safing/portmaster/service/nameserver/nsutil"
"github.com/safing/portmaster/service/network"
"github.com/safing/portmaster/service/network/packet"
"github.com/safing/portmaster/service/profile/endpoints"
)
var resolverFilterLists = []string{"17-DNS"}

View file

@ -6,8 +6,8 @@ import (
"github.com/safing/portbase/api"
"github.com/safing/portbase/config"
"github.com/safing/portbase/notifications"
"github.com/safing/portmaster/core"
"github.com/safing/spn/captain"
"github.com/safing/portmaster/service/core"
"github.com/safing/portmaster/spn/captain"
)
// Configuration Keys.

View file

@ -10,11 +10,11 @@ import (
"github.com/safing/portbase/database"
"github.com/safing/portbase/log"
"github.com/safing/portmaster/network"
"github.com/safing/portmaster/network/netutils"
"github.com/safing/portmaster/profile"
"github.com/safing/portmaster/profile/endpoints"
"github.com/safing/portmaster/resolver"
"github.com/safing/portmaster/service/network"
"github.com/safing/portmaster/service/network/netutils"
"github.com/safing/portmaster/service/profile"
"github.com/safing/portmaster/service/profile/endpoints"
"github.com/safing/portmaster/service/resolver"
)
func filterDNSSection(

View file

@ -3,8 +3,8 @@ package inspection
import (
"sync"
"github.com/safing/portmaster/network"
"github.com/safing/portmaster/network/packet"
"github.com/safing/portmaster/service/network"
"github.com/safing/portmaster/service/network/packet"
)
//nolint:golint,stylecheck // FIXME

View file

@ -16,7 +16,7 @@ import (
"golang.org/x/sys/unix"
"github.com/safing/portbase/log"
"github.com/safing/portmaster/network/packet"
"github.com/safing/portmaster/service/network/packet"
)
//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang -cflags "-O2 -g -Wall -Werror" bpf ../programs/bandwidth.c

View file

@ -15,7 +15,7 @@ import (
"github.com/cilium/ebpf/rlimit"
"github.com/safing/portbase/log"
"github.com/safing/portmaster/network/packet"
"github.com/safing/portmaster/service/network/packet"
)
//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang -cflags "-O2 -g -Wall -Werror" -type Event bpf ../programs/monitor.c

Some files were not shown because too many files have changed in this diff Show more