Mercurial > hg > nginx
diff src/mail/ngx_mail_parse.c @ 1136:68f30ab68bb7
Many changes:
*) rename imap to mail, sort pop3/imap functions
*) smtp auth support
*) pop3 starttls only
*) fix segfault if cram-md5 was used without apop
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 19 Mar 2007 13:36:56 +0000 |
parents | src/imap/ngx_imap_parse.c@e3aa8f305d21 |
children | 27f2299e0d80 |
line wrap: on
line diff
copy from src/imap/ngx_imap_parse.c copy to src/mail/ngx_mail_parse.c --- a/src/imap/ngx_imap_parse.c +++ b/src/mail/ngx_mail_parse.c @@ -7,10 +7,207 @@ #include <ngx_config.h> #include <ngx_core.h> #include <ngx_event.h> -#include <ngx_imap.h> +#include <ngx_mail.h> -ngx_int_t ngx_imap_parse_command(ngx_imap_session_t *s) +ngx_int_t ngx_pop3_parse_command(ngx_mail_session_t *s) +{ + u_char ch, *p, *c, c0, c1, c2, c3; + ngx_str_t *arg; + enum { + sw_start = 0, + sw_spaces_before_argument, + sw_argument, + sw_almost_done + } state; + + state = s->state; + + for (p = s->buffer->pos; p < s->buffer->last; p++) { + ch = *p; + + switch (state) { + + /* POP3 command */ + case sw_start: + if (ch == ' ' || ch == CR || ch == LF) { + c = s->buffer->start; + + if (p - c == 4) { + + c0 = ngx_toupper(c[0]); + c1 = ngx_toupper(c[1]); + c2 = ngx_toupper(c[2]); + c3 = ngx_toupper(c[3]); + + if (c0 == 'U' && c1 == 'S' && c2 == 'E' && c3 == 'R') + { + s->command = NGX_POP3_USER; + + } else if (c0 == 'P' && c1 == 'A' && c2 == 'S' && c3 == 'S') + { + s->command = NGX_POP3_PASS; + + } else if (c0 == 'A' && c1 == 'P' && c2 == 'O' && c3 == 'P') + { + s->command = NGX_POP3_APOP; + + } else if (c0 == 'Q' && c1 == 'U' && c2 == 'I' && c3 == 'T') + { + s->command = NGX_POP3_QUIT; + + } else if (c0 == 'C' && c1 == 'A' && c2 == 'P' && c3 == 'A') + { + s->command = NGX_POP3_CAPA; + + } else if (c0 == 'A' && c1 == 'U' && c2 == 'T' && c3 == 'H') + { + s->command = NGX_POP3_AUTH; + + } else if (c0 == 'N' && c1 == 'O' && c2 == 'O' && c3 == 'P') + { + s->command = NGX_POP3_NOOP; +#if (NGX_MAIL_SSL) + } else if (c0 == 'S' && c1 == 'T' && c2 == 'L' && c3 == 'S') + { + s->command = NGX_POP3_STLS; +#endif + } else { + goto invalid; + } + + } else { + goto invalid; + } + + switch (ch) { + case ' ': + state = sw_spaces_before_argument; + break; + case CR: + state = sw_almost_done; + break; + case LF: + goto done; + } + break; + } + + if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) { + goto invalid; + } + + break; + + case sw_spaces_before_argument: + switch (ch) { + case ' ': + break; + case CR: + state = sw_almost_done; + s->arg_end = p; + break; + case LF: + s->arg_end = p; + goto done; + default: + if (s->args.nelts <= 2) { + state = sw_argument; + s->arg_start = p; + break; + } + goto invalid; + } + break; + + case sw_argument: + switch (ch) { + + case ' ': + + /* + * the space should be considered as part of the at username + * or password, but not of argument in other commands + */ + + if (s->command == NGX_POP3_USER + || s->command == NGX_POP3_PASS) + { + break; + } + + /* fall through */ + + case CR: + case LF: + arg = ngx_array_push(&s->args); + if (arg == NULL) { + return NGX_ERROR; + } + arg->len = p - s->arg_start; + arg->data = s->arg_start; + s->arg_start = NULL; + + switch (ch) { + case ' ': + state = sw_spaces_before_argument; + break; + case CR: + state = sw_almost_done; + break; + case LF: + goto done; + } + break; + + default: + break; + } + break; + + case sw_almost_done: + switch (ch) { + case LF: + goto done; + default: + goto invalid; + } + } + } + + s->buffer->pos = p; + s->state = state; + + return NGX_AGAIN; + +done: + + s->buffer->pos = p + 1; + + if (s->arg_start) { + arg = ngx_array_push(&s->args); + if (arg == NULL) { + return NGX_ERROR; + } + arg->len = s->arg_end - s->arg_start; + arg->data = s->arg_start; + s->arg_start = NULL; + } + + s->state = (s->command != NGX_POP3_AUTH) ? sw_start : sw_argument; + + return NGX_OK; + +invalid: + + s->state = sw_start; + s->arg_start = NULL; + + return NGX_MAIL_PARSE_INVALID_COMMAND; +} + + +ngx_int_t ngx_imap_parse_command(ngx_mail_session_t *s) { u_char ch, *p, *c; ngx_str_t *arg; @@ -46,10 +243,10 @@ ngx_int_t ngx_imap_parse_command(ngx_ima break; case CR: s->state = sw_start; - return NGX_IMAP_PARSE_INVALID_COMMAND; + return NGX_MAIL_PARSE_INVALID_COMMAND; case LF: s->state = sw_start; - return NGX_IMAP_PARSE_INVALID_COMMAND; + return NGX_MAIL_PARSE_INVALID_COMMAND; } break; @@ -59,10 +256,10 @@ ngx_int_t ngx_imap_parse_command(ngx_ima break; case CR: s->state = sw_start; - return NGX_IMAP_PARSE_INVALID_COMMAND; + return NGX_MAIL_PARSE_INVALID_COMMAND; case LF: s->state = sw_start; - return NGX_IMAP_PARSE_INVALID_COMMAND; + return NGX_MAIL_PARSE_INVALID_COMMAND; default: s->cmd_start = p; state = sw_command; @@ -119,7 +316,7 @@ ngx_int_t ngx_imap_parse_command(ngx_ima } break; -#if (NGX_IMAP_SSL) +#if (NGX_MAIL_SSL) case 8: if ((c[0] == 'S'|| c[0] == 's') && (c[1] == 'T'|| c[1] == 't') @@ -387,11 +584,11 @@ invalid: s->no_sync_literal = 0; s->literal_len = 0; - return NGX_IMAP_PARSE_INVALID_COMMAND; + return NGX_MAIL_PARSE_INVALID_COMMAND; } -ngx_int_t ngx_pop3_parse_command(ngx_imap_session_t *s) +ngx_int_t ngx_smtp_parse_command(ngx_mail_session_t *s) { u_char ch, *p, *c, c0, c1, c2, c3; ngx_str_t *arg; @@ -409,7 +606,7 @@ ngx_int_t ngx_pop3_parse_command(ngx_ima switch (state) { - /* POP3 command */ + /* SMTP command */ case sw_start: if (ch == ' ' || ch == CR || ch == LF) { c = s->buffer->start; @@ -421,38 +618,34 @@ ngx_int_t ngx_pop3_parse_command(ngx_ima c2 = ngx_toupper(c[2]); c3 = ngx_toupper(c[3]); - if (c0 == 'U' && c1 == 'S' && c2 == 'E' && c3 == 'R') - { - s->command = NGX_POP3_USER; - - } else if (c0 == 'P' && c1 == 'A' && c2 == 'S' && c3 == 'S') + if (c0 == 'H' && c1 == 'E' && c2 == 'L' && c3 == 'O') { - s->command = NGX_POP3_PASS; + s->command = NGX_SMTP_HELO; - } else if (c0 == 'A' && c1 == 'P' && c2 == 'O' && c3 == 'P') + } else if (c0 == 'E' && c1 == 'H' && c2 == 'L' && c3 == 'O') { - s->command = NGX_POP3_APOP; + s->command = NGX_SMTP_EHLO; } else if (c0 == 'Q' && c1 == 'U' && c2 == 'I' && c3 == 'T') { - s->command = NGX_POP3_QUIT; - - } else if (c0 == 'C' && c1 == 'A' && c2 == 'P' && c3 == 'A') - { - s->command = NGX_POP3_CAPA; + s->command = NGX_SMTP_QUIT; } else if (c0 == 'A' && c1 == 'U' && c2 == 'T' && c3 == 'H') { - s->command = NGX_POP3_AUTH; + s->command = NGX_SMTP_AUTH; } else if (c0 == 'N' && c1 == 'O' && c2 == 'O' && c3 == 'P') { - s->command = NGX_POP3_NOOP; -#if (NGX_IMAP_SSL) - } else if (c0 == 'S' && c1 == 'T' && c2 == 'L' && c3 == 'S') + s->command = NGX_SMTP_NOOP; + + } else if (c0 == 'M' && c1 == 'A' && c2 == 'I' && c3 == 'L') { - s->command = NGX_POP3_STLS; -#endif + s->command = NGX_SMTP_MAIL; + + } else if (c0 == 'R' && c1 == 'S' && c2 == 'E' && c3 == 'T') + { + s->command = NGX_SMTP_RSET; + } else { goto invalid; } @@ -503,22 +696,7 @@ ngx_int_t ngx_pop3_parse_command(ngx_ima case sw_argument: switch (ch) { - case ' ': - - /* - * the space should be considered as part of the at username - * or password, but not of argument in other commands - */ - - if (s->command == NGX_POP3_USER - || s->command == NGX_POP3_PASS) - { - break; - } - - /* fall through */ - case CR: case LF: arg = ngx_array_push(&s->args); @@ -575,7 +753,8 @@ done: s->arg_start = NULL; } - s->state = (s->command != NGX_POP3_AUTH) ? sw_start : sw_argument; + s->state = (s->command != NGX_SMTP_AUTH) ? sw_start : sw_argument; + return NGX_OK; invalid: @@ -583,5 +762,5 @@ invalid: s->state = sw_start; s->arg_start = NULL; - return NGX_IMAP_PARSE_INVALID_COMMAND; + return NGX_MAIL_PARSE_INVALID_COMMAND; }