commit a102cae: [Minor] Add a simple way to limit number of email addresses

Vsevolod Stakhov vsevolod at highsecure.ru
Tue May 19 16:21:06 UTC 2020


Author: Vsevolod Stakhov
Date: 2020-05-19 17:00:25 +0100
URL: https://github.com/rspamd/rspamd/commit/a102caecf7ab481bf4f3f5f4a233a5e64467e4d2

[Minor] Add a simple way to limit number of email addresses

---
 src/libmime/email_addr.c   | 35 ++++++++++++++++++++++++++---------
 src/libmime/email_addr.h   | 12 ++++++------
 src/libmime/mime_headers.c | 10 +++++-----
 src/libserver/cfg_rcl.c    |  2 +-
 src/libserver/milter.c     |  8 ++++----
 src/libserver/protocol.c   |  6 +++---
 src/lua/lua_util.c         |  2 +-
 7 files changed, 46 insertions(+), 29 deletions(-)

diff --git a/src/libmime/email_addr.c b/src/libmime/email_addr.c
index 4e09de6fb..1987c58c3 100644
--- a/src/libmime/email_addr.c
+++ b/src/libmime/email_addr.c
@@ -48,7 +48,7 @@ rspamd_email_address_unescape (struct rspamd_email_address *addr)
 }
 
 struct rspamd_email_address *
-rspamd_email_address_from_smtp (const gchar *str, guint len)
+rspamd_email_address_from_smtp (const gchar *str, guint len, gint max_elements)
 {
 	struct rspamd_email_address addr, *ret;
 	gsize nlen;
@@ -203,10 +203,21 @@ static inline gboolean
 rspamd_email_address_check_and_add (const gchar *start, gsize len,
 									GPtrArray *res,
 									rspamd_mempool_t *pool,
-									GString *ns)
+									GString *ns,
+									gint max_elements)
 {
 	struct rspamd_email_address addr;
 
+	g_assert (res != NULL);
+
+	if (max_elements > 0 && res->len >= max_elements) {
+		msg_info_pool_check ("reached maximum number of elements %d when adding %v",
+				max_elements,
+				ns);
+
+		return FALSE;
+	}
+
 	/* The whole email is likely address */
 	memset (&addr, 0, sizeof (addr));
 	rspamd_smtp_addr_parse (start, len, &addr);
@@ -231,9 +242,10 @@ rspamd_email_address_check_and_add (const gchar *start, gsize len,
 }
 
 GPtrArray *
-rspamd_email_address_from_mime (rspamd_mempool_t *pool,
-		const gchar *hdr, guint len,
-		GPtrArray *src)
+rspamd_email_address_from_mime (rspamd_mempool_t *pool, const gchar *hdr,
+								guint len,
+								GPtrArray *src,
+								gint max_elements)
 {
 	GPtrArray *res = src;
 	gboolean seen_at = FALSE;
@@ -253,6 +265,11 @@ rspamd_email_address_from_mime (rspamd_mempool_t *pool,
 		rspamd_mempool_add_destructor (pool, rspamd_email_address_list_destroy,
 				res);
 	}
+	else if (max_elements > 0 && res->len >= max_elements) {
+		msg_info_pool_check ("reached maximum number of elements %d", max_elements);
+
+		return res;
+	}
 
 	ns = g_string_sized_new (len);
 	cpy = g_string_sized_new (len);
@@ -371,7 +388,7 @@ rspamd_email_address_from_mime (rspamd_mempool_t *pool,
 					}
 
 					if (!rspamd_email_address_check_and_add (c, t - c + 1,
-							res, pool, ns)) {
+							res, pool, ns, max_elements)) {
 						rspamd_email_address_add (pool, res, NULL, ns);
 					}
 
@@ -407,7 +424,7 @@ rspamd_email_address_from_mime (rspamd_mempool_t *pool,
 		case parse_addr:
 			if (*p == '>') {
 				if (!rspamd_email_address_check_and_add (c, p - c + 1,
-						res, pool, ns)) {
+						res, pool, ns, max_elements)) {
 					rspamd_email_address_add (pool, res, NULL, ns);
 				}
 
@@ -447,7 +464,7 @@ rspamd_email_address_from_mime (rspamd_mempool_t *pool,
 				if (seen_at) {
 					/* The whole email is likely address */
 					if (!rspamd_email_address_check_and_add (c, p - c,
-							res, pool, ns)) {
+							res, pool, ns, max_elements)) {
 						if (res->len == 0) {
 							rspamd_email_address_add (pool, res, NULL, ns);
 						}
@@ -469,7 +486,7 @@ rspamd_email_address_from_mime (rspamd_mempool_t *pool,
 	case parse_addr:
 		if (p > c) {
 			if (!rspamd_email_address_check_and_add (c, p - c,
-					res, pool, ns)) {
+					res, pool, ns, max_elements)) {
 				if (res->len == 0) {
 					rspamd_email_address_add (pool, res, NULL, ns);
 				}
diff --git a/src/libmime/email_addr.h b/src/libmime/email_addr.h
index 13e94f7cc..2452fc7aa 100644
--- a/src/libmime/email_addr.h
+++ b/src/libmime/email_addr.h
@@ -67,8 +67,9 @@ struct rspamd_task;
  * @param len length of string
  * @return
  */
-struct rspamd_email_address *rspamd_email_address_from_smtp (
-		const gchar *str, guint len);
+struct rspamd_email_address *rspamd_email_address_from_smtp (const gchar *str,
+		guint len,
+		gint max_elements);
 
 /**
  * Parses email address from the mime header, decodes names and return the array
@@ -79,10 +80,9 @@ struct rspamd_email_address *rspamd_email_address_from_smtp (
  * @param len
  * @return
  */
-GPtrArray *rspamd_email_address_from_mime (rspamd_mempool_t *pool,
-										   const gchar *hdr,
-										   guint len,
-										   GPtrArray *src);
+GPtrArray *
+rspamd_email_address_from_mime (rspamd_mempool_t *pool, const gchar *hdr, guint len,
+		GPtrArray *src, gint max_elements);
 
 /**
  * Destroys list of email addresses
diff --git a/src/libmime/mime_headers.c b/src/libmime/mime_headers.c
index 582f11d7a..55d04d69a 100644
--- a/src/libmime/mime_headers.c
+++ b/src/libmime/mime_headers.c
@@ -62,25 +62,25 @@ rspamd_mime_header_check_special (struct rspamd_task *task,
 	case 0x76F31A09F4352521ULL:	/* to */
 		MESSAGE_FIELD (task, rcpt_mime) = rspamd_email_address_from_mime (task->task_pool,
 				rh->decoded, strlen (rh->decoded),
-				MESSAGE_FIELD (task, rcpt_mime));
+				MESSAGE_FIELD (task, rcpt_mime), -1);
 		rh->flags |= RSPAMD_HEADER_TO|RSPAMD_HEADER_RCPT|RSPAMD_HEADER_UNIQUE;
 		break;
 	case 0x7EB117C1480B76ULL:	/* cc */
 		MESSAGE_FIELD (task, rcpt_mime) = rspamd_email_address_from_mime (task->task_pool,
 				rh->decoded, strlen (rh->decoded),
-				MESSAGE_FIELD (task, rcpt_mime));
+				MESSAGE_FIELD (task, rcpt_mime), -1);
 		rh->flags |= RSPAMD_HEADER_CC|RSPAMD_HEADER_RCPT|RSPAMD_HEADER_UNIQUE;
 		break;
 	case 0xE4923E11C4989C8DULL:	/* bcc */
 		MESSAGE_FIELD (task, rcpt_mime) = rspamd_email_address_from_mime (task->task_pool,
 				rh->decoded, strlen (rh->decoded),
-				MESSAGE_FIELD (task, rcpt_mime));
+				MESSAGE_FIELD (task, rcpt_mime), -1);
 		rh->flags |= RSPAMD_HEADER_BCC|RSPAMD_HEADER_RCPT|RSPAMD_HEADER_UNIQUE;
 		break;
 	case 0x41E1985EDC1CBDE4ULL:	/* from */
 		MESSAGE_FIELD (task, from_mime) = rspamd_email_address_from_mime (task->task_pool,
 				rh->decoded, strlen (rh->decoded),
-				MESSAGE_FIELD (task, from_mime));
+				MESSAGE_FIELD (task, from_mime), -1);
 		rh->flags |= RSPAMD_HEADER_FROM|RSPAMD_HEADER_SENDER|RSPAMD_HEADER_UNIQUE;
 		break;
 	case 0x43A558FC7C240226ULL:	/* message-id */ {
@@ -129,7 +129,7 @@ rspamd_mime_header_check_special (struct rspamd_task *task,
 	case 0xEE4AA2EAAC61D6F4ULL:	/* return-path */
 		if (task->from_envelope == NULL) {
 			task->from_envelope = rspamd_email_address_from_smtp (rh->decoded,
-					strlen (rh->decoded));
+					strlen (rh->decoded), -1);
 		}
 		rh->flags = RSPAMD_HEADER_RETURN_PATH|RSPAMD_HEADER_UNIQUE;
 		break;
diff --git a/src/libserver/cfg_rcl.c b/src/libserver/cfg_rcl.c
index ff256c413..dc568297b 100644
--- a/src/libserver/cfg_rcl.c
+++ b/src/libserver/cfg_rcl.c
@@ -3392,7 +3392,7 @@ rspamd_rcl_parse_struct_mime_addr (rspamd_mempool_t *pool,
 		if (ucl_object_type (cur) == UCL_STRING) {
 			val = ucl_object_tostring (obj);
 			tmp_addr = rspamd_email_address_from_mime (pool, val,
-					strlen (val), tmp_addr);
+					strlen (val), tmp_addr, -1);
 		}
 		else {
 			g_set_error (err,
diff --git a/src/libserver/milter.c b/src/libserver/milter.c
index dc398912d..4713b7371 100644
--- a/src/libserver/milter.c
+++ b/src/libserver/milter.c
@@ -603,7 +603,7 @@ rspamd_milter_process_command (struct rspamd_milter_session *session,
 				cpy = rspamd_mempool_alloc (priv->pool, zero - pos);
 				memcpy (cpy, pos, zero - pos);
 				msg_debug_milter ("got mail: %*s", (int)(zero - pos), cpy);
-				addr = rspamd_email_address_from_smtp (cpy, zero - pos);
+				addr = rspamd_email_address_from_smtp (cpy, zero - pos, -1);
 
 				if (addr) {
 					session->from = addr;
@@ -618,7 +618,7 @@ rspamd_milter_process_command (struct rspamd_milter_session *session,
 				/* That actually should not happen */
 				cpy = rspamd_mempool_alloc (priv->pool, end - pos);
 				memcpy (cpy, pos, end - pos);
-				addr = rspamd_email_address_from_smtp (cpy, end - pos);
+				addr = rspamd_email_address_from_smtp (cpy, end - pos, -1);
 
 				if (addr) {
 					session->from = addr;
@@ -707,7 +707,7 @@ rspamd_milter_process_command (struct rspamd_milter_session *session,
 				memcpy (cpy, pos, end - pos);
 
 				msg_debug_milter ("got rcpt: %*s", (int)(zero - pos), cpy);
-				addr = rspamd_email_address_from_smtp (cpy, zero - pos);
+				addr = rspamd_email_address_from_smtp (cpy, zero - pos, -1);
 
 				if (addr) {
 					if (!session->rcpts) {
@@ -726,7 +726,7 @@ rspamd_milter_process_command (struct rspamd_milter_session *session,
 				msg_debug_milter ("got weird rcpt: %*s", (int)(end - pos),
 						pos);
 				/* That actually should not happen */
-				addr = rspamd_email_address_from_smtp (cpy, end - pos);
+				addr = rspamd_email_address_from_smtp (cpy, end - pos, -1);
 
 				if (addr) {
 					if (!session->rcpts) {
diff --git a/src/libserver/protocol.c b/src/libserver/protocol.c
index 9d1276064..1d51ff28f 100644
--- a/src/libserver/protocol.c
+++ b/src/libserver/protocol.c
@@ -292,7 +292,7 @@ rspamd_protocol_process_recipients (struct rspamd_task *task,
 			else if (*p == ',' && start_addr != NULL && p > start_addr) {
 				/* We have finished address, check what we have */
 				addr = rspamd_email_address_from_smtp (start_addr,
-						p - start_addr);
+						p - start_addr, -1);
 
 				if (addr) {
 					if (task->rcpt_envelope == NULL) {
@@ -322,7 +322,7 @@ rspamd_protocol_process_recipients (struct rspamd_task *task,
 	if (start_addr && p > start_addr) {
 		switch (state) {
 		case normal_string:
-			addr = rspamd_email_address_from_smtp (start_addr, end - start_addr);
+			addr = rspamd_email_address_from_smtp (start_addr, end - start_addr, -1);
 
 			if (addr) {
 				if (task->rcpt_envelope == NULL) {
@@ -495,7 +495,7 @@ rspamd_protocol_handle_headers (struct rspamd_task *task,
 				IF_HEADER (FROM_HEADER) {
 					task->from_envelope = rspamd_email_address_from_smtp (
 							hv_tok->begin,
-							hv_tok->len);
+							hv_tok->len, -1);
 					msg_debug_protocol ("read from header, value: %T", hv_tok);
 
 					if (!task->from_envelope) {
diff --git a/src/lua/lua_util.c b/src/lua/lua_util.c
index 5948f4b4b..4d2758c5e 100644
--- a/src/lua/lua_util.c
+++ b/src/lua/lua_util.c
@@ -1650,7 +1650,7 @@ lua_util_parse_mail_address (lua_State *L)
 			own_pool = TRUE;
 		}
 
-		addrs = rspamd_email_address_from_mime (pool, str, len, NULL);
+		addrs = rspamd_email_address_from_mime (pool, str, len, NULL, -1);
 
 		if (addrs == NULL) {
 			lua_pushnil (L);


More information about the Commits mailing list