Merge pull request #52 from safing/feature/firewall-resolver-improvements
Firewall and Resolver improvements
This commit is contained in:
@@ -31,7 +31,7 @@ type EndpointDomain struct {
|
||||
}
|
||||
|
||||
func (ep *EndpointDomain) check(entity *intel.Entity, domain string) (EPResult, Reason) {
|
||||
result, reason := ep.match(ep, entity, ep.Domain, "domain matches")
|
||||
result, reason := ep.match(ep, entity, ep.OriginalValue, "domain matches")
|
||||
|
||||
switch ep.MatchType {
|
||||
case domainMatchTypeExact:
|
||||
|
||||
106
profile/endpoints/endpoint-scopes.go
Normal file
106
profile/endpoints/endpoint-scopes.go
Normal file
@@ -0,0 +1,106 @@
|
||||
package endpoints
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/safing/portmaster/network/netutils"
|
||||
|
||||
"github.com/safing/portmaster/intel"
|
||||
)
|
||||
|
||||
const (
|
||||
scopeLocalhost = 1
|
||||
scopeLocalhostName = "Localhost"
|
||||
scopeLocalhostMatcher = "localhost"
|
||||
|
||||
scopeLAN = 2
|
||||
scopeLANName = "LAN"
|
||||
scopeLANMatcher = "lan"
|
||||
|
||||
scopeInternet = 4
|
||||
scopeInternetName = "Internet"
|
||||
scopeInternetMatcher = "internet"
|
||||
)
|
||||
|
||||
// EndpointScope matches network scopes.
|
||||
type EndpointScope struct {
|
||||
EndpointBase
|
||||
|
||||
scopes uint8
|
||||
}
|
||||
|
||||
// Matches checks whether the given entity matches this endpoint definition.
|
||||
func (ep *EndpointScope) Matches(entity *intel.Entity) (EPResult, Reason) {
|
||||
if entity.IP == nil {
|
||||
return Undeterminable, nil
|
||||
}
|
||||
|
||||
classification := netutils.ClassifyIP(entity.IP)
|
||||
var scope uint8
|
||||
switch classification {
|
||||
case netutils.HostLocal:
|
||||
scope = scopeLocalhost
|
||||
case netutils.LinkLocal:
|
||||
scope = scopeLAN
|
||||
case netutils.SiteLocal:
|
||||
scope = scopeLAN
|
||||
case netutils.Global:
|
||||
scope = scopeInternet
|
||||
case netutils.LocalMulticast:
|
||||
scope = scopeLAN
|
||||
case netutils.GlobalMulticast:
|
||||
scope = scopeInternet
|
||||
}
|
||||
|
||||
if ep.scopes&scope > 0 {
|
||||
return ep.match(ep, entity, ep.Scopes(), "scope matches")
|
||||
}
|
||||
return NoMatch, nil
|
||||
}
|
||||
|
||||
// Scopes returns the string representation of all scopes.
|
||||
func (ep *EndpointScope) Scopes() string {
|
||||
// single scope
|
||||
switch ep.scopes {
|
||||
case scopeLocalhost:
|
||||
return scopeLocalhostName
|
||||
case scopeLAN:
|
||||
return scopeLANName
|
||||
case scopeInternet:
|
||||
return scopeInternetName
|
||||
}
|
||||
|
||||
// multiple scopes
|
||||
var s []string
|
||||
if ep.scopes&scopeLocalhost > 0 {
|
||||
s = append(s, scopeLocalhostName)
|
||||
}
|
||||
if ep.scopes&scopeLAN > 0 {
|
||||
s = append(s, scopeLANName)
|
||||
}
|
||||
if ep.scopes&scopeInternet > 0 {
|
||||
s = append(s, scopeInternetName)
|
||||
}
|
||||
return strings.Join(s, ",")
|
||||
}
|
||||
|
||||
func (ep *EndpointScope) String() string {
|
||||
return ep.renderPPP(ep.Scopes())
|
||||
}
|
||||
|
||||
func parseTypeScope(fields []string) (Endpoint, error) {
|
||||
ep := &EndpointScope{}
|
||||
for _, val := range strings.Split(strings.ToLower(fields[1]), ",") {
|
||||
switch val {
|
||||
case scopeLocalhostMatcher:
|
||||
ep.scopes ^= scopeLocalhost
|
||||
case scopeLANMatcher:
|
||||
ep.scopes ^= scopeLAN
|
||||
case scopeInternetMatcher:
|
||||
ep.scopes ^= scopeInternet
|
||||
default:
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
return ep.parsePPP(ep, fields)
|
||||
}
|
||||
@@ -201,7 +201,7 @@ func invalidDefinitionError(fields []string, msg string) error {
|
||||
return fmt.Errorf(`invalid endpoint definition: "%s" - %s`, strings.Join(fields, " "), msg)
|
||||
}
|
||||
|
||||
func parseEndpoint(value string) (endpoint Endpoint, err error) {
|
||||
func parseEndpoint(value string) (endpoint Endpoint, err error) { //nolint:gocognit
|
||||
fields := strings.Fields(value)
|
||||
if len(fields) < 2 {
|
||||
return nil, fmt.Errorf(`invalid endpoint definition: "%s"`, value)
|
||||
@@ -231,6 +231,10 @@ func parseEndpoint(value string) (endpoint Endpoint, err error) {
|
||||
if endpoint, err = parseTypeASN(fields); endpoint != nil || err != nil {
|
||||
return
|
||||
}
|
||||
// scopes
|
||||
if endpoint, err = parseTypeScope(fields); endpoint != nil || err != nil {
|
||||
return
|
||||
}
|
||||
// lists
|
||||
if endpoint, err = parseTypeList(fields); endpoint != nil || err != nil {
|
||||
return
|
||||
|
||||
@@ -43,6 +43,12 @@ func TestEndpointParsing(t *testing.T) {
|
||||
testParsing(t, "+ AS1234")
|
||||
testParsing(t, "+ AS12345")
|
||||
|
||||
// network scope
|
||||
testParsing(t, "+ Localhost")
|
||||
testParsing(t, "+ LAN")
|
||||
testParsing(t, "+ Internet")
|
||||
testParsing(t, "+ Localhost,LAN,Internet")
|
||||
|
||||
// protocol and ports
|
||||
testParsing(t, "+ * TCP/1-1024")
|
||||
testParsing(t, "+ * */DNS")
|
||||
|
||||
@@ -342,7 +342,26 @@ func TestEndpointMatching(t *testing.T) {
|
||||
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
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user