blacklist.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. package blacklist
  2. import (
  3. "errors"
  4. "net"
  5. "strconv"
  6. "strings"
  7. db "imuslab.com/arozos/mod/database"
  8. )
  9. /*
  10. ArozOS Blacklist Module
  11. Author: tobychui
  12. This module record the IP blacklist of users trying to enter the
  13. system without permission
  14. */
  15. type BlackList struct {
  16. Enabled bool
  17. database *db.Database
  18. }
  19. func NewBlacklistManager(sysdb *db.Database) *BlackList {
  20. sysdb.NewTable("ipblacklist")
  21. return &BlackList{
  22. Enabled: true,
  23. database: sysdb,
  24. }
  25. }
  26. func (bl *BlackList) IsBanned(ip string) bool {
  27. if bl.database.KeyExists("ipblacklist", ip) {
  28. return true
  29. }
  30. return false
  31. }
  32. func (bl *BlackList) SetBan(ipRange string) error {
  33. //Check if the IP range is correct
  34. err := validateIpRange(ipRange)
  35. if err != nil {
  36. return err
  37. }
  38. return nil
  39. }
  40. func ipInRange(ip string, ipRange string) bool {
  41. ip = strings.TrimSpace(ip)
  42. ipRange = strings.TrimSpace(ipRange)
  43. if ip == ipRange {
  44. //For fields that the ipRange is the ip itself
  45. return true
  46. }
  47. //Try matching range
  48. if strings.Contains(ipRange, "-") {
  49. //For range, in A.B.C.D, the A.B.C part must be the same, so do prefix matching
  50. ips := strings.Split(ipRange, "-")
  51. startSubnet := ips[0][:strings.LastIndex(ips[0], ".")]
  52. targetIpSubnet := ip[:strings.LastIndex(ip, ".")]
  53. if startSubnet == targetIpSubnet {
  54. //Check the last value in range
  55. StartDval, _ := strconv.Atoi(ips[0][strings.LastIndex(ips[0], ".")+1:])
  56. EndDval, _ := strconv.Atoi(ips[1][strings.LastIndex(ips[1], ".")+1:])
  57. thisDVal, _ := strconv.Atoi(ip[strings.LastIndex(ip, ".")+1:])
  58. if thisDVal > StartDval && thisDVal < EndDval {
  59. //In range
  60. return true
  61. } else {
  62. //Not in range
  63. return false
  64. }
  65. } else {
  66. //Subnet different. Must be not in this range
  67. return false
  68. }
  69. }
  70. return false
  71. }
  72. //Check if the given IP Range string is actually an IP range
  73. func validateIpRange(ipRange string) error {
  74. ipRange = strings.TrimSpace(ipRange)
  75. ipRange = strings.ReplaceAll(ipRange, " ", "")
  76. if strings.Contains(ipRange, "-") {
  77. //This is a range
  78. if strings.Count(ipRange, "-") != 1 {
  79. //Invalid range defination
  80. return errors.New("Invalid ip range defination")
  81. }
  82. ips := strings.Split(ipRange, "-")
  83. //Check if the starting IP and ending IP are both valid
  84. if net.ParseIP(ips[0]) == nil {
  85. return errors.New("Starting ip is invalid")
  86. }
  87. if net.ParseIP(ips[1]) == nil {
  88. return errors.New("Ending ip is invalid")
  89. }
  90. //Check if the ending IP is larger than the starting IP
  91. startingIpInt, _ := strconv.Atoi(strings.ReplaceAll(ips[0], ".", ""))
  92. endingIpInt, _ := strconv.Atoi(strings.ReplaceAll(ips[1], ".", ""))
  93. if startingIpInt >= endingIpInt {
  94. return errors.New("Invalid ip range: Starting IP is larger or equal to ending ip")
  95. }
  96. //Check if they are in the same subnet
  97. startSubnet := ips[0][:strings.LastIndex(ips[0], ".")]
  98. endSubnet := ips[1][:strings.LastIndex(ips[1], ".")]
  99. if startSubnet != endSubnet {
  100. //They are not in the same subnet
  101. return errors.New("IP range subnet mismatch")
  102. }
  103. } else {
  104. //This is a single IP instead of range. Check if it is a valid IP addr
  105. if net.ParseIP(ipRange) != nil {
  106. //Ok
  107. return nil
  108. } else {
  109. return errors.New("Invalid ip given")
  110. }
  111. }
  112. return nil
  113. }