commit 6808cdc: [Project] Implement extensions logic for fuzzy storage
Vsevolod Stakhov
vsevolod at highsecure.ru
Mon Jun 22 17:49:08 UTC 2020
Author: Vsevolod Stakhov
Date: 2020-06-22 18:47:02 +0100
URL: https://github.com/rspamd/rspamd/commit/6808cdc0b20afbcca8da2847e3bc31bd510d6c21 (HEAD -> master)
[Project] Implement extensions logic for fuzzy storage
---
src/fuzzy_storage.c | 142 +++++++++++++++++++++++++++++++++++++++++++++
src/libserver/fuzzy_wire.h | 3 +-
2 files changed, 144 insertions(+), 1 deletion(-)
diff --git a/src/fuzzy_storage.c b/src/fuzzy_storage.c
index b009a4c00..53e9f1efa 100644
--- a/src/fuzzy_storage.c
+++ b/src/fuzzy_storage.c
@@ -209,6 +209,7 @@ struct fuzzy_session {
struct ev_io io;
ref_entry_t ref;
struct fuzzy_key_stat *key_stat;
+ struct rspamd_fuzzy_cmd_extension *extensions;
guchar nm[rspamd_cryptobox_MAX_NMBYTES];
};
@@ -1213,6 +1214,135 @@ rspamd_fuzzy_decrypt_command (struct fuzzy_session *s, guchar *buf, gsize buflen
return TRUE;
}
+
+static gboolean
+rspamd_fuzzy_extensions_from_wire (struct fuzzy_session *s, guchar *buf, gsize buflen)
+{
+ struct rspamd_fuzzy_cmd_extension *ext;
+ guchar *storage, *p = buf, *end = buf + buflen;
+ gsize st_len = 0, n_ext = 0;
+
+ /* Read number of extensions to allocate array */
+ while (p < end) {
+ guchar cmd = *p++;
+
+ if (p < end) {
+ if (cmd == RSPAMD_FUZZY_EXT_SOURCE_DOMAIN) {
+ /* Next byte is buf length */
+ guchar dom_len = *p++;
+
+ if (dom_len <= (end - p)) {
+ st_len += dom_len;
+ n_ext ++;
+ }
+ else {
+ /* Truncation */
+ return FALSE;
+ }
+
+ p += dom_len;
+ }
+ else if (cmd == RSPAMD_FUZZY_EXT_SOURCE_IP4) {
+ if (end - p >= sizeof (in_addr_t)) {
+ p += sizeof (in_addr_t);
+ n_ext ++;
+ st_len += sizeof (in_addr_t);
+ }
+ else {
+ /* Truncation */
+ return FALSE;
+ }
+
+ p += sizeof (in_addr_t);
+ }
+ else if (cmd == RSPAMD_FUZZY_EXT_SOURCE_IP6) {
+ if (end - p >= sizeof (in6_addr_t)) {
+ p += sizeof (in6_addr_t);
+ n_ext ++;
+ st_len += sizeof (in6_addr_t);
+ }
+ else {
+ /* Truncation */
+ return FALSE;
+ }
+
+ p += sizeof (in6_addr_t);
+ }
+ }
+ else {
+ /* Truncated extension */
+ return FALSE;
+ }
+ }
+
+ if (n_ext > 0) {
+ p = buf;
+ /*
+ * Memory layout: n_ext of struct rspamd_fuzzy_cmd_extension
+ * payload for each extension in a continious data segment
+ */
+ storage = g_malloc (n_ext * sizeof (struct rspamd_fuzzy_cmd_extension) +
+ st_len);
+
+ guchar *data_buf = storage +
+ n_ext * sizeof (struct rspamd_fuzzy_cmd_extension);
+ ext = (struct rspamd_fuzzy_cmd_extension *)storage;
+
+ /* All validation has been done, so we can just go further */
+ while (p < end) {
+ guchar cmd = *p++;
+
+ if (cmd == RSPAMD_FUZZY_EXT_SOURCE_DOMAIN) {
+ /* Next byte is buf length */
+ guchar dom_len = *p++;
+ guchar *dest = data_buf;
+
+ ext->ext = RSPAMD_FUZZY_EXT_SOURCE_DOMAIN;
+ ext->next = ext + 1;
+ ext->length = dom_len;
+ ext->payload = dest;
+ memcpy (dest, p, dom_len);
+ p += dom_len;
+ data_buf += dom_len;
+ ext = ext->next;
+ }
+ else if (cmd == RSPAMD_FUZZY_EXT_SOURCE_IP4) {
+ guchar *dest = data_buf;
+
+ ext->ext = RSPAMD_FUZZY_EXT_SOURCE_IP4;
+ ext->next = ext + 1;
+ ext->length = sizeof (in_addr_t);
+ ext->payload = dest;
+ memcpy (dest, p, sizeof (in_addr_t));
+ p += sizeof (in_addr_t);
+ data_buf += sizeof (in_addr_t);
+ ext = ext->next;
+ }
+ else if (cmd == RSPAMD_FUZZY_EXT_SOURCE_IP6) {
+ guchar *dest = data_buf;
+
+ ext->ext = RSPAMD_FUZZY_EXT_SOURCE_IP6;
+ ext->next = ext + 1;
+ ext->length = sizeof (in6_addr_t);
+ ext->payload = dest;
+ memcpy (dest, p, sizeof (in6_addr_t));
+ p += sizeof (in_addr_t);
+ data_buf += sizeof (in6_addr_t);
+ ext = ext->next;
+ }
+ }
+
+ /* Last next should be NULL */
+ ext->next = NULL;
+
+ /* Rewind to the begin */
+ ext = (struct rspamd_fuzzy_cmd_extension *)storage;
+ s->extensions = ext;
+ }
+
+ return TRUE;
+}
+
static gboolean
rspamd_fuzzy_cmd_from_wire (guchar *buf, guint buflen, struct fuzzy_session *s)
{
@@ -1298,6 +1428,14 @@ rspamd_fuzzy_cmd_from_wire (guchar *buf, guint buflen, struct fuzzy_session *s)
}
}
+ if (buflen > 0) {
+ /* Process possible extensions */
+ if (!rspamd_fuzzy_extensions_from_wire (s, buf, buflen)) {
+ msg_debug ("truncated fuzzy shingles command of size %d received", buflen);
+ return FALSE;
+ }
+ }
+
return TRUE;
}
@@ -1315,6 +1453,10 @@ fuzzy_session_destroy (gpointer d)
REF_RELEASE (session->ip_stat);
}
+ if (session->extensions) {
+ g_free (session->extensions);
+ }
+
g_free (session);
}
diff --git a/src/libserver/fuzzy_wire.h b/src/libserver/fuzzy_wire.h
index af3122e84..82e386657 100644
--- a/src/libserver/fuzzy_wire.h
+++ b/src/libserver/fuzzy_wire.h
@@ -103,7 +103,8 @@ enum rspamd_fuzzy_extension_type {
struct rspamd_fuzzy_cmd_extension {
enum rspamd_fuzzy_extension_type ext;
guint length;
- guchar payload[];
+ struct rspamd_fuzzy_cmd_extension *next;
+ guchar *payload;
};
struct rspamd_fuzzy_stat_entry {
More information about the Commits
mailing list