diff options
-rw-r--r-- | smtpd/smtp_session.c | 28 | ||||
-rw-r--r-- | smtpd/smtpd.h | 2 |
2 files changed, 27 insertions, 3 deletions
diff --git a/smtpd/smtp_session.c b/smtpd/smtp_session.c index 9ca5d957..cc845087 100644 --- a/smtpd/smtp_session.c +++ b/smtpd/smtp_session.c @@ -40,6 +40,8 @@ #include "smtpd.h" #include "log.h" +#define SMTP_KICKTHRESHOLD 50 + #define SMTP_MAXMAIL 100 #define SMTP_MAXRCPT 1000 @@ -646,6 +648,7 @@ session_io(struct io *io, int evt) io_set_write(&s->s_io); session_respond(s, SMTPD_BANNER, env->sc_hostname); } + s->kickcount = 0; session_enter_state(s, S_GREETED); break; @@ -668,6 +671,11 @@ session_io(struct io *io, int evt) if (s->s_state == S_DATACONTENT && strcmp(line, ".")) { /* more data to come */ session_line(s, line, len); + if (s->s_flags & F_KICK) { + stat_increment("smtp.kick", 1); + session_destroy(s, "kick"); + return; + } goto nextline; } @@ -680,6 +688,11 @@ session_io(struct io *io, int evt) } session_line(s, line, len); + if (s->s_flags & F_KICK) { + stat_increment("smtp.kick", 1); + session_destroy(s, "kick"); + return; + } iobuf_normalize(&s->s_iobuf); io_set_write(io); break; @@ -760,9 +773,10 @@ session_pickup(struct session *s, struct submit_status *ss) break; case S_AUTH_FINALIZE: - if (s->s_flags & F_AUTHENTICATED) + if (s->s_flags & F_AUTHENTICATED) { session_respond(s, "235 Authentication succeeded"); - else + s->kickcount = 0; + } else session_respond(s, "535 Authentication failed"); session_enter_state(s, S_HELO); break; @@ -798,6 +812,7 @@ session_pickup(struct session *s, struct submit_status *ss) session_respond(s, "250-AUTH PLAIN LOGIN"); session_respond(s, "250 HELP"); } + s->kickcount = 0; break; case S_MAIL_MFA: @@ -835,6 +850,7 @@ session_pickup(struct session *s, struct submit_status *ss) session_enter_state(s, S_RCPT); s->rcptcount++; + s->kickcount--; s->s_msg.dest = ss->u.maddr; session_respond(s, "%d 2.0.0 Recipient ok", ss->code); break; @@ -890,6 +906,7 @@ session_pickup(struct session *s, struct submit_status *ss) session_enter_state(s, S_HELO); s->s_msg.id = 0; s->mailcount++; + s->kickcount = 0; bzero(&s->s_nresp, sizeof(s->s_nresp)); break; @@ -905,8 +922,13 @@ session_line(struct session *s, char *line, size_t len) { struct submit_status ss; - if (s->s_state != S_DATACONTENT) + if (s->s_state != S_DATACONTENT) { log_trace(TRACE_SMTP, "smtp: %p: <<< %s", s, line); + if (++s->kickcount >= SMTP_KICKTHRESHOLD) { + s->s_flags |= F_KICK; + return; + } + } switch (s->s_state) { case S_AUTH_INIT: diff --git a/smtpd/smtpd.h b/smtpd/smtpd.h index 91d4b403..28d1ea02 100644 --- a/smtpd/smtpd.h +++ b/smtpd/smtpd.h @@ -525,6 +525,7 @@ enum session_flags { F_AUTHENTICATED = 0x08, F_WAITIMSG = 0x10, F_ZOMBIE = 0x20, + F_KICK = 0x40, }; struct session { @@ -543,6 +544,7 @@ struct session { struct timeval s_tv; struct envelope s_msg; short s_nresp[STATE_COUNT]; + size_t kickcount; size_t mailcount; size_t rcptcount; long s_datalen; |