Exemple #1
0
gboolean
rspamd_init_filters (struct rspamd_config *cfg, bool reconfig)
{
	GList *cur;
	module_t *mod, **pmod;
	struct module_ctx *mod_ctx;

	/* Init all compiled modules */
	if (!reconfig) {
		for (pmod = cfg->compiled_modules; pmod != NULL && *pmod != NULL; pmod ++) {
			mod = *pmod;
			mod_ctx = g_slice_alloc0 (sizeof (struct module_ctx));

			if (mod->module_init_func (cfg, &mod_ctx) == 0) {
				g_hash_table_insert (cfg->c_modules,
						(gpointer) mod->name,
						mod_ctx);
				mod_ctx->mod = mod;
			}
		}
	}

	cur = g_list_first (cfg->filters);

	while (cur) {
		/* Perform modules configuring */
		mod_ctx = NULL;
		mod_ctx = g_hash_table_lookup (cfg->c_modules, cur->data);

		if (mod_ctx) {
			mod = mod_ctx->mod;
			mod_ctx->enabled = TRUE;

			if (reconfig) {
				(void)mod->module_reconfig_func (cfg);
				msg_debug_config ("reconfig of %s", mod->name);
			}
			else {
				(void)mod->module_config_func (cfg);
			}
		}

		if (mod_ctx == NULL) {
			msg_warn_config ("requested unknown module %s", cur->data);
		}

		cur = g_list_next (cur);
	}

	return rspamd_init_lua_filters (cfg);
}
Exemple #2
0
gboolean
rspamd_config_add_metric_symbol (struct rspamd_config *cfg,
		const gchar *metric_name, const gchar *symbol,
		gdouble score, const gchar *description, const gchar *group,
		gboolean one_shot, gboolean rewrite_existing)
{
	struct rspamd_symbols_group *sym_group;
	struct rspamd_symbol_def *sym_def;
	GList *metric_list;
	struct metric *metric;
	gdouble *score_ptr;

	g_assert (cfg != NULL);
	g_assert (symbol != NULL);

	if (metric_name == NULL) {
		metric_name = DEFAULT_METRIC;
	}

	metric = g_hash_table_lookup (cfg->metrics, metric_name);

	if (metric == NULL) {
		msg_err_config ("metric %s has not been found", metric_name);
		return FALSE;
	}

	if (g_hash_table_lookup (cfg->metrics_symbols, symbol) != NULL &&
			!rewrite_existing) {
		msg_debug_config ("symbol %s has been already registered, do not override");
		return FALSE;
	}

	sym_def =
		rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (struct rspamd_symbol_def));
	score_ptr = rspamd_mempool_alloc (cfg->cfg_pool, sizeof (gdouble));

	*score_ptr = score;
	sym_def->score = score;
	sym_def->weight_ptr = score_ptr;
	sym_def->name = rspamd_mempool_strdup (cfg->cfg_pool, symbol);
	sym_def->one_shot = one_shot;

	if (description) {
		sym_def->description = rspamd_mempool_strdup (cfg->cfg_pool, description);
	}

	msg_debug_config ("registered symbol %s with weight %.2f in metric %s and group %s",
			sym_def->name, score, metric->name, group);

	g_hash_table_insert (metric->symbols, sym_def->name, sym_def);

	if ((metric_list =
		g_hash_table_lookup (cfg->metrics_symbols, sym_def->name)) == NULL) {
		metric_list = g_list_prepend (NULL, metric);
		rspamd_mempool_add_destructor (cfg->cfg_pool,
			(rspamd_mempool_destruct_t)g_list_free,
			metric_list);
		g_hash_table_insert (cfg->metrics_symbols, sym_def->name, metric_list);
	}
	else {
		/* Slow but keep start element of list in safe */
		if (!g_list_find (metric_list, metric)) {
			metric_list = g_list_append (metric_list, metric);
		}
	}

	/* Search for symbol group */
	if (group == NULL) {
		group = "ungrouped";
	}

	sym_group = g_hash_table_lookup (metric->groups, group);
	if (sym_group == NULL) {
		/* Create new group */
		sym_group = rspamd_config_new_group (cfg, metric, group);
	}

	sym_def->gr = sym_group;
	g_hash_table_insert (sym_group->symbols, sym_def->name, sym_def);

	return TRUE;
}
Exemple #3
0
void
rspamd_stat_init (struct rspamd_config *cfg, struct event_base *ev_base)
{
	GList *cur, *curst;
	struct rspamd_classifier_config *clf;
	struct rspamd_statfile_config *stf;
	struct rspamd_stat_backend *bk;
	struct rspamd_statfile *st;
	struct rspamd_classifier *cl;
	const ucl_object_t *cache_obj = NULL, *cache_name_obj;
	const gchar *cache_name = NULL;

	if (stat_ctx == NULL) {
		stat_ctx = g_slice_alloc0 (sizeof (*stat_ctx));
	}

	stat_ctx->backends_subrs = stat_backends;
	stat_ctx->backends_count = G_N_ELEMENTS (stat_backends);
	stat_ctx->classifiers_subrs = stat_classifiers;
	stat_ctx->classifiers_count = G_N_ELEMENTS (stat_classifiers);
	stat_ctx->tokenizers_subrs = stat_tokenizers;
	stat_ctx->tokenizers_count = G_N_ELEMENTS (stat_tokenizers);
	stat_ctx->caches_subrs = stat_caches;
	stat_ctx->caches_count = G_N_ELEMENTS (stat_caches);
	stat_ctx->cfg = cfg;
	stat_ctx->statfiles = g_ptr_array_new ();
	stat_ctx->classifiers = g_ptr_array_new ();
	stat_ctx->async_elts = g_queue_new ();
	stat_ctx->ev_base = ev_base;
	REF_RETAIN (stat_ctx->cfg);

	/* Create statfiles from the classifiers */
	cur = cfg->classifiers;

	while (cur) {
		clf = cur->data;
		bk = rspamd_stat_get_backend (clf->backend);

		if (bk == NULL) {
			msg_err_config ("cannot get backend of type %s, so disable classifier"
					" %s completely", clf->backend, clf->name);
			cur = g_list_next (cur);
			continue;
		}

		/* XXX:
		 * Here we get the first classifier tokenizer config as the only one
		 * We NO LONGER support multiple tokenizers per rspamd instance
		 */
		if (stat_ctx->tkcf == NULL) {
			stat_ctx->tokenizer = rspamd_stat_get_tokenizer (clf->tokenizer->name);
			g_assert (stat_ctx->tokenizer != NULL);
			stat_ctx->tkcf = stat_ctx->tokenizer->get_config (cfg->cfg_pool,
					clf->tokenizer, NULL);
		}

		cl = g_slice_alloc0 (sizeof (*cl));
		cl->cfg = clf;
		cl->ctx = stat_ctx;
		cl->statfiles_ids = g_array_new (FALSE, FALSE, sizeof (gint));
		cl->subrs = rspamd_stat_get_classifier (clf->classifier);
		g_assert (cl->subrs != NULL);
		cl->subrs->init_func (cfg->cfg_pool, cl);

		/* Init classifier cache */
		cache_name = NULL;

		if (clf->opts) {
			cache_obj = ucl_object_find_key (clf->opts, "cache");
			cache_name_obj = NULL;

			if (cache_obj) {
				cache_name_obj = ucl_object_find_any_key (cache_obj,
						"name", "type", NULL);
			}

			if (cache_name_obj) {
				cache_name = ucl_object_tostring (cache_name_obj);
			}
		}

		if (cache_name == NULL) {
			/* We assume that learn cache is the same as backend */
			cache_name = clf->backend;
		}

		curst = clf->statfiles;

		while (curst) {
			stf = curst->data;
			st = g_slice_alloc0 (sizeof (*st));
			st->classifier = cl;
			st->stcf = stf;
			st->backend = bk;
			st->bkcf = bk->init (stat_ctx, cfg, st);
			msg_debug_config ("added backend %s for symbol %s",
					bk->name, stf->symbol);

			/* XXX: bad hack to pass statfiles configuration to cache */
			if (cl->cache == NULL) {
				cl->cache = rspamd_stat_get_cache (cache_name);
				g_assert (cl->cache != NULL);
				cl->cachecf = cl->cache->init (stat_ctx, cfg, st, cache_obj);

				if (cl->cachecf == NULL) {
					msg_err_config ("error adding cache %s for symbol %s",
							cl->cache->name, stf->symbol);
					cl->cache = NULL;
				}
				else {
					msg_debug_config ("added cache %s for symbol %s",
							cl->cache->name, stf->symbol);
				}
			}

			if (st->bkcf == NULL) {
				msg_err_config ("cannot init backend %s for statfile %s",
						clf->backend, stf->symbol);

				g_slice_free1 (sizeof (*st), st);
			}
			else {
				st->id = stat_ctx->statfiles->len;
				g_ptr_array_add (stat_ctx->statfiles, st);
				g_array_append_val (cl->statfiles_ids, st->id);
			}

			curst = curst->next;
		}

		g_ptr_array_add (stat_ctx->classifiers, cl);

		cur = cur->next;
	}
}