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");
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;
}
{
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");
}
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;
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;
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;
#include "map.h"
#include "main.h"
#include "settings.h"
+#include "filter.h"
#include "json/jansson.h"
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)
{
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;
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;
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);
}
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)));
}
}
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)
{