diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2016-12-12 13:44:08 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2016-12-12 13:44:08 +0000 |
commit | 1d95f1678637f30b6bf453f781b5938d64354228 (patch) | |
tree | 2ee99ae2bc79323bd96dad52157e6e6be67ba45a /src/libmime | |
parent | 55467ed90c19bc82506433f8f7d274b5bfb8d10f (diff) | |
download | rspamd-1d95f1678637f30b6bf453f781b5938d64354228.tar.gz rspamd-1d95f1678637f30b6bf453f781b5938d64354228.zip |
[Rework] Implement content type parser for mime
Diffstat (limited to 'src/libmime')
-rw-r--r-- | src/libmime/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/libmime/content_type.c | 79 | ||||
-rw-r--r-- | src/libmime/content_type.h | 61 | ||||
-rw-r--r-- | src/libmime/smtp_parsers.h | 4 |
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_ */ |