From 747f2839b029685d4d9ec2faec5785fa8cc0fcce Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Wed, 14 Dec 2016 13:42:26 +0000 Subject: [PATCH] [Feature] Add mime tool to explore messages --- test/rspamd_test_suite.c | 6 +- utils/CMakeLists.txt | 3 +- utils/mime_tool.c | 158 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 164 insertions(+), 3 deletions(-) create mode 100644 utils/mime_tool.c diff --git a/test/rspamd_test_suite.c b/test/rspamd_test_suite.c index 17e4ff872..ddce88d3d 100644 --- a/test/rspamd_test_suite.c +++ b/test/rspamd_test_suite.c @@ -21,7 +21,8 @@ main (int argc, char **argv) cfg->log_type = RSPAMD_LOG_CONSOLE; cfg->log_level = G_LOG_LEVEL_INFO; - rspamd_set_logger (cfg, g_quark_from_static_string("rspamd-test"), rspamd_main); + rspamd_set_logger (cfg, g_quark_from_static_string("rspamd-test"), + &rspamd_main->logger, rspamd_main->server_pool); (void)rspamd_log_open (rspamd_main->logger); g_test_init (&argc, &argv, NULL); @@ -33,7 +34,8 @@ main (int argc, char **argv) if (g_test_verbose ()) { cfg->log_level = G_LOG_LEVEL_DEBUG; - rspamd_set_logger (cfg, g_quark_from_static_string("rspamd-test"), rspamd_main); + rspamd_set_logger (cfg, g_quark_from_static_string("rspamd-test"), + &rspamd_main->logger, rspamd_main->server_pool); (void)rspamd_log_reopen (rspamd_main->logger); } diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index fbfaa4a09..81430d1e7 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -3,7 +3,7 @@ SET(UTILBENCHSRC rspamd_http_bench.c) SET(RECVBENCHSRC received_parser_bench.c) SET(CTYPEBENCHSRC content_type_bench.c) SET(BASE64SRC base64.c) - +SET(MIMESRC mime_tool.c) MACRO(ADD_UTIL NAME) ADD_EXECUTABLE("${NAME}" "${ARGN}") @@ -27,6 +27,7 @@ ADD_UTIL(rspamd-http-bench ${UTILBENCHSRC}) ADD_UTIL(rspamd-received-bench ${RECVBENCHSRC}) ADD_UTIL(rspamd-ctype-bench ${CTYPEBENCHSRC}) ADD_UTIL(rspamd-base64 ${BASE64SRC}) +ADD_UTIL(rspamd-mime-tool ${MIMESRC}) # Redirector IF (ENABLE_REDIRECTOR MATCHES "ON") diff --git a/utils/mime_tool.c b/utils/mime_tool.c new file mode 100644 index 000000000..bc7cda2e4 --- /dev/null +++ b/utils/mime_tool.c @@ -0,0 +1,158 @@ +/*- + * 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 "config.h" +#include "printf.h" +#include "message.h" +#include "util.h" +#include "content_type.h" +#include "task.h" +#include "mime_parser.h" +#include "unix-std.h" + + +static void +rspamd_show_normal (struct rspamd_mime_part *part) +{ + rspamd_printf ("got normal part %p: parent: %p, type: %T/%T," + "length: %z (%z raw)\n", + part, part->parent_part, + &part->ct->type, &part->ct->subtype, + part->parsed_data.len, + part->raw_data.len); +} + +static void +rspamd_show_multipart (struct rspamd_mime_part *part) +{ + struct rspamd_mime_part *cur; + guint i; + + rspamd_printf ("got multipart part %p: parent: %p, type: %T/%T, children: [", + part, part->parent_part, + &part->ct->type, &part->ct->subtype); + + if (part->children) { + for (i = 0; i < part->children->len; i ++) { + cur = g_ptr_array_index (part->children, i); + + if (i != 0) { + rspamd_printf (", %p{%T/%T}", cur, + &cur->ct->type, &cur->ct->subtype); + } + else { + rspamd_printf ("%p{%T/%T}", cur, + &cur->ct->type, &cur->ct->subtype); + } + } + } + + rspamd_printf ("]\n"); +} + +static void +rspamd_show_message (struct rspamd_mime_part *part) +{ + rspamd_printf ("got message part %p: parent: %p, type: %T/%T", + part, part->parent_part); +} + +static void +rspamd_process_file (struct rspamd_config *cfg, const gchar *fname, gint mode) +{ + struct rspamd_task *task; + gint fd; + gpointer map; + struct stat st; + GError *err = NULL; + struct rspamd_mime_part *part; + guint i; + + fd = open (fname, O_RDONLY); + + if (fd == -1) { + rspamd_fprintf (stderr, "cannot open %s: %s\n", fname, strerror (errno)); + exit (EXIT_FAILURE); + } + + if (fstat (fd, &st) == -1) { + rspamd_fprintf (stderr, "cannot stat %s: %s\n", fname, strerror (errno)); + exit (EXIT_FAILURE); + } + + map = mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); + close (fd); + + if (map == MAP_FAILED) { + rspamd_fprintf (stderr, "cannot mmap %s: %s\n", fname, strerror (errno)); + exit (EXIT_FAILURE); + } + + task = rspamd_task_new (NULL, cfg); + task->msg.begin = map; + task->msg.len = st.st_size; + + if (!rspamd_mime_parse_task (task, &err)) { + rspamd_fprintf (stderr, "cannot parse %s: %e\n", fname, err); + g_error_free (err); + } + + for (i = 0; i < task->parts->len; i ++) { + part = g_ptr_array_index (task->parts, i); + + if (part->ct->flags & RSPAMD_CONTENT_TYPE_MULTIPART) { + rspamd_show_multipart (part); + } + else if (part->ct->flags & RSPAMD_CONTENT_TYPE_MESSAGE) { + rspamd_show_message (part); + } + else { + rspamd_show_normal (part); + } + } + + rspamd_task_free (task); + munmap (map, st.st_size); +} + +int +main (int argc, char **argv) +{ + gint i, start = 1; + struct rspamd_config *cfg; + rspamd_logger_t *logger = NULL; + + cfg = rspamd_config_new (); + cfg->libs_ctx = rspamd_init_libs (); + cfg->log_type = RSPAMD_LOG_CONSOLE; + rspamd_set_logger (cfg, g_quark_from_static_string ("mime"), &logger, NULL); + (void) rspamd_log_open (logger); + g_log_set_default_handler (rspamd_glib_log_function, logger); + g_set_printerr_handler (rspamd_glib_printerr_function); + rspamd_config_post_load (cfg, + RSPAMD_CONFIG_INIT_LIBS|RSPAMD_CONFIG_INIT_URL|RSPAMD_CONFIG_INIT_NO_TLD); + + for (i = start; i < argc; i ++) { + if (argv[i]) { + rspamd_process_file (cfg, argv[i], 0); + } + } + + rspamd_log_close (logger); + REF_RELEASE (cfg); + + return 0; +} -- 2.39.5