8d9a76c751
Rewrites the compiler from ~440 to ~1700 lines covering all major shorewall firewall features: loopback, conntrack fast-path, anti-spoof, DHCP, intra-zone, blacklist/whitelist, conntrack notrack, tunnels (13 types), rules with sections, DNAT/redirect, SNAT/masquerade, static NAT, policies with zone exclusions, MSS clamping, rate limiting, connection limiting, negated addresses, ICMP type matching, TCP RST reject, user/UID matching, mark match/set, NFQUEUE, NONAT, and policy-level rate/conn limiting. Adds full config types for all shorewall subsystems (mangle, accounting, maclist, netmap, providers, tunnels, conntrack, blrules, proxyarp/ndp, routes, tc, secmarks), shorewall migration tooling, expanded CLI commands, expression-level diff engine, and 49 unit tests.
56 lines
1.6 KiB
Go
56 lines
1.6 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"unicode"
|
|
)
|
|
|
|
// ValidateName checks that a name follows shorewall naming conventions:
|
|
// starts with a letter, composed of letters, digits, and underscores.
|
|
func ValidateName(name, kind string) error {
|
|
if len(name) == 0 {
|
|
return fmt.Errorf("%s name is empty", kind)
|
|
}
|
|
if !unicode.IsLetter(rune(name[0])) {
|
|
return fmt.Errorf("%s name %q must start with a letter", kind, name)
|
|
}
|
|
for _, r := range name {
|
|
if !unicode.IsLetter(r) && !unicode.IsDigit(r) && r != '_' {
|
|
return fmt.Errorf("%s name %q contains invalid character %q", kind, name, r)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ValidateInterfaceRef checks that an interface reference is valid.
|
|
// Strips any @suffix (e.g. "sit1@NONE" -> "sit1"), allows trailing + for wildcards.
|
|
func ValidateInterfaceRef(name string) string {
|
|
if idx := strings.IndexByte(name, '@'); idx >= 0 {
|
|
name = name[:idx]
|
|
}
|
|
return name
|
|
}
|
|
|
|
// IsWildcardInterface returns true if the interface name is a wildcard (ends with +).
|
|
func IsWildcardInterface(name string) bool {
|
|
return strings.HasSuffix(name, "+")
|
|
}
|
|
|
|
// ValidateDNSName checks shorewall's DNS name rules: fully qualified,
|
|
// minimum two periods. Returns an error if the name looks like a DNS name
|
|
// but doesn't meet the requirements.
|
|
func ValidateDNSName(name string) error {
|
|
if !strings.Contains(name, ".") {
|
|
return nil
|
|
}
|
|
count := strings.Count(name, ".")
|
|
if count < 2 {
|
|
trimmed := strings.TrimSuffix(name, ".")
|
|
if strings.Count(trimmed, ".") < 1 {
|
|
return fmt.Errorf("DNS name %q must be fully qualified with at least two periods", name)
|
|
}
|
|
}
|
|
return nil
|
|
}
|