123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- --[[
- Copyright (c) 2022, Vsevolod Stakhov <vsevolod@rspamd.com>
-
- 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.
- ]]--
-
- if confighelp then
- return
- end
-
- -- Trie is rspamd module designed to define and operate with suffix trie
-
- local N = 'trie'
- local rspamd_logger = require "rspamd_logger"
- local rspamd_trie = require "rspamd_trie"
- local fun = require "fun"
- local lua_util = require "lua_util"
-
- local mime_trie
- local raw_trie
- local body_trie
-
- -- here we store all patterns as text
- local mime_patterns = {}
- local raw_patterns = {}
- local body_patterns = {}
-
- -- here we store params for each pattern, so for each i = 1..n patterns[i]
- -- should have corresponding params[i]
- local mime_params = {}
- local raw_params = {}
- local body_params = {}
-
- local function tries_callback(task)
-
- local matched = {}
-
- local function gen_trie_cb(type)
- local patterns = mime_patterns
- local params = mime_params
- if type == 'rawmessage' then
- patterns = raw_patterns
- params = raw_params
- elseif type == 'rawbody' then
- patterns = body_patterns
- params = body_params
- end
-
- return function (idx, pos)
- local param = params[idx]
- local pattern = patterns[idx]
- local pattern_idx = pattern .. tostring(idx) .. type
-
- if param['multi'] or not matched[pattern_idx] then
- lua_util.debugm(N, task, "<%1> matched pattern %2 at pos %3",
- task:get_message_id(), pattern, pos)
- task:insert_result(param['symbol'], 1.0, type)
- if not param['multi'] then
- matched[pattern_idx] = true
- end
- end
- end
- end
-
- if mime_trie then
- mime_trie:search_mime(task, gen_trie_cb('mime'))
- end
- if raw_trie then
- raw_trie:search_rawmsg(task, gen_trie_cb('rawmessage'))
- end
- if body_trie then
- body_trie:search_rawbody(task, gen_trie_cb('rawbody'))
- end
- end
-
- local function process_single_pattern(pat, symbol, cf)
- if pat then
- local multi = false
- if cf['multi'] then multi = true end
-
- if cf['raw'] then
- table.insert(raw_patterns, pat)
- table.insert(raw_params, {symbol=symbol, multi=multi})
- elseif cf['body'] then
- table.insert(body_patterns, pat)
- table.insert(body_params, {symbol=symbol, multi=multi})
- else
- table.insert(mime_patterns, pat)
- table.insert(mime_params, {symbol=symbol, multi=multi})
- end
- end
- end
-
- local function process_trie_file(symbol, cf)
- local file = io.open(cf['file'])
-
- if not file then
- rspamd_logger.errx(rspamd_config, 'Cannot open trie file %1', cf['file'])
- else
- if cf['binary'] then
- rspamd_logger.errx(rspamd_config, 'binary trie patterns are not implemented yet: %1',
- cf['file'])
- else
- for line in file:lines() do
- local pat = string.match(line, '^([^#].*[^%s])%s*$')
- process_single_pattern(pat, symbol, cf)
- end
- end
- end
- end
-
- local function process_trie_conf(symbol, cf)
- if type(cf) ~= 'table' then
- rspamd_logger.errx(rspamd_config, 'invalid value for symbol %1: "%2", expected table',
- symbol, cf)
- return
- end
-
- if cf['file'] then
- process_trie_file(symbol, cf)
- elseif cf['patterns'] then
- fun.each(function(pat)
- process_single_pattern(pat, symbol, cf)
- end, cf['patterns'])
- end
- end
-
- local opts = rspamd_config:get_all_opt("trie")
- if opts then
- for sym, opt in pairs(opts) do
- process_trie_conf(sym, opt)
- end
-
- if #raw_patterns > 0 then
- raw_trie = rspamd_trie.create(raw_patterns)
- rspamd_logger.infox(rspamd_config, 'registered raw search trie from %1 patterns', #raw_patterns)
- end
-
- if #mime_patterns > 0 then
- mime_trie = rspamd_trie.create(mime_patterns)
- rspamd_logger.infox(rspamd_config, 'registered mime search trie from %1 patterns', #mime_patterns)
- end
-
- if #body_patterns > 0 then
- body_trie = rspamd_trie.create(body_patterns)
- rspamd_logger.infox(rspamd_config, 'registered body search trie from %1 patterns', #body_patterns)
- end
-
- local id = -1
- if mime_trie or raw_trie or body_trie then
- id = rspamd_config:register_symbol({
- name = 'TRIE_CALLBACK',
- type = 'callback',
- callback = tries_callback
- })
- else
- rspamd_logger.infox(rspamd_config, 'no tries defined')
- end
-
- if id ~= -1 then
- for sym in pairs(opts) do
- rspamd_config:register_symbol({
- name = sym,
- type = 'virtual',
- parent = id
- })
- end
- end
- else
- rspamd_logger.infox(rspamd_config, "Module is unconfigured")
- lua_util.disable_module(N, "config")
- end
|