package security import ( "net" "github.com/wormhole/wormhole/internal/cache" "github.com/wormhole/wormhole/internal/store" ) type Service struct { cache *cache.Manager store *store.Store } func NewService(c *cache.Manager, st *store.Store) *Service { return &Service{cache: c, store: st} } func (s *Service) Allow(ip string, clientID uint, resourceType string, resourceID uint) bool { scopes := []cache.Scope{ {Kind: "global", ResourceID: 0}, {Kind: "client", ResourceID: clientID}, } if resourceType == "host" || resourceType == "tunnel" { scopes = append(scopes, cache.Scope{Kind: resourceType, ResourceID: resourceID}) } return s.cache.AllowIP(ip, scopes) } func (s *Service) BlockIP(ip, scope string, resourceID uint, remark string) error { rule := &store.IPRule{ Scope: scope, ResourceID: resourceID, Type: "deny", Pattern: ip, PatternKind: "exact", Priority: 100, Remark: remark, } if err := s.store.CreateIPRule(rule); err != nil { return err } return s.cache.ReloadIPRules(s.store) } func DetectPatternKind(pattern string) string { if _, _, err := net.ParseCIDR(pattern); err == nil { return "cidr" } if len(pattern) > 0 && (pattern[0] == '^' || pattern[len(pattern)-1] == '$' || containsMeta(pattern)) { return "regex" } return "exact" } func containsMeta(s string) bool { for _, c := range s { switch c { case '.', '*', '+', '?', '[', ']', '(', ')', '|', '\\': return true } } return false }