123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- 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
- }
|