diff options
author | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2010-07-31 18:59:40 +0400 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2010-07-31 18:59:40 +0400 |
commit | 2a8b8ce671babd92cd60fbd70be9edf97cc20603 (patch) | |
tree | fe4c61979cd646544d5e2be1e89c8c8d9241e3af | |
parent | 7c778294a9625ee4954f784763495e05af513510 (diff) | |
download | rspamd-2a8b8ce671babd92cd60fbd70be9edf97cc20603.tar.gz rspamd-2a8b8ce671babd92cd60fbd70be9edf97cc20603.zip |
* Write symbols weights to rspamc output
* Improve logic of selecting rspamc version
* Do not try to parse broken DNS replies
* Add 'raw' flag to FROM_EXCESS_BASE64 rule (requested by citrin)
-rw-r--r-- | conf/lua/regexp/headers.lua | 2 | ||||
-rw-r--r-- | perl/lib/Mail/Rspamd/Client.pm | 6 | ||||
-rwxr-xr-x | rspamc.pl.in | 1 | ||||
-rw-r--r-- | src/dns.c | 2 | ||||
-rw-r--r-- | src/main.h | 2 | ||||
-rw-r--r-- | src/protocol.c | 53 | ||||
-rw-r--r-- | src/protocol.h | 1 |
7 files changed, 49 insertions, 18 deletions
diff --git a/conf/lua/regexp/headers.lua b/conf/lua/regexp/headers.lua index d296b3653..4c415a2f3 100644 --- a/conf/lua/regexp/headers.lua +++ b/conf/lua/regexp/headers.lua @@ -77,7 +77,7 @@ reconf['TRACKER_ID'] = '/^[a-z0-9]{6,24}[-_a-z0-9]{2,36}[a-z0-9]{6,24}\\s*\\z/is -- Regexp that checks that from header is encoded with base64 (search in raw headers) local from_encoded_b64 = 'From=/\\=\\?\\S+\\?B\\?/iX' -- From contains only 7bit characters (parsed headers are used) -local from_needs_mime = 'From=/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f-\\xff]/H' +local from_needs_mime = 'From=/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f-\\xff]/Hr' -- Final rule reconf['FROM_EXCESS_BASE64'] = string.format('%s & !%s', from_encoded_b64, from_needs_mime) diff --git a/perl/lib/Mail/Rspamd/Client.pm b/perl/lib/Mail/Rspamd/Client.pm index 789b3187d..4af7a02d9 100644 --- a/perl/lib/Mail/Rspamd/Client.pm +++ b/perl/lib/Mail/Rspamd/Client.pm @@ -35,7 +35,7 @@ $VERSION = "1.02"; my $EOL = "\015\012"; my $BLANK = $EOL x 2; -my $PROTOVERSION = 'RSPAMC/1.0'; +my $PROTOVERSION = 'RSPAMC/1.2'; =head1 PUBLIC METHODS @@ -953,14 +953,16 @@ sub _do_rspamc_command { } else { foreach my $line (@lines) { - if ($line =~ m!Metric: (\S+); (\S+); (\S+) / (\S+)!) { + if ($line =~ m!Metric: (\S+); (\S+); (\S+) / (\S+) (/ (\S+))?!) { $metrics{$1} = { isspam => $2, score => $3 + 0, threshold => $4 + 0, + reject_score => $6, symbols => [], urls => [], messages => [], + action => 'no action', }; $cur_metric = $1; } diff --git a/rspamc.pl.in b/rspamc.pl.in index b2f6162d8..8d69e341a 100755 --- a/rspamc.pl.in +++ b/rspamc.pl.in @@ -288,6 +288,7 @@ if ($cmd =~ /(SYMBOLS|PROCESS|CHECK|URLS|EMAILS)/i) { elsif ($cmd =~ /(STAT|LEARN|SHUTDOWN|RELOAD|UPTIME|COUNTERS|FUZZY_ADD|FUZZY_DEL|WEIGHTS)/i) { $cfg{'command'} = $1; $cfg{'control'} = 1; + $cfg{'hosts'} = ['localhost:11334']; } else { die "unknown command $cmd"; @@ -771,7 +771,7 @@ dns_parse_rr (guint8 *in, union rspamd_reply_element *elt, guint8 **pos, struct msg_info ("bad RR name"); return -1; } - if (p - *pos >= *remain - sizeof (guint16) * 5) { + if (p - *pos >= *remain - sizeof (guint16) * 5 || *remain <= 0) { msg_info ("stripped dns reply"); return -1; } diff --git a/src/main.h b/src/main.h index e35a7eea3..697c63f47 100644 --- a/src/main.h +++ b/src/main.h @@ -173,7 +173,7 @@ struct worker_task { } state; /**< current session state */ size_t content_length; /**< length of user's input */ enum rspamd_protocol proto; /**< protocol (rspamc or spamc) */ - const char *proto_ver; /**< protocol version */ + guint proto_ver; /**< protocol version */ enum rspamd_command cmd; /**< command */ struct custom_command *custom_cmd; /**< custom command if any */ int sock; /**< socket descriptor */ diff --git a/src/protocol.c b/src/protocol.c index cb79b258c..297aaa922 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -92,6 +92,20 @@ static GList *custom_commands = NULL; /* For default metric, dirty hack, but much faster than hash lookup */ static double default_score, default_required_score; +G_INLINE_FUNC const char * +rspamc_proto_str (guint ver) +{ + if (ver >= 12) { + return "1.2"; + } + else if (ver >= 11) { + return "1.1"; + } + else { + return "1.0"; + } +} + static char * separate_command (f_str_t * in, char c) { @@ -120,7 +134,7 @@ parse_command (struct worker_task *task, f_str_t * line) struct custom_command *cmd; GList *cur; - task->proto_ver = RSPAMC_PROTO_1_1; + task->proto_ver = 11; token = separate_command (line, ' '); if (line == NULL || token == NULL) { debug_task ("bad command"); @@ -202,12 +216,15 @@ parse_command (struct worker_task *task, f_str_t * line) if (g_ascii_strncasecmp (line->begin, RSPAMC_GREETING, sizeof (RSPAMC_GREETING) - 1) == 0) { task->proto = RSPAMC_PROTO; - task->proto_ver = RSPAMC_PROTO_1_0; + task->proto_ver = 10; if (*(line->begin + sizeof (RSPAMC_GREETING) - 1) == '/') { /* Extract protocol version */ token = line->begin + sizeof (RSPAMC_GREETING); if (strncmp (token, RSPAMC_PROTO_1_1, sizeof (RSPAMC_PROTO_1_1) - 1) == 0) { - task->proto_ver = RSPAMC_PROTO_1_1; + task->proto_ver = 11; + } + else if (strncmp (token, RSPAMC_PROTO_1_2, sizeof (RSPAMC_PROTO_1_2) - 1) == 0) { + task->proto_ver = 12; } } } @@ -529,7 +546,12 @@ metric_symbols_callback (gpointer key, gpointer value, void *user_data) } if (s->options) { - r = rspamd_snprintf (outbuf, OUTBUFSIZ, "Symbol: %s; ", (char *)key); + if (task->proto_ver >= 12) { + r = rspamd_snprintf (outbuf, OUTBUFSIZ, "Symbol: %s(%.2f); ", (char *)key, s->score); + } + else { + r = rspamd_snprintf (outbuf, OUTBUFSIZ, "Symbol: %s; ", (char *)key); + } cur = s->options; while (cur) { if (g_list_next (cur)) { @@ -547,7 +569,12 @@ metric_symbols_callback (gpointer key, gpointer value, void *user_data) } } else { - r = rspamd_snprintf (outbuf, OUTBUFSIZ, "Symbol: %s" CRLF, (char *)key); + if (task->proto_ver >= 12) { + r = rspamd_snprintf (outbuf, OUTBUFSIZ, "Symbol: %s(%.2f)" CRLF, (char *)key, s->score); + } + else { + r = rspamd_snprintf (outbuf, OUTBUFSIZ, "Symbol: %s" CRLF, (char *)key); + } } cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset, cd->log_size - cd->log_offset, "%s,", (char *)key); @@ -670,7 +697,7 @@ show_metric_result (gpointer metric_name, gpointer metric_value, void *user_data r = rspamd_snprintf (outbuf, sizeof (outbuf), "Spam: False ; 0 / %.2f" CRLF, ms); } else { - if (strcmp (task->proto_ver, RSPAMC_PROTO_1_1) == 0) { + if (task->proto_ver >= 11) { if (!task->is_skipped) { r = rspamd_snprintf (outbuf, sizeof (outbuf), "Metric: default; False; 0 / %.2f / %.2f" CRLF, ms, rs); } @@ -709,7 +736,7 @@ show_metric_result (gpointer metric_name, gpointer metric_value, void *user_data r = rspamd_snprintf (outbuf, sizeof (outbuf), "Spam: %s ; %.2f / %.2f" CRLF, (is_spam) ? "True" : "False", metric_res->score, ms); } else { - if (strcmp (task->proto_ver, RSPAMC_PROTO_1_1) == 0) { + if (task->proto_ver >= 11) { if (!task->is_skipped) { r = rspamd_snprintf (outbuf, sizeof (outbuf), "Metric: %s; %s; %.2f / %.2f / %.2f" CRLF, (char *)metric_name, (is_spam) ? "True" : "False", metric_res->score, ms, rs); @@ -793,7 +820,7 @@ write_check_reply (struct worker_task *task) struct metric_callback_data cd; r = rspamd_snprintf (outbuf, sizeof (outbuf), "%s/%s 0 %s" CRLF, (task->proto == SPAMC_PROTO) ? SPAMD_REPLY_BANNER : RSPAMD_REPLY_BANNER, - task->proto_ver, "OK"); + rspamc_proto_str (task->proto_ver), "OK"); if (! rspamd_dispatcher_write (task->dispatcher, outbuf, r, TRUE, FALSE)) { return FALSE; } @@ -882,7 +909,7 @@ write_process_reply (struct worker_task *task) r = rspamd_snprintf (outbuf, sizeof (outbuf), "%s/%s 0 %s" CRLF "Content-Length: %zd" CRLF CRLF, (task->proto == SPAMC_PROTO) ? SPAMD_REPLY_BANNER : RSPAMD_REPLY_BANNER, - task->proto_ver, "OK", task->msg->len); + rspamc_proto_str (task->proto_ver), "OK", task->msg->len); cd.task = task; cd.log_buf = logbuf; @@ -970,12 +997,12 @@ write_reply (struct worker_task *task) /* Write error message and error code to reply */ if (task->proto == SPAMC_PROTO) { r = rspamd_snprintf (outbuf, sizeof (outbuf), "%s/%s %d %s" CRLF CRLF, - SPAMD_REPLY_BANNER, task->proto_ver, task->error_code, SPAMD_ERROR); + SPAMD_REPLY_BANNER, rspamc_proto_str (task->proto_ver), task->error_code, SPAMD_ERROR); debug_task ("writing error: %s", outbuf); } else { r = rspamd_snprintf (outbuf, sizeof (outbuf), "%s/%s %d %s" CRLF "%s: %s" CRLF CRLF, - RSPAMD_REPLY_BANNER, task->proto_ver, task->error_code, SPAMD_ERROR, ERROR_HEADER, task->last_error); + RSPAMD_REPLY_BANNER, rspamc_proto_str (task->proto_ver), task->error_code, SPAMD_ERROR, ERROR_HEADER, task->last_error); debug_task ("writing error: %s", outbuf); } /* Write to bufferevent error message */ @@ -994,12 +1021,12 @@ write_reply (struct worker_task *task) break; case CMD_SKIP: r = rspamd_snprintf (outbuf, sizeof (outbuf), "%s/%s 0 %s" CRLF, - (task->proto == SPAMC_PROTO) ? SPAMD_REPLY_BANNER : RSPAMD_REPLY_BANNER, task->proto_ver, SPAMD_OK); + (task->proto == SPAMC_PROTO) ? SPAMD_REPLY_BANNER : RSPAMD_REPLY_BANNER, rspamc_proto_str (task->proto_ver), SPAMD_OK); return rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE); break; case CMD_PING: r = rspamd_snprintf (outbuf, sizeof (outbuf), "%s/%s 0 PONG" CRLF, - (task->proto == SPAMC_PROTO) ? SPAMD_REPLY_BANNER : RSPAMD_REPLY_BANNER, task->proto_ver); + (task->proto == SPAMC_PROTO) ? SPAMD_REPLY_BANNER : RSPAMD_REPLY_BANNER, rspamc_proto_str (task->proto_ver)); return rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE); break; case CMD_OTHER: diff --git a/src/protocol.h b/src/protocol.h index d45e5c555..c216259f6 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -15,6 +15,7 @@ #define RSPAMC_PROTO_1_0 "1.0" #define RSPAMC_PROTO_1_1 "1.1" +#define RSPAMC_PROTO_1_2 "1.2" /* * Reply messages |