]> source.dussan.org Git - rspamd.git/commitdiff
[MajorFeature] Add preliminary version of updates
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 5 Mar 2016 13:36:51 +0000 (13:36 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 5 Mar 2016 13:36:51 +0000 (13:36 +0000)
This plugin is intended to load dynamic updates for rspamd. Now its
functionality is very limited.

src/plugins/lua/rspamd_update.lua [new file with mode: 0644]

diff --git a/src/plugins/lua/rspamd_update.lua b/src/plugins/lua/rspamd_update.lua
new file mode 100644 (file)
index 0000000..85b49bb
--- /dev/null
@@ -0,0 +1,116 @@
+--[[
+Copyright (c) 2016, 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.
+]]--
+
+-- 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