mirror of
https://github.com/safing/portmaster
synced 2025-09-01 18:19:12 +00:00
388 lines
8.6 KiB
Go
388 lines
8.6 KiB
Go
package endpoints
|
|
|
|
import (
|
|
"net"
|
|
"runtime"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/safing/portmaster/core/pmtesting"
|
|
"github.com/safing/portmaster/intel"
|
|
)
|
|
|
|
func TestMain(m *testing.M) {
|
|
pmtesting.TestMain(m, intel.Module)
|
|
}
|
|
|
|
func testEndpointMatch(t *testing.T, ep Endpoint, entity *intel.Entity, expectedResult EPResult) {
|
|
result, _ := ep.Matches(entity)
|
|
if result != expectedResult {
|
|
t.Errorf(
|
|
"line %d: unexpected result for endpoint %s and entity %+v: result=%s, expected=%s",
|
|
getLineNumberOfCaller(1),
|
|
ep,
|
|
entity,
|
|
result,
|
|
expectedResult,
|
|
)
|
|
}
|
|
}
|
|
|
|
func testFormat(t *testing.T, endpoint string) {
|
|
_, err := parseEndpoint(endpoint)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestEndpointFormat(t *testing.T) {
|
|
testFormat(t, "+ .")
|
|
testFormat(t, "+ .at")
|
|
testFormat(t, "+ .at.")
|
|
testFormat(t, "+ 1.at")
|
|
testFormat(t, "+ 1.at.")
|
|
testFormat(t, "+ 1.f.ix.de.")
|
|
}
|
|
|
|
func TestEndpointMatching(t *testing.T) {
|
|
// ANY
|
|
|
|
ep, err := parseEndpoint("+ *")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "example.com.",
|
|
}).Init(), Permitted)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "example.com.",
|
|
IP: net.ParseIP("10.2.3.4"),
|
|
Protocol: 6,
|
|
Port: 443,
|
|
}).Init(), Permitted)
|
|
|
|
// DOMAIN
|
|
|
|
// wildcard domains
|
|
ep, err = parseEndpoint("+ *example.com")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "example.com.",
|
|
}).Init(), Permitted)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "abc.example.com.",
|
|
}).Init(), Permitted)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "abc-example.com.",
|
|
}).Init(), Permitted)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "example.com.",
|
|
IP: net.ParseIP("10.2.3.4"),
|
|
Protocol: 6,
|
|
Port: 443,
|
|
}).Init(), Permitted)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "abc.example.com.",
|
|
IP: net.ParseIP("10.2.3.4"),
|
|
Protocol: 6,
|
|
Port: 443,
|
|
}).Init(), Permitted)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "abc-example.com.",
|
|
IP: net.ParseIP("10.2.3.4"),
|
|
Protocol: 6,
|
|
Port: 443,
|
|
}).Init(), Permitted)
|
|
|
|
ep, err = parseEndpoint("+ *.example.com")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "example.com.",
|
|
}).Init(), NoMatch)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "abc.example.com.",
|
|
}).Init(), Permitted)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "abc-example.com.",
|
|
}).Init(), NoMatch)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "example.com.",
|
|
IP: net.ParseIP("10.2.3.4"),
|
|
Protocol: 6,
|
|
Port: 443,
|
|
}).Init(), NoMatch)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "abc.example.com.",
|
|
IP: net.ParseIP("10.2.3.4"),
|
|
Protocol: 6,
|
|
Port: 443,
|
|
}).Init(), Permitted)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "abc-example.com.",
|
|
IP: net.ParseIP("10.2.3.4"),
|
|
Protocol: 6,
|
|
Port: 443,
|
|
}).Init(), NoMatch)
|
|
|
|
ep, err = parseEndpoint("+ .example.com")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "example.com.",
|
|
}).Init(), Permitted)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "abc.example.com.",
|
|
}).Init(), Permitted)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "abc-example.com.",
|
|
}).Init(), NoMatch)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "example.com.",
|
|
IP: net.ParseIP("10.2.3.4"),
|
|
Protocol: 6,
|
|
Port: 443,
|
|
}).Init(), Permitted)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "abc.example.com.",
|
|
IP: net.ParseIP("10.2.3.4"),
|
|
Protocol: 6,
|
|
Port: 443,
|
|
}).Init(), Permitted)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "abc-example.com.",
|
|
IP: net.ParseIP("10.2.3.4"),
|
|
Protocol: 6,
|
|
Port: 443,
|
|
}).Init(), NoMatch)
|
|
|
|
ep, err = parseEndpoint("+ example.*")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "example.com.",
|
|
}).Init(), Permitted)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "abc.example.com.",
|
|
}).Init(), NoMatch)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "example.com.",
|
|
IP: net.ParseIP("10.2.3.4"),
|
|
Protocol: 6,
|
|
Port: 443,
|
|
}).Init(), Permitted)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "abc.example.com.",
|
|
IP: net.ParseIP("10.2.3.4"),
|
|
Protocol: 6,
|
|
Port: 443,
|
|
}).Init(), NoMatch)
|
|
|
|
ep, err = parseEndpoint("+ *.exampl*")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "example.com.",
|
|
}).Init(), NoMatch)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "abc.example.com.",
|
|
}).Init(), Permitted)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "example.com.",
|
|
IP: net.ParseIP("10.2.3.4"),
|
|
Protocol: 6,
|
|
Port: 443,
|
|
}).Init(), NoMatch)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "abc.example.com.",
|
|
IP: net.ParseIP("10.2.3.4"),
|
|
Protocol: 6,
|
|
Port: 443,
|
|
}).Init(), Permitted)
|
|
|
|
ep, err = parseEndpoint("+ *.com.")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "example.com.",
|
|
}).Init(), Permitted)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "example.org.",
|
|
}).Init(), NoMatch)
|
|
|
|
// protocol
|
|
|
|
ep, err = parseEndpoint("+ example.com UDP")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "example.com.",
|
|
IP: net.ParseIP("10.2.3.4"),
|
|
Protocol: 6,
|
|
Port: 443,
|
|
}).Init(), NoMatch)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "example.com.",
|
|
IP: net.ParseIP("10.2.3.4"),
|
|
Protocol: 17,
|
|
Port: 443,
|
|
}).Init(), Permitted)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "example.com.",
|
|
}).Init(), Undeterminable)
|
|
|
|
// ports
|
|
|
|
ep, err = parseEndpoint("+ example.com 17/442-444")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
entity := (&intel.Entity{
|
|
Domain: "example.com.",
|
|
IP: net.ParseIP("10.2.3.4"),
|
|
Protocol: 17,
|
|
Port: 441,
|
|
}).Init()
|
|
testEndpointMatch(t, ep, entity, NoMatch)
|
|
|
|
entity.Port = 442
|
|
testEndpointMatch(t, ep, entity, Permitted)
|
|
|
|
entity.Port = 443
|
|
testEndpointMatch(t, ep, entity, Permitted)
|
|
|
|
entity.Port = 444
|
|
testEndpointMatch(t, ep, entity, Permitted)
|
|
|
|
entity.Port = 445
|
|
testEndpointMatch(t, ep, entity, NoMatch)
|
|
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "example.com.",
|
|
}).Init(), Undeterminable)
|
|
|
|
// IP
|
|
|
|
ep, err = parseEndpoint("+ 10.2.3.4")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "",
|
|
IP: net.ParseIP("10.2.3.4"),
|
|
Protocol: 6,
|
|
Port: 443,
|
|
}).Init(), Permitted)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "example.com.",
|
|
IP: net.ParseIP("10.2.3.4"),
|
|
Protocol: 17,
|
|
Port: 443,
|
|
}).Init(), Permitted)
|
|
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "",
|
|
IP: net.ParseIP("10.2.3.3"),
|
|
Protocol: 6,
|
|
Port: 443,
|
|
}).Init(), NoMatch)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "example.com.",
|
|
IP: net.ParseIP("10.2.3.5"),
|
|
Protocol: 17,
|
|
Port: 443,
|
|
}).Init(), NoMatch)
|
|
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
Domain: "example.com.",
|
|
}).Init(), Undeterminable)
|
|
|
|
// IP Range
|
|
|
|
ep, err = parseEndpoint("+ 10.2.3.0/24")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
IP: net.ParseIP("10.2.2.4"),
|
|
}).Init(), NoMatch)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
IP: net.ParseIP("10.2.3.4"),
|
|
}).Init(), Permitted)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
IP: net.ParseIP("10.2.4.4"),
|
|
}).Init(), NoMatch)
|
|
|
|
// ASN
|
|
|
|
ep, err = parseEndpoint("+ AS13335")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
IP: net.ParseIP("1.1.1.2"),
|
|
}).Init(), Permitted)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
IP: net.ParseIP("8.8.8.8"),
|
|
}).Init(), NoMatch)
|
|
|
|
// Country
|
|
|
|
ep, err = parseEndpoint("+ AT")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
IP: net.ParseIP("194.232.104.1"), // orf.at
|
|
}).Init(), Permitted)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
IP: net.ParseIP("151.101.1.164"), // nytimes.com
|
|
}).Init(), NoMatch)
|
|
|
|
// Scope
|
|
|
|
ep, err = parseEndpoint("+ Localhost,LAN")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
IP: net.ParseIP("192.168.0.1"),
|
|
}).Init(), Permitted)
|
|
testEndpointMatch(t, ep, (&intel.Entity{
|
|
IP: net.ParseIP("151.101.1.164"), // nytimes.com
|
|
}).Init(), NoMatch)
|
|
|
|
// Lists
|
|
|
|
_, err = parseEndpoint("+ L:A,B,C")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// TODO: write test for lists matcher
|
|
|
|
}
|
|
|
|
func getLineNumberOfCaller(levels int) int {
|
|
_, _, line, _ := runtime.Caller(levels + 1) //nolint:dogsled
|
|
return line
|
|
}
|