aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lualib/lua_squeeze_rules.lua97
-rw-r--r--lualib/lua_util.lua1
-rw-r--r--rules/headers_checks.lua2
-rw-r--r--rules/misc.lua4
-rw-r--r--src/lua/lua_config.c84
5 files changed, 175 insertions, 13 deletions
diff --git a/lualib/lua_squeeze_rules.lua b/lualib/lua_squeeze_rules.lua
new file mode 100644
index 000000000..d740e2ee0
--- /dev/null
+++ b/lualib/lua_squeeze_rules.lua
@@ -0,0 +1,97 @@
+--[[
+Copyright (c) 2018, 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.
+]]--
+
+local exports = {}
+local logger = require 'rspamd_logger'
+
+-- Squeezed rules part
+local squeezed_rules = {} -- plain vector of all rules squeezed
+local squeezed_symbols = {} -- indexed by name of symbol
+local squeezed_deps = {} -- squeezed deps
+local SN = 'lua_squeeze'
+local squeeze_function_id
+
+local function lua_squeeze_function(task)
+ if not squeezed_symbols then
+ for k,v in pairs(squeezed_symbols) do
+ if not squeezed_exceptions[k] then
+ logger.debugm(SN, task, 'added squeezed rule: %s', k)
+ table.insert(squeezed_rules, v)
+ else
+ logger.debugm(SN, task, 'skipped squeezed rule: %s', k)
+ end
+ end
+
+ squeezed_symbols = nil
+ end
+
+ for _,func in ipairs(squeezed_rules) do
+ local ret = func(task)
+
+ if ret then
+ -- Function has returned something, so it is rule, not a plugin
+ logger.errx(task, 'hui: %s', ret)
+ end
+ end
+end
+
+exports.squeeze_rule = function(s, func)
+ if s then
+ if not squeezed_symbols[s] then
+ squeezed_symbols[s] = {
+ cb = func,
+ order = 0,
+ }
+ logger.debugm(SN, rspamd_config, 'squeezed rule: %s', s)
+ else
+ logger.warnx(rspamd_config, 'duplicate symbol registered: %s, skip', s)
+ end
+ else
+ -- Unconditionally add function to the squeezed rules
+ logger.debugm(SN, rspamd_config, 'squeezed unnamed rule: %s', #squeezed_rules)
+ table.insert(squeezed_rules, func)
+ end
+
+ if not squeeze_function_id then
+ squeeze_function_id = rspamd_config:register_symbol{
+ type = 'callback',
+ callback = lua_squeeze_function,
+ name = 'LUA_SQUEEZE',
+ description = 'Meta rule for Lua rules that can be squeezed',
+ no_squeeze = true, -- to avoid infinite recursion
+ }
+ end
+
+ return squeeze_function_id
+end
+
+exports.squeeze_dependency = function(from, to)
+ logger.debugm(SN, rspamd_config, 'squeeze dep %s->%s', to, from)
+
+ if not squeezed_deps[to] then
+ squeezed_deps[to] = {}
+ end
+
+ if not squeezed_symbols[to][from] then
+ squeezed_symbols[to][from] = true
+ else
+ logger.warnx('duplicate dependency %s->%s', to, from)
+ end
+
+ return true
+end
+
+return exports \ No newline at end of file
diff --git a/lualib/lua_util.lua b/lualib/lua_util.lua
index d41d79fea..33d7e3714 100644
--- a/lualib/lua_util.lua
+++ b/lualib/lua_util.lua
@@ -22,6 +22,7 @@ limitations under the License.
local exports = {}
local lpeg = require 'lpeg'
+
local split_grammar = {}
local function rspamd_str_split(s, sep)
local gr = split_grammar[sep]
diff --git a/rules/headers_checks.lua b/rules/headers_checks.lua
index 334e0ab93..00f2e505a 100644
--- a/rules/headers_checks.lua
+++ b/rules/headers_checks.lua
@@ -310,7 +310,7 @@ rspamd_config:register_symbol{
group = 'headers',
}
-rspamd_config:register_dependency(check_replyto_id, 'FROM_NAME_HAS_TITLE')
+rspamd_config:register_dependency('CHECK_REPLYTO', 'FROM_NAME_HAS_TITLE')
local check_mime_id = rspamd_config:register_symbol{
name = 'CHECK_MIME',
diff --git a/rules/misc.lua b/rules/misc.lua
index 702431c1a..2646e42d6 100644
--- a/rules/misc.lua
+++ b/rules/misc.lua
@@ -338,8 +338,8 @@ local freemail_reply_neq_from_id = rspamd_config:register_symbol({
score = 3.0,
group = 'headers',
})
-rspamd_config:register_dependency(freemail_reply_neq_from_id, 'FREEMAIL_REPLYTO')
-rspamd_config:register_dependency(freemail_reply_neq_from_id, 'FREEMAIL_FROM')
+rspamd_config:register_dependency('FREEMAIL_REPLYTO_NEQ_FROM_DOM', 'FREEMAIL_REPLYTO')
+rspamd_config:register_dependency('FREEMAIL_REPLYTO_NEQ_FROM_DOM', 'FREEMAIL_FROM')
rspamd_config.OMOGRAPH_URL = {
callback = function(task)
diff --git a/src/lua/lua_config.c b/src/lua/lua_config.c
index b03c11910..d6a4ad550 100644
--- a/src/lua/lua_config.c
+++ b/src/lua/lua_config.c
@@ -1277,13 +1277,13 @@ rspamd_register_symbol_fromlua (lua_State *L,
if (ref != -1) {
/*
- * We call for routine called lua_util.squeeze_rule if it exists
+ * We call for routine called lua_squeeze_rules.squeeze_rule if it exists
*/
lua_pushcfunction (L, &rspamd_lua_traceback);
err_idx = lua_gettop (L);
if (!no_squeeze && (type & (SYMBOL_TYPE_CALLBACK|SYMBOL_TYPE_NORMAL)) &&
- rspamd_lua_require_function (L, "lua_util", "squeeze_rule")) {
+ rspamd_lua_require_function (L, "lua_squeeze_rules", "squeeze_rule")) {
if (name) {
lua_pushstring (L, name);
}
@@ -1297,14 +1297,16 @@ rspamd_register_symbol_fromlua (lua_State *L,
/* Now call for squeeze function */
if (lua_pcall (L, 2, 1, err_idx) != 0) {
GString *tb = lua_touserdata (L, -1);
- msg_err_config ("call to finishing script failed: %v", tb);
+ msg_err_config ("call to squeeze_rule failed: %v", tb);
if (tb) {
g_string_free (tb, TRUE);
}
}
- if (!lua_toboolean (L, -1)) {
+ ret = lua_tonumber (L, -1);
+
+ if (ret == -1) {
/* Do direct registration */
cd = rspamd_mempool_alloc0 (cfg->cfg_pool,
sizeof (struct lua_callback_data));
@@ -1324,6 +1326,9 @@ rspamd_register_symbol_fromlua (lua_State *L,
cd,
type,
parent);
+ rspamd_mempool_add_destructor (cfg->cfg_pool,
+ (rspamd_mempool_destruct_t)lua_destroy_cfg_symbol,
+ cd);
}
}
else {
@@ -1345,6 +1350,9 @@ rspamd_register_symbol_fromlua (lua_State *L,
cd,
type,
parent);
+ rspamd_mempool_add_destructor (cfg->cfg_pool,
+ (rspamd_mempool_destruct_t)lua_destroy_cfg_symbol,
+ cd);
}
/* Cleanup lua stack */
@@ -1360,10 +1368,6 @@ rspamd_register_symbol_fromlua (lua_State *L,
parent);
}
- rspamd_mempool_add_destructor (cfg->cfg_pool,
- (rspamd_mempool_destruct_t)lua_destroy_cfg_symbol,
- cd);
-
return ret;
}
@@ -1812,12 +1816,52 @@ lua_config_register_callback_symbol_priority (lua_State * L)
return 1;
}
+static gboolean
+rspamd_lua_squeeze_dependency (lua_State *L, struct rspamd_config *cfg,
+ const gchar *name,
+ const gchar *from)
+{
+ gint err_idx;
+ gboolean ret = FALSE;
+
+ lua_pushcfunction (L, &rspamd_lua_traceback);
+ err_idx = lua_gettop (L);
+
+ if (rspamd_lua_require_function (L, "lua_squeeze_rules", "squeeze_dependency")) {
+ lua_pushstring (L, name);
+
+ if (from) {
+ lua_pushstring (L, from);
+ }
+ else {
+ lua_pushnil (L);
+ }
+
+ if (lua_pcall (L, 2, 1, err_idx) != 0) {
+ GString *tb = lua_touserdata (L, -1);
+ msg_err_config ("call to squeeze_dependency script failed: %v", tb);
+
+ if (tb) {
+ g_string_free (tb, TRUE);
+ }
+ }
+ else {
+ ret = lua_toboolean (L, -1);
+ }
+ }
+
+ lua_settop (L, err_idx - 1);
+
+ return ret;
+}
+
static gint
lua_config_register_dependency (lua_State * L)
{
struct rspamd_config *cfg = lua_check_config (L, 1);
const gchar *name = NULL, *from = NULL;
gint id;
+ gboolean skip_squeeze = FALSE;
if (cfg == NULL) {
lua_error (L);
@@ -1828,16 +1872,36 @@ lua_config_register_dependency (lua_State * L)
id = luaL_checknumber (L, 2);
name = luaL_checkstring (L, 3);
+ if (lua_isboolean (L, 4)) {
+ skip_squeeze = lua_toboolean (L, 4);
+ }
+
+ msg_warn_config ("calling for obsolete method to register deps for symbol %d->%s",
+ id, name);
+
if (id > 0 && name != NULL) {
- rspamd_symbols_cache_add_dependency (cfg->cache, id, name);
+
+ if (skip_squeeze || !rspamd_lua_squeeze_dependency (L, cfg, name,
+ rspamd_symbols_cache_symbol_by_id (cfg->cache, id))) {
+ rspamd_symbols_cache_add_dependency (cfg->cache, id, name);
+ }
}
}
else {
from = luaL_checkstring (L,2);
name = luaL_checkstring (L, 3);
+ if (lua_isboolean (L, 4)) {
+ skip_squeeze = lua_toboolean (L, 4);
+ }
+
if (from != NULL && name != NULL) {
- rspamd_symbols_cache_add_delayed_dependency (cfg->cache, from, name);
+
+ if (skip_squeeze || !rspamd_lua_squeeze_dependency (L, cfg, name, from)) {
+ rspamd_symbols_cache_add_delayed_dependency (cfg->cache, from,
+ name);
+ }
+
}
}