# HG changeset patch # User Maxim Dounin # Date 1253998335 -14400 # Node ID 5938746e70c2ae3e83fb402c030635f5ab459251 # Parent 9773720b845e15edf0c72aa1d51b268161361aef Mail: get rid of ugly protocol check in ngx_mail_auth_parse(). Instead, use index of argument which holds authentication mechanism name. For IMAP and POP3 it's 0, for SMTP - 1 as SMTP preserves command in first argument to allow pipelining support. While here, add check that we actually have argument holding authentication mechanism name. Currently IMAP has no appropriate checks before calling ngx_mail_auth_parse() which results in possible access of uninitialized memory. diff --git a/src/mail/ngx_mail.h b/src/mail/ngx_mail.h --- a/src/mail/ngx_mail.h +++ b/src/mail/ngx_mail.h @@ -380,7 +380,8 @@ ngx_int_t ngx_mail_auth_login_password(n ngx_int_t ngx_mail_auth_cram_md5_salt(ngx_mail_session_t *s, ngx_connection_t *c, char *prefix, size_t len); ngx_int_t ngx_mail_auth_cram_md5(ngx_mail_session_t *s, ngx_connection_t *c); -ngx_int_t ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c); +ngx_int_t ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c, + ngx_uint_t n); void ngx_mail_send(ngx_event_t *wev); ngx_int_t ngx_mail_read_command(ngx_mail_session_t *s, ngx_connection_t *c); diff --git a/src/mail/ngx_mail_imap_handler.c b/src/mail/ngx_mail_imap_handler.c --- a/src/mail/ngx_mail_imap_handler.c +++ b/src/mail/ngx_mail_imap_handler.c @@ -358,7 +358,7 @@ ngx_mail_imap_authenticate(ngx_mail_sess } #endif - rc = ngx_mail_auth_parse(s, c); + rc = ngx_mail_auth_parse(s, c, 0); switch (rc) { diff --git a/src/mail/ngx_mail_parse.c b/src/mail/ngx_mail_parse.c --- a/src/mail/ngx_mail_parse.c +++ b/src/mail/ngx_mail_parse.c @@ -859,7 +859,7 @@ invalid: ngx_int_t -ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c) +ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c, ngx_uint_t n) { ngx_str_t *arg; ngx_uint_t nelts; @@ -873,11 +873,13 @@ ngx_mail_auth_parse(ngx_mail_session_t * arg = s->args.elts; nelts = s->args.nelts; - if (s->protocol == NGX_MAIL_SMTP_PROTOCOL) { - arg++; - nelts--; + if (nelts <= n) { + return NGX_MAIL_PARSE_INVALID_COMMAND; } + arg += n; + nelts -= n; + if (arg[0].len == 5) { if (ngx_strncasecmp(arg[0].data, (u_char *) "LOGIN", 5) == 0) { @@ -900,8 +902,7 @@ ngx_mail_auth_parse(ngx_mail_session_t * } if (nelts == 2) { - return ngx_mail_auth_plain(s, c, - (s->protocol == NGX_MAIL_SMTP_PROTOCOL) ? 2 : 1); + return ngx_mail_auth_plain(s, c, n + 1); } } diff --git a/src/mail/ngx_mail_pop3_handler.c b/src/mail/ngx_mail_pop3_handler.c --- a/src/mail/ngx_mail_pop3_handler.c +++ b/src/mail/ngx_mail_pop3_handler.c @@ -462,7 +462,7 @@ ngx_mail_pop3_auth(ngx_mail_session_t *s return NGX_OK; } - rc = ngx_mail_auth_parse(s, c); + rc = ngx_mail_auth_parse(s, c, 0); switch (rc) { diff --git a/src/mail/ngx_mail_smtp_handler.c b/src/mail/ngx_mail_smtp_handler.c --- a/src/mail/ngx_mail_smtp_handler.c +++ b/src/mail/ngx_mail_smtp_handler.c @@ -613,7 +613,7 @@ ngx_mail_smtp_auth(ngx_mail_session_t *s return NGX_OK; } - rc = ngx_mail_auth_parse(s, c); + rc = ngx_mail_auth_parse(s, c, 1); switch (rc) {