141 lines
2.8 KiB
Go
141 lines
2.8 KiB
Go
package nebula
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"regexp"
|
|
)
|
|
|
|
type AllowList struct {
|
|
// The values of this cidrTree are `bool`, signifying allow/deny
|
|
cidrTree *CIDR6Tree
|
|
}
|
|
|
|
type RemoteAllowList struct {
|
|
AllowList *AllowList
|
|
|
|
// Inside Range Specific, keys of this tree are inside CIDRs and values
|
|
// are *AllowList
|
|
insideAllowLists *CIDR6Tree
|
|
}
|
|
|
|
type LocalAllowList struct {
|
|
AllowList *AllowList
|
|
|
|
// To avoid ambiguity, all rules must be true, or all rules must be false.
|
|
nameRules []AllowListNameRule
|
|
}
|
|
|
|
type AllowListNameRule struct {
|
|
Name *regexp.Regexp
|
|
Allow bool
|
|
}
|
|
|
|
func (al *AllowList) Allow(ip net.IP) bool {
|
|
if al == nil {
|
|
return true
|
|
}
|
|
|
|
result := al.cidrTree.MostSpecificContains(ip)
|
|
switch v := result.(type) {
|
|
case bool:
|
|
return v
|
|
default:
|
|
panic(fmt.Errorf("invalid state, allowlist returned: %T %v", result, result))
|
|
}
|
|
}
|
|
|
|
func (al *AllowList) AllowIpV4(ip uint32) bool {
|
|
if al == nil {
|
|
return true
|
|
}
|
|
|
|
result := al.cidrTree.MostSpecificContainsIpV4(ip)
|
|
switch v := result.(type) {
|
|
case bool:
|
|
return v
|
|
default:
|
|
panic(fmt.Errorf("invalid state, allowlist returned: %T %v", result, result))
|
|
}
|
|
}
|
|
|
|
func (al *AllowList) AllowIpV6(hi, lo uint64) bool {
|
|
if al == nil {
|
|
return true
|
|
}
|
|
|
|
result := al.cidrTree.MostSpecificContainsIpV6(hi, lo)
|
|
switch v := result.(type) {
|
|
case bool:
|
|
return v
|
|
default:
|
|
panic(fmt.Errorf("invalid state, allowlist returned: %T %v", result, result))
|
|
}
|
|
}
|
|
|
|
func (al *LocalAllowList) Allow(ip net.IP) bool {
|
|
if al == nil {
|
|
return true
|
|
}
|
|
return al.AllowList.Allow(ip)
|
|
}
|
|
|
|
func (al *LocalAllowList) AllowName(name string) bool {
|
|
if al == nil || len(al.nameRules) == 0 {
|
|
return true
|
|
}
|
|
|
|
for _, rule := range al.nameRules {
|
|
if rule.Name.MatchString(name) {
|
|
return rule.Allow
|
|
}
|
|
}
|
|
|
|
// If no rules match, return the default, which is the inverse of the rules
|
|
return !al.nameRules[0].Allow
|
|
}
|
|
|
|
func (al *RemoteAllowList) AllowUnknownVpnIp(ip net.IP) bool {
|
|
if al == nil {
|
|
return true
|
|
}
|
|
return al.AllowList.Allow(ip)
|
|
}
|
|
|
|
func (al *RemoteAllowList) Allow(vpnIp uint32, ip net.IP) bool {
|
|
if !al.getInsideAllowList(vpnIp).Allow(ip) {
|
|
return false
|
|
}
|
|
return al.AllowList.Allow(ip)
|
|
}
|
|
|
|
func (al *RemoteAllowList) AllowIpV4(vpnIp uint32, ip uint32) bool {
|
|
if al == nil {
|
|
return true
|
|
}
|
|
if !al.getInsideAllowList(vpnIp).AllowIpV4(ip) {
|
|
return false
|
|
}
|
|
return al.AllowList.AllowIpV4(ip)
|
|
}
|
|
|
|
func (al *RemoteAllowList) AllowIpV6(vpnIp uint32, hi, lo uint64) bool {
|
|
if al == nil {
|
|
return true
|
|
}
|
|
if !al.getInsideAllowList(vpnIp).AllowIpV6(hi, lo) {
|
|
return false
|
|
}
|
|
return al.AllowList.AllowIpV6(hi, lo)
|
|
}
|
|
|
|
func (al *RemoteAllowList) getInsideAllowList(vpnIp uint32) *AllowList {
|
|
if al.insideAllowLists != nil {
|
|
inside := al.insideAllowLists.MostSpecificContainsIpV4(vpnIp)
|
|
if inside != nil {
|
|
return inside.(*AllowList)
|
|
}
|
|
}
|
|
return nil
|
|
}
|