authelia/internal/authorization/ip_matcher.go

67 lines
1.5 KiB
Go

package authorization
import (
"net"
"strings"
"github.com/authelia/authelia/internal/configuration/schema"
)
func selectMatchingNetworkGroups(networks []string, aclNetworks []schema.ACLNetwork) []schema.ACLNetwork {
selectedNetworkGroups := []schema.ACLNetwork{}
for _, network := range networks {
for _, n := range aclNetworks {
for _, ng := range n.Name {
if network == ng {
selectedNetworkGroups = append(selectedNetworkGroups, n)
}
}
}
}
return selectedNetworkGroups
}
func isIPAddressOrCIDR(ip net.IP, network string) bool {
switch {
case ip.String() == network:
return true
case strings.Contains(network, "/"):
return parseCIDR(ip, network)
}
return false
}
func parseCIDR(ip net.IP, network string) bool {
_, ipNet, _ := net.ParseCIDR(network)
return ipNet.Contains(ip)
}
// isIPMatching check whether user's IP is in one of the network ranges.
func isIPMatching(ip net.IP, networks []string, aclNetworks []schema.ACLNetwork) bool {
// If no network is provided in the rule, we match any network
if len(networks) == 0 {
return true
}
matchingNetworkGroups := selectMatchingNetworkGroups(networks, aclNetworks)
for _, network := range networks {
if net.ParseIP(network) == nil && !strings.Contains(network, "/") {
for _, n := range matchingNetworkGroups {
for _, network := range n.Networks {
if isIPAddressOrCIDR(ip, network) {
return true
}
}
}
} else if isIPAddressOrCIDR(ip, network) {
return true
}
}
return false
}