]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
* Add limit of maximum allowed smtp session errors
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Fri, 18 Jun 2010 15:49:13 +0000 (19:49 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Fri, 18 Jun 2010 15:49:13 +0000 (19:49 +0400)
src/smtp.c
src/smtp.h
src/smtp_proto.c
src/smtp_proto.h

index 7860f1ac529d2dcd12c77edc4d0bc1fc38354953..c5abf5eecbb77b5ab429b8edfd9e63b0b1891c32 100644 (file)
@@ -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);
        }
index 83d89c5aa91da48a685384eee679e04bd53fa9a6..11062543d83872254f39239fae50863493339208 100644 (file)
@@ -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;
index b80573276e2c7816e32fb230e4dc5d6d93cf1ea6..e372cec55b2d4fde0d6fff3e11e791d2a3a106db 100644 (file)
@@ -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;
                        }
index f451f3abf308b04ad2b9b36bea3b40afe6424cc2..d44cbe7b1c06de6690ec995f81cbdb93573baea7 100644 (file)
@@ -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