123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- package access
- import (
- "encoding/json"
- "errors"
- "net"
- "os"
- "path/filepath"
- )
- // Check both blacklist and whitelist for access for both geoIP and ip / CIDR ranges
- func (s *AccessRule) AllowIpAccess(ipaddr string) bool {
- if s.IsBlacklisted(ipaddr) {
- return false
- }
- return s.IsWhitelisted(ipaddr)
- }
- // Check both blacklist and whitelist for access using net.Conn
- func (s *AccessRule) AllowConnectionAccess(conn net.Conn) bool {
- if addr, ok := conn.RemoteAddr().(*net.TCPAddr); ok {
- return s.AllowIpAccess(addr.IP.String())
- }
- return true
- }
- // Toggle black list
- func (s *AccessRule) ToggleBlacklist(enabled bool) {
- s.BlacklistEnabled = enabled
- s.SaveChanges()
- }
- // Toggel white list
- func (s *AccessRule) ToggleWhitelist(enabled bool) {
- s.WhitelistEnabled = enabled
- s.SaveChanges()
- }
- /*
- Check if a IP address is blacklisted, in either country or IP blacklist
- IsBlacklisted default return is false (allow access)
- */
- func (s *AccessRule) IsBlacklisted(ipAddr string) bool {
- if !s.BlacklistEnabled {
- //Blacklist not enabled. Always return false
- return false
- }
- if ipAddr == "" {
- //Unable to get the target IP address
- return false
- }
- countryCode, err := s.parent.Options.GeoDB.ResolveCountryCodeFromIP(ipAddr)
- if err != nil {
- return false
- }
- if s.IsCountryCodeBlacklisted(countryCode.CountryIsoCode) {
- return true
- }
- if s.IsIPBlacklisted(ipAddr) {
- return true
- }
- return false
- }
- /*
- IsWhitelisted check if a given IP address is in the current
- server's white list.
- Note that the Whitelist default result is true even
- when encountered error
- */
- func (s *AccessRule) IsWhitelisted(ipAddr string) bool {
- if !s.WhitelistEnabled {
- //Whitelist not enabled. Always return true (allow access)
- return true
- }
- if ipAddr == "" {
- //Unable to get the target IP address, assume ok
- return true
- }
- countryCode, err := s.parent.Options.GeoDB.ResolveCountryCodeFromIP(ipAddr)
- if err != nil {
- return true
- }
- if s.IsCountryCodeWhitelisted(countryCode.CountryIsoCode) {
- return true
- }
- if s.IsIPWhitelisted(ipAddr) {
- return true
- }
- return false
- }
- /* Utilities function */
- // Update the current access rule to json file
- func (s *AccessRule) SaveChanges() error {
- if s.parent == nil {
- return errors.New("save failed: access rule detached from controller")
- }
- saveTarget := filepath.Join(s.parent.Options.ConfigFolder, s.ID+".json")
- js, err := json.MarshalIndent(s, "", " ")
- if err != nil {
- return err
- }
- err = os.WriteFile(saveTarget, js, 0775)
- return err
- }
- // Delete this access rule, this will only delete the config file.
- // for runtime delete, use DeleteAccessRuleByID from parent Controller
- func (s *AccessRule) DeleteConfigFile() error {
- saveTarget := filepath.Join(s.parent.Options.ConfigFolder, s.ID+".json")
- return os.Remove(saveTarget)
- }
- // Delete the access rule by given ID
- func (c *Controller) DeleteAccessRuleByID(accessRuleID string) error {
- targetAccessRule, err := c.GetAccessRuleByID(accessRuleID)
- if err != nil {
- return err
- }
- //Delete config file associated with this access rule
- err = targetAccessRule.DeleteConfigFile()
- if err != nil {
- return err
- }
- //Delete the access rule in runtime
- c.ProxyAccessRule.Delete(accessRuleID)
- return nil
- }
- // Create a deep copy object of the access rule list
- func deepCopy(valueList map[string]string) map[string]string {
- result := map[string]string{}
- js, _ := json.Marshal(valueList)
- json.Unmarshal(js, &result)
- return result
- }
|