123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- --[[
- Copyright (c) 2011-2015, Vsevolod Stakhov <vsevolod@highsecure.ru>
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- ]]--
-
- -- Emails is module for different checks for emails inside messages
-
- -- Rules format:
- -- symbol = sym, map = file:///path/to/file, domain_only = yes
- -- symbol = sym2, dnsbl = bl.somehost.com, domain_only = no
- local rules = {}
- local logger = require "rspamd_logger"
-
- -- Check rule for a single email
- local function check_email_rule(task, rule, addr)
- local function emails_dns_cb(resolver, to_resolve, results, err)
- if results then
- logger.infox(task, '<%1> email: [%2] resolved for symbol: %3',
- task:get_message_id(), to_resolve, rule['symbol'])
- task:insert_result(rule['symbol'], 1)
- end
- end
- if rule['dnsbl'] then
- local to_resolve = ''
- if rule['domain_only'] then
- to_resolve = string.format('%s.%s', addr:get_host(), rule['dnsbl'])
- else
- to_resolve = string.format('%s.%s.%s', addr:get_user(), addr:get_host(), rule['dnsbl'])
- end
-
- task:get_resolver():resolve_a({
- task=task,
- name = to_resolve,
- callback = emails_dns_cb})
- elseif rule['map'] then
- if rule['domain_only'] then
- local key = addr:get_host()
- if rule['map']:get_key(key) then
- task:insert_result(rule['symbol'], 1)
- logger.infox(task, '<%1> email: \'%2\' is found in list: %3',
- task:get_message_id(), key, rule['symbol'])
- end
- else
- local key = string.format('%s@%s', addr:get_user(), addr:get_host())
- if rule['map']:get_key(key) then
- task:insert_result(rule['symbol'], 1)
- logger.infox(task, '<%1> email: \'%2\' is found in list: %3',
- task:get_message_id(), key, rule['symbol'])
- end
- end
- end
- end
-
- -- Check email
- local function check_emails(task)
- local emails = task:get_emails()
- local checked = {}
- if emails then
- for _,addr in ipairs(emails) do
- local to_check = string.format('%s@%s', addr:get_user(), addr:get_host())
- if not checked['to_check'] then
- for _,rule in ipairs(rules) do
- check_email_rule(task, rule, addr)
- end
- checked[to_check] = true
- end
- end
- end
- end
-
- local opts = rspamd_config:get_all_opt('emails', 'rule')
- if opts and type(opts) == 'table' then
- local r = opts['rule']
-
- if r then
- for k,v in pairs(r) do
- local rule = v
- if not rule['symbol'] then
- rule['symbol'] = k
- end
-
- if rule['map'] then
- rule['name'] = rule['map']
- rule['map'] = rspamd_config:add_map({
- url = rule['name'],
- description = string.format('Emails rule %s', rule['symbol']),
- type = 'regexp'
- })
- end
- if not rule['symbol'] or (not rule['map'] and not rule['dnsbl']) then
- logger.errx(rspamd_config, 'incomplete rule')
- else
- table.insert(rules, rule)
- end
- end
- end
- end
-
- if #rules > 0 then
- -- add fake symbol to check all maps inside a single callback
- local id = rspamd_config:register_symbol({
- type = 'callback',
- callback = check_emails
- })
- for _,rule in ipairs(rules) do
- rspamd_config:register_symbol({
- name = rule['symbol'],
- type = 'virtual',
- parent = id
- })
- end
- end
|