blacklist.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  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. //Check if a given IP is banned
  27. func (bl *BlackList) IsBanned(ip string) bool {
  28. if bl.Enabled == false {
  29. return false
  30. }
  31. if bl.database.KeyExists("ipblacklist", ip) {
  32. return true
  33. }
  34. return false
  35. }
  36. //Set the ban state of a ip or ip range
  37. func (bl *BlackList) Ban(ipRange string) error {
  38. //Check if the IP range is correct
  39. err := validateIpRange(ipRange)
  40. if err != nil {
  41. return err
  42. }
  43. //Push it to the ban list
  44. ipRange = strings.TrimSpace(ipRange)
  45. ipRange = strings.ReplaceAll(ipRange, " ", "")
  46. return bl.database.Write("ipblacklist", ipRange, true)
  47. }
  48. func (bl *BlackList) UnBan(ipRange string) error {
  49. //Check if the IP range is correct
  50. return nil
  51. }
  52. //Check if an given ip in the given range
  53. func ipInRange(ip string, ipRange string) bool {
  54. ip = strings.TrimSpace(ip)
  55. ipRange = strings.TrimSpace(ipRange)
  56. if ip == ipRange {
  57. //For fields that the ipRange is the ip itself
  58. return true
  59. }
  60. //Try matching range
  61. if strings.Contains(ipRange, "-") {
  62. //For range, in A.B.C.D, the A.B.C part must be the same, so do prefix matching
  63. ips := strings.Split(ipRange, "-")
  64. startSubnet := ips[0][:strings.LastIndex(ips[0], ".")]
  65. targetIpSubnet := ip[:strings.LastIndex(ip, ".")]
  66. if startSubnet == targetIpSubnet {
  67. //Check the last value in range
  68. StartDval, _ := strconv.Atoi(ips[0][strings.LastIndex(ips[0], ".")+1:])
  69. EndDval, _ := strconv.Atoi(ips[1][strings.LastIndex(ips[1], ".")+1:])
  70. thisDVal, _ := strconv.Atoi(ip[strings.LastIndex(ip, ".")+1:])
  71. if thisDVal > StartDval && thisDVal < EndDval {
  72. //In range
  73. return true
  74. } else {
  75. //Not in range
  76. return false
  77. }
  78. } else {
  79. //Subnet different. Must be not in this range
  80. return false
  81. }
  82. }
  83. return false
  84. }
  85. //Check if the given IP Range string is actually an IP range
  86. func validateIpRange(ipRange string) error {
  87. ipRange = strings.TrimSpace(ipRange)
  88. ipRange = strings.ReplaceAll(ipRange, " ", "")
  89. if strings.Contains(ipRange, "-") {
  90. //This is a range
  91. if strings.Count(ipRange, "-") != 1 {
  92. //Invalid range defination
  93. return errors.New("Invalid ip range defination")
  94. }
  95. ips := strings.Split(ipRange, "-")
  96. //Check if the starting IP and ending IP are both valid
  97. if net.ParseIP(ips[0]) == nil {
  98. return errors.New("Starting ip is invalid")
  99. }
  100. if net.ParseIP(ips[1]) == nil {
  101. return errors.New("Ending ip is invalid")
  102. }
  103. //Check if the ending IP is larger than the starting IP
  104. startingIpInt, _ := strconv.Atoi(strings.ReplaceAll(ips[0], ".", ""))
  105. endingIpInt, _ := strconv.Atoi(strings.ReplaceAll(ips[1], ".", ""))
  106. if startingIpInt >= endingIpInt {
  107. return errors.New("Invalid ip range: Starting IP is larger or equal to ending ip")
  108. }
  109. //Check if they are in the same subnet
  110. startSubnet := ips[0][:strings.LastIndex(ips[0], ".")]
  111. endSubnet := ips[1][:strings.LastIndex(ips[1], ".")]
  112. if startSubnet != endSubnet {
  113. //They are not in the same subnet
  114. return errors.New("IP range subnet mismatch")
  115. }
  116. } else {
  117. //This is a single IP instead of range. Check if it is a valid IP addr
  118. if net.ParseIP(ipRange) != nil {
  119. //Ok
  120. return nil
  121. } else {
  122. return errors.New("Invalid ip given")
  123. }
  124. }
  125. return nil
  126. }