summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2010-06-18 19:49:13 +0400
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2010-06-18 19:49:13 +0400
commite4eb49311b06fc0f820fb64d800d15a295d190a6 (patch)
treee8bfa05fd2baebf9275f38b95650f794cf3fd68a /src
parent42641b4dc3e6b8a42a3a2ff33097403ab4193d30 (diff)
downloadrspamd-e4eb49311b06fc0f820fb64d800d15a295d190a6.tar.gz
rspamd-e4eb49311b06fc0f820fb64d800d15a295d190a6.zip
* Add limit of maximum allowed smtp session errors
Diffstat (limited to 'src')
-rw-r--r--src/smtp.c21
-rw-r--r--src/smtp.h4
-rw-r--r--src/smtp_proto.c1
-rw-r--r--src/smtp_proto.h1
4 files changed, 27 insertions, 0 deletions
diff --git a/src/smtp.c b/src/smtp.c
index 7860f1ac5..c5abf5eec 100644
--- a/src/smtp.c
+++ b/src/smtp.c
@@ -175,6 +175,7 @@ read_smtp_command (struct smtp_session *session, f_str_t *line)
if (! parse_smtp_command (session, line, &cmd)) {
session->error = SMTP_ERROR_BAD_COMMAND;
+ session->errors ++;
return FALSE;
}
@@ -185,6 +186,9 @@ read_smtp_command (struct smtp_session *session, f_str_t *line)
if (parse_smtp_helo (session, cmd)) {
session->state = SMTP_STATE_FROM;
}
+ else {
+ session->errors ++;
+ }
return TRUE;
}
else {
@@ -203,6 +207,7 @@ read_smtp_command (struct smtp_session *session, f_str_t *line)
session->state = SMTP_STATE_RCPT;
}
else {
+ session->errors ++;
return FALSE;
}
}
@@ -235,6 +240,7 @@ read_smtp_command (struct smtp_session *session, f_str_t *line)
return TRUE;
}
else {
+ session->errors ++;
return FALSE;
}
}
@@ -257,6 +263,7 @@ read_smtp_command (struct smtp_session *session, f_str_t *line)
if (session->state == SMTP_STATE_RCPT) {
if (session->rcpt == NULL) {
session->error = SMTP_ERROR_RECIPIENTS;
+ session->errors ++;
return FALSE;
}
if (session->upstream == NULL) {
@@ -287,6 +294,7 @@ read_smtp_command (struct smtp_session *session, f_str_t *line)
return TRUE;
improper_sequence:
+ session->errors ++;
session->error = SMTP_ERROR_SEQUENCE;
return FALSE;
}
@@ -420,6 +428,13 @@ smtp_read_socket (f_str_t * in, void *arg)
case SMTP_STATE_DATA:
read_smtp_command (session, in);
if (session->state != SMTP_STATE_WAIT_UPSTREAM) {
+ if (session->errors > session->ctx->max_errors) {
+ session->error = SMTP_ERROR_LIMIT;
+ session->state = SMTP_STATE_CRITICAL_ERROR;
+ rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE);
+ destroy_session (session->s);
+ return FALSE;
+ }
smtp_write_socket (session);
}
break;
@@ -987,6 +1002,12 @@ config_smtp_worker (struct rspamd_worker *worker)
else {
ctx->metric = DEFAULT_METRIC;
}
+ if ((value = g_hash_table_lookup (worker->cf->params, "smtp_max_errors")) != NULL) {
+ ctx->max_errors = strtoul (value, NULL, 10);
+ }
+ else {
+ ctx->max_errors = DEFAULT_MAX_ERRORS;
+ }
if ((value = g_hash_table_lookup (worker->cf->params, "smtp_reject_message")) != NULL) {
ctx->reject_message = memory_pool_strdup (ctx->pool, value);
}
diff --git a/src/smtp.h b/src/smtp.h
index 83d89c5aa..11062543d 100644
--- a/src/smtp.h
+++ b/src/smtp.h
@@ -15,6 +15,7 @@ struct smtp_upstream {
};
#define MAX_UPSTREAM 128
+#define DEFAULT_MAX_ERRORS 10
struct smtp_worker_ctx {
struct smtp_upstream upstreams[MAX_UPSTREAM];
@@ -31,6 +32,7 @@ struct smtp_worker_ctx {
char *smtp_capabilities;
char *reject_message;
size_t max_size;
+ guint max_errors;
char *metric;
};
@@ -76,6 +78,8 @@ struct smtp_session {
GList *from;
GList *rcpt;
GList *cur_rcpt;
+
+ guint errors;
struct rspamd_async_session *s;
rspamd_io_dispatcher_t *dispatcher;
diff --git a/src/smtp_proto.c b/src/smtp_proto.c
index b80573276..e372cec55 100644
--- a/src/smtp_proto.c
+++ b/src/smtp_proto.c
@@ -511,6 +511,7 @@ smtp_upstream_read_socket (f_str_t * in, void *arg)
else {
session->rcpt = g_list_delete_link (session->rcpt, session->rcpt);
}
+ session->errors ++;
session->state = SMTP_STATE_RCPT;
return TRUE;
}
diff --git a/src/smtp_proto.h b/src/smtp_proto.h
index f451f3abf..d44cbe7b1 100644
--- a/src/smtp_proto.h
+++ b/src/smtp_proto.h
@@ -10,6 +10,7 @@
#define SMTP_ERROR_SEQUENCE "503 Bad sequence of commands" CRLF
#define SMTP_ERROR_RECIPIENTS "554 No valid recipients" CRLF
#define SMTP_ERROR_UNIMPLIMENTED "502 Command not implemented" CRLF
+#define SMTP_ERROR_LIMIT "505 Too many errors. Aborting." CRLF
#define SMTP_ERROR_UPSTREAM "421 Service not available, closing transmission channel" CRLF
#define SMTP_ERROR_FILE "420 Service not available, filesystem error" CRLF
#define SMTP_ERROR_OK "250 Requested mail action okay, completed" CRLF