From e242903967917614509a7eca05c4d6d9988f4a83 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Sat, 5 Mar 2016 13:36:51 +0000 Subject: [MajorFeature] Add preliminary version of updates This plugin is intended to load dynamic updates for rspamd. Now its functionality is very limited. --- src/plugins/lua/rspamd_update.lua | 116 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/plugins/lua/rspamd_update.lua diff --git a/src/plugins/lua/rspamd_update.lua b/src/plugins/lua/rspamd_update.lua new file mode 100644 index 000000000..85b49bb10 --- /dev/null +++ b/src/plugins/lua/rspamd_update.lua @@ -0,0 +1,116 @@ +--[[ +Copyright (c) 2016, Vsevolod Stakhov + +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. +]]-- + +-- This plugin implements dynamic updates for rspamd + +local ucl = require "ucl" +require "fun" () +local rspamd_logger = require "rspamd_logger" +local updates_priority = 2 +local rspamd_config = rspamd_config +local hash = require "rspamd_cryptobox_hash" +local rspamd_version = rspamd_version + +local function process_symbols(obj) + each(function(sym, score) + rspamd_config:set_metric_symbol({ + name = sym, + score = score, + priority = updates_priority + }) + end, obj) +end +local function process_actions(obj) + each(function(act, score) + rspamd_config:set_metric_action({ + name = act, + score = score, + priority = updates_priority + }) + end, obj) +end + +local function process_actions(obj) + each(function(key, code) + dostring(code) + end, obj) +end + +local function check_version(obj) + local ret = true + + if obj['min_version'] then + if rspamd_version('cmp', obj['min_version']) < 0 then + ret = false + rspamd_logger.errx(rspamd_config, 'updates require at least %s version of rspamd', + obj['min_version']) + end + end + if obj['max_version'] then + if rspamd_version('cmp', obj['max_version']) > 0 then + ret = false + rspamd_logger.errx(rspamd_config, 'updates require maximum %s version of rspamd', + obj['max_version']) + end + end + + return ret +end + +local function process_updates(data) + local ucl = require "ucl" + local parser = ucl.parser() + local res,err = parser:parse_string(data) + + if not res then + rspamd_logger.warnx(rspamd_config, 'cannot parse updates map: ' .. err) + else + local h = hash.create() + h:update(data) + local obj = parser:get_object() + + if check_version(obj) then + if obj['symbols'] then + process_symbols(obj['symbols']) + end + if obj['actions'] then + process_actions(obj['actions']) + end + if obj['rules'] then + process_rules(obj['rules']) + end + + rspamd_logger.infox(rspamd_config, 'loaded new rules with hash "%s"', + h:hex()) + end + end + + return res +end + +-- Configuration part +local section = rspamd_config:get_all_opt("rspamd_update") +if section then + each(function(k, elt) + if k == 'priority' then + updates_priority = tonumber(elt) + else + if not rspamd_config:add_map(elt, "rspamd updates map", process_updates) then + rspamd_logger.errx(rspamd_config, 'cannot load settings from %1', elt) + end + end + end, section) +end -- cgit v1.2.3