commit 052ccc7: [Feature] Support uuencoding

Vsevolod Stakhov vsevolod at highsecure.ru
Wed Oct 23 16:07:07 UTC 2019


Author: Vsevolod Stakhov
Date: 2019-10-23 17:03:19 +0100
URL: https://github.com/rspamd/rspamd/commit/052ccc761e2e9000ed11fcdd121585da77256bf6 (HEAD -> master)

[Feature] Support uuencoding

---
 lualib/lua_magic/init.lua |  2 ++
 src/libmime/message.h     |  1 +
 src/libmime/mime_parser.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 68 insertions(+)

diff --git a/lualib/lua_magic/init.lua b/lualib/lua_magic/init.lua
index d87e40d58..2bfc067e3 100644
--- a/lualib/lua_magic/init.lua
+++ b/lualib/lua_magic/init.lua
@@ -228,6 +228,8 @@ local function match_chunk(chunk, input, tlen, offset, trie, processed_tbl, log_
       for _,position in ipairs(match.positions) do
         local matched = false
         for _,pos in ipairs(matched_positions) do
+          lua_util.debugm(N, log_obj, 'found match %s at offset %s(from %s)',
+              pattern.ext, pos, offset)
           if not match_position(pos + offset, position) then
             matched = true
             break
diff --git a/src/libmime/message.h b/src/libmime/message.h
index 642c19a0e..f3a8315fc 100644
--- a/src/libmime/message.h
+++ b/src/libmime/message.h
@@ -44,6 +44,7 @@ enum rspamd_cte {
 	RSPAMD_CTE_8BIT = 2,
 	RSPAMD_CTE_QP = 3,
 	RSPAMD_CTE_B64 = 4,
+	RSPAMD_CTE_UUE = 5,
 };
 
 struct rspamd_mime_text_part;
diff --git a/src/libmime/mime_parser.c b/src/libmime/mime_parser.c
index dc3ef4b7c..e11b59e34 100644
--- a/src/libmime/mime_parser.c
+++ b/src/libmime/mime_parser.c
@@ -105,6 +105,9 @@ rspamd_cte_to_string (enum rspamd_cte ct)
 	case RSPAMD_CTE_B64:
 		ret = "base64";
 		break;
+	case RSPAMD_CTE_UUE:
+		ret = "X-uuencode";
+		break;
 	default:
 		break;
 	}
@@ -131,6 +134,15 @@ rspamd_cte_from_string (const gchar *str)
 	else if (strcmp (str, "base64") == 0) {
 		ret = RSPAMD_CTE_B64;
 	}
+	else if (strcmp (str, "X-uuencode") == 0) {
+		ret = RSPAMD_CTE_UUE;
+	}
+	else if (strcmp (str, "uuencode") == 0) {
+		ret = RSPAMD_CTE_UUE;
+	}
+	else if (strcmp (str, "X-uue") == 0) {
+		ret = RSPAMD_CTE_UUE;
+	}
 
 	return ret;
 }
@@ -172,6 +184,11 @@ rspamd_mime_parse_cte (const gchar *in, gsize len)
 	case 0x171029DE1B0423A9ULL: /* base-64 */
 		ret = RSPAMD_CTE_B64;
 		break;
+	case 0x420b54dc00d13cecULL: /* uuencode */
+	case 0x8df6700b8f6c4cf9ULL: /* x-uuencode */
+	case 0x41f725ec544356d3ULL: /* x-uue */
+		ret = RSPAMD_CTE_UUE;
+		break;
 	}
 
 	return ret;
@@ -195,6 +212,33 @@ rspamd_mime_part_get_cte_heuristic (struct rspamd_task *task,
 		p ++;
 	}
 
+	if (end - p > sizeof ("begin-base64 ")) {
+		const guchar *uue_start;
+
+		if (memcmp (p, "begin ", sizeof ("begin ") - 1) == 0) {
+			uue_start = p + sizeof ("begin ") - 1;
+
+			while (uue_start < end && g_ascii_isspace (*uue_start)) {
+				uue_start ++;
+			}
+
+			if (uue_start < end && g_ascii_isdigit (*uue_start)) {
+				return RSPAMD_CTE_UUE;
+			}
+		}
+		else if (memcmp (p, "begin-base64 ", sizeof ("begin-base64 ") - 1) == 0) {
+			uue_start = p + sizeof ("begin ") - 1;
+
+			while (uue_start < end && g_ascii_isspace (*uue_start)) {
+				uue_start ++;
+			}
+
+			if (uue_start < end && g_ascii_isdigit (*uue_start)) {
+				return RSPAMD_CTE_UUE;
+			}
+		}
+	}
+
 	if (end > p + 2) {
 		if (*(end - 1) == '=') {
 			neqsign ++;
@@ -512,6 +556,27 @@ rspamd_mime_parse_normal_part (struct rspamd_task *task,
 		rspamd_mempool_add_destructor (task->task_pool,
 				(rspamd_mempool_destruct_t)rspamd_fstring_free, parsed);
 		break;
+	case RSPAMD_CTE_UUE:
+		parsed = rspamd_fstring_sized_new (part->raw_data.len / 4 * 3 + 12);
+		r = rspamd_decode_uue_buf (part->raw_data.begin, part->raw_data.len,
+				parsed->str, parsed->allocated);
+		rspamd_mempool_add_destructor (task->task_pool,
+				(rspamd_mempool_destruct_t)rspamd_fstring_free, parsed);
+		if (r != -1) {
+			parsed->len = r;
+			part->parsed_data.begin = parsed->str;
+			part->parsed_data.len = parsed->len;
+		}
+		else {
+			msg_err_task ("invalid quoted-printable encoded part, assume 8bit");
+			part->ct->flags |= RSPAMD_CONTENT_TYPE_BROKEN;
+			part->cte = RSPAMD_CTE_8BIT;
+			memcpy (parsed->str, part->raw_data.begin, part->raw_data.len);
+			parsed->len = part->raw_data.len;
+			part->parsed_data.begin = parsed->str;
+			part->parsed_data.len = parsed->len;
+		}
+		break;
 	default:
 		g_assert_not_reached ();
 	}


More information about the Commits mailing list