]> source.dussan.org Git - rspamd.git/commitdiff
[Feature] Allow differen modes for fuzzy rules 5131/head
authorVsevolod Stakhov <vsevolod@rspamd.com>
Mon, 9 Sep 2024 17:55:55 +0000 (18:55 +0100)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Mon, 9 Sep 2024 17:55:55 +0000 (18:55 +0100)
src/plugins/fuzzy_check.c

index 6ca6f34591702a2b6f24b41fd8fa506e4c4c0144..ece9a91e0657a56c08b3c21aedde9e6e1703089a 100644 (file)
@@ -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 */