aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--rules/misc.lua18
-rw-r--r--rules/regexp/headers.lua3
-rw-r--r--src/libmime/message.h15
-rw-r--r--src/libmime/mime_expressions.c42
-rw-r--r--src/libmime/mime_parser.c25
-rw-r--r--src/lua/lua_html.c1
-rw-r--r--src/lua/lua_mimepart.c26
7 files changed, 93 insertions, 37 deletions
diff --git a/rules/misc.lua b/rules/misc.lua
index 28fb19f5c..151500d88 100644
--- a/rules/misc.lua
+++ b/rules/misc.lua
@@ -716,13 +716,15 @@ local check_mime_id = rspamd_config:register_callback_symbol('CHECK_MIME', 1.0,
-- Make sure there is a MIME-Version header
local mv = task:get_header('MIME-Version')
+ local missing_mime = false
if (not mv) then
- task:insert_result('MISSING_MIME_VERSION', 1.0)
+ missing_mime = true
end
local found_ma = false
local found_plain = false
local found_html = false
+ local cte_7bit = false
for _,p in ipairs(parts) do
local mtype,subtype = p:get_type()
@@ -731,13 +733,27 @@ local check_mime_id = rspamd_config:register_callback_symbol('CHECK_MIME', 1.0,
found_ma = true
end
if (ctype == 'text/plain') then
+ if p:get_cte() == '7bit' then
+ cte_7bit = true
+ end
found_plain = true
end
if (ctype == 'text/html') then
+ if p:get_cte() == '7bit' then
+ cte_7bit = true
+ end
found_html = true
end
end
+ if missing_mime then
+ if not found_ma and ((found_plain or found_html) and cte_7bit) then
+ -- Skip symbol insertion
+ else
+ task:insert_result('MISSING_MIME_VERSION', 1.0)
+ end
+ end
+
if (found_ma) then
if (not found_plain) then
task:insert_result('MIME_MA_MISSING_TEXT', 1.0)
diff --git a/rules/regexp/headers.lua b/rules/regexp/headers.lua
index 30ccd5d0f..f58feeaf8 100644
--- a/rules/regexp/headers.lua
+++ b/rules/regexp/headers.lua
@@ -107,7 +107,8 @@ reconf['R_RCVD_SPAMBOTS'] = {
-- Charset is missing in message
reconf['R_MISSING_CHARSET'] = {
- re = string.format('content_type_is_type(text) & !content_type_has_param(charset) & !%s', r_cte_7bit),
+ re = string.format('content_type_is_type(text) & !content_type_has_param(charset) & !%s',
+ r_cte_7bit),
score = 2.5,
description = 'Charset is missing in a message',
group = 'header'
diff --git a/src/libmime/message.h b/src/libmime/message.h
index 6004d1759..03e0e8345 100644
--- a/src/libmime/message.h
+++ b/src/libmime/message.h
@@ -163,4 +163,19 @@ GPtrArray *rspamd_message_get_header_from_hash (GHashTable *htb,
const gchar *field,
gboolean strong);
+
+/**
+ * Converts string to cte
+ * @param str
+ * @return
+ */
+enum rspamd_cte rspamd_cte_from_string (const gchar *str);
+
+/**
+ * Converts cte to string
+ * @param ct
+ * @return
+ */
+const gchar* rspamd_cte_to_string (enum rspamd_cte ct);
+
#endif
diff --git a/src/libmime/mime_expressions.c b/src/libmime/mime_expressions.c
index 8a5672459..71b8d4bdc 100644
--- a/src/libmime/mime_expressions.c
+++ b/src/libmime/mime_expressions.c
@@ -1252,11 +1252,10 @@ rspamd_compare_transfer_encoding (struct rspamd_task * task,
GArray * args,
void *unused)
{
- GPtrArray *headerlist;
struct expression_argument *arg;
guint i;
- struct rspamd_mime_header *rh;
- static const char *hname = "Content-Transfer-Encoding";
+ struct rspamd_mime_part *part;
+ enum rspamd_cte cte;
if (args == NULL) {
msg_warn_task ("no parameters to function");
@@ -1269,39 +1268,16 @@ rspamd_compare_transfer_encoding (struct rspamd_task * task,
return FALSE;
}
- headerlist = rspamd_message_get_header_array (task, hname, FALSE);
+ cte = rspamd_cte_from_string (arg->data);
- if (headerlist) {
- for (i = 0; i < headerlist->len; i ++) {
- rh = g_ptr_array_index (headerlist, i);
-
- if (rh->decoded == NULL) {
- continue;
- }
-
- if (g_ascii_strcasecmp (rh->decoded, arg->data) == 0) {
- return TRUE;
- }
- }
+ if (cte == RSPAMD_CTE_UNKNOWN) {
+ msg_warn_task ("unknown cte: %s", arg->data);
+ return FALSE;
}
- /*
- * In fact, we need to check 'Content-Transfer-Encoding' for each part
- * as gmime has 'strange' assumptions
- */
- headerlist = rspamd_message_get_mime_header_array (task,
- arg->data,
- FALSE);
-
- if (headerlist) {
- for (i = 0; i < headerlist->len; i ++) {
- rh = g_ptr_array_index (headerlist, i);
-
- if (rh->decoded == NULL) {
- continue;
- }
-
- if (g_ascii_strcasecmp (rh->decoded, arg->data) == 0) {
+ PTR_ARRAY_FOREACH (task->parts, i, part) {
+ if (IS_CT_TEXT (part->ct)) {
+ if (part->cte == cte) {
return TRUE;
}
}
diff --git a/src/libmime/mime_parser.c b/src/libmime/mime_parser.c
index b16983287..a9bb0748a 100644
--- a/src/libmime/mime_parser.c
+++ b/src/libmime/mime_parser.c
@@ -81,7 +81,7 @@ rspamd_mime_parser_quark (void)
return g_quark_from_static_string ("mime-parser");
}
-static const gchar*
+const gchar*
rspamd_cte_to_string (enum rspamd_cte ct)
{
const gchar *ret = "unknown";
@@ -106,6 +106,29 @@ rspamd_cte_to_string (enum rspamd_cte ct)
return ret;
}
+enum rspamd_cte
+rspamd_cte_from_string (const gchar *str)
+{
+ enum rspamd_cte ret = RSPAMD_CTE_UNKNOWN;
+
+ g_assert (str != NULL);
+
+ if (strcmp (str, "7bit") == 0) {
+ ret = RSPAMD_CTE_7BIT;
+ }
+ else if (strcmp (str, "8bit") == 0) {
+ ret = RSPAMD_CTE_8BIT;
+ }
+ else if (strcmp (str, "quoted-printable") == 0) {
+ ret = RSPAMD_CTE_QP;
+ }
+ else if (strcmp (str, "base64") == 0) {
+ ret = RSPAMD_CTE_B64;
+ }
+
+ return ret;
+}
+
static void
rspamd_mime_parser_init_lib (void)
{
diff --git a/src/lua/lua_html.c b/src/lua/lua_html.c
index 0ec561338..65fb99326 100644
--- a/src/lua/lua_html.c
+++ b/src/lua/lua_html.c
@@ -354,6 +354,7 @@ lua_html_push_block (lua_State *L, struct html_block *bl)
if (bl->style.len > 0) {
lua_pushstring (L, "style");
t = lua_newuserdata (L, sizeof (*t));
+ rspamd_lua_setclass (L, "rspamd{text}", -1);
t->start = bl->style.start;
t->len = bl->style.len;
t->flags = 0;
diff --git a/src/lua/lua_mimepart.c b/src/lua/lua_mimepart.c
index 1ff3dbd58..8a9fb85e1 100644
--- a/src/lua/lua_mimepart.c
+++ b/src/lua/lua_mimepart.c
@@ -226,9 +226,17 @@ LUA_FUNCTION_DEF (mimepart, get_length);
/***
* @method mime_part:get_type()
* Extract content-type string of the mime part
- * @return {string} content type in form 'type/subtype'
+ * @return {string,string} content type in form 'type','subtype'
*/
LUA_FUNCTION_DEF (mimepart, get_type);
+
+/***
+ * @method mime_part:get_cte()
+ * Extract content-transfer-encoding for a part
+ * @return {string} content transfer encoding (e.g. `base64` or `7bit`)
+ */
+LUA_FUNCTION_DEF (mimepart, get_cte);
+
/***
* @method mime_part:get_filename()
* Extract filename associated with mime part if it is an attachement
@@ -304,6 +312,7 @@ static const struct luaL_reg mimepartlib_m[] = {
LUA_INTERFACE_DEF (mimepart, get_content),
LUA_INTERFACE_DEF (mimepart, get_length),
LUA_INTERFACE_DEF (mimepart, get_type),
+ LUA_INTERFACE_DEF (mimepart, get_cte),
LUA_INTERFACE_DEF (mimepart, get_filename),
LUA_INTERFACE_DEF (mimepart, get_header),
LUA_INTERFACE_DEF (mimepart, get_header_raw),
@@ -689,6 +698,21 @@ lua_mimepart_get_type (lua_State * L)
}
static gint
+lua_mimepart_get_cte (lua_State * L)
+{
+ struct rspamd_mime_part *part = lua_check_mimepart (L);
+
+ if (part == NULL) {
+ lua_pushnil (L);
+ return 1;
+ }
+
+ lua_pushstring (L, rspamd_cte_to_string (part->cte));
+
+ return 1;
+}
+
+static gint
lua_mimepart_get_filename (lua_State * L)
{
struct rspamd_mime_part *part = lua_check_mimepart (L);