From 16b914e3eadc0bbc42df7a49081b8215742a6c76 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Mon, 9 Sep 2024 18:55:55 +0100 Subject: [PATCH] [Feature] Allow differen modes for fuzzy rules --- src/plugins/fuzzy_check.c | 58 +++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/src/plugins/fuzzy_check.c b/src/plugins/fuzzy_check.c index 6ca6f3459..ece9a91e0 100644 --- a/src/plugins/fuzzy_check.c +++ b/src/plugins/fuzzy_check.c @@ -71,6 +71,12 @@ struct fuzzy_mapping { double weight; }; +enum fuzzy_rule_mode { + fuzzy_rule_read_only, + fuzzy_rule_write_only, + fuzzy_rule_read_write +}; + struct fuzzy_rule { struct upstream_list *servers; const char *symbol; @@ -87,7 +93,7 @@ struct fuzzy_rule { struct rspamd_cryptobox_pubkey *peer_key; double max_score; double weight_threshold; - gboolean read_only; + enum fuzzy_rule_mode mode; gboolean skip_unknown; gboolean no_share; gboolean no_subject; @@ -331,7 +337,7 @@ fuzzy_rule_new(const char *default_symbol, rspamd_mempool_t *pool) rspamd_mempool_add_destructor(pool, (rspamd_mempool_destruct_t) g_hash_table_unref, rule->mappings); - rule->read_only = FALSE; + rule->mode = fuzzy_rule_read_write; rule->weight_threshold = NAN; return rule; @@ -461,7 +467,26 @@ fuzzy_parse_rule(struct rspamd_config *cfg, const ucl_object_t *obj, if ((value = ucl_object_lookup(obj, "read_only")) != NULL) { - rule->read_only = ucl_obj_toboolean(value); + rule->mode = ucl_obj_toboolean(value) ? fuzzy_rule_read_only : fuzzy_rule_read_write; + } + + if ((value = ucl_object_lookup(obj, "mode")) != NULL) { + const char *mode_str = ucl_object_tostring(value); + + if (g_ascii_strcasecmp(mode_str, "read_only") == 0) { + rule->mode = fuzzy_rule_read_only; + } + else if (g_ascii_strcasecmp(mode_str, "write_only") == 0) { + rule->mode = fuzzy_rule_write_only; + } + else if (g_ascii_strcasecmp(mode_str, "read_write") == 0) { + rule->mode = fuzzy_rule_read_write; + } + else { + msg_warn_config("unknown mode: %s, use read_write by default", + mode_str); + rule->mode = fuzzy_rule_read_write; + } } if ((value = ucl_object_lookup(obj, "skip_unknown")) != NULL) { @@ -3450,11 +3475,14 @@ fuzzy_symbol_callback(struct rspamd_task *task, PTR_ARRAY_FOREACH(fuzzy_module_ctx->fuzzy_rules, i, rule) { - commands = fuzzy_generate_commands(task, rule, FUZZY_CHECK, 0, 0, 0); + if (rule->mode != fuzzy_rule_write_only) { + commands = fuzzy_generate_commands(task, rule, FUZZY_CHECK, 0, 0, 0); - if (commands != NULL) { - register_fuzzy_client_call(task, rule, commands); + if (commands != NULL) { + register_fuzzy_client_call(task, rule, commands); + } } + /* Skip write only rules from checks */ } rspamd_symcache_item_async_dec_check(task, item, M); @@ -3541,9 +3569,9 @@ register_fuzzy_controller_call(struct rspamd_http_connection_entry *entry, } static void -fuzzy_process_handler(struct rspamd_http_connection_entry *conn_ent, - struct rspamd_http_message *msg, int cmd, int value, int flag, - struct fuzzy_ctx *ctx, gboolean is_hash, unsigned int flags) +fuzzy_modify_handler(struct rspamd_http_connection_entry *conn_ent, + struct rspamd_http_message *msg, int cmd, int value, int flag, + struct fuzzy_ctx *ctx, gboolean is_hash, unsigned int flags) { struct fuzzy_rule *rule; struct rspamd_controller_session *session = conn_ent->ud; @@ -3591,7 +3619,7 @@ fuzzy_process_handler(struct rspamd_http_connection_entry *conn_ent, PTR_ARRAY_FOREACH(fuzzy_module_ctx->fuzzy_rules, i, rule) { - if (rule->read_only) { + if (rule->mode == fuzzy_rule_read_only) { continue; } @@ -3846,8 +3874,8 @@ fuzzy_controller_handler(struct rspamd_http_connection_entry *conn_ent, send_flags |= FUZZY_CHECK_FLAG_NOTEXT; } - fuzzy_process_handler(conn_ent, msg, cmd, value, flag, - (struct fuzzy_ctx *) ctx, is_hash, send_flags); + fuzzy_modify_handler(conn_ent, msg, cmd, value, flag, + (struct fuzzy_ctx *) ctx, is_hash, send_flags); return 0; } @@ -3929,7 +3957,7 @@ fuzzy_check_lua_process_learn(struct rspamd_task *task, if (!res) { break; } - if (rule->read_only) { + if (rule->mode == fuzzy_rule_read_only) { continue; } @@ -4231,7 +4259,7 @@ fuzzy_lua_gen_hashes_handler(lua_State *L) PTR_ARRAY_FOREACH(fuzzy_module_ctx->fuzzy_rules, i, rule) { - if (rule->read_only) { + if (rule->mode == fuzzy_rule_read_only) { continue; } @@ -4459,7 +4487,7 @@ fuzzy_lua_list_storages(lua_State *L) { lua_newtable(L); - lua_pushboolean(L, rule->read_only); + lua_pushboolean(L, rule->mode == fuzzy_rule_read_only); lua_setfield(L, -2, "read_only"); /* Push servers */ -- 2.39.5