0,
NULL
},
+ {
+ "rcpt",
+ handle_view_rcpt,
+ 0,
+ NULL
+ },
{
"symbols",
handle_view_symbols,
struct rspamd_view *view = ctx->section_pointer;
if (!add_view_from (view, data)) {
- msg_err ("invalid from line in view definition: ip = '%s'", data);
+ msg_err ("invalid from line in view definition: from = '%s'", data);
return FALSE;
}
return TRUE;
}
gboolean
+handle_view_rcpt (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, int offset)
+{
+ struct rspamd_view *view = ctx->section_pointer;
+
+ if (!add_view_rcpt (view, data)) {
+ msg_err ("invalid from line in view definition: rcpt = '%s'", data);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+gboolean
handle_view_symbols (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, int offset)
{
struct rspamd_view *view = ctx->section_pointer;
if (!add_view_symbols (view, data)) {
- msg_err ("invalid symbols line in view definition: ip = '%s'", data);
+ msg_err ("invalid symbols line in view definition: symbols = '%s'", data);
return FALSE;
}
cfg->domain_settings_str = memory_pool_strdup (cfg->cfg_pool, data);
gboolean handle_view_ip (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, int offset);
gboolean handle_view_client_ip (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, int offset);
gboolean handle_view_from (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, int offset);
+gboolean handle_view_rcpt (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, int offset);
gboolean handle_view_symbols (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, int offset);
gboolean handle_user_settings (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, int offset);
return FALSE;
}
+gboolean
+add_view_rcpt (struct rspamd_view * view, char *line)
+{
+ struct rspamd_regexp *re = NULL;
+
+ if (add_map (line, read_host_list, fin_host_list, (void **)&view->rcpt_hash)) {
+ return TRUE;
+ }
+ else if ((re = parse_regexp (view->pool, line, TRUE)) != NULL) {
+ view->rcpt_re_list = g_list_prepend (view->rcpt_re_list, re);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
gboolean
add_view_symbols (struct rspamd_view * view, char *line)
{
return NULL;
}
+G_INLINE_FUNC gboolean
+check_view_rcpt (struct rspamd_view *v, struct worker_task *task)
+{
+ GList *cur, *cur_re;
+ char rcpt_user[256], *p;
+ gint l;
+ struct rspamd_regexp *re;
+
+ cur = task->rcpt;
+ while (cur) {
+ if ((p = strchr (cur->data, '@')) != NULL) {
+ l = MIN (sizeof (rcpt_user) - 1, p - (char *)cur->data);
+ memcpy (rcpt_user, cur->data, l);
+ rcpt_user[l] = '\0';
+ /* First try to lookup in hashtable */
+ if (g_hash_table_lookup (v->rcpt_hash, rcpt_user) != NULL) {
+ return TRUE;
+ }
+ /* Then try to match re */
+ cur_re = v->rcpt_re_list;
+
+ while (cur_re) {
+ re = cur_re->data;
+ if (g_regex_match (re->regexp, rcpt_user, 0, NULL) == TRUE) {
+ return TRUE;
+ }
+ cur_re = g_list_next (cur_re);
+ }
+ }
+ /* Now check the whole recipient */
+ if (g_hash_table_lookup (v->rcpt_hash, cur->data) != NULL) {
+ return TRUE;
+ }
+ /* Then try to match re */
+ cur_re = v->rcpt_re_list;
+
+ while (cur_re) {
+ re = cur_re->data;
+ if (g_regex_match (re->regexp, cur->data, 0, NULL) == TRUE) {
+ return TRUE;
+ }
+ cur_re = g_list_next (cur_re);
+ }
+ cur = g_list_next (cur);
+ }
+
+ return FALSE;
+}
+
+static struct rspamd_view *
+find_view_by_rcpt (GList * views, struct worker_task *task)
+{
+ GList *cur;
+ struct rspamd_view *v;
+
+ if (task->from == NULL) {
+ return NULL;
+ }
+
+ cur = views;
+ while (cur) {
+ v = cur->data;
+ if (check_view_rcpt (v, task)) {
+ return v;
+ }
+ cur = g_list_next (cur);
+ }
+
+ return NULL;
+}
+
static gboolean
match_view_symbol (struct rspamd_view *v, const char *symbol)
{
if ((selected = find_view_by_ip (views, task)) == NULL) {
if ((selected = find_view_by_client_ip (views, task)) == NULL) {
if ((selected = find_view_by_from (views, task)) == NULL) {
- /* No matching view for this task */
- task->view_checked = TRUE;
- return TRUE;
+ if ((selected = find_view_by_rcpt (views, task)) == NULL) {
+ /* No matching view for this task */
+ task->view_checked = TRUE;
+ return TRUE;
+ }
}
}
}
GList *from_re_list;
GHashTable *from_hash;
+ GList *rcpt_re_list;
+ GHashTable *rcpt_hash;
+
radix_tree_t *ip_tree;
radix_tree_t *client_ip_tree;
struct rspamd_view* init_view (memory_pool_t *pool);
gboolean add_view_from (struct rspamd_view *view, char *line);
+gboolean add_view_rcpt (struct rspamd_view *view, char *line);
gboolean add_view_ip (struct rspamd_view *view, char *line);
gboolean add_view_client_ip (struct rspamd_view *view, char *line);
gboolean add_view_symbols (struct rspamd_view *view, char *line);