mirror of
https://github.com/safing/portmaster
synced 2025-09-02 18:49:14 +00:00
Validate resolver config for unknown parameters
This commit is contained in:
parent
52506ffb1e
commit
75b3c40ffc
1 changed files with 35 additions and 12 deletions
|
@ -27,6 +27,14 @@ type Scope struct {
|
||||||
Resolvers []*Resolver
|
Resolvers []*Resolver
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
parameterName = "name"
|
||||||
|
parameterVerify = "verify"
|
||||||
|
parameterBlockedIf = "blockedif"
|
||||||
|
parameterSearch = "search"
|
||||||
|
parameterSearchOnly = "search-only"
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
globalResolvers []*Resolver // all (global) resolvers
|
globalResolvers []*Resolver // all (global) resolvers
|
||||||
localResolvers []*Resolver // all resolvers that are in site-local or link-local IP ranges
|
localResolvers []*Resolver // all resolvers that are in site-local or link-local IP ranges
|
||||||
|
@ -122,31 +130,47 @@ func createResolver(resolverURL, source string) (*Resolver, bool, error) {
|
||||||
return nil, true, nil // skip
|
return nil, true, nil // skip
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get parameters and check if keys exist.
|
||||||
query := u.Query()
|
query := u.Query()
|
||||||
verifyDomain := query.Get("verify")
|
for key := range query {
|
||||||
|
switch key {
|
||||||
|
case parameterName,
|
||||||
|
parameterVerify,
|
||||||
|
parameterBlockedIf,
|
||||||
|
parameterSearch,
|
||||||
|
parameterSearchOnly:
|
||||||
|
// Known key, continue.
|
||||||
|
default:
|
||||||
|
// Unknown key, abort.
|
||||||
|
return nil, false, fmt.Errorf(`unknown parameter "%s"`, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check domain verification config.
|
||||||
|
verifyDomain := query.Get(parameterVerify)
|
||||||
if verifyDomain != "" && u.Scheme != ServerTypeDoT {
|
if verifyDomain != "" && u.Scheme != ServerTypeDoT {
|
||||||
return nil, false, fmt.Errorf("domain verification only supported in DOT")
|
return nil, false, fmt.Errorf("domain verification only supported in DOT")
|
||||||
}
|
}
|
||||||
|
|
||||||
if verifyDomain == "" && u.Scheme == ServerTypeDoT {
|
if verifyDomain == "" && u.Scheme == ServerTypeDoT {
|
||||||
return nil, false, fmt.Errorf("DOT must have a verify query parameter set")
|
return nil, false, fmt.Errorf("DOT must have a verify query parameter set")
|
||||||
}
|
}
|
||||||
|
|
||||||
blockType := query.Get("blockedif")
|
// Check block detection type.
|
||||||
|
blockType := query.Get(parameterBlockedIf)
|
||||||
if blockType == "" {
|
if blockType == "" {
|
||||||
blockType = BlockDetectionZeroIP
|
blockType = BlockDetectionZeroIP
|
||||||
}
|
}
|
||||||
|
|
||||||
switch blockType {
|
switch blockType {
|
||||||
case BlockDetectionDisabled, BlockDetectionEmptyAnswer, BlockDetectionRefused, BlockDetectionZeroIP:
|
case BlockDetectionDisabled, BlockDetectionEmptyAnswer, BlockDetectionRefused, BlockDetectionZeroIP:
|
||||||
default:
|
default:
|
||||||
return nil, false, fmt.Errorf("invalid value for upstream block detection (blockedif=)")
|
return nil, false, fmt.Errorf("invalid value for upstream block detection (blockedif=)")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build resolver.
|
||||||
newResolver := &Resolver{
|
newResolver := &Resolver{
|
||||||
ConfigURL: resolverURL,
|
ConfigURL: resolverURL,
|
||||||
Info: &ResolverInfo{
|
Info: &ResolverInfo{
|
||||||
Name: query.Get("name"),
|
Name: query.Get(parameterName),
|
||||||
Type: u.Scheme,
|
Type: u.Scheme,
|
||||||
Source: source,
|
Source: source,
|
||||||
IP: ip,
|
IP: ip,
|
||||||
|
@ -159,7 +183,7 @@ func createResolver(resolverURL, source string) (*Resolver, bool, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse search domains.
|
// Parse search domains.
|
||||||
searchDomains := query.Get("search")
|
searchDomains := query.Get(parameterSearch)
|
||||||
if searchDomains != "" {
|
if searchDomains != "" {
|
||||||
err = configureSearchDomains(newResolver, strings.Split(searchDomains, ","), true)
|
err = configureSearchDomains(newResolver, strings.Split(searchDomains, ","), true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -168,14 +192,13 @@ func createResolver(resolverURL, source string) (*Resolver, bool, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if searchOnly is set and valid.
|
// Check if searchOnly is set and valid.
|
||||||
if query.Has("searchOnly") {
|
if query.Has(parameterSearchOnly) {
|
||||||
newResolver.SearchOnly = true
|
newResolver.SearchOnly = true
|
||||||
|
if query.Get(parameterSearchOnly) != "" {
|
||||||
if query.Get("searchOnly") != "" {
|
return nil, false, fmt.Errorf("%s may only be used as an empty parameter", parameterSearchOnly)
|
||||||
return nil, false, errors.New("searchOnly may only be used as an empty parameter")
|
|
||||||
}
|
}
|
||||||
if len(newResolver.Search) == 0 {
|
if len(newResolver.Search) == 0 {
|
||||||
return nil, false, errors.New("cannot use searchOnly without search scopes")
|
return nil, false, fmt.Errorf("cannot use %s without search scopes", parameterSearchOnly)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,7 +209,7 @@ func createResolver(resolverURL, source string) (*Resolver, bool, error) {
|
||||||
func configureSearchDomains(resolver *Resolver, searches []string, hardfail bool) error {
|
func configureSearchDomains(resolver *Resolver, searches []string, hardfail bool) error {
|
||||||
// Check all search domains.
|
// Check all search domains.
|
||||||
for i, value := range searches {
|
for i, value := range searches {
|
||||||
trimmedDomain := strings.Trim(value, ".")
|
trimmedDomain := strings.ToLower(strings.Trim(value, "."))
|
||||||
err := checkSearchScope(trimmedDomain)
|
err := checkSearchScope(trimmedDomain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if hardfail {
|
if hardfail {
|
||||||
|
|
Loading…
Add table
Reference in a new issue