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.

emails.lua 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. --[[
  2. Copyright (c) 2011-2015, 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. -- Emails is module for different checks for emails inside messages
  14. -- Rules format:
  15. -- symbol = sym, map = file:///path/to/file, domain_only = yes
  16. -- symbol = sym2, dnsbl = bl.somehost.com, domain_only = no
  17. local rules = {}
  18. local logger = require "rspamd_logger"
  19. -- Check rule for a single email
  20. local function check_email_rule(task, rule, addr)
  21. local function emails_dns_cb(resolver, to_resolve, results, err)
  22. if results then
  23. logger.infox(task, '<%1> email: [%2] resolved for symbol: %3',
  24. task:get_message_id(), to_resolve, rule['symbol'])
  25. task:insert_result(rule['symbol'], 1)
  26. end
  27. end
  28. if rule['dnsbl'] then
  29. local to_resolve = ''
  30. if rule['domain_only'] then
  31. to_resolve = string.format('%s.%s', addr:get_host(), rule['dnsbl'])
  32. else
  33. to_resolve = string.format('%s.%s.%s', addr:get_user(), addr:get_host(), rule['dnsbl'])
  34. end
  35. task:get_resolver():resolve_a({
  36. task=task,
  37. name = to_resolve,
  38. callback = emails_dns_cb})
  39. elseif rule['map'] then
  40. if rule['domain_only'] then
  41. local key = addr:get_host()
  42. if rule['map']:get_key(key) then
  43. task:insert_result(rule['symbol'], 1)
  44. logger.infox(task, '<%1> email: \'%2\' is found in list: %3',
  45. task:get_message_id(), key, rule['symbol'])
  46. end
  47. else
  48. local key = string.format('%s@%s', addr:get_user(), addr:get_host())
  49. if rule['map']:get_key(key) then
  50. task:insert_result(rule['symbol'], 1)
  51. logger.infox(task, '<%1> email: \'%2\' is found in list: %3',
  52. task:get_message_id(), key, rule['symbol'])
  53. end
  54. end
  55. end
  56. end
  57. -- Check email
  58. local function check_emails(task)
  59. local emails = task:get_emails()
  60. local checked = {}
  61. if emails then
  62. for _,addr in ipairs(emails) do
  63. local to_check = string.format('%s@%s', addr:get_user(), addr:get_host())
  64. if not checked['to_check'] then
  65. for _,rule in ipairs(rules) do
  66. check_email_rule(task, rule, addr)
  67. end
  68. checked[to_check] = true
  69. end
  70. end
  71. end
  72. end
  73. local opts = rspamd_config:get_all_opt('emails', 'rule')
  74. if opts and type(opts) == 'table' then
  75. local r = opts['rule']
  76. if r then
  77. for k,v in pairs(r) do
  78. local rule = v
  79. if not rule['symbol'] then
  80. rule['symbol'] = k
  81. end
  82. if rule['map'] then
  83. rule['name'] = rule['map']
  84. rule['map'] = rspamd_config:add_map({
  85. url = rule['name'],
  86. description = string.format('Emails rule %s', rule['symbol']),
  87. type = 'regexp'
  88. })
  89. end
  90. if not rule['symbol'] or (not rule['map'] and not rule['dnsbl']) then
  91. logger.errx(rspamd_config, 'incomplete rule')
  92. else
  93. table.insert(rules, rule)
  94. end
  95. end
  96. end
  97. end
  98. if #rules > 0 then
  99. -- add fake symbol to check all maps inside a single callback
  100. local id = rspamd_config:register_symbol({
  101. type = 'callback',
  102. callback = check_emails
  103. })
  104. for _,rule in ipairs(rules) do
  105. rspamd_config:register_symbol({
  106. name = rule['symbol'],
  107. type = 'virtual',
  108. parent = id
  109. })
  110. end
  111. end