|
@@ -0,0 +1,137 @@
|
|
|
+package blacklist
|
|
|
+
|
|
|
+import (
|
|
|
+ "errors"
|
|
|
+ "net"
|
|
|
+ "strconv"
|
|
|
+ "strings"
|
|
|
+
|
|
|
+ db "imuslab.com/arozos/mod/database"
|
|
|
+)
|
|
|
+
|
|
|
+/*
|
|
|
+
|
|
|
+ ArozOS Blacklist Module
|
|
|
+ Author: tobychui
|
|
|
+
|
|
|
+ This module record the IP blacklist of users trying to enter the
|
|
|
+ system without permission
|
|
|
+
|
|
|
+*/
|
|
|
+
|
|
|
+type BlackList struct {
|
|
|
+ Enabled bool
|
|
|
+ database *db.Database
|
|
|
+}
|
|
|
+
|
|
|
+func NewBlacklistManager(sysdb *db.Database) *BlackList {
|
|
|
+ sysdb.NewTable("ipblacklist")
|
|
|
+
|
|
|
+ return &BlackList{
|
|
|
+ Enabled: true,
|
|
|
+ database: sysdb,
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func (bl *BlackList) IsBanned(ip string) bool {
|
|
|
+ if bl.database.KeyExists("ipblacklist", ip) {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ return false
|
|
|
+}
|
|
|
+
|
|
|
+func (bl *BlackList) SetBan(ipRange string) error {
|
|
|
+ //Check if the IP range is correct
|
|
|
+ err := validateIpRange(ipRange)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func ipInRange(ip string, ipRange string) bool {
|
|
|
+ ip = strings.TrimSpace(ip)
|
|
|
+ ipRange = strings.TrimSpace(ipRange)
|
|
|
+ if ip == ipRange {
|
|
|
+ //For fields that the ipRange is the ip itself
|
|
|
+ return true
|
|
|
+ }
|
|
|
+
|
|
|
+ //Try matching range
|
|
|
+ if strings.Contains(ipRange, "-") {
|
|
|
+ //For range, in A.B.C.D, the A.B.C part must be the same, so do prefix matching
|
|
|
+ ips := strings.Split(ipRange, "-")
|
|
|
+ startSubnet := ips[0][:strings.LastIndex(ips[0], ".")]
|
|
|
+ targetIpSubnet := ip[:strings.LastIndex(ip, ".")]
|
|
|
+ if startSubnet == targetIpSubnet {
|
|
|
+ //Check the last value in range
|
|
|
+ StartDval, _ := strconv.Atoi(ips[0][strings.LastIndex(ips[0], ".")+1:])
|
|
|
+ EndDval, _ := strconv.Atoi(ips[1][strings.LastIndex(ips[1], ".")+1:])
|
|
|
+ thisDVal, _ := strconv.Atoi(ip[strings.LastIndex(ip, ".")+1:])
|
|
|
+
|
|
|
+ if thisDVal > StartDval && thisDVal < EndDval {
|
|
|
+ //In range
|
|
|
+ return true
|
|
|
+ } else {
|
|
|
+ //Not in range
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ //Subnet different. Must be not in this range
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ return false
|
|
|
+}
|
|
|
+
|
|
|
+//Check if the given IP Range string is actually an IP range
|
|
|
+func validateIpRange(ipRange string) error {
|
|
|
+ ipRange = strings.TrimSpace(ipRange)
|
|
|
+ ipRange = strings.ReplaceAll(ipRange, " ", "")
|
|
|
+ if strings.Contains(ipRange, "-") {
|
|
|
+ //This is a range
|
|
|
+ if strings.Count(ipRange, "-") != 1 {
|
|
|
+ //Invalid range defination
|
|
|
+ return errors.New("Invalid ip range defination")
|
|
|
+ }
|
|
|
+ ips := strings.Split(ipRange, "-")
|
|
|
+ //Check if the starting IP and ending IP are both valid
|
|
|
+ if net.ParseIP(ips[0]) == nil {
|
|
|
+ return errors.New("Starting ip is invalid")
|
|
|
+ }
|
|
|
+
|
|
|
+ if net.ParseIP(ips[1]) == nil {
|
|
|
+ return errors.New("Ending ip is invalid")
|
|
|
+ }
|
|
|
+
|
|
|
+ //Check if the ending IP is larger than the starting IP
|
|
|
+ startingIpInt, _ := strconv.Atoi(strings.ReplaceAll(ips[0], ".", ""))
|
|
|
+ endingIpInt, _ := strconv.Atoi(strings.ReplaceAll(ips[1], ".", ""))
|
|
|
+
|
|
|
+ if startingIpInt >= endingIpInt {
|
|
|
+ return errors.New("Invalid ip range: Starting IP is larger or equal to ending ip")
|
|
|
+ }
|
|
|
+
|
|
|
+ //Check if they are in the same subnet
|
|
|
+ startSubnet := ips[0][:strings.LastIndex(ips[0], ".")]
|
|
|
+ endSubnet := ips[1][:strings.LastIndex(ips[1], ".")]
|
|
|
+
|
|
|
+ if startSubnet != endSubnet {
|
|
|
+ //They are not in the same subnet
|
|
|
+ return errors.New("IP range subnet mismatch")
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ //This is a single IP instead of range. Check if it is a valid IP addr
|
|
|
+ if net.ParseIP(ipRange) != nil {
|
|
|
+ //Ok
|
|
|
+ return nil
|
|
|
+ } else {
|
|
|
+ return errors.New("Invalid ip given")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|