aboutsummaryrefslogtreecommitdiffstats
path: root/src/protocol.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2011-03-31 20:06:25 +0400
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2011-03-31 20:06:25 +0400
commite414be40592724a884b4900c7ab199ebeaf5e171 (patch)
tree33f4f7abc0d9a975b4a2e124e6ee064d75529ff3 /src/protocol.c
parent33b5aa19d7ec8ff59601c8495a8bc7813b0e6939 (diff)
downloadrspamd-e414be40592724a884b4900c7ab199ebeaf5e171.tar.gz
rspamd-e414be40592724a884b4900c7ab199ebeaf5e171.zip
* Add ability to learn rspamd via worker (without password)0.3.11
Diffstat (limited to 'src/protocol.c')
-rw-r--r--src/protocol.c62
1 files changed, 57 insertions, 5 deletions
diff --git a/src/protocol.c b/src/protocol.c
index 8ffaddea1..ac8515004 100644
--- a/src/protocol.c
+++ b/src/protocol.c
@@ -64,6 +64,11 @@
#define MSG_CMD_PROCESS "process"
/*
+ * Learn specified statfile using message
+ */
+#define MSG_CMD_LEARN "learn"
+
+/*
* spamassassin greeting:
*/
#define SPAMC_GREETING "SPAMC"
@@ -81,6 +86,7 @@
#define NRCPT_HEADER "Recipient-Number"
#define RCPT_HEADER "Rcpt"
#define SUBJECT_HEADER "Subject"
+#define STATFILE_HEADER "Statfile"
#define QUEUE_ID_HEADER "Queue-ID"
#define ERROR_HEADER "Error"
#define USER_HEADER "User"
@@ -198,6 +204,22 @@ parse_check_command (struct worker_task *task, gchar *token)
return FALSE;
}
break;
+ case 'l':
+ case 'L':
+ if (g_ascii_strcasecmp (token + 1, MSG_CMD_LEARN + 1) == 0) {
+ if (task->allow_learn) {
+ task->cmd = CMD_LEARN;
+ }
+ else {
+ msg_info ("learning is disabled");
+ return FALSE;
+ }
+ }
+ else {
+ debug_task ("bad command: %s", token);
+ return FALSE;
+ }
+ break;
default:
cur = custom_commands;
while (cur) {
@@ -306,8 +328,8 @@ parse_http_command (struct worker_task *task, f_str_t * line)
}
else {
/* Copy command */
- cmd = memory_pool_alloc (task->task_pool, p - c);
- rspamd_strlcpy (cmd, c, p - c);
+ cmd = memory_pool_alloc (task->task_pool, p - c + 1);
+ rspamd_strlcpy (cmd, c, p - c + 1);
/* Skip the first '/' */
if (*cmd == '/') {
cmd ++;
@@ -379,8 +401,22 @@ parse_header (struct worker_task *task, f_str_t * line)
}
else {
if (task->content_length > 0) {
- rspamd_set_dispatcher_policy (task->dispatcher, BUFFER_CHARACTER, task->content_length);
- task->state = READ_MESSAGE;
+ if (task->cmd == CMD_LEARN) {
+ if (task->statfile != NULL) {
+ rspamd_set_dispatcher_policy (task->dispatcher, BUFFER_CHARACTER, task->content_length);
+ task->state = READ_MESSAGE;
+ }
+ else {
+ task->last_error = "Unknown statfile";
+ task->error_code = RSPAMD_STATFILE_ERROR;
+ task->state = WRITE_ERROR;
+ return FALSE;
+ }
+ }
+ else {
+ rspamd_set_dispatcher_policy (task->dispatcher, BUFFER_CHARACTER, task->content_length);
+ task->state = READ_MESSAGE;
+ }
}
else {
task->last_error = "Unknown content length";
@@ -528,6 +564,9 @@ parse_header (struct worker_task *task, f_str_t * line)
if (g_ascii_strncasecmp (headern, SUBJECT_HEADER, sizeof (SUBJECT_HEADER) - 1) == 0) {
task->subject = memory_pool_fstrdup (task->task_pool, line);
}
+ else if (g_ascii_strncasecmp (headern, STATFILE_HEADER, sizeof (STATFILE_HEADER) - 1) == 0) {
+ task->statfile = memory_pool_fstrdup (task->task_pool, line);
+ }
else {
return FALSE;
}
@@ -1433,7 +1472,7 @@ write_reply (struct worker_task *task)
/* Write error message and error code to reply */
if (task->is_http) {
r = rspamd_snprintf (outbuf, sizeof (outbuf), "HTTP/1.0 400 Bad request" CRLF
- "Connection: close" CRLF CRLF);
+ "Connection: close" CRLF CRLF "Error: %d - %s" CRLF, task->error_code, task->last_error);
}
else {
if (task->proto == SPAMC_PROTO) {
@@ -1471,6 +1510,19 @@ write_reply (struct worker_task *task)
(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_LEARN:
+ if (task->is_http) {
+ r = rspamd_snprintf (outbuf, sizeof (outbuf), "HTTP/1.0 200 Ok" CRLF
+ "Connection: close" CRLF CRLF "%s" CRLF, task->last_error);
+ }
+ else {
+ r = rspamd_snprintf (outbuf, sizeof (outbuf), "%s/%s 0 LEARN" CRLF CRLF "%s" CRLF,
+ (task->proto == SPAMC_PROTO) ? SPAMD_REPLY_BANNER : RSPAMD_REPLY_BANNER,
+ rspamc_proto_str (task->proto_ver),
+ task->last_error);
+ }
+ return rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE, FALSE);
+ break;
case CMD_OTHER:
return task->custom_cmd->func (task);
}