You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

maps.lua 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. --[[
  2. Copyright (c) 2017, Vsevolod Stakhov <vsevolod@highsecure.ru>
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ]]--
  13. local exports = {}
  14. local function rspamd_map_add_from_ucl(opt, mtype, description)
  15. local ret = {
  16. get_key = function(t, k)
  17. if t.__data then
  18. return t.__data:get_key(k)
  19. end
  20. return nil
  21. end
  22. }
  23. local ret_mt = {
  24. __index = function(t, k)
  25. if t.__data then
  26. return t.get_key(k)
  27. end
  28. return nil
  29. end
  30. }
  31. if not opt then
  32. return nil
  33. end
  34. if type(opt) == 'string' then
  35. -- We have a single string, so we treat it as a map
  36. local map = rspamd_config:add_map{
  37. type = mtype,
  38. description = description,
  39. url = opt,
  40. }
  41. if map then
  42. ret.__data = map
  43. setmetatable(ret, ret_mt)
  44. return ret
  45. end
  46. elseif type(opt) == 'table' then
  47. -- it might be plain map or map of plain elements
  48. if opt[1] then
  49. if mtype == 'radix' then
  50. if string.find(opt[1], '^%d') then
  51. local map = rspamd_config:radix_from_ucl(opt)
  52. if map then
  53. ret.__data = map
  54. setmetatable(ret, ret_mt)
  55. return ret
  56. end
  57. else
  58. -- Plain table
  59. local map = rspamd_config:add_map{
  60. type = mtype,
  61. description = description,
  62. url = opt,
  63. }
  64. if map then
  65. ret.__data = map
  66. setmetatable(ret, ret_mt)
  67. return ret
  68. end
  69. end
  70. elseif mtype == 'regexp' then
  71. -- Plain table
  72. local map = rspamd_config:add_map{
  73. type = mtype,
  74. description = description,
  75. url = opt,
  76. }
  77. if map then
  78. ret.__data = map
  79. setmetatable(ret, ret_mt)
  80. return ret
  81. end
  82. else
  83. if string.find(opt[1], '^/%a') or string.find(opt[1], '^http') then
  84. -- Plain table
  85. local map = rspamd_config:add_map{
  86. type = mtype,
  87. description = description,
  88. url = opt,
  89. }
  90. if map then
  91. ret.__data = map
  92. setmetatable(ret, ret_mt)
  93. return ret
  94. end
  95. else
  96. local data = {}
  97. local nelts = 0
  98. for _,elt in ipairs(opt) do
  99. if type(elt) == 'string' then
  100. data[elt] = true
  101. nelts = nelts + 1
  102. end
  103. end
  104. if nelts > 0 then
  105. ret.__data = data
  106. ret.get_key = function(t, k)
  107. if k ~= '__data' then
  108. return t.__data[k]
  109. end
  110. return nil
  111. end
  112. return ret
  113. end
  114. end
  115. end
  116. else
  117. local map = rspamd_config:add_map{
  118. type = mtype,
  119. description = description,
  120. url = opt,
  121. }
  122. if map then
  123. ret.__data = map
  124. setmetatable(ret, ret_mt)
  125. return ret
  126. end
  127. end
  128. end
  129. return nil
  130. end
  131. local function rspamd_map_add(mname, optname, mtype, description)
  132. local opt = rspamd_config:get_module_opt(mname, optname)
  133. return rspamd_map_add_from_ucl(opt, mtype, description)
  134. end
  135. exports.rspamd_map_add = rspamd_map_add
  136. exports.rspamd_map_add_from_ucl = rspamd_map_add_from_ucl
  137. -- Check `what` for being lua_map name, otherwise just compares key with what
  138. local function rspamd_maybe_check_map(key, what)
  139. local fun = require "fun"
  140. local function starts(where,st)
  141. return string.sub(where,1,string.len(st))==st
  142. end
  143. if type(what) == "table" then
  144. return fun.any(function(elt) return rspamd_maybe_check_map(key, elt) end, what)
  145. end
  146. if type(rspamd_maps) == "table" then
  147. local mn
  148. if starts(what, "map:") then
  149. mn = string.sub(what, 4)
  150. elseif starts(what, "map://") then
  151. mn = string.sub(what, 6)
  152. end
  153. if mn and rspamd_maps[mn] then
  154. return rspamd_maps[mn]:get_key(key)
  155. else
  156. return what:lower() == key
  157. end
  158. else
  159. return what:lower() == key
  160. end
  161. end
  162. exports.rspamd_maybe_check_map = rspamd_maybe_check_map
  163. return exports