summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/rspamc.152
-rw-r--r--doc/rspamc.pod43
-rw-r--r--doc/rspamd.86
-rw-r--r--src/client/rspamc.c133
-rw-r--r--src/dynamic_cfg.c22
5 files changed, 175 insertions, 81 deletions
diff --git a/doc/rspamc.1 b/doc/rspamc.1
index 63d301051..e8f38bf81 100644
--- a/doc/rspamc.1
+++ b/doc/rspamc.1
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.07)
+.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.16)
.\"
.\" Standard preamble:
.\" ========================================================================
@@ -124,18 +124,19 @@
.\" ========================================================================
.\"
.IX Title "rspamc 1"
-.TH rspamc 1 "2011-03-15" "rspamd-0.3.8" "Rspamd documentation"
+.TH rspamc 1 "2012-10-02" "rspamd-0.5.2" "Rspamd documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
-.SH "NAME"
+.SH "RSPAMC"
.IX Header "RSPAMC"
rspamc \- a simple client for rspamd spam filtering system
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
-rspamc [\fB\-h\fR \fIhost[:port]\fR] [\fB\-p\fR] [\fB\-v\fR]
-[\fB\-i\fR \fIip\fR] [\fB\-s\fR \fIstatfile\fR] [\fB\-w\fR \fIweight\fR]
+rspamc [\fB\-h\fR \fIhost[:port]\fR] [\fB\-p\fR] [\fB\-v\fR] [\fB\-b\fR \fIbind_address\fR] [\fB\-u\fR \fIuser\fR]
+[\fB\-F\fR \fIfrom\fR] [\fB\-r\fR \fIrcpt\fR] [\fB\-d\fR \fIdeliver-to\fR]
+[\fB\-i\fR \fIip\fR] [\fB\-c\fR \fIclassifier\fR] [\fB\-w\fR \fIweight\fR]
[\fB\-P\fR \fIpassword\fR] [\fB\-f\fR \fIflag\fR] [\fB\-t\fR \fItimeout\fR] [command] [file [file ...]]
.PP
rspamc [\fB\-\-help\fR]
@@ -148,7 +149,24 @@ rspamc [\fB\-\-help\fR]
.IP "\fB\-h\fR \fIhost[:port]\fR, \fB\-\-connect\fR \fIhost[:port]\fR" 4
.IX Item "-h host[:port], --connect host[:port]"
Specify host and port for connecting to rspamd server. Default host is \fIlocalhost\fR and
-default port is \fI11333\fR for checking messages and \fI11334\fR for learning and statistic.
+default port is \fI11333\fR for checking messages and \fI11334\fR for learning and statistic.
+Also it is possible to specify a unix socket for all operations (for example:
+\&\fBrspamc\fR \fB\-h\fR /path/to/soket)
+.IP "\fB\-b\fR \fIlocal_ip\fR, \fB\-\-bind\fR \fIlocal_ip\fR" 4
+.IX Item "-b local_ip, --bind local_ip"
+Specify explicit \s-1IP\s0 address to bind a client for operations.
+.IP "\fB\-u\fR \fIuser\fR, \fB\-\-user\fR \fIuser\fR" 4
+.IX Item "-u user, --user user"
+Specify username for connection with rspamd server.
+.IP "\fB\-F\fR \fIfrom_addr\fR, \fB\-\-from\fR \fIfrom_addr\fR" 4
+.IX Item "-F from_addr, --from from_addr"
+Specify \s-1SMTP\s0 \s-1FROM\s0 address for connection with rspamd server.
+.IP "\fB\-r\fR \fIrcpt_addr\fR, \fB\-\-rcpt\fR \fIrcpt_addr\fR" 4
+.IX Item "-r rcpt_addr, --rcpt rcpt_addr"
+Specify \s-1SMTP\s0 \s-1RCPT\s0 \s-1TO\s0 address for connection with rspamd server.
+.IP "\fB\-d\fR \fIdeliver_addr\fR, \fB\-\-deliver\fR \fIdeliver_addr\fR" 4
+.IX Item "-d deliver_addr, --deliver deliver_addr"
+Specify real delivery address for connection with rspamd server.
.IP "\fB\-p\fR, \fB\-\-pass\-all\fR" 4
.IX Item "-p, --pass-all"
Pass all filters when checking messages. Ignored in case of learning.
@@ -158,9 +176,9 @@ Be more verbose while displaying results. For example show descriptions of symbo
.IP "\fB\-P\fR \fIpassword\fR, \fB\-\-password\fR \fIpassword\fR" 4
.IX Item "-P password, --password password"
Specify controller's password. Mandatory option for learning.
-.IP "\fB\-s\fR \fIstatfile\fR, \fB\-\-statfile\fR \fIstatfile\fR" 4
-.IX Item "-s statfile, --statfile statfile"
-Specify statfile's symbol to learn message. Mandatory option for learning.
+.IP "\fB\-c\fR \fIclassifier\fR, \fB\-\-classifier\fR \fIclassifier\fR" 4
+.IX Item "-c classifier, --classifier classifier"
+Specify classifier to learn message. Mandatory option for learning. Bayes classifier is used by default if this option is omitted.
.IP "\fB\-i\fR \fIip\fR, \fB\-\-ip\fR \fIip\fR" 4
.IX Item "-i ip, --ip ip"
Add \s-1IP\s0 header when scanning message. Useful for checking messages and emulating that client comes from
@@ -194,7 +212,7 @@ Check files:
Learn files:
.PP
.Vb 1
-\& rspamc \-P pass \-s BAYES_SPAM file1 file2 file3
+\& rspamc \-P pass learn_spam file1 file2 file3
.Ve
.PP
Add fuzzy hash to set 2:
@@ -220,12 +238,24 @@ Get uptime:
.Vb 1
\& rspamc uptime
.Ve
+.PP
+Add custom rule's weight:
+.PP
+.Vb 1
+\& rspamc add_symbol test 1.5
+.Ve
+.PP
+Add custom action's weight:
+.PP
+.Vb 1
+\& rspamc add_action reject 7.1
+.Ve
.SH "AUTHOR"
.IX Header "AUTHOR"
Vsevolod Stakhov <vsevolod@highsecure.ru>
.SH "COPYRIGHT AND LICENSE"
.IX Header "COPYRIGHT AND LICENSE"
-Copyright 2011 by Vsevolod Stakhov <vsevolod@highsecure.ru>.
+Copyright 2011\-2012 by Vsevolod Stakhov <vsevolod@highsecure.ru>.
.PP
This program is free software; you may redistribute it and/or modify it
under the terms of \s-1BSD\s0 license.
diff --git a/doc/rspamc.pod b/doc/rspamc.pod
index ebb452b4d..ddf5d81fb 100644
--- a/doc/rspamc.pod
+++ b/doc/rspamc.pod
@@ -4,8 +4,9 @@ rspamc - a simple client for rspamd spam filtering system
=head1 SYNOPSIS
-rspamc [B<-h> I<host[:port]>] [B<-p>] [B<-v>]
-[B<-i> I<ip>] [B<-s> I<statfile>] [B<-w> I<weight>]
+rspamc [B<-h> I<host[:port]>] [B<-p>] [B<-v>] [B<-b> I<bind_address>] [B<-u> I<user>]
+[B<-F> I<from>] [B<-r> I<rcpt>] [B<-d> I<deliver-to>]
+[B<-i> I<ip>] [B<-c> I<classifier>] [B<-w> I<weight>]
[B<-P> I<password>] [B<-f> I<flag>] [B<-t> I<timeout>] [command] [file [file ...]]
rspamc [B<--help>]
@@ -23,6 +24,28 @@ B<Rspamc> has several mandatory options for learning: I<password> and I<statfile
Specify host and port for connecting to rspamd server. Default host is I<localhost> and
default port is I<11333> for checking messages and I<11334> for learning and statistic.
+Also it is possible to specify a unix socket for all operations (for example:
+B<rspamc> B<-h> /path/to/soket)
+
+=item B<-b> I<local_ip>, B<--bind> I<local_ip>
+
+Specify explicit IP address to bind a client for operations.
+
+=item B<-u> I<user>, B<--user> I<user>
+
+Specify username for connection with rspamd server.
+
+=item B<-F> I<from_addr>, B<--from> I<from_addr>
+
+Specify SMTP FROM address for connection with rspamd server.
+
+=item B<-r> I<rcpt_addr>, B<--rcpt> I<rcpt_addr>
+
+Specify SMTP RCPT TO address for connection with rspamd server.
+
+=item B<-d> I<deliver_addr>, B<--deliver> I<deliver_addr>
+
+Specify real delivery address for connection with rspamd server.
=item B<-p>, B<--pass-all>
@@ -36,9 +59,9 @@ Be more verbose while displaying results. For example show descriptions of symbo
Specify controller's password. Mandatory option for learning.
-=item B<-s> I<statfile>, B<--statfile> I<statfile>
+=item B<-c> I<classifier>, B<--classifier> I<classifier>
-Specify statfile's symbol to learn message. Mandatory option for learning.
+Specify classifier to learn message. Mandatory option for learning. Bayes classifier is used by default if this option is omitted.
=item B<-i> I<ip>, B<--ip> I<ip>
@@ -75,7 +98,7 @@ Check files:
Learn files:
- rspamc -P pass -s BAYES_SPAM file1 file2 file3
+ rspamc -P pass learn_spam file1 file2 file3
Add fuzzy hash to set 2:
@@ -93,13 +116,21 @@ Get uptime:
rspamc uptime
+Add custom rule's weight:
+
+ rspamc add_symbol test 1.5
+
+Add custom action's weight:
+
+ rspamc add_action reject 7.1
+
=head1 AUTHOR
Vsevolod Stakhov <vsevolod@highsecure.ru>
=head1 COPYRIGHT AND LICENSE
-Copyright 2011 by Vsevolod Stakhov <vsevolod@highsecure.ru>.
+Copyright 2011-2012 by Vsevolod Stakhov <vsevolod@highsecure.ru>.
This program is free software; you may redistribute it and/or modify it
under the terms of BSD license.
diff --git a/doc/rspamd.8 b/doc/rspamd.8
index 498784d73..68a004387 100644
--- a/doc/rspamd.8
+++ b/doc/rspamd.8
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.07)
+.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.16)
.\"
.\" Standard preamble:
.\" ========================================================================
@@ -124,12 +124,12 @@
.\" ========================================================================
.\"
.IX Title "rspamd 8"
-.TH rspamd 8 "2011-03-15" "rspamd-0.3.8" "Rspamd documentation"
+.TH rspamd 8 "2012-10-02" "rspamd-0.5.2" "Rspamd documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
-.SH "NAME"
+.SH "RSPAMD"
.IX Header "RSPAMD"
rspamd \- main daemon for rspamd spam filtering system
.SH "SYNOPSIS"
diff --git a/src/client/rspamc.c b/src/client/rspamc.c
index 877b0285f..aae8345d5 100644
--- a/src/client/rspamc.c
+++ b/src/client/rspamc.c
@@ -38,7 +38,7 @@ static gchar *from = NULL;
static gchar *deliver_to = NULL;
static gchar *rcpt = NULL;
static gchar *user = NULL;
-static gchar *classifier = NULL;
+static gchar *classifier = "bayes";
static gchar *local_addr = NULL;
static gint weight = 1;
static gint flag;
@@ -75,7 +75,9 @@ enum rspamc_command {
RSPAMC_COMMAND_FUZZY_ADD,
RSPAMC_COMMAND_FUZZY_DEL,
RSPAMC_COMMAND_STAT,
- RSPAMC_COMMAND_UPTIME
+ RSPAMC_COMMAND_UPTIME,
+ RSPAMC_COMMAND_ADD_SYMBOL,
+ RSPAMC_COMMAND_ADD_ACTION
};
/*
@@ -131,6 +133,12 @@ check_rspamc_command (const gchar *cmd)
else if (g_ascii_strcasecmp (cmd, "UPTIME") == 0) {
return RSPAMC_COMMAND_UPTIME;
}
+ else if (g_ascii_strcasecmp (cmd, "ADD_SYMBOL") == 0) {
+ return RSPAMC_COMMAND_ADD_SYMBOL;
+ }
+ else if (g_ascii_strcasecmp (cmd, "ADD_ACTION") == 0) {
+ return RSPAMC_COMMAND_ADD_ACTION;
+ }
return RSPAMC_COMMAND_UNKNOWN;
}
@@ -379,6 +387,8 @@ scan_rspamd_file (const gchar *file)
struct rspamd_result *res;
GHashTable *opts;
+ /* Add server */
+ add_rspamd_server (FALSE);
/* Init options hash */
opts = g_hash_table_new (g_str_hash, g_str_equal);
add_options (opts);
@@ -470,6 +480,8 @@ learn_rspamd_file (gboolean is_spam, const gchar *file)
exit (EXIT_FAILURE);
}
+ /* Add server */
+ add_rspamd_server (TRUE);
params = g_hash_table_new (g_str_hash, g_str_equal);
g_hash_table_insert (params, "Classifier", classifier);
@@ -573,6 +585,9 @@ fuzzy_rspamd_file (const gchar *file, gboolean delete)
gchar valuebuf[sizeof("65535")], flagbuf[sizeof("65535")];
struct rspamd_controller_result *res;
+ /* Add server */
+ add_rspamd_server (TRUE);
+
params = g_hash_table_new (g_str_hash, g_str_equal);
rspamd_snprintf (valuebuf, sizeof (valuebuf), "%d", weight);
rspamd_snprintf (flagbuf, sizeof (flagbuf), "%d", flag);
@@ -609,16 +624,15 @@ fuzzy_rspamd_file (const gchar *file, gboolean delete)
}
static void
-rspamd_do_controller_simple_command (gchar *command)
+rspamd_do_controller_simple_command (gchar *command, GHashTable *kwattrs)
{
GError *err = NULL;
GList *results, *cur;
struct rspamd_controller_result *res;
-
/* Add server */
add_rspamd_server (TRUE);
- results = rspamd_controller_command_simple (client, command, password, NULL, &err);
+ results = rspamd_controller_command_simple (client, command, password, kwattrs, &err);
if (results == NULL || err != NULL) {
if (err != NULL) {
fprintf (stderr, "cannot perform command: %s\n", err->message);
@@ -651,10 +665,13 @@ rspamd_do_controller_simple_command (gchar *command)
gint
main (gint argc, gchar **argv, gchar **env)
{
- enum rspamc_command cmd;
- gint i;
- struct in_addr ina;
+ enum rspamc_command cmd;
+ gint i;
+ struct in_addr ina;
+ GHashTable *kwattrs;
+
+ kwattrs = g_hash_table_new (g_str_hash, g_str_equal);
read_cmd_line (&argc, &argv);
@@ -711,10 +728,10 @@ main (gint argc, gchar **argv, gchar **env)
fuzzy_rspamd_stdin (TRUE);
break;
case RSPAMC_COMMAND_STAT:
- rspamd_do_controller_simple_command ("stat");
+ rspamd_do_controller_simple_command ("stat", NULL);
break;
case RSPAMC_COMMAND_UPTIME:
- rspamd_do_controller_simple_command ("uptime");
+ rspamd_do_controller_simple_command ("uptime", NULL);
break;
default:
fprintf (stderr, "invalid arguments\n");
@@ -722,61 +739,69 @@ main (gint argc, gchar **argv, gchar **env)
}
}
else {
- add_rspamd_server (FALSE);
scan_rspamd_file (argv[1]);
}
}
else {
if ((cmd = check_rspamc_command (argv[1])) != RSPAMC_COMMAND_UNKNOWN) {
/* In case of command read arguments starting from 2 */
- switch (cmd) {
- case RSPAMC_COMMAND_SYMBOLS:
- /* Add server */
- add_rspamd_server (FALSE);
- break;
- default:
- add_rspamd_server (TRUE);
- break;
- }
- for (i = 2; i < argc; i ++) {
- if (tty) {
- printf ("\033[1m");
+ if (cmd == RSPAMC_COMMAND_ADD_SYMBOL || cmd == RSPAMC_COMMAND_ADD_ACTION) {
+ if (argc < 4 || argc > 5) {
+ fprintf (stderr, "invalid arguments\n");
+ exit (EXIT_FAILURE);
}
- PRINT_FUNC ("Results for file: %s\n\n", argv[i]);
- if (tty) {
- printf ("\033[0m");
+ if (argc == 5) {
+ g_hash_table_insert (kwattrs, "metric", argv[2]);
+ g_hash_table_insert (kwattrs, "name", argv[3]);
+ g_hash_table_insert (kwattrs, "value", argv[4]);
}
- switch (cmd) {
- case RSPAMC_COMMAND_SYMBOLS:
- scan_rspamd_file (argv[i]);
- break;
- case RSPAMC_COMMAND_LEARN_SPAM:
- if (classifier != NULL) {
- learn_rspamd_file (TRUE, argv[i]);
- }
- else {
- fprintf (stderr, "no classifier specified\n");
- exit (EXIT_FAILURE);
+ else {
+ g_hash_table_insert (kwattrs, "name", argv[2]);
+ g_hash_table_insert (kwattrs, "value", argv[3]);
+ }
+ rspamd_do_controller_simple_command (cmd == RSPAMC_COMMAND_ADD_SYMBOL ? "add_symbol" : "add_action", kwattrs);
+ }
+ else {
+ for (i = 2; i < argc; i ++) {
+ if (tty) {
+ printf ("\033[1m");
}
- break;
- case RSPAMC_COMMAND_LEARN_HAM:
- if (classifier != NULL) {
- learn_rspamd_file (FALSE, argv[i]);
+ PRINT_FUNC ("Results for file: %s\n\n", argv[i]);
+ if (tty) {
+ printf ("\033[0m");
}
- else {
- fprintf (stderr, "no classifier specified\n");
+ switch (cmd) {
+ case RSPAMC_COMMAND_SYMBOLS:
+ scan_rspamd_file (argv[i]);
+ break;
+ case RSPAMC_COMMAND_LEARN_SPAM:
+ if (classifier != NULL) {
+ learn_rspamd_file (TRUE, argv[i]);
+ }
+ else {
+ fprintf (stderr, "no classifier specified\n");
+ exit (EXIT_FAILURE);
+ }
+ break;
+ case RSPAMC_COMMAND_LEARN_HAM:
+ if (classifier != NULL) {
+ learn_rspamd_file (FALSE, argv[i]);
+ }
+ else {
+ fprintf (stderr, "no classifier specified\n");
+ exit (EXIT_FAILURE);
+ }
+ break;
+ case RSPAMC_COMMAND_FUZZY_ADD:
+ fuzzy_rspamd_file (argv[i], FALSE);
+ break;
+ case RSPAMC_COMMAND_FUZZY_DEL:
+ fuzzy_rspamd_file (argv[i], TRUE);
+ break;
+ default:
+ fprintf (stderr, "invalid arguments\n");
exit (EXIT_FAILURE);
}
- break;
- case RSPAMC_COMMAND_FUZZY_ADD:
- fuzzy_rspamd_file (argv[i], FALSE);
- break;
- case RSPAMC_COMMAND_FUZZY_DEL:
- fuzzy_rspamd_file (argv[i], TRUE);
- break;
- default:
- fprintf (stderr, "invalid arguments\n");
- exit (EXIT_FAILURE);
}
}
}
@@ -789,5 +814,7 @@ main (gint argc, gchar **argv, gchar **env)
rspamd_client_close (client);
+ g_hash_table_destroy (kwattrs);
+
return 0;
}
diff --git a/src/dynamic_cfg.c b/src/dynamic_cfg.c
index 1375463f0..279b1e0a9 100644
--- a/src/dynamic_cfg.c
+++ b/src/dynamic_cfg.c
@@ -499,7 +499,7 @@ add_dynamic_symbol (struct config_file *cfg, const gchar *metric_name, const gch
{
GList *cur;
struct dynamic_cfg_metric *metric = NULL;
- struct dynamic_cfg_symbol *sym;
+ struct dynamic_cfg_symbol *sym = NULL;
if (cfg->dynamic_conf == NULL) {
msg_info ("dynamic conf is disabled");
@@ -523,6 +523,7 @@ add_dynamic_symbol (struct config_file *cfg, const gchar *metric_name, const gch
sym = cur->data;
if (g_ascii_strcasecmp (sym->name, symbol) == 0) {
sym->value = value;
+ msg_debug ("change value of action %s to %.2f", symbol, value);
break;
}
sym = NULL;
@@ -534,6 +535,7 @@ add_dynamic_symbol (struct config_file *cfg, const gchar *metric_name, const gch
sym->name = g_strdup (symbol);
sym->value = value;
metric->symbols = g_list_prepend (metric->symbols, sym);
+ msg_debug ("create symbol %s in metric %s", symbol, metric_name);
}
}
else {
@@ -545,6 +547,7 @@ add_dynamic_symbol (struct config_file *cfg, const gchar *metric_name, const gch
metric->symbols = g_list_prepend (metric->symbols, sym);
metric->name = g_strdup (metric_name);
cfg->current_dynamic_conf = g_list_prepend (cfg->current_dynamic_conf, metric);
+ msg_debug ("create metric %s for symbol %s", metric_name, symbol);
}
apply_dynamic_conf (cfg->current_dynamic_conf, cfg);
@@ -566,7 +569,7 @@ add_dynamic_action (struct config_file *cfg, const gchar *metric_name, const gch
{
GList *cur;
struct dynamic_cfg_metric *metric = NULL;
- struct dynamic_cfg_action *act;
+ struct dynamic_cfg_action *act = NULL;
gint real_act;
if (cfg->dynamic_conf == NULL) {
@@ -590,12 +593,13 @@ add_dynamic_action (struct config_file *cfg, const gchar *metric_name, const gch
}
if (metric != NULL) {
- /* Search for a symbol */
- cur = metric->symbols;
+ /* Search for an action */
+ cur = metric->actions;
while (cur) {
act = cur->data;
if ((gint)act->action == real_act) {
act->value = value;
+ msg_debug ("change value of action %s to %.2f", action, value);
break;
}
act = NULL;
@@ -603,21 +607,23 @@ add_dynamic_action (struct config_file *cfg, const gchar *metric_name, const gch
}
if (act == NULL) {
/* Action not found, insert it */
- act = g_slice_alloc (sizeof (struct dynamic_cfg_symbol));
+ act = g_slice_alloc (sizeof (struct dynamic_cfg_action));
act->action = real_act;
act->value = value;
- metric->actions = g_list_prepend (metric->symbols, act);
+ metric->actions = g_list_prepend (metric->actions, act);
+ msg_debug ("create action %s in metric %s", action, metric_name);
}
}
else {
/* Metric not found, create it */
metric = g_slice_alloc0 (sizeof (struct dynamic_cfg_metric));
- act = g_slice_alloc (sizeof (struct dynamic_cfg_symbol));
+ act = g_slice_alloc (sizeof (struct dynamic_cfg_action));
act->action = real_act;
act->value = value;
- metric->actions = g_list_prepend (metric->symbols, act);
+ metric->actions = g_list_prepend (metric->actions, act);
metric->name = g_strdup (metric_name);
cfg->current_dynamic_conf = g_list_prepend (cfg->current_dynamic_conf, metric);
+ msg_debug ("create metric %s for action %s", metric_name, action);
}
apply_dynamic_conf (cfg->current_dynamic_conf, cfg);