Kaynağa Gözat

* Add ability to recursive scan over multipart's parts for functions:

 - content_type_is_type
 - content_type_is_subtype
 - content_type_compare_param
 - content_type_has_param
* Add ability to specify any of actions in user's settings, not only reject.
tags/0.3.3
Vsevolod Stakhov 13 yıl önce
ebeveyn
işleme
7a09c641f8
8 değiştirilmiş dosya ile 416 ekleme ve 172 silme
  1. 2
    24
      src/cfg_xml.c
  2. 241
    86
      src/expressions.c
  3. 74
    0
      src/filter.c
  4. 4
    0
      src/filter.h
  5. 6
    53
      src/protocol.c
  6. 0
    3
      src/protocol.h
  7. 87
    6
      src/settings.c
  8. 2
    0
      src/settings.h

+ 2
- 24
src/cfg_xml.c Dosyayı Görüntüle

@@ -690,28 +690,6 @@ worker_handle_bind (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GH
return TRUE;
}

static inline gboolean
check_action (const gchar *data, gint *result)
{
if (g_ascii_strncasecmp (data, "reject", sizeof ("reject") - 1) == 0) {
*result = METRIC_ACTION_REJECT;
}
else if (g_ascii_strncasecmp (data, "greylist", sizeof ("greylist") - 1) == 0) {
*result = METRIC_ACTION_GREYLIST;
}
else if (g_ascii_strncasecmp (data, "add_header", sizeof ("add_header") - 1) == 0) {
*result = METRIC_ACTION_ADD_HEADER;
}
else if (g_ascii_strncasecmp (data, "rewrite_subject", sizeof ("rewrite_subject") - 1) == 0) {
*result = METRIC_ACTION_REWRITE_SUBJECT;
}
else {
msg_err ("unknown action for metric: %s", data);
return FALSE;
}
return TRUE;
}

gboolean
handle_metric_action (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset)
{
@@ -722,14 +700,14 @@ handle_metric_action (struct config_file *cfg, struct rspamd_xml_userdata *ctx,

/* First of all check whether we have data with weight (reject:50 for example) */
if ((p = strchr (data, ':')) == NULL) {
if (check_action (data, &res)) {
if (check_action_str (data, &res)) {
metric->action = res;
return TRUE;
}
return FALSE;
}
else {
if (!check_action (data, &res)) {
if (!check_action_str (data, &res)) {
return FALSE;
}
else {

+ 241
- 86
src/expressions.c Dosyayı Görüntüle

@@ -1003,10 +1003,13 @@ rspamd_content_type_compare_param (struct worker_task * task, GList * args, void
gchar *param_name, *param_pattern;
const gchar *param_data;
struct rspamd_regexp *re;
struct expression_argument *arg;
struct expression_argument *arg, *arg1;
GMimeObject *part;
const GMimeContentType *ct;
GMimeContentType *ct;
gint r;
gboolean recursive = FALSE, result = FALSE;
GList *cur;
struct mime_part *cur_part;

if (args == NULL) {
msg_warn ("no parameters to function");
@@ -1022,45 +1025,83 @@ rspamd_content_type_compare_param (struct worker_task * task, GList * args, void
arg = get_function_arg (args->data, task, TRUE);
param_pattern = arg->data;


part = g_mime_message_get_mime_part (task->message);
if (part) {
ct = g_mime_object_get_content_type (part);
ct = (GMimeContentType *)g_mime_object_get_content_type (part);
if (args->next) {
args = g_list_next (args);
arg1 = get_function_arg (args->data, task, TRUE);
if (g_ascii_strncasecmp (arg1->data, "true", sizeof ("true") - 1) == 0) {
recursive = TRUE;
}
}
else {
/*
* If user did not specify argument, let's assume that he wants
* recursive search if mime part is multipart/mixed
*/
if (g_mime_content_type_is_type (ct, "multipart", "*")) {
recursive = TRUE;
}
}

if (recursive) {
cur = task->parts;
}

#ifndef GMIME24
g_object_unref (part);
#endif
for (;;) {
if ((param_data = g_mime_content_type_get_parameter ((GMimeContentType *)ct, param_name)) == NULL) {
result = FALSE;
}
if (*param_pattern == '/') {
/* This is regexp, so compile and create g_regexp object */
if ((re = re_cache_check (param_pattern, task->cfg->cfg_pool)) == NULL) {
re = parse_regexp (task->cfg->cfg_pool, param_pattern, task->cfg->raw_mode);
if (re == NULL) {
msg_warn ("cannot compile regexp for function");
return FALSE;
}
re_cache_add (param_pattern, re, task->cfg->cfg_pool);
}
if ((r = task_cache_check (task, re)) == -1) {
if (g_regex_match (re->regexp, param_data, 0, NULL) == TRUE) {
task_cache_add (task, re, 1);
return TRUE;
}
task_cache_add (task, re, 0);
}
else {

if ((param_data = g_mime_content_type_get_parameter ((GMimeContentType *)ct, param_name)) == NULL) {
return FALSE;
}
if (*param_pattern == '/') {
/* This is regexp, so compile and create g_regexp object */
if ((re = re_cache_check (param_pattern, task->cfg->cfg_pool)) == NULL) {
re = parse_regexp (task->cfg->cfg_pool, param_pattern, task->cfg->raw_mode);
if (re == NULL) {
msg_warn ("cannot compile regexp for function");
return FALSE;
}
re_cache_add (param_pattern, re, task->cfg->cfg_pool);
}
if ((r = task_cache_check (task, re)) == -1) {
if (g_regex_match (re->regexp, param_data, 0, NULL) == TRUE) {
task_cache_add (task, re, 1);
else {
/* Just do strcasecmp */
if (g_ascii_strcasecmp (param_data, param_pattern) == 0) {
return TRUE;
}
task_cache_add (task, re, 0);
}
else {
return r == 1;
/* Get next part */
if (! recursive) {
return result;
}
}
else {
/* Just do strcasecmp */
if (g_ascii_strcasecmp (param_data, param_pattern) == 0) {
return TRUE;
else if (cur != NULL) {
cur_part = cur->data;
if (cur_part->type != NULL) {
ct = cur_part->type;
}
cur = g_list_next (cur);
}
else {
/* All is done */
return result;
}
}
}

}

return FALSE;
}
@@ -1070,9 +1111,12 @@ rspamd_content_type_has_param (struct worker_task * task, GList * args, void *un
{
gchar *param_name;
const gchar *param_data;
struct expression_argument *arg;
struct expression_argument *arg, *arg1;
GMimeObject *part;
const GMimeContentType *ct;
GMimeContentType *ct;
gboolean recursive = FALSE, result = FALSE;
GList *cur;
struct mime_part *cur_part;

if (args == NULL) {
msg_warn ("no parameters to function");
@@ -1080,18 +1124,55 @@ rspamd_content_type_has_param (struct worker_task * task, GList * args, void *un
}
arg = get_function_arg (args->data, task, TRUE);
param_name = arg->data;

part = g_mime_message_get_mime_part (task->message);
if (part) {
ct = g_mime_object_get_content_type (part);
ct = (GMimeContentType *)g_mime_object_get_content_type (part);
if (args->next) {
args = g_list_next (args);
arg1 = get_function_arg (args->data, task, TRUE);
if (g_ascii_strncasecmp (arg1->data, "true", sizeof ("true") - 1) == 0) {
recursive = TRUE;
}
}
else {
/*
* If user did not specify argument, let's assume that he wants
* recursive search if mime part is multipart/mixed
*/
if (g_mime_content_type_is_type (ct, "multipart", "*")) {
recursive = TRUE;
}
}

if (recursive) {
cur = task->parts;
}

#ifndef GMIME24
g_object_unref (part);
#endif

debug_task ("checking %s param", param_name);
param_data = g_mime_content_type_get_parameter ((GMimeContentType *)ct, param_name);
if (param_data == NULL) {
return FALSE;
for (;;) {
if ((param_data = g_mime_content_type_get_parameter ((GMimeContentType *)ct, param_name)) != NULL) {
return TRUE;
}
/* Get next part */
if (! recursive) {
return result;
}
else if (cur != NULL) {
cur_part = cur->data;
if (cur_part->type != NULL) {
ct = cur_part->type;
}
cur = g_list_next (cur);
}
else {
/* All is done */
return result;
}
}

}

return TRUE;
@@ -1100,58 +1181,95 @@ rspamd_content_type_has_param (struct worker_task * task, GList * args, void *un
gboolean
rspamd_content_type_is_subtype (struct worker_task *task, GList * args, void *unused)
{
gchar *param_pattern;
gchar *param_pattern;
struct rspamd_regexp *re;
struct expression_argument *arg;
struct expression_argument *arg, *arg1;
GMimeObject *part;
GMimeContentType *ct;
gint r;
gboolean recursive = FALSE, result = FALSE;
GList *cur;
struct mime_part *cur_part;

if (args == NULL) {
msg_warn ("no parameters to function");
return FALSE;
}

arg = get_function_arg (args->data, task, TRUE);
param_pattern = arg->data;

part = g_mime_message_get_mime_part (task->message);
if (part) {
ct = (GMimeContentType *)g_mime_object_get_content_type (part);
if (args->next) {
args = g_list_next (args);
arg1 = get_function_arg (args->data, task, TRUE);
if (g_ascii_strncasecmp (arg1->data, "true", sizeof ("true") - 1) == 0) {
recursive = TRUE;
}
}
else {
/*
* If user did not specify argument, let's assume that he wants
* recursive search if mime part is multipart/mixed
*/
if (g_mime_content_type_is_type (ct, "multipart", "*")) {
recursive = TRUE;
}
}

if (recursive) {
cur = task->parts;
}

#ifndef GMIME24
g_object_unref (part);
#endif
for (;;) {
if (*param_pattern == '/') {
/* This is regexp, so compile and create g_regexp object */
if ((re = re_cache_check (param_pattern, task->cfg->cfg_pool)) == NULL) {
re = parse_regexp (task->cfg->cfg_pool, param_pattern, task->cfg->raw_mode);
if (re == NULL) {
msg_warn ("cannot compile regexp for function");
return FALSE;
}
re_cache_add (param_pattern, re, task->cfg->cfg_pool);
}
if ((r = task_cache_check (task, re)) == -1) {
if (g_regex_match (re->regexp, ct->subtype, 0, NULL) == TRUE) {
task_cache_add (task, re, 1);
return TRUE;
}
task_cache_add (task, re, 0);
}
else {

if (ct == NULL ) {
return FALSE;
}

if (*param_pattern == '/') {
/* This is regexp, so compile and create g_regexp object */
if ((re = re_cache_check (param_pattern, task->cfg->cfg_pool)) == NULL) {
re = parse_regexp (task->cfg->cfg_pool, param_pattern, task->cfg->raw_mode);
if (re == NULL) {
msg_warn ("cannot compile regexp for function");
return FALSE;
}
re_cache_add (param_pattern, re, task->cfg->cfg_pool);
}
if ((r = task_cache_check (task, re)) == -1) {
if (g_regex_match (re->regexp, ct->subtype, 0, NULL) == TRUE) {
task_cache_add (task, re, 1);
else {
/* Just do strcasecmp */
if (g_ascii_strcasecmp (ct->subtype, param_pattern) == 0) {
return TRUE;
}
task_cache_add (task, re, 0);
}
else {
return r == 1;
/* Get next part */
if (! recursive) {
return result;
}
}
else {
/* Just do strcasecmp */
if (ct->subtype && g_ascii_strcasecmp (ct->subtype, param_pattern) == 0) {
return TRUE;
else if (cur != NULL) {
cur_part = cur->data;
if (cur_part->type != NULL) {
ct = cur_part->type;
}
cur = g_list_next (cur);
}
else {
/* All is done */
return result;
}
}

}

return FALSE;
@@ -1160,59 +1278,96 @@ rspamd_content_type_is_subtype (struct worker_task *task, GList * args, void *un
gboolean
rspamd_content_type_is_type (struct worker_task * task, GList * args, void *unused)
{
gchar *param_pattern;
gchar *param_pattern;
struct rspamd_regexp *re;
struct expression_argument *arg, *arg1;
GMimeObject *part;
GMimeContentType *ct;
struct expression_argument *arg;
gint r;
gboolean recursive = FALSE, result = FALSE;
GList *cur;
struct mime_part *cur_part;

if (args == NULL) {
msg_warn ("no parameters to function");
return FALSE;
}

arg = get_function_arg (args->data, task, TRUE);
param_pattern = arg->data;


part = g_mime_message_get_mime_part (task->message);
if (part) {
ct = (GMimeContentType *)g_mime_object_get_content_type (part);
if (args->next) {
args = g_list_next (args);
arg1 = get_function_arg (args->data, task, TRUE);
if (g_ascii_strncasecmp (arg1->data, "true", sizeof ("true") - 1) == 0) {
recursive = TRUE;
}
}
else {
/*
* If user did not specify argument, let's assume that he wants
* recursive search if mime part is multipart/mixed
*/
if (g_mime_content_type_is_type (ct, "multipart", "*")) {
recursive = TRUE;
}
}

if (recursive) {
cur = task->parts;
}

#ifndef GMIME24
g_object_unref (part);
#endif
for (;;) {
if (*param_pattern == '/') {
/* This is regexp, so compile and create g_regexp object */
if ((re = re_cache_check (param_pattern, task->cfg->cfg_pool)) == NULL) {
re = parse_regexp (task->cfg->cfg_pool, param_pattern, task->cfg->raw_mode);
if (re == NULL) {
msg_warn ("cannot compile regexp for function");
return FALSE;
}
re_cache_add (param_pattern, re, task->cfg->cfg_pool);
}
if ((r = task_cache_check (task, re)) == -1) {
if (g_regex_match (re->regexp, ct->type, 0, NULL) == TRUE) {
task_cache_add (task, re, 1);
return TRUE;
}
task_cache_add (task, re, 0);
}
else {

if (ct == NULL) {
return FALSE;
}

if (*param_pattern == '/') {
/* This is regexp, so compile and create g_regexp object */
if ((re = re_cache_check (param_pattern, task->cfg->cfg_pool)) == NULL) {
re = parse_regexp (task->cfg->cfg_pool, param_pattern, task->cfg->raw_mode);
if (re == NULL) {
msg_warn ("cannot compile regexp for function");
return FALSE;
}
re_cache_add (param_pattern, re, task->cfg->cfg_pool);
}
if ((r = task_cache_check (task, re)) == -1) {
if (g_regex_match (re->regexp, ct->type, 0, NULL) == TRUE) {
task_cache_add (task, re, 1);
else {
/* Just do strcasecmp */
if (g_ascii_strcasecmp (ct->type, param_pattern) == 0) {
return TRUE;
}
task_cache_add (task, re, 0);
}
else {
return r == 1;
/* Get next part */
if (! recursive) {
return result;
}
}
else {
/* Just do strcasecmp */
if (ct->type && g_ascii_strcasecmp (ct->type, param_pattern) == 0) {
return TRUE;
else if (cur != NULL) {
cur_part = cur->data;
if (cur_part->type != NULL) {
ct = cur_part->type;
}
cur = g_list_next (cur);
}
else {
/* All is done */
return result;
}
}

}

return FALSE;

+ 74
- 0
src/filter.c Dosyayı Görüntüle

@@ -612,6 +612,80 @@ insert_headers (struct worker_task *task)
g_hash_table_foreach (task->results, insert_metric_header, task);
}

gboolean
check_action_str (const gchar *data, gint *result)
{
if (g_ascii_strncasecmp (data, "reject", sizeof ("reject") - 1) == 0) {
*result = METRIC_ACTION_REJECT;
}
else if (g_ascii_strncasecmp (data, "greylist", sizeof ("greylist") - 1) == 0) {
*result = METRIC_ACTION_GREYLIST;
}
else if (g_ascii_strncasecmp (data, "add_header", sizeof ("add_header") - 1) == 0) {
*result = METRIC_ACTION_ADD_HEADER;
}
else if (g_ascii_strncasecmp (data, "rewrite_subject", sizeof ("rewrite_subject") - 1) == 0) {
*result = METRIC_ACTION_REWRITE_SUBJECT;
}
else {
msg_err ("unknown action for metric: %s", data);
return FALSE;
}
return TRUE;
}

const gchar *
str_action_metric (enum rspamd_metric_action action)
{
switch (action) {
case METRIC_ACTION_REJECT:
return "reject";
case METRIC_ACTION_SOFT_REJECT:
return "soft reject";
case METRIC_ACTION_REWRITE_SUBJECT:
return "rewrite subject";
case METRIC_ACTION_ADD_HEADER:
return "add header";
case METRIC_ACTION_GREYLIST:
return "greylist";
case METRIC_ACTION_NOACTION:
return "no action";
}

return "unknown action";
}

gint
check_metric_action (double score, double required_score, struct metric *metric)
{
GList *cur;
struct metric_action *action, *selected_action = NULL;

if (score >= required_score) {
return metric->action;
}
else if (metric->actions == NULL) {
return METRIC_ACTION_NOACTION;
}
else {
cur = metric->actions;
while (cur) {
action = cur->data;
if (score >= action->score) {
selected_action = action;
}
cur = g_list_next (cur);
}
if (selected_action) {
return selected_action->action;
}
else {
return METRIC_ACTION_NOACTION;
}
}
}


/*
* vi:ts=4
*/

+ 4
- 0
src/filter.h Dosyayı Görüntüle

@@ -111,4 +111,8 @@ void make_composites (struct worker_task *task);
*/
double factor_consolidation_func (struct worker_task *task, const gchar *metric_name, const gchar *unused);

gboolean check_action_str (const gchar *data, gint *result);
const gchar *str_action_metric (enum rspamd_metric_action action);
gint check_metric_action (double score, double required_score, struct metric *metric);

#endif

+ 6
- 53
src/protocol.c Dosyayı Görüntüle

@@ -620,57 +620,6 @@ show_metric_symbols (struct metric_result *metric_res, struct metric_callback_da
return TRUE;
}

const gchar *
str_action_metric (enum rspamd_metric_action action)
{
switch (action) {
case METRIC_ACTION_REJECT:
return "reject";
case METRIC_ACTION_SOFT_REJECT:
return "soft reject";
case METRIC_ACTION_REWRITE_SUBJECT:
return "rewrite subject";
case METRIC_ACTION_ADD_HEADER:
return "add header";
case METRIC_ACTION_GREYLIST:
return "greylist";
case METRIC_ACTION_NOACTION:
return "no action";
}

return "unknown action";
}

gint
check_metric_action (double score, double required_score, struct metric *metric)
{
GList *cur;
struct metric_action *action, *selected_action = NULL;

if (score >= required_score) {
return metric->action;
}
else if (metric->actions == NULL) {
return METRIC_ACTION_NOACTION;
}
else {
cur = metric->actions;
while (cur) {
action = cur->data;
if (score >= action->score) {
selected_action = action;
}
cur = g_list_next (cur);
}
if (selected_action) {
return selected_action->action;
}
else {
return METRIC_ACTION_NOACTION;
}
}
}

static void
show_metric_result (gpointer metric_name, gpointer metric_value, void *user_data)
{
@@ -682,7 +631,7 @@ show_metric_result (gpointer metric_name, gpointer metric_value, void *user_data
struct metric *m;
gint is_spam = 0;
double ms = 0, rs = 0;
enum rspamd_metric_action action;
enum rspamd_metric_action action = METRIC_ACTION_NOACTION;

if (! cd->alive) {
return;
@@ -730,10 +679,14 @@ show_metric_result (gpointer metric_name, gpointer metric_value, void *user_data
ms = metric_res->metric->required_score;
rs = metric_res->metric->reject_score;
}
if (! check_metric_action_settings (task, metric_res->metric, metric_res->score, &action)) {
action = check_metric_action (metric_res->score, ms, metric_res->metric);
}

if (metric_res->score >= ms) {
is_spam = 1;
}
action = check_metric_action (metric_res->score, ms, metric_res->metric);
if (task->proto == SPAMC_PROTO) {
r = rspamd_snprintf (outbuf, sizeof (outbuf), "Spam: %s ; %.2f / %.2f" CRLF, (is_spam) ? "True" : "False", metric_res->score, ms);
}

+ 0
- 3
src/protocol.h Dosyayı Görüntüle

@@ -77,7 +77,4 @@ gboolean write_reply (struct worker_task *task) G_GNUC_WARN_UNUSED_RESULT;
*/
void register_protocol_command (const gchar *name, protocol_reply_func func);

const gchar *str_action_metric (enum rspamd_metric_action action);
gint check_metric_action (double score, double required_score, struct metric *metric);

#endif

+ 87
- 6
src/settings.c Dosyayı Görüntüle

@@ -27,6 +27,7 @@
#include "map.h"
#include "main.h"
#include "settings.h"
#include "filter.h"
#include "json/jansson.h"

struct json_buf {
@@ -36,6 +37,19 @@ struct json_buf {
size_t buflen;
};

static void
settings_actions_free (gpointer data)
{
GList *cur = data;

while (cur) {
g_free (cur->data);
cur = g_list_next (cur);
}

g_list_free ((GList *)data);
}

static void
settings_free (gpointer data)
{
@@ -104,10 +118,12 @@ void
json_fin_cb (memory_pool_t * pool, struct map_cb_data *data)
{
struct json_buf *jb;
gint nelts, i, n, a;
json_t *js, *cur_elt, *cur_nm, *it_val;
gint nelts, i, n, j;
json_t *js, *cur_elt, *cur_nm, *it_val, *act_it, *act_value;
json_error_t je;
struct metric_action *new_act;
struct rspamd_settings *cur_settings;
GList *cur_act;
gchar *cur_name;
void *json_it;
double *score;
@@ -156,6 +172,7 @@ json_fin_cb (memory_pool_t * pool, struct map_cb_data *data)
cur_settings = g_malloc (sizeof (struct rspamd_settings));
cur_settings->metric_scores = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
cur_settings->reject_scores = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
cur_settings->metric_actions = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, settings_actions_free);
cur_settings->factors = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
cur_settings->whitelist = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
cur_settings->statfile_alias = NULL;
@@ -201,7 +218,29 @@ json_fin_cb (memory_pool_t * pool, struct map_cb_data *data)
if (it_val && json_is_number (it_val)) {
score = g_malloc (sizeof (double));
*score = json_number_value (it_val);
g_hash_table_insert (cur_settings->metric_scores, g_strdup (json_object_iter_key (json_it)), score);
g_hash_table_insert (cur_settings->metric_scores,
g_strdup (json_object_iter_key (json_it)), score);
}
else if (it_val && json_is_object (it_val)) {
/* Assume this as actions hash */
cur_act = NULL;
act_it = json_object_iter (it_val);
while (act_it) {
act_value = json_object_iter_value (act_it);
if (it_val && json_is_number (act_value)) {
if (check_action_str (json_object_iter_key (act_it), &j)) {
new_act = g_malloc (sizeof (struct metric_action));
new_act->action = j;
new_act->score = json_number_value (act_value);
cur_act = g_list_prepend (cur_act, new_act);
}
}
act_it = json_object_iter_next (it_val, act_it);
}
if (cur_act != NULL) {
g_hash_table_insert (cur_settings->metric_actions,
g_strdup (json_object_iter_key (json_it)), cur_act);
}
}
json_it = json_object_iter_next (cur_nm, json_it);
}
@@ -225,10 +264,11 @@ json_fin_cb (memory_pool_t * pool, struct map_cb_data *data)
cur_nm = json_object_get (cur_elt, "whitelist");
if (cur_nm != NULL && json_is_array (cur_nm)) {
n = json_array_size(cur_nm);
for(a = 0; a < n; a++) {
it_val = json_array_get(cur_nm, a);
for(j = 0; j < n; j++) {
it_val = json_array_get(cur_nm, j);
if (it_val && json_is_string (it_val)) {
g_hash_table_insert (cur_settings->whitelist, g_strdup (json_string_value (it_val)), g_strdup (json_string_value (it_val)));
g_hash_table_insert (cur_settings->whitelist,
g_strdup (json_string_value (it_val)), g_strdup (json_string_value (it_val)));
}
}
@@ -390,6 +430,47 @@ check_metric_settings (struct worker_task * task, struct metric * metric, double
return FALSE;
}

gboolean
check_metric_action_settings (struct worker_task *task, struct metric *metric, double score, enum rspamd_metric_action *result)
{
struct rspamd_settings *us = NULL, *ds = NULL;
struct metric_action *act;
GList *cur;
enum rspamd_metric_action res = METRIC_ACTION_NOACTION;

if (check_setting (task, &us, &ds)) {
if (us != NULL) {
if ((cur = g_hash_table_lookup (us->metric_actions, metric->name)) != NULL) {
while (cur) {
act = cur->data;
if (score >= act->score) {
res = act->action;
}
cur = g_list_next (cur);
}
}
}
else if (ds != NULL) {
if ((cur = g_hash_table_lookup (ds->metric_actions, metric->name)) != NULL) {
while (cur) {
act = cur->data;
if (score >= act->score) {
res = act->action;
}
cur = g_list_next (cur);
}
}
}
}

if (res != METRIC_ACTION_NOACTION && result != NULL) {
*result = res;
return TRUE;
}

return FALSE;
}

gboolean
check_factor_settings (struct worker_task * task, const gchar *symbol, double *factor)
{

+ 2
- 0
src/settings.h Dosyayı Görüntüle

@@ -7,6 +7,7 @@
struct rspamd_settings {
GHashTable *metric_scores; /**< hash table of metric require scores for this setting */
GHashTable *reject_scores; /**< hash table of metric reject scores for this setting */
GHashTable *metric_actions; /**< hash table of metric actions for this setting */
GHashTable *factors; /**< hash table of new factors for this setting */
GHashTable *whitelist; /**< hash table of whitelist for this setting */
gchar *statfile_alias; /**< alias for statfile used */
@@ -17,6 +18,7 @@ struct rspamd_settings {
gboolean read_settings (const gchar *path, struct config_file *cfg, GHashTable *table);
void init_settings (struct config_file *cfg);
gboolean check_metric_settings (struct worker_task *task, struct metric *metric, double *score, double *rscore);
gboolean check_metric_action_settings (struct worker_task *task, struct metric *metric, double score, enum rspamd_metric_action *result);
gboolean check_factor_settings (struct worker_task *task, const gchar *symbol, double *factor);
gboolean check_want_spam (struct worker_task *task);


Loading…
İptal
Kaydet