changeset 468:2580fe1c5a9a PATCH_NGINX_MAIL_0_6

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.
author Maxim Dounin <mdounin@mdounin.ru>
date Sun, 11 Jan 2009 23:19:26 +0300
parents d67e93e97b4a
children 9f7bf771ebf0
files src/mail/ngx_mail.h src/mail/ngx_mail_handler.c src/mail/ngx_mail_imap_handler.c src/mail/ngx_mail_parse.c src/mail/ngx_mail_pop3_handler.c src/mail/ngx_mail_smtp_handler.c
diffstat 6 files changed, 45 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- 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,
--- 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]);
 
--- 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;
--- 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;
         }
 
--- 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;
--- 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;