diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mail/ngx_mail.h | 2 | ||||
-rw-r--r-- | src/mail/ngx_mail_handler.c | 12 | ||||
-rw-r--r-- | src/mail/ngx_mail_parse.c | 30 | ||||
-rw-r--r-- | src/mail/ngx_mail_proxy_module.c | 7 | ||||
-rw-r--r-- | src/mail/ngx_mail_smtp_handler.c | 83 |
5 files changed, 71 insertions, 63 deletions
diff --git a/src/mail/ngx_mail.h b/src/mail/ngx_mail.h index ccdfb8c6f..dc39f1e13 100644 --- a/src/mail/ngx_mail.h +++ b/src/mail/ngx_mail.h @@ -234,6 +234,8 @@ typedef struct { ngx_str_t smtp_from; ngx_str_t smtp_to; + ngx_str_t cmd; + ngx_uint_t command; ngx_array_t args; diff --git a/src/mail/ngx_mail_handler.c b/src/mail/ngx_mail_handler.c index ae955f9c6..7cfff1a07 100644 --- a/src/mail/ngx_mail_handler.c +++ b/src/mail/ngx_mail_handler.c @@ -620,7 +620,9 @@ ngx_mail_read_command(ngx_mail_session_t *s, ngx_connection_t *c) return NGX_ERROR; } - return NGX_AGAIN; + if (s->buffer->pos == s->buffer->last) { + return NGX_AGAIN; + } } cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); @@ -661,8 +663,12 @@ void ngx_mail_auth(ngx_mail_session_t *s, ngx_connection_t *c) { s->args.nelts = 0; - s->buffer->pos = s->buffer->start; - s->buffer->last = s->buffer->start; + + if (s->buffer->pos == s->buffer->last) { + s->buffer->pos = s->buffer->start; + s->buffer->last = s->buffer->start; + } + s->state = 0; if (c->read->timer_set) { diff --git a/src/mail/ngx_mail_parse.c b/src/mail/ngx_mail_parse.c index 7de6c19a1..b158f5a0f 100644 --- a/src/mail/ngx_mail_parse.c +++ b/src/mail/ngx_mail_parse.c @@ -626,6 +626,8 @@ ngx_mail_smtp_parse_command(ngx_mail_session_t *s) ngx_str_t *arg; enum { sw_start = 0, + sw_command, + sw_invalid, sw_spaces_before_argument, sw_argument, sw_almost_done @@ -640,8 +642,14 @@ ngx_mail_smtp_parse_command(ngx_mail_session_t *s) /* SMTP command */ case sw_start: + s->cmd_start = p; + state = sw_command; + + /* fall through */ + + case sw_command: if (ch == ' ' || ch == CR || ch == LF) { - c = s->buffer->start; + c = s->cmd_start; if (p - c == 4) { @@ -719,6 +727,9 @@ ngx_mail_smtp_parse_command(ngx_mail_session_t *s) goto invalid; } + s->cmd.data = s->cmd_start; + s->cmd.len = p - s->cmd_start; + switch (ch) { case ' ': state = sw_spaces_before_argument; @@ -738,6 +749,9 @@ ngx_mail_smtp_parse_command(ngx_mail_session_t *s) break; + case sw_invalid: + goto invalid; + case sw_spaces_before_argument: switch (ch) { case ' ': @@ -824,9 +838,21 @@ done: invalid: - s->state = sw_start; + s->state = sw_invalid; s->arg_start = NULL; + /* skip invalid command till LF */ + + for (p = s->buffer->pos; p < s->buffer->last; p++) { + if (*p == LF) { + s->state = sw_start; + p++; + break; + } + } + + s->buffer->pos = p; + return NGX_MAIL_PARSE_INVALID_COMMAND; } diff --git a/src/mail/ngx_mail_proxy_module.c b/src/mail/ngx_mail_proxy_module.c index 4ea608cea..ed9e0e2d1 100644 --- a/src/mail/ngx_mail_proxy_module.c +++ b/src/mail/ngx_mail_proxy_module.c @@ -657,7 +657,12 @@ ngx_mail_proxy_smtp_handler(ngx_event_t *rev) c->log->action = NULL; ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in"); - ngx_mail_proxy_handler(s->connection->write); + if (s->buffer->pos == s->buffer->last) { + ngx_mail_proxy_handler(s->connection->write); + + } else { + ngx_mail_proxy_handler(c->write); + } return; diff --git a/src/mail/ngx_mail_smtp_handler.c b/src/mail/ngx_mail_smtp_handler.c index c118f547d..0238b6282 100644 --- a/src/mail/ngx_mail_smtp_handler.c +++ b/src/mail/ngx_mail_smtp_handler.c @@ -486,6 +486,10 @@ ngx_mail_smtp_auth_state(ngx_event_t *rev) } } + if (s->buffer->pos < s->buffer->last) { + s->blocked = 1; + } + switch (rc) { case NGX_DONE: @@ -505,11 +509,14 @@ ngx_mail_smtp_auth_state(ngx_event_t *rev) case NGX_OK: s->args.nelts = 0; - s->buffer->pos = s->buffer->start; - s->buffer->last = s->buffer->start; + + if (s->buffer->pos == s->buffer->last) { + s->buffer->pos = s->buffer->start; + s->buffer->last = s->buffer->start; + } if (s->state) { - s->arg_start = s->buffer->start; + s->arg_start = s->buffer->pos; } ngx_mail_send(c->write); @@ -652,9 +659,7 @@ ngx_mail_smtp_auth(ngx_mail_session_t *s, ngx_connection_t *c) static ngx_int_t ngx_mail_smtp_mail(ngx_mail_session_t *s, ngx_connection_t *c) { - u_char ch; - ngx_str_t l; - ngx_uint_t i; + ngx_str_t *arg, cmd; ngx_mail_smtp_srv_conf_t *sscf; sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module); @@ -672,37 +677,20 @@ ngx_mail_smtp_mail(ngx_mail_session_t *s, ngx_connection_t *c) return NGX_OK; } - l.len = s->buffer->last - s->buffer->start; - l.data = s->buffer->start; - - for (i = 0; i < l.len; i++) { - ch = l.data[i]; - - if (ch != CR && ch != LF) { - continue; - } - - l.data[i] = ' '; - } - - while (i) { - if (l.data[i - 1] != ' ') { - break; - } - - i--; - } + arg = s->args.elts; + arg += s->args.nelts - 1; - l.len = i; + cmd.len = arg->data + arg->len - s->cmd.data; + cmd.data = s->cmd.data; - s->smtp_from.len = l.len; + s->smtp_from.len = cmd.len; - s->smtp_from.data = ngx_pnalloc(c->pool, l.len); + s->smtp_from.data = ngx_pnalloc(c->pool, cmd.len); if (s->smtp_from.data == NULL) { return NGX_ERROR; } - ngx_memcpy(s->smtp_from.data, l.data, l.len); + ngx_memcpy(s->smtp_from.data, cmd.data, cmd.len); ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, "smtp mail from:\"%V\"", &s->smtp_from); @@ -716,46 +704,27 @@ ngx_mail_smtp_mail(ngx_mail_session_t *s, ngx_connection_t *c) static ngx_int_t ngx_mail_smtp_rcpt(ngx_mail_session_t *s, ngx_connection_t *c) { - u_char ch; - ngx_str_t l; - ngx_uint_t i; + ngx_str_t *arg, cmd; if (s->smtp_from.len == 0) { ngx_str_set(&s->out, smtp_bad_sequence); return NGX_OK; } - l.len = s->buffer->last - s->buffer->start; - l.data = s->buffer->start; - - for (i = 0; i < l.len; i++) { - ch = l.data[i]; - - if (ch != CR && ch != LF) { - continue; - } - - l.data[i] = ' '; - } - - while (i) { - if (l.data[i - 1] != ' ') { - break; - } - - i--; - } + arg = s->args.elts; + arg += s->args.nelts - 1; - l.len = i; + cmd.len = arg->data + arg->len - s->cmd.data; + cmd.data = s->cmd.data; - s->smtp_to.len = l.len; + s->smtp_to.len = cmd.len; - s->smtp_to.data = ngx_pnalloc(c->pool, l.len); + s->smtp_to.data = ngx_pnalloc(c->pool, cmd.len); if (s->smtp_to.data == NULL) { return NGX_ERROR; } - ngx_memcpy(s->smtp_to.data, l.data, l.len); + ngx_memcpy(s->smtp_to.data, cmd.data, cmd.len); ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, "smtp rcpt to:\"%V\"", &s->smtp_to); |