aboutsummaryrefslogtreecommitdiffstats
path: root/src/libmime
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2016-12-12 13:44:08 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2016-12-12 13:44:08 +0000
commit1d95f1678637f30b6bf453f781b5938d64354228 (patch)
tree2ee99ae2bc79323bd96dad52157e6e6be67ba45a /src/libmime
parent55467ed90c19bc82506433f8f7d274b5bfb8d10f (diff)
downloadrspamd-1d95f1678637f30b6bf453f781b5938d64354228.tar.gz
rspamd-1d95f1678637f30b6bf453f781b5938d64354228.zip
[Rework] Implement content type parser for mime
Diffstat (limited to 'src/libmime')
-rw-r--r--src/libmime/CMakeLists.txt3
-rw-r--r--src/libmime/content_type.c79
-rw-r--r--src/libmime/content_type.h61
-rw-r--r--src/libmime/smtp_parsers.h4
4 files changed, 146 insertions, 1 deletions
diff --git a/src/libmime/CMakeLists.txt b/src/libmime/CMakeLists.txt
index a4485461a..39bd2d402 100644
--- a/src/libmime/CMakeLists.txt
+++ b/src/libmime/CMakeLists.txt
@@ -5,6 +5,7 @@ SET(LIBRSPAMDMIMESRC
${CMAKE_CURRENT_SOURCE_DIR}/filter.c
${CMAKE_CURRENT_SOURCE_DIR}/images.c
${CMAKE_CURRENT_SOURCE_DIR}/message.c
- ${CMAKE_CURRENT_SOURCE_DIR}/archives.c)
+ ${CMAKE_CURRENT_SOURCE_DIR}/archives.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/content_type.c)
SET(RSPAMD_MIME ${LIBRSPAMDMIMESRC} PARENT_SCOPE) \ No newline at end of file
diff --git a/src/libmime/content_type.c b/src/libmime/content_type.c
new file mode 100644
index 000000000..9161850c9
--- /dev/null
+++ b/src/libmime/content_type.c
@@ -0,0 +1,79 @@
+/*-
+ * Copyright 2016 Vsevolod Stakhov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "libmime/content_type.h"
+#include "smtp_parsers.h"
+#include "utlist.h"
+
+void
+rspamd_content_type_add_param (rspamd_mempool_t *pool,
+ struct rspamd_content_type *ct,
+ const gchar *name_start, const gchar *name_end,
+ const gchar *value_start, const gchar *value_end)
+{
+ rspamd_ftok_t srch;
+ struct rspamd_content_type_param *found = NULL, *nparam;
+
+ g_assert (ct != NULL);
+
+ srch.begin = name_start;
+ srch.len = name_end - name_start;
+
+ if (ct->attrs) {
+ found = g_hash_table_lookup (ct->attrs, &srch);
+ }
+ else {
+ ct->attrs = g_hash_table_new (rspamd_ftok_icase_hash,
+ rspamd_ftok_icase_equal);
+ }
+
+ nparam = rspamd_mempool_alloc (pool, sizeof (*nparam));
+ nparam->name.begin = name_start;
+ nparam->name.len = name_end - name_start;
+ nparam->value.begin = value_start;
+ nparam->value.len = value_end - value_start;
+ DL_APPEND (found, nparam);
+
+ if (!found) {
+ g_hash_table_insert (ct->attrs, &nparam->name, nparam);
+ }
+}
+
+struct rspamd_content_type *
+rspamd_content_type_parse (const gchar *in,
+ gsize len, rspamd_mempool_t *pool)
+{
+ struct rspamd_content_type *res = NULL, val;
+
+ val.lc_data = rspamd_mempool_alloc (pool, len);
+ memcpy (val.lc_data, in, len);
+ rspamd_str_lc (val.lc_data, len);
+
+ if (rspamd_content_type_parser (val.lc_data, len, &val, pool)) {
+ res = rspamd_mempool_alloc (pool, sizeof (val));
+ memcpy (res, &val, sizeof (val));
+
+ if (res->attrs) {
+ rspamd_mempool_add_destructor (pool,
+ (rspamd_mempool_destruct_t)g_hash_table_unref, res->attrs);
+ }
+ }
+ else {
+ msg_warn_pool ("cannot parse content type: %*s", (gint)len, val.lc_data);
+ }
+
+ return res;
+}
diff --git a/src/libmime/content_type.h b/src/libmime/content_type.h
new file mode 100644
index 000000000..7c129936d
--- /dev/null
+++ b/src/libmime/content_type.h
@@ -0,0 +1,61 @@
+/*-
+ * Copyright 2016 Vsevolod Stakhov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef SRC_LIBMIME_CONTENT_TYPE_H_
+#define SRC_LIBMIME_CONTENT_TYPE_H_
+
+#include "config.h"
+#include "libutil/fstring.h"
+#include "libutil/mem_pool.h"
+
+struct rspamd_content_type_param {
+ rspamd_ftok_t name;
+ rspamd_ftok_t value;
+ struct rspamd_content_type_param *prev, *next;
+};
+
+struct rspamd_content_type {
+ gchar *lc_data;
+ rspamd_ftok_t type;
+ rspamd_ftok_t subtype;
+ rspamd_ftok_t charset;
+ GHashTable *attrs; /* Can be empty */
+};
+
+/**
+ * Adds new parameter to content type structure
+ * @param ct
+ * @param name_start
+ * @param name_end
+ * @param value_start
+ * @param value_end
+ */
+void
+rspamd_content_type_add_param (rspamd_mempool_t *pool,
+ struct rspamd_content_type *ct,
+ const gchar *name_start, const gchar *name_end,
+ const gchar *value_start, const gchar *value_end);
+
+/**
+ * Parse content type from the header (performs copy + lowercase)
+ * @param in
+ * @param len
+ * @param pool
+ * @return
+ */
+struct rspamd_content_type * rspamd_content_type_parse (const gchar *in,
+ gsize len, rspamd_mempool_t *pool);
+
+#endif /* SRC_LIBMIME_CONTENT_TYPE_H_ */
diff --git a/src/libmime/smtp_parsers.h b/src/libmime/smtp_parsers.h
index 07bd24688..0d6e23413 100644
--- a/src/libmime/smtp_parsers.h
+++ b/src/libmime/smtp_parsers.h
@@ -18,6 +18,7 @@
#include "config.h"
#include "email_addr.h"
+#include "content_type.h"
#include "task.h"
#include "message.h"
@@ -30,4 +31,7 @@ void rspamd_strip_newlines_parse (const gchar *begin, const gchar *pe,
GByteArray *data, gboolean is_html, guint *newlines_count,
GPtrArray *newlines);
+gboolean rspamd_content_type_parser (const char *data, size_t len,
+ struct rspamd_content_type *ct, rspamd_mempool_t *pool);
+
#endif /* SRC_LIBMIME_SMTP_PARSERS_H_ */