# HG changeset patch # User Maxim Dounin # Date 1231705166 -10800 # Node ID 2580fe1c5a9a300134ea707c5e27d871bc0237f0 # Parent d67e93e97b4a6710677c033292ddb386d55949e2 Mail: support for smtp auth login with username. According to "[MS-XLOGIN]: SMTP Protocol AUTH LOGIN Extension Specification" (http://msdn.microsoft.com/en-us/library/cc433484.aspx) there is special mode called "AUTH LOGIN with User Name". And it seems to be used by some Microsoft software seen in wild. 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 @@ -258,11 +258,12 @@ typedef struct { #define NGX_SMTP_STARTTLS 13 -#define NGX_MAIL_AUTH_PLAIN 0 -#define NGX_MAIL_AUTH_LOGIN 1 -#define NGX_MAIL_AUTH_APOP 2 -#define NGX_MAIL_AUTH_CRAM_MD5 3 -#define NGX_MAIL_AUTH_NONE 4 +#define NGX_MAIL_AUTH_PLAIN 0 +#define NGX_MAIL_AUTH_LOGIN 1 +#define NGX_MAIL_AUTH_APOP 2 +#define NGX_MAIL_AUTH_CRAM_MD5 3 +#define NGX_MAIL_AUTH_NONE 4 +#define NGX_MAIL_AUTH_LOGIN_USERNAME 5 #define NGX_MAIL_AUTH_PLAIN_ENABLED 0x0002 @@ -346,7 +347,7 @@ ngx_int_t ngx_mail_salt(ngx_mail_session ngx_int_t ngx_mail_auth_plain(ngx_mail_session_t *s, ngx_connection_t *c, ngx_uint_t n); ngx_int_t ngx_mail_auth_login_username(ngx_mail_session_t *s, - ngx_connection_t *c); + ngx_connection_t *c, ngx_int_t initial); ngx_int_t ngx_mail_auth_login_password(ngx_mail_session_t *s, ngx_connection_t *c); ngx_int_t ngx_mail_auth_cram_md5_salt(ngx_mail_session_t *s, diff --git a/src/mail/ngx_mail_handler.c b/src/mail/ngx_mail_handler.c --- a/src/mail/ngx_mail_handler.c +++ b/src/mail/ngx_mail_handler.c @@ -356,12 +356,18 @@ ngx_mail_auth_plain(ngx_mail_session_t * ngx_int_t -ngx_mail_auth_login_username(ngx_mail_session_t *s, ngx_connection_t *c) +ngx_mail_auth_login_username(ngx_mail_session_t *s, ngx_connection_t *c, + ngx_int_t initial) { ngx_str_t *arg; arg = s->args.elts; + if (initial) { + /* username in initial response */ + arg += (s->protocol == NGX_MAIL_SMTP_PROTOCOL) ? 2 : 1; + } + ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, "mail auth login username: \"%V\"", &arg[0]); 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 @@ -205,7 +205,7 @@ ngx_mail_imap_auth_state(ngx_event_t *re break; case ngx_imap_auth_login_username: - rc = ngx_mail_auth_login_username(s, c); + rc = ngx_mail_auth_login_username(s, c, 0); tag = 0; s->out.len = sizeof(imap_password) - 1; @@ -370,6 +370,14 @@ ngx_mail_imap_authenticate(ngx_mail_sess return NGX_OK; + case NGX_MAIL_AUTH_LOGIN_USERNAME: + + s->out.len = sizeof(imap_password) - 1; + s->out.data = imap_password; + s->mail_state = ngx_imap_auth_login_password; + + return ngx_mail_auth_login_username(s, c, 1); + case NGX_MAIL_AUTH_PLAIN: s->out.len = sizeof(imap_plain_next) - 1; 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 @@ -886,6 +886,10 @@ ngx_mail_auth_parse(ngx_mail_session_t * return NGX_MAIL_AUTH_LOGIN; } + if (nelts == 2) { + return NGX_MAIL_AUTH_LOGIN_USERNAME; + } + return NGX_MAIL_PARSE_INVALID_COMMAND; } 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 @@ -226,7 +226,7 @@ ngx_mail_pop3_auth_state(ngx_event_t *re break; case ngx_pop3_auth_login_username: - rc = ngx_mail_auth_login_username(s, c); + rc = ngx_mail_auth_login_username(s, c, 0); s->out.len = sizeof(pop3_password) - 1; s->out.data = pop3_password; @@ -474,6 +474,14 @@ ngx_mail_pop3_auth(ngx_mail_session_t *s return NGX_OK; + case NGX_MAIL_AUTH_LOGIN_USERNAME: + + s->out.len = sizeof(pop3_password) - 1; + s->out.data = pop3_password; + s->mail_state = ngx_pop3_auth_login_password; + + return ngx_mail_auth_login_username(s, c, 1); + case NGX_MAIL_AUTH_PLAIN: s->out.len = sizeof(pop3_next) - 1; 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 @@ -446,7 +446,7 @@ ngx_mail_smtp_auth_state(ngx_event_t *re break; case ngx_smtp_auth_login_username: - rc = ngx_mail_auth_login_username(s, c); + rc = ngx_mail_auth_login_username(s, c, 0); s->out.len = sizeof(smtp_password) - 1; s->out.data = smtp_password; @@ -602,6 +602,14 @@ ngx_mail_smtp_auth(ngx_mail_session_t *s return NGX_OK; + case NGX_MAIL_AUTH_LOGIN_USERNAME: + + s->out.len = sizeof(smtp_password) - 1; + s->out.data = smtp_password; + s->mail_state = ngx_smtp_auth_login_password; + + return ngx_mail_auth_login_username(s, c, 1); + case NGX_MAIL_AUTH_PLAIN: s->out.len = sizeof(smtp_next) - 1;