From 81fd72379a9b16aac7905d59bf76acfdd2f4e03e Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Tue, 26 Oct 2010 21:38:03 +0400 Subject: [PATCH] Add add_header action to smtp proxy. In raw mode scan stripped html parts when regexp are not 'raw'. --- src/cfg_file.h | 1 + src/expressions.c | 1 + src/filter.c | 1 - src/plugins/regexp.c | 13 ++++++-- src/smtp.c | 1 + src/smtp_proto.c | 12 +------- src/smtp_utils.c | 72 ++++++++++++++++++++++++++++++++++++++++++++ src/smtp_utils.h | 4 +++ 8 files changed, 91 insertions(+), 14 deletions(-) diff --git a/src/cfg_file.h b/src/cfg_file.h index ddc78b150..9045d3a7a 100644 --- a/src/cfg_file.h +++ b/src/cfg_file.h @@ -83,6 +83,7 @@ struct rspamd_regexp { GRegex *raw_regexp; /**< glib regexp structure for raw matching */ gchar *header; /**< header name for header regexps */ gboolean is_test; /**< true if this expression must be tested */ + gboolean is_raw; /**< true if this regexp is done by raw matching */ }; /** diff --git a/src/expressions.c b/src/expressions.c index c4fa738b5..1f83c2827 100644 --- a/src/expressions.c +++ b/src/expressions.c @@ -642,6 +642,7 @@ parse_regexp (memory_pool_t * pool, gchar *line, gboolean raw_mode) break; case 'r': regexp_flags |= G_REGEX_RAW; + result->is_raw = TRUE; p++; break; /* Type flags */ diff --git a/src/filter.c b/src/filter.c index 9cc6e542f..73f45211b 100644 --- a/src/filter.c +++ b/src/filter.c @@ -628,7 +628,6 @@ check_action_str (const gchar *data, gint *result) *result = METRIC_ACTION_REWRITE_SUBJECT; } else { - msg_err ("unknown action for metric: %s", data); return FALSE; } return TRUE; diff --git a/src/plugins/regexp.c b/src/plugins/regexp.c index c70b5d232..8a33402f2 100644 --- a/src/plugins/regexp.c +++ b/src/plugins/regexp.c @@ -613,6 +613,8 @@ process_regexp (struct rspamd_regexp *re, struct worker_task *task, const gchar .re = re, .found = FALSE }; + guint8 *ct; + gsize clen; gint r; @@ -710,8 +712,15 @@ process_regexp (struct rspamd_regexp *re, struct worker_task *task, const gchar else { regexp = re->regexp; } - - if (g_regex_match_full (regexp, part->orig->data, part->orig->len, 0, 0, NULL, &err) == TRUE) { + if (re->is_raw) { + ct = part->orig->data; + clen = part->orig->len; + } + else { + ct = part->content->data; + clen = part->content->len; + } + if (g_regex_match_full (regexp, ct, clen, 0, 0, NULL, &err) == TRUE) { if (G_UNLIKELY (re->is_test)) { msg_info ("process test regexp %s for mime part returned TRUE", re->regexp_text); } diff --git a/src/smtp.c b/src/smtp.c index 1bda83423..6cecb52e6 100644 --- a/src/smtp.c +++ b/src/smtp.c @@ -342,6 +342,7 @@ process_smtp_data (struct smtp_session *session) } } else { + msg_info ("not scan message as it is %z bytes and maximum is %z", st.st_size, session->ctx->max_size); session->task = NULL; return smtp_send_upstream_message (session); } diff --git a/src/smtp_proto.c b/src/smtp_proto.c index ee9084f28..6df3c18c6 100644 --- a/src/smtp_proto.c +++ b/src/smtp_proto.c @@ -582,17 +582,7 @@ smtp_upstream_read_socket (f_str_t * in, void *arg) return FALSE; } else if (r == 1) { - r = strlen (session->cfg->temp_dir) + sizeof ("/rspamd-XXXXXX"); - session->temp_name = memory_pool_alloc (session->pool, r); - rspamd_snprintf (session->temp_name, r, "%s%crspamd-XXXXXX", session->cfg->temp_dir, G_DIR_SEPARATOR); -#ifdef HAVE_MKSTEMP - /* Umask is set before */ - session->temp_fd = mkstemp (session->temp_name); -#else - session->temp_fd = g_mkstemp_full (session->temp_name, O_RDWR, S_IWUSR | S_IRUSR); -#endif - if (session->temp_fd == -1) { - msg_err ("mkstemp error: %s", strerror (errno)); + if (! make_smtp_tempfile (session)) { session->error = SMTP_ERROR_FILE; session->state = SMTP_STATE_CRITICAL_ERROR; rspamd_dispatcher_restore (session->dispatcher); diff --git a/src/smtp_utils.c b/src/smtp_utils.c index 1a30112ee..c15bc063e 100644 --- a/src/smtp_utils.c +++ b/src/smtp_utils.c @@ -185,11 +185,36 @@ smtp_metric_callback (gpointer key, gpointer value, gpointer ud) #endif } +gboolean +make_smtp_tempfile (struct smtp_session *session) +{ + gsize r; + + r = strlen (session->cfg->temp_dir) + sizeof ("/rspamd-XXXXXX"); + session->temp_name = memory_pool_alloc (session->pool, r); + rspamd_snprintf (session->temp_name, r, "%s%crspamd-XXXXXX", session->cfg->temp_dir, G_DIR_SEPARATOR); +#ifdef HAVE_MKSTEMP + /* Umask is set before */ + session->temp_fd = mkstemp (session->temp_name); +#else + session->temp_fd = g_mkstemp_full (session->temp_name, O_RDWR, S_IWUSR | S_IRUSR); +#endif + if (session->temp_fd == -1) { + msg_err ("mkstemp error: %s", strerror (errno)); + + return FALSE; + } + + return TRUE; +} + gboolean write_smtp_reply (struct smtp_session *session) { gchar logbuf[1024]; struct smtp_metric_callback_data cd; + GMimeStream *stream; + int old_fd; /* Check metrics */ cd.session = session; @@ -218,6 +243,53 @@ write_smtp_reply (struct smtp_session *session) destroy_session (session->s); return FALSE; } + else if (cd.action <= METRIC_ACTION_ADD_HEADER || cd.action <= METRIC_ACTION_REWRITE_SUBJECT) { + old_fd = session->temp_fd; + if (! make_smtp_tempfile (session)) { + session->error = SMTP_ERROR_FILE; + session->state = SMTP_STATE_CRITICAL_ERROR; + rspamd_dispatcher_restore (session->dispatcher); + if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) { + goto err; + } + destroy_session (session->s); + return FALSE; + } + if (cd.action <= METRIC_ACTION_ADD_HEADER) { +#ifndef GMIME24 + g_mime_message_add_header (session->task->message, "X-Spam", "true"); +#else + g_mime_object_append_header (GMIME_OBJECT (session->task->message), "X-Spam", "true"); +#endif + } + else if (cd.action <= METRIC_ACTION_REWRITE_SUBJECT) { + /* XXX: add this action */ + } + stream = g_mime_stream_fs_new (session->temp_fd); + g_mime_stream_fs_set_owner (GMIME_STREAM_FS (stream), FALSE); + close (old_fd); + + if (g_mime_object_write_to_stream (GMIME_OBJECT (session->task->message), stream) == -1) { + msg_err ("cannot write MIME object to stream: %s", strerror (errno)); + session->error = SMTP_ERROR_FILE; + session->state = SMTP_STATE_CRITICAL_ERROR; + rspamd_dispatcher_restore (session->dispatcher); + if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) { + goto err; + } + destroy_session (session->s); + return FALSE; + } + g_object_unref (stream); + } /* XXX: Add other actions */ return smtp_send_upstream_message (session); +err: + session->error = SMTP_ERROR_FILE; + session->state = SMTP_STATE_CRITICAL_ERROR; + if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) { + return FALSE; + } + destroy_session (session->s); + return FALSE; } diff --git a/src/smtp_utils.h b/src/smtp_utils.h index 0374a715e..e61a85ae2 100644 --- a/src/smtp_utils.h +++ b/src/smtp_utils.h @@ -23,6 +23,10 @@ gboolean smtp_send_upstream_message (struct smtp_session *session); */ gboolean create_smtp_upstream_connection (struct smtp_session *session); +/** + * Create temporary file for smtp session + */ +gboolean make_smtp_tempfile (struct smtp_session *session); /** * Write reply to upstream -- 2.39.5