changeset 6773:73b451d304c0

Mail: extensible auth methods in pop3 module.
author Maxim Dounin <mdounin@mdounin.ru>
date Tue, 18 Oct 2016 19:38:46 +0300
parents 20eb4587225b
children bcb107bb89cd
files src/mail/ngx_mail_pop3_module.c
diffstat 1 files changed, 66 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/src/mail/ngx_mail_pop3_module.c
+++ b/src/mail/ngx_mail_pop3_module.c
@@ -33,19 +33,13 @@ static ngx_conf_bitmask_t  ngx_mail_pop3
 };
 
 
-static ngx_str_t  ngx_mail_pop3_auth_plain_capability =
-    ngx_string("+OK methods supported:" CRLF
-               "LOGIN" CRLF
-               "PLAIN" CRLF
-               "." CRLF);
-
-
-static ngx_str_t  ngx_mail_pop3_auth_cram_md5_capability =
-    ngx_string("+OK methods supported:" CRLF
-               "LOGIN" CRLF
-               "PLAIN" CRLF
-               "CRAM-MD5" CRLF
-               "." CRLF);
+static ngx_str_t  ngx_mail_pop3_auth_methods_names[] = {
+    ngx_string("PLAIN"),
+    ngx_string("LOGIN"),
+    ngx_null_string,  /* APOP */
+    ngx_string("CRAM-MD5"),
+    ngx_null_string   /* NONE */
+};
 
 
 static ngx_mail_protocol_t  ngx_mail_pop3_protocol = {
@@ -140,13 +134,17 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t 
     u_char      *p;
     size_t       size, stls_only_size;
     ngx_str_t   *c, *d;
-    ngx_uint_t   i;
+    ngx_uint_t   i, m;
 
     ngx_conf_merge_bitmask_value(conf->auth_methods,
                                  prev->auth_methods,
                                  (NGX_CONF_BITMASK_SET
                                   |NGX_MAIL_AUTH_PLAIN_ENABLED));
 
+    if (conf->auth_methods & NGX_MAIL_AUTH_PLAIN_ENABLED) {
+        conf->auth_methods |= NGX_MAIL_AUTH_LOGIN_ENABLED;
+    }
+
     if (conf->capabilities.nelts == 0) {
         conf->capabilities = prev->capabilities;
     }
@@ -179,11 +177,15 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t 
         stls_only_size += c[i].len + sizeof(CRLF) - 1;
     }
 
-    if (conf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) {
-        size += sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1;
+    size += sizeof("SASL") - 1 + sizeof(CRLF) - 1;
 
-    } else {
-        size += sizeof("SASL LOGIN PLAIN" CRLF) - 1;
+    for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
+         m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
+         m <<= 1, i++)
+    {
+        if (m & conf->auth_methods) {
+            size += 1 + ngx_mail_pop3_auth_methods_names[i].len;
+        }
     }
 
     p = ngx_pnalloc(cf->pool, size);
@@ -202,15 +204,21 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t 
         *p++ = CR; *p++ = LF;
     }
 
-    if (conf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) {
-        p = ngx_cpymem(p, "SASL LOGIN PLAIN CRAM-MD5" CRLF,
-                       sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1);
+    p = ngx_cpymem(p, "SASL", sizeof("SASL") - 1);
 
-    } else {
-        p = ngx_cpymem(p, "SASL LOGIN PLAIN" CRLF,
-                       sizeof("SASL LOGIN PLAIN" CRLF) - 1);
+    for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
+         m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
+         m <<= 1, i++)
+    {
+        if (m & conf->auth_methods) {
+            *p++ = ' ';
+            p = ngx_cpymem(p, ngx_mail_pop3_auth_methods_names[i].data,
+                           ngx_mail_pop3_auth_methods_names[i].len);
+        }
     }
 
+    *p++ = CR; *p++ = LF;
+
     *p++ = '.'; *p++ = CR; *p = LF;
 
 
@@ -231,13 +239,43 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t 
     *p++ = '.'; *p++ = CR; *p = LF;
 
 
-    if (conf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) {
-        conf->auth_capability = ngx_mail_pop3_auth_cram_md5_capability;
+    size = sizeof("+OK methods supported:" CRLF) - 1
+           + sizeof("." CRLF) - 1;
+
+    for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
+         m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
+         m <<= 1, i++)
+    {
+        if (m & conf->auth_methods) {
+            size += ngx_mail_pop3_auth_methods_names[i].len
+                    + sizeof(CRLF) - 1;
+        }
+    }
+
+    p = ngx_pnalloc(cf->pool, size);
+    if (p == NULL) {
+        return NGX_CONF_ERROR;
+    }
 
-    } else {
-        conf->auth_capability = ngx_mail_pop3_auth_plain_capability;
+    conf->auth_capability.data = p;
+    conf->auth_capability.len = size;
+
+    p = ngx_cpymem(p, "+OK methods supported:" CRLF,
+                   sizeof("+OK methods supported:" CRLF) - 1);
+
+    for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
+         m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
+         m <<= 1, i++)
+    {
+        if (m & conf->auth_methods) {
+            p = ngx_cpymem(p, ngx_mail_pop3_auth_methods_names[i].data,
+                           ngx_mail_pop3_auth_methods_names[i].len);
+            *p++ = CR; *p++ = LF;
+        }
     }
 
+    *p++ = '.'; *p++ = CR; *p = LF;
+
 
     p = ngx_pnalloc(cf->pool, stls_only_size);
     if (p == NULL) {