aboutsummaryrefslogtreecommitdiffstats
path: root/src/libserver/protocol.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libserver/protocol.c')
-rw-r--r--src/libserver/protocol.c265
1 files changed, 148 insertions, 117 deletions
diff --git a/src/libserver/protocol.c b/src/libserver/protocol.c
index fc4096f8c..30a155229 100644
--- a/src/libserver/protocol.c
+++ b/src/libserver/protocol.c
@@ -22,11 +22,11 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "cfg_file.h"
#include "config.h"
#include "main.h"
-#include "util.h"
-#include "cfg_file.h"
#include "message.h"
+#include "util.h"
/* Max line size */
#define OUTBUFSIZ BUFSIZ
@@ -35,7 +35,7 @@
* described below
*/
#define MSG_CMD_CHECK "check"
-/*
+/*
* Check if message is spam or not, and return score plus list
* of symbols hit
*/
@@ -95,7 +95,7 @@
#define DELIVER_TO_HEADER "Deliver-To"
#define NO_LOG_HEADER "Log"
-static GList *custom_commands = NULL;
+static GList *custom_commands = NULL;
/*
@@ -104,20 +104,22 @@ static GList *custom_commands = NULL;
static gchar *
rspamd_protocol_escape_braces (GString *in)
{
- gint len = 0;
- gchar *orig, *p;
+ gint len = 0;
+ gchar *orig, *p;
orig = in->str;
- while ((g_ascii_isspace (*orig) || *orig == '<') && orig - in->str < (gint)in->len) {
- orig ++;
+ while ((g_ascii_isspace (*orig) || *orig ==
+ '<') && orig - in->str < (gint)in->len) {
+ orig++;
}
g_string_erase (in, 0, orig - in->str);
p = in->str;
- while ((!g_ascii_isspace (*p) && *p != '>') && p - in->str < (gint)in->len) {
- p ++;
- len ++;
+ while ((!g_ascii_isspace (*p) && *p !=
+ '>') && p - in->str < (gint)in->len) {
+ p++;
+ len++;
}
g_string_truncate (in, len);
@@ -126,10 +128,11 @@ rspamd_protocol_escape_braces (GString *in)
}
static gboolean
-rspamd_protocol_handle_url (struct rspamd_task *task, struct rspamd_http_message *msg)
+rspamd_protocol_handle_url (struct rspamd_task *task,
+ struct rspamd_http_message *msg)
{
- GList *cur;
- struct custom_command *cmd;
+ GList *cur;
+ struct custom_command *cmd;
const gchar *p;
if (msg->url == NULL || msg->url->len == 0) {
@@ -224,13 +227,14 @@ err:
gboolean
rspamd_protocol_handle_headers (struct rspamd_task *task,
- struct rspamd_http_message *msg)
+ struct rspamd_http_message *msg)
{
- gchar *headern, *err, *tmp;
- gboolean res = TRUE;
- struct rspamd_http_header *h;
+ gchar *headern, *err, *tmp;
+ gboolean res = TRUE;
+ struct rspamd_http_header *h;
- LL_FOREACH (msg->headers, h) {
+ LL_FOREACH (msg->headers, h)
+ {
headern = h->name->str;
switch (headern[0]) {
@@ -238,7 +242,8 @@ rspamd_protocol_handle_headers (struct rspamd_task *task,
case 'D':
if (g_ascii_strcasecmp (headern, DELIVER_TO_HEADER) == 0) {
task->deliver_to = rspamd_protocol_escape_braces (h->value);
- debug_task ("read deliver-to header, value: %s", task->deliver_to);
+ debug_task ("read deliver-to header, value: %s",
+ task->deliver_to);
}
else {
debug_task ("wrong header: %s", headern);
@@ -327,7 +332,7 @@ rspamd_protocol_handle_headers (struct rspamd_task *task,
case 'P':
if (g_ascii_strcasecmp (headern, PASS_HEADER) == 0) {
if (h->value->len == sizeof ("all") - 1 &&
- g_ascii_strcasecmp (h->value->str, "all") == 0) {
+ g_ascii_strcasecmp (h->value->str, "all") == 0) {
task->pass_all_filters = TRUE;
debug_task ("pass all filters");
}
@@ -373,7 +378,8 @@ rspamd_protocol_handle_headers (struct rspamd_task *task,
}
if (!res && task->cfg->strict_protocol_headers) {
- msg_err ("deny processing of a request with incorrect or unknown headers");
+ msg_err (
+ "deny processing of a request with incorrect or unknown headers");
task->last_error = "invalid header";
task->error_code = 400;
return FALSE;
@@ -384,7 +390,7 @@ rspamd_protocol_handle_headers (struct rspamd_task *task,
gboolean
rspamd_protocol_handle_request (struct rspamd_task *task,
- struct rspamd_http_message *msg)
+ struct rspamd_http_message *msg)
{
gboolean ret = TRUE;
@@ -407,19 +413,22 @@ rspamd_protocol_handle_request (struct rspamd_task *task,
static void
write_hashes_to_log (struct rspamd_task *task, GString *logbuf)
{
- GList *cur;
- struct mime_text_part *text_part;
-
+ GList *cur;
+ struct mime_text_part *text_part;
+
cur = task->text_parts;
while (cur) {
text_part = cur->data;
if (text_part->fuzzy) {
if (cur->next != NULL) {
- rspamd_printf_gstring (logbuf, " part: %Xd,", text_part->fuzzy->h);
+ rspamd_printf_gstring (logbuf,
+ " part: %Xd,",
+ text_part->fuzzy->h);
}
else {
- rspamd_printf_gstring (logbuf, " part: %Xd", text_part->fuzzy->h);
+ rspamd_printf_gstring (logbuf, " part: %Xd",
+ text_part->fuzzy->h);
}
}
cur = g_list_next (cur);
@@ -439,18 +448,20 @@ struct tree_cb_data {
static gboolean
urls_protocol_cb (gpointer key, gpointer value, gpointer ud)
{
- struct tree_cb_data *cb = ud;
- struct uri *url = value;
- ucl_object_t *obj;
+ struct tree_cb_data *cb = ud;
+ struct uri *url = value;
+ ucl_object_t *obj;
obj = ucl_object_fromlstring (url->host, url->hostlen);
DL_APPEND (cb->top->value.av, obj);
if (cb->task->cfg->log_urls) {
- msg_info ("<%s> URL: %s - %s: %s", cb->task->message_id, cb->task->user ?
- cb->task->user : (cb->task->from ? cb->task->from : "unknown"),
- rspamd_inet_address_to_string (&cb->task->from_addr),
- struri (url));
+ msg_info ("<%s> URL: %s - %s: %s",
+ cb->task->message_id,
+ cb->task->user ?
+ cb->task->user : (cb->task->from ? cb->task->from : "unknown"),
+ rspamd_inet_address_to_string (&cb->task->from_addr),
+ struri (url));
}
return FALSE;
@@ -459,8 +470,8 @@ urls_protocol_cb (gpointer key, gpointer value, gpointer ud)
static ucl_object_t *
rspamd_urls_tree_ucl (GTree *input, struct rspamd_task *task)
{
- struct tree_cb_data cb;
- ucl_object_t *obj;
+ struct tree_cb_data cb;
+ ucl_object_t *obj;
obj = ucl_object_typed_new (UCL_ARRAY);
cb.top = obj;
@@ -474,9 +485,9 @@ rspamd_urls_tree_ucl (GTree *input, struct rspamd_task *task)
static gboolean
emails_protocol_cb (gpointer key, gpointer value, gpointer ud)
{
- struct tree_cb_data *cb = ud;
- struct uri *url = value;
- ucl_object_t *obj;
+ struct tree_cb_data *cb = ud;
+ struct uri *url = value;
+ ucl_object_t *obj;
obj = ucl_object_fromlstring (url->user, url->userlen + url->hostlen + 1);
DL_APPEND (cb->top->value.av, obj);
@@ -487,8 +498,8 @@ emails_protocol_cb (gpointer key, gpointer value, gpointer ud)
static ucl_object_t *
rspamd_emails_tree_ucl (GTree *input, struct rspamd_task *task)
{
- struct tree_cb_data cb;
- ucl_object_t *obj;
+ struct tree_cb_data cb;
+ ucl_object_t *obj;
obj = ucl_object_typed_new (UCL_ARRAY);
cb.top = obj;
@@ -504,9 +515,9 @@ rspamd_emails_tree_ucl (GTree *input, struct rspamd_task *task)
static const gchar *
make_rewritten_subject (struct metric *metric, struct rspamd_task *task)
{
- static gchar subj_buf[1024];
- gchar *p = subj_buf, *end, *c, *res;
- const gchar *s;
+ static gchar subj_buf[1024];
+ gchar *p = subj_buf, *end, *c, *res;
+ const gchar *s;
end = p + sizeof(subj_buf);
c = metric->subject;
@@ -522,13 +533,15 @@ make_rewritten_subject (struct metric *metric, struct rspamd_task *task)
c += 2;
}
else {
- *p = *c ++;
+ *p = *c++;
}
- p ++;
+ p++;
}
res = g_mime_utils_header_encode_text (subj_buf);
- rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t)g_free, res);
+ rspamd_mempool_add_destructor (task->task_pool,
+ (rspamd_mempool_destruct_t)g_free,
+ res);
return res;
}
@@ -536,8 +549,8 @@ make_rewritten_subject (struct metric *metric, struct rspamd_task *task)
static ucl_object_t *
rspamd_str_list_ucl (GList *str_list)
{
- ucl_object_t *top = NULL, *obj;
- GList *cur;
+ ucl_object_t *top = NULL, *obj;
+ GList *cur;
top = ucl_object_typed_new (UCL_ARRAY);
cur = str_list;
@@ -552,40 +565,46 @@ rspamd_str_list_ucl (GList *str_list)
static ucl_object_t *
rspamd_metric_symbol_ucl (struct rspamd_task *task, struct metric *m,
- struct symbol *sym, GString *logbuf)
+ struct symbol *sym, GString *logbuf)
{
- ucl_object_t *obj = NULL;
- const gchar *description = NULL;
+ ucl_object_t *obj = NULL;
+ const gchar *description = NULL;
rspamd_printf_gstring (logbuf, "%s,", sym->name);
description = g_hash_table_lookup (m->descriptions, sym->name);
obj = ucl_object_typed_new (UCL_OBJECT);
- ucl_object_insert_key (obj, ucl_object_fromstring (sym->name), "name", 0, false);
- ucl_object_insert_key (obj, ucl_object_fromdouble (sym->score), "score", 0, false);
+ ucl_object_insert_key (obj, ucl_object_fromstring (
+ sym->name), "name", 0, false);
+ ucl_object_insert_key (obj, ucl_object_fromdouble (
+ sym->score), "score", 0, false);
if (description) {
- ucl_object_insert_key (obj, ucl_object_fromstring (description), "description", 0, false);
+ ucl_object_insert_key (obj, ucl_object_fromstring (
+ description), "description", 0, false);
}
if (sym->options != NULL) {
- ucl_object_insert_key (obj, rspamd_str_list_ucl (sym->options), "options", 0, false);
+ ucl_object_insert_key (obj, rspamd_str_list_ucl (
+ sym->options), "options", 0, false);
}
return obj;
}
static ucl_object_t *
-rspamd_metric_result_ucl (struct rspamd_task *task, struct metric_result *mres, GString *logbuf)
+rspamd_metric_result_ucl (struct rspamd_task *task,
+ struct metric_result *mres,
+ GString *logbuf)
{
- GHashTableIter hiter;
- struct symbol *sym;
- struct metric *m;
- gboolean is_spam;
- enum rspamd_metric_action action = METRIC_ACTION_NOACTION;
- ucl_object_t *obj = NULL, *sobj;
- gdouble required_score;
- gpointer h, v;
- const gchar *subject;
- gchar action_char;
+ GHashTableIter hiter;
+ struct symbol *sym;
+ struct metric *m;
+ gboolean is_spam;
+ enum rspamd_metric_action action = METRIC_ACTION_NOACTION;
+ ucl_object_t *obj = NULL, *sobj;
+ gdouble required_score;
+ gpointer h, v;
+ const gchar *subject;
+ gchar action_char;
m = mres->metric;
@@ -603,26 +622,27 @@ rspamd_metric_result_ucl (struct rspamd_task *task, struct metric_result *mres,
action_char = 'F';
}
rspamd_printf_gstring (logbuf, "(%s: %c (%s): [%.2f/%.2f] [",
- m->name, action_char,
- str_action_metric (action),
- mres->score, required_score);
+ m->name, action_char,
+ str_action_metric (action),
+ mres->score, required_score);
obj = ucl_object_typed_new (UCL_OBJECT);
- ucl_object_insert_key (obj, ucl_object_frombool (is_spam),
- "is_spam", 0, false);
- ucl_object_insert_key (obj, ucl_object_frombool (task->is_skipped),
- "is_skipped", 0, false);
+ ucl_object_insert_key (obj, ucl_object_frombool (is_spam),
+ "is_spam", 0, false);
+ ucl_object_insert_key (obj, ucl_object_frombool (task->is_skipped),
+ "is_skipped", 0, false);
ucl_object_insert_key (obj, ucl_object_fromdouble (mres->score),
- "score", 0, false);
+ "score", 0, false);
ucl_object_insert_key (obj, ucl_object_fromdouble (required_score),
- "required_score", 0, false);
- ucl_object_insert_key (obj, ucl_object_fromstring (str_action_metric (action)),
- "action", 0, false);
+ "required_score", 0, false);
+ ucl_object_insert_key (obj,
+ ucl_object_fromstring (str_action_metric (action)),
+ "action", 0, false);
if (action == METRIC_ACTION_REWRITE_SUBJECT) {
subject = make_rewritten_subject (m, task);
ucl_object_insert_key (obj, ucl_object_fromstring (subject),
- "subject", 0, false);
+ "subject", 0, false);
}
/* Now handle symbols */
g_hash_table_iter_init (&hiter, mres->symbols);
@@ -634,28 +654,31 @@ rspamd_metric_result_ucl (struct rspamd_task *task, struct metric_result *mres,
/* Cut the trailing comma if needed */
if (logbuf->str[logbuf->len - 1] == ',') {
- logbuf->len --;
+ logbuf->len--;
}
#ifdef HAVE_CLOCK_GETTIME
rspamd_printf_gstring (logbuf, "]), len: %z, time: %s, dns req: %d,",
- task->msg->len, calculate_check_time (&task->tv, &task->ts,
- task->cfg->clock_res, &task->scan_milliseconds), task->dns_requests);
+ task->msg->len, calculate_check_time (&task->tv, &task->ts,
+ task->cfg->clock_res, &task->scan_milliseconds), task->dns_requests);
#else
rspamd_printf_gstring (logbuf, "]), len: %z, time: %s, dns req: %d,",
- task->msg->len,
- calculate_check_time (&task->tv, task->cfg->clock_res, &task->scan_milliseconds),
- task->dns_requests);
+ task->msg->len,
+ calculate_check_time (&task->tv, task->cfg->clock_res,
+ &task->scan_milliseconds),
+ task->dns_requests);
#endif
return obj;
}
static void
-rspamd_ucl_tolegacy_output (struct rspamd_task *task, ucl_object_t *top, GString *out)
+rspamd_ucl_tolegacy_output (struct rspamd_task *task,
+ ucl_object_t *top,
+ GString *out)
{
const ucl_object_t *metric, *score,
- *required_score, *is_spam, *elt;
+ *required_score, *is_spam, *elt;
ucl_object_iter_t iter = NULL;
metric = ucl_object_find_key (top, DEFAULT_METRIC);
@@ -663,10 +686,11 @@ rspamd_ucl_tolegacy_output (struct rspamd_task *task, ucl_object_t *top, GString
score = ucl_object_find_key (metric, "score");
required_score = ucl_object_find_key (metric, "required_score");
is_spam = ucl_object_find_key (metric, "is_spam");
- g_string_append_printf (out, "Metric: default; %s; %.2f / %.2f / 0.0\r\n",
- ucl_object_toboolean (is_spam) ? "True" : "False",
- ucl_object_todouble (score),
- ucl_object_todouble (required_score));
+ g_string_append_printf (out,
+ "Metric: default; %s; %.2f / %.2f / 0.0\r\n",
+ ucl_object_toboolean (is_spam) ? "True" : "False",
+ ucl_object_todouble (score),
+ ucl_object_todouble (required_score));
elt = ucl_object_find_key (metric, "action");
if (elt != NULL) {
g_string_append_printf (out, "Action: %s\r\n",
@@ -679,34 +703,38 @@ rspamd_ucl_tolegacy_output (struct rspamd_task *task, ucl_object_t *top, GString
const ucl_object_t *sym_score;
sym_score = ucl_object_find_key (elt, "score");
g_string_append_printf (out, "Symbol: %s(%.2f)\r\n",
- ucl_object_key (elt),
- ucl_object_todouble (sym_score));
+ ucl_object_key (elt),
+ ucl_object_todouble (sym_score));
}
}
elt = ucl_object_find_key (metric, "subject");
if (elt != NULL) {
g_string_append_printf (out, "Subject: %s\r\n",
- ucl_object_tostring (elt));
+ ucl_object_tostring (elt));
}
}
g_string_append_printf (out, "Message-ID: %s\r\n", task->message_id);
}
void
-rspamd_protocol_http_reply (struct rspamd_http_message *msg, struct rspamd_task *task)
+rspamd_protocol_http_reply (struct rspamd_http_message *msg,
+ struct rspamd_task *task)
{
- GString *logbuf;
- struct metric_result *metric_res;
- GHashTableIter hiter;
- gpointer h, v;
- ucl_object_t *top = NULL, *obj;
- gdouble required_score;
- gint action;
+ GString *logbuf;
+ struct metric_result *metric_res;
+ GHashTableIter hiter;
+ gpointer h, v;
+ ucl_object_t *top = NULL, *obj;
+ gdouble required_score;
+ gint action;
/* Output the first line - check status */
logbuf = g_string_sized_new (BUFSIZ);
- rspamd_printf_gstring (logbuf, "id: <%s>, qid: <%s>, ", task->message_id, task->queue_id);
+ rspamd_printf_gstring (logbuf,
+ "id: <%s>, qid: <%s>, ",
+ task->message_id,
+ task->queue_id);
if (task->user) {
rspamd_printf_gstring (logbuf, "user: %s, ", task->user);
@@ -726,18 +754,20 @@ rspamd_protocol_http_reply (struct rspamd_http_message *msg, struct rspamd_task
}
if (task->messages != NULL) {
- ucl_object_insert_key (top, rspamd_str_list_ucl (task->messages), "messages", 0, false);
+ ucl_object_insert_key (top, rspamd_str_list_ucl (
+ task->messages), "messages", 0, false);
}
if (g_tree_nnodes (task->urls) > 0) {
- ucl_object_insert_key (top, rspamd_urls_tree_ucl (task->urls, task), "urls", 0, false);
+ ucl_object_insert_key (top, rspamd_urls_tree_ucl (task->urls,
+ task), "urls", 0, false);
}
if (g_tree_nnodes (task->emails) > 0) {
ucl_object_insert_key (top, rspamd_emails_tree_ucl (task->emails, task),
- "emails", 0, false);
+ "emails", 0, false);
}
-
+
ucl_object_insert_key (top, ucl_object_fromstring (task->message_id),
- "message-id", 0, false);
+ "message-id", 0, false);
write_hashes_to_log (task, logbuf);
if (!task->no_log) {
@@ -758,11 +788,12 @@ rspamd_protocol_http_reply (struct rspamd_http_message *msg, struct rspamd_task
/* Update stat for default metric */
metric_res = g_hash_table_lookup (task->results, DEFAULT_METRIC);
if (metric_res != NULL) {
- required_score = metric_res->metric->actions[METRIC_ACTION_REJECT].score;
+ required_score =
+ metric_res->metric->actions[METRIC_ACTION_REJECT].score;
action = check_metric_action (metric_res->score, required_score,
metric_res->metric);
if (action <= METRIC_ACTION_NOACTION) {
- task->worker->srv->stat->actions_stat[action] ++;
+ task->worker->srv->stat->actions_stat[action]++;
}
}
@@ -773,9 +804,9 @@ rspamd_protocol_http_reply (struct rspamd_http_message *msg, struct rspamd_task
void
rspamd_protocol_write_reply (struct rspamd_task *task)
{
- struct rspamd_http_message *msg;
- const gchar *ctype = "application/json";
- ucl_object_t *top = NULL;
+ struct rspamd_http_message *msg;
+ const gchar *ctype = "application/json";
+ ucl_object_t *top = NULL;
msg = rspamd_http_new_message (HTTP_RESPONSE);
if (!task->is_json) {
@@ -792,7 +823,7 @@ rspamd_protocol_write_reply (struct rspamd_task *task)
msg->code = 500 + task->error_code % 100;
msg->status = g_string_new (task->last_error);
ucl_object_insert_key (top, ucl_object_fromstring (task->last_error),
- "error", 0, false);
+ "error", 0, false);
msg->body = g_string_sized_new (256);
rspamd_ucl_emit_gstring (top, UCL_EMIT_JSON_COMPACT, msg->body);
ucl_object_unref (top);
@@ -818,13 +849,13 @@ rspamd_protocol_write_reply (struct rspamd_task *task)
rspamd_http_connection_reset (task->http_conn);
rspamd_http_connection_write_message (task->http_conn, msg, NULL,
- ctype, task, task->sock, &task->tv, task->ev_base);
+ ctype, task, task->sock, &task->tv, task->ev_base);
}
void
register_protocol_command (const gchar *name, protocol_reply_func func)
{
- struct custom_command *cmd;
+ struct custom_command *cmd;
cmd = g_malloc (sizeof (struct custom_command));
cmd->name = name;