Merge pull request #52 from safing/feature/firewall-resolver-improvements

Firewall and Resolver improvements
This commit is contained in:
Patrick Pacher
2020-05-20 18:07:48 +02:00
committed by GitHub
70 changed files with 2288 additions and 1549 deletions

View File

@@ -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:

View 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)
}

View File

@@ -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

View File

@@ -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")

View File

@@ -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
}