Browse Source

Added whitelist

Toby Chui 11 months ago
parent
commit
ba96805245
3 changed files with 45 additions and 61 deletions
  1. 37 56
      mod/access/whitelist.go
  2. 5 4
      mod/dynamicproxy/Server.go
  3. 3 1
      mod/dynamicproxy/typedef.go

+ 37 - 56
mod/access/whitelist.go

@@ -1,7 +1,6 @@
 package access
 
 import (
-	"encoding/json"
 	"strings"
 
 	"imuslab.com/zoraxy/mod/netutils"
@@ -29,72 +28,66 @@ type WhitelistEntry struct {
 
 func (s *AccessRule) AddCountryCodeToWhitelist(countryCode string, comment string) {
 	countryCode = strings.ToLower(countryCode)
-	entry := WhitelistEntry{
-		EntryType: EntryType_CountryCode,
-		CC:        countryCode,
-		Comment:   comment,
-	}
-
-	s.GetDatabase().Write(s.GetFullTableName("whitelist-cn"), countryCode, entry)
+	newWhitelistCC := deepCopy(*s.WhiteListCountryCode)
+	newWhitelistCC[countryCode] = comment
+	s.WhiteListCountryCode = &newWhitelistCC
+	s.SaveChanges()
 }
 
 func (s *AccessRule) RemoveCountryCodeFromWhitelist(countryCode string) {
 	countryCode = strings.ToLower(countryCode)
-	s.GetDatabase().Delete(s.GetFullTableName("whitelist-cn"), countryCode)
+	newWhitelistCC := deepCopy(*s.WhiteListCountryCode)
+	delete(newWhitelistCC, countryCode)
+	s.WhiteListCountryCode = &newWhitelistCC
+	s.SaveChanges()
 }
 
 func (s *AccessRule) IsCountryCodeWhitelisted(countryCode string) bool {
 	countryCode = strings.ToLower(countryCode)
-	return s.GetDatabase().KeyExists(s.GetFullTableName("whitelist-cn"), countryCode)
+	whitelistCC := *s.WhiteListCountryCode
+	_, ok := whitelistCC[countryCode]
+	return ok
 }
 
 func (s *AccessRule) GetAllWhitelistedCountryCode() []*WhitelistEntry {
 	whitelistedCountryCode := []*WhitelistEntry{}
-	entries, err := s.GetDatabase().ListTable(s.GetFullTableName("whitelist-cn"))
-	if err != nil {
-		return whitelistedCountryCode
+	whitelistCC := *s.WhiteListCountryCode
+	for cc, comment := range whitelistCC {
+		whitelistedCountryCode = append(whitelistedCountryCode, &WhitelistEntry{
+			EntryType: EntryType_CountryCode,
+			CC:        cc,
+			Comment:   comment,
+		})
 	}
-	for _, keypairs := range entries {
-		thisWhitelistEntry := WhitelistEntry{}
-		json.Unmarshal(keypairs[1], &thisWhitelistEntry)
-		whitelistedCountryCode = append(whitelistedCountryCode, &thisWhitelistEntry)
-	}
-
 	return whitelistedCountryCode
 }
 
 //IP Whitelist
 
 func (s *AccessRule) AddIPToWhiteList(ipAddr string, comment string) {
-	thisIpEntry := WhitelistEntry{
-		EntryType: EntryType_IP,
-		IP:        ipAddr,
-		Comment:   comment,
-	}
-
-	s.GetDatabase().Write(s.GetFullTableName("whitelist-ip"), ipAddr, thisIpEntry)
+	newWhitelistIP := deepCopy(*s.WhiteListIP)
+	newWhitelistIP[ipAddr] = comment
+	s.WhiteListIP = &newWhitelistIP
+	s.SaveChanges()
 }
 
 func (s *AccessRule) RemoveIPFromWhiteList(ipAddr string) {
-	s.GetDatabase().Delete(s.GetFullTableName("whitelist-ip"), ipAddr)
+	newWhitelistIP := deepCopy(*s.WhiteListIP)
+	delete(newWhitelistIP, ipAddr)
+	s.WhiteListIP = &newWhitelistIP
+	s.SaveChanges()
 }
 
 func (s *AccessRule) IsIPWhitelisted(ipAddr string) bool {
-	isWhitelisted := s.GetDatabase().KeyExists(s.GetFullTableName("whitelist-ip"), ipAddr)
-	if isWhitelisted {
-		//single IP whitelist entry
-		return true
-	}
-
 	//Check for IP wildcard and CIRD rules
-	AllWhitelistedIps := s.GetAllWhitelistedIpAsStringSlice()
-	for _, whitelistRules := range AllWhitelistedIps {
-		wildcardMatch := netutils.MatchIpWildcard(ipAddr, whitelistRules)
+	WhitelistedIP := *s.WhiteListIP
+	for ipOrCIDR, _ := range WhitelistedIP {
+		wildcardMatch := netutils.MatchIpWildcard(ipAddr, ipOrCIDR)
 		if wildcardMatch {
 			return true
 		}
 
-		cidrMatch := netutils.MatchIpCIDR(ipAddr, whitelistRules)
+		cidrMatch := netutils.MatchIpCIDR(ipAddr, ipOrCIDR)
 		if cidrMatch {
 			return true
 		}
@@ -105,27 +98,15 @@ func (s *AccessRule) IsIPWhitelisted(ipAddr string) bool {
 
 func (s *AccessRule) GetAllWhitelistedIp() []*WhitelistEntry {
 	whitelistedIp := []*WhitelistEntry{}
-	entries, err := s.GetDatabase().ListTable(s.GetFullTableName("whitelist-ip"))
-	if err != nil {
-		return whitelistedIp
-	}
-
-	for _, keypairs := range entries {
-		//ip := string(keypairs[0])
-		thisEntry := WhitelistEntry{}
-		json.Unmarshal(keypairs[1], &thisEntry)
+	currentWhitelistedIP := *s.WhiteListIP
+	for ipOrCIDR, comment := range currentWhitelistedIP {
+		thisEntry := WhitelistEntry{
+			EntryType: EntryType_IP,
+			IP:        ipOrCIDR,
+			Comment:   comment,
+		}
 		whitelistedIp = append(whitelistedIp, &thisEntry)
 	}
 
 	return whitelistedIp
 }
-
-func (s *AccessRule) GetAllWhitelistedIpAsStringSlice() []string {
-	allWhitelistedIPs := []string{}
-	entries := s.GetAllWhitelistedIp()
-	for _, entry := range entries {
-		allWhitelistedIPs = append(allWhitelistedIPs, entry.IP)
-	}
-
-	return allWhitelistedIPs
-}

+ 5 - 4
mod/dynamicproxy/Server.go

@@ -7,7 +7,7 @@ import (
 	"path/filepath"
 	"strings"
 
-	"imuslab.com/zoraxy/mod/geodb"
+	"imuslab.com/zoraxy/mod/netutils"
 )
 
 /*
@@ -35,6 +35,7 @@ func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 		if matchedRoutingRule.UseSystemAccessControl {
 			//This matching rule request system access control.
 			//check access logic
+			//TODO: Change this to routing rule's acess check
 			respWritten := h.handleAccessRouting(w, r)
 			if respWritten {
 				return
@@ -208,8 +209,8 @@ func (h *ProxyHandler) handleRootRouting(w http.ResponseWriter, r *http.Request)
 // if the return value is false, you can continue process the response writer
 func (h *ProxyHandler) handleAccessRouting(w http.ResponseWriter, r *http.Request) bool {
 	//Check if this ip is in blacklist
-	clientIpAddr := geodb.GetRequesterIP(r)
-	if h.Parent.Option.GeodbStore.IsBlacklisted(clientIpAddr) {
+	clientIpAddr := netutils.GetRequesterIP(r)
+	if h.Parent.Option.AccessController.GlobalAccessRule.IsBlacklisted(clientIpAddr) {
 		w.Header().Set("Content-Type", "text/html; charset=utf-8")
 		w.WriteHeader(http.StatusForbidden)
 		template, err := os.ReadFile(filepath.Join(h.Parent.Option.WebDirectory, "templates/blacklist.html"))
@@ -223,7 +224,7 @@ func (h *ProxyHandler) handleAccessRouting(w http.ResponseWriter, r *http.Reques
 	}
 
 	//Check if this ip is in whitelist
-	if !h.Parent.Option.GeodbStore.IsWhitelisted(clientIpAddr) {
+	if !h.Parent.Option.AccessController.GlobalAccessRule.IsWhitelisted(clientIpAddr) {
 		w.Header().Set("Content-Type", "text/html; charset=utf-8")
 		w.WriteHeader(http.StatusForbidden)
 		template, err := os.ReadFile(filepath.Join(h.Parent.Option.WebDirectory, "templates/whitelist.html"))

+ 3 - 1
mod/dynamicproxy/typedef.go

@@ -6,6 +6,7 @@ import (
 	"net/http"
 	"sync"
 
+	"imuslab.com/zoraxy/mod/access"
 	"imuslab.com/zoraxy/mod/dynamicproxy/dpcore"
 	"imuslab.com/zoraxy/mod/dynamicproxy/redirection"
 	"imuslab.com/zoraxy/mod/geodb"
@@ -34,7 +35,8 @@ type RouterOption struct {
 	ForceHttpsRedirect bool   //Force redirection of http to https endpoint
 	TlsManager         *tlscert.Manager
 	RedirectRuleTable  *redirection.RuleTable
-	GeodbStore         *geodb.Store //GeoIP blacklist and whitelist
+	GeodbStore         *geodb.Store       //GeoIP resolver
+	AccessController   *access.Controller //Blacklist / whitelist controller
 	StatisticCollector *statistic.Collector
 	WebDirectory       string //The static web server directory containing the templates folder
 }