diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-08-01 21:49:22 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-08-01 21:49:22 +0100 |
commit | 05ca72e767b9e90b82b21685299017cf39416a7e (patch) | |
tree | b9d058c31e777d4c0781f4b5f902d8b053d865c5 /src/client | |
parent | afec411bb53827296eebc1973c9cb65fe67d16f6 (diff) | |
download | rspamd-05ca72e767b9e90b82b21685299017cf39416a7e.tar.gz rspamd-05ca72e767b9e90b82b21685299017cf39416a7e.zip |
Add support for mime output.
Diffstat (limited to 'src/client')
-rw-r--r-- | src/client/rspamc.c | 142 |
1 files changed, 132 insertions, 10 deletions
diff --git a/src/client/rspamc.c b/src/client/rspamc.c index a8c65c2f8..3530fa66c 100644 --- a/src/client/rspamc.c +++ b/src/client/rspamc.c @@ -118,6 +118,17 @@ static GOptionEntry entries[] = { NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL } }; +/* Copy to avoid linking with librspamdserver */ +enum rspamd_metric_action { + METRIC_ACTION_REJECT = 0, + METRIC_ACTION_SOFT_REJECT, + METRIC_ACTION_REWRITE_SUBJECT, + METRIC_ACTION_ADD_HEADER, + METRIC_ACTION_GREYLIST, + METRIC_ACTION_NOACTION, + METRIC_ACTION_MAX +}; + static void rspamc_symbols_output (FILE *out, ucl_object_t *obj); static void rspamc_uptime_output (FILE *out, ucl_object_t *obj); static void rspamc_counters_output (FILE *out, ucl_object_t *obj); @@ -786,6 +797,110 @@ rspamc_output_headers (FILE *out, struct rspamd_http_message *msg) rspamd_fprintf (out, "\n"); } +static gboolean +rspamd_action_from_str (const gchar *data, gint *result) +{ + if (g_ascii_strncasecmp (data, "reject", sizeof ("reject") - 1) == 0) { + *result = METRIC_ACTION_REJECT; + } + else if (g_ascii_strncasecmp (data, "greylist", + sizeof ("greylist") - 1) == 0) { + *result = METRIC_ACTION_GREYLIST; + } + else if (g_ascii_strncasecmp (data, "add_header", sizeof ("add_header") - + 1) == 0) { + *result = METRIC_ACTION_ADD_HEADER; + } + else if (g_ascii_strncasecmp (data, "rewrite_subject", + sizeof ("rewrite_subject") - 1) == 0) { + *result = METRIC_ACTION_REWRITE_SUBJECT; + } + else if (g_ascii_strncasecmp (data, "add header", sizeof ("add header") - + 1) == 0) { + *result = METRIC_ACTION_ADD_HEADER; + } + else if (g_ascii_strncasecmp (data, "rewrite subject", + sizeof ("rewrite subject") - 1) == 0) { + *result = METRIC_ACTION_REWRITE_SUBJECT; + } + else if (g_ascii_strncasecmp (data, "soft_reject", + sizeof ("soft_reject") - 1) == 0) { + *result = METRIC_ACTION_SOFT_REJECT; + } + else if (g_ascii_strncasecmp (data, "soft reject", + sizeof ("soft reject") - 1) == 0) { + *result = METRIC_ACTION_SOFT_REJECT; + } + else { + return FALSE; + } + return TRUE; +} + +static void +rspamc_mime_output (FILE *out, ucl_object_t *result, GString *input) +{ + GMimeStream *stream; + GByteArray ar; + GMimeParser *parser; + GMimeMessage *message; + const ucl_object_t *metric, *res; + const gchar *action = "no action"; + gint act; + gboolean is_spam = FALSE; + const gchar *hdr_scanned, *hdr_spam; + + ar.data = input->str; + ar.len = input->len; + + stream = g_mime_stream_mem_new_with_byte_array (&ar); + g_mime_stream_mem_set_owner (GMIME_STREAM_MEM (stream), FALSE); + parser = g_mime_parser_new_with_stream (stream); + g_object_unref (stream); + + message = g_mime_parser_construct_message (parser); + + if (message == NULL) { + rspamd_fprintf (stderr,"cannot construct mime from stream"); + return; + } + + metric = ucl_object_find_key (result, "default"); + + if (metric != NULL) { + res = ucl_object_find_key (metric, "action"); + + if (res) { + action = ucl_object_tostring (res); + } + } + + rspamd_action_from_str (action, &act); + + if (act < METRIC_ACTION_GREYLIST) { + is_spam = TRUE; + } + + hdr_scanned = "rspamc " RVERSION; + g_mime_object_append_header (GMIME_OBJECT (message), "X-Spam-Scanner", + hdr_scanned); + if (is_spam) { + hdr_spam = "yes"; + g_mime_object_append_header (GMIME_OBJECT (message), "X-Spam", hdr_spam); + } + + g_mime_object_append_header (GMIME_OBJECT (message), "X-Spam-Action", + action); + + /* Write message */ + stream = g_mime_stream_file_new (out); + g_mime_stream_file_set_owner (GMIME_STREAM_FILE (stream), FALSE); + g_mime_object_write_to_stream (GMIME_OBJECT (message), stream); + g_object_unref (stream); + g_object_unref (message); + g_object_unref (parser); +} + static void rspamc_client_execute_cmd (struct rspamc_command *cmd, ucl_object_t *result, GString *input) @@ -815,18 +930,24 @@ rspamc_client_execute_cmd (struct rspamc_command *cmd, ucl_object_t *result, out = fdopen (infd, "w"); if (result != NULL) { - if (raw || cmd->command_output_func == NULL) { - if (json) { - ucl_out = ucl_object_emit (result, UCL_EMIT_JSON); + + if (cmd->cmd == RSPAMC_COMMAND_SYMBOLS && mime_output && input) { + rspamc_mime_output (out, result, input); + } + else { + if (raw || cmd->command_output_func == NULL) { + if (json) { + ucl_out = ucl_object_emit (result, UCL_EMIT_JSON); + } + else { + ucl_out = ucl_object_emit (result, UCL_EMIT_CONFIG); + } + rspamd_fprintf (out, "%s", ucl_out); + free (ucl_out); } else { - ucl_out = ucl_object_emit (result, UCL_EMIT_CONFIG); + cmd->command_output_func (out, result); } - rspamd_fprintf (out, "%s", ucl_out); - free (ucl_out); - } - else { - cmd->command_output_func (out, result); } ucl_object_unref (result); @@ -835,7 +956,6 @@ rspamc_client_execute_cmd (struct rspamc_command *cmd, ucl_object_t *result, rspamd_fprintf (out, "%s\n", err->message); } - rspamd_fprintf (out, "\n"); fflush (out); fclose (out); @@ -1028,6 +1148,7 @@ main (gint argc, gchar **argv, gchar **env) } ev_base = event_init (); + g_mime_init (0); /* Now read other args from argc and argv */ if (argc == 1) { @@ -1114,6 +1235,7 @@ main (gint argc, gchar **argv, gchar **env) event_base_loop (ev_base, 0); g_hash_table_destroy (kwattrs); + g_mime_shutdown (); return 0; } |