changeset 396:e2d916d7e50f PATCH_NGINX_MAIL_0_1

Mail: starttls only support for SMTP. Capabilities tweaks according to starttls settings.
author Maxim Dounin <mdounin@mdounin.ru>
date Wed, 18 Jul 2007 02:54:56 +0000
parents 1c0300c3ae88
children 1aac47be9772
files src/mail/ngx_mail.h src/mail/ngx_mail_core_module.c src/mail/ngx_mail_handler.c
diffstat 3 files changed, 74 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/mail/ngx_mail.h
+++ b/src/mail/ngx_mail.h
@@ -93,6 +93,8 @@ typedef struct {
     ngx_str_t               imap_starttls_only_capability;
 
     ngx_str_t               smtp_capability;
+    ngx_str_t               smtp_starttls_capability;
+    ngx_str_t               smtp_starttls_only_capability;
 
     ngx_str_t               server_name;
     ngx_str_t               smtp_server_name;
--- a/src/mail/ngx_mail_core_module.c
+++ b/src/mail/ngx_mail_core_module.c
@@ -278,7 +278,7 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t 
     ngx_mail_core_srv_conf_t *prev = parent;
     ngx_mail_core_srv_conf_t *conf = child;
 
-    u_char      *p;
+    u_char      *p, *auth_p;
     size_t       size, stls_only_size;
     ngx_str_t   *c, *d;
     ngx_uint_t   i, m;
@@ -582,6 +582,8 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t 
         *p++ = CR; *p++ = LF;
     }
 
+    auth_p = p;
+
     *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = ' ';
     *p++ = 'A'; *p++ = 'U'; *p++ = 'T'; *p++ = 'H';
 
@@ -598,6 +600,42 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t 
 
     *p++ = CR; *p = LF;
 
+    size += sizeof("250 STARTTLS" CRLF) - 1;
+
+    p = ngx_palloc(cf->pool, size);
+    if (p == NULL) {
+        return NGX_CONF_ERROR;
+    }
+
+    conf->smtp_starttls_capability.len = size;
+    conf->smtp_starttls_capability.data = p;
+
+    p = ngx_cpymem(p, conf->smtp_capability.data,
+                   conf->smtp_capability.len);
+
+    p = ngx_cpymem(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1);
+    *p++ = CR; *p = LF;
+
+    p = conf->smtp_starttls_capability.data
+        + (auth_p - conf->smtp_capability.data) + 3;
+    *p = '-';
+
+    size = (auth_p - conf->smtp_capability.data)
+        + sizeof("250 STARTTLS" CRLF) - 1; 
+
+    p = ngx_palloc(cf->pool, size);
+    if (p == NULL) {
+        return NGX_CONF_ERROR;
+    }
+
+    conf->smtp_starttls_only_capability.len = size;
+    conf->smtp_starttls_only_capability.data = p;
+
+    p = ngx_cpymem(p, conf->smtp_capability.data,
+                   auth_p - conf->smtp_capability.data);
+
+    p = ngx_cpymem(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1);
+
     return NGX_CONF_OK;
 }
 
--- a/src/mail/ngx_mail_handler.c
+++ b/src/mail/ngx_mail_handler.c
@@ -1311,6 +1311,26 @@ ngx_smtp_auth_state(ngx_event_t *rev)
 
                 } else {
                     s->esmtp = 1;
+
+#if (NGX_MAIL_SSL)
+
+                    if (c->ssl == NULL) {
+                        sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
+
+                        if (sslcf->starttls == NGX_MAIL_STARTTLS_ON) {
+                            size = cscf->smtp_starttls_capability.len;
+                            text = cscf->smtp_starttls_capability.data;
+                            break;
+                        }
+
+                        if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
+                            size = cscf->smtp_starttls_only_capability.len;
+                            text = cscf->smtp_starttls_only_capability.data;
+                            break;
+                        }
+                    }
+#endif
+
                     size = cscf->smtp_capability.len;
                     text = cscf->smtp_capability.data;
                 }
@@ -1319,6 +1339,18 @@ ngx_smtp_auth_state(ngx_event_t *rev)
 
             case NGX_SMTP_AUTH:
 
+#if (NGX_MAIL_SSL)
+
+                if (c->ssl == NULL) {
+                    sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
+
+                    if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
+                        rc = NGX_MAIL_PARSE_INVALID_COMMAND;
+                        break;
+                    }
+                }
+#endif
+
                 if (s->args.nelts == 0) {
                     text = smtp_invalid_argument;
                     size = sizeof(smtp_invalid_argument) - 1;
@@ -1471,6 +1503,7 @@ ngx_smtp_auth_state(ngx_event_t *rev)
                 break;
 
 #if (NGX_MAIL_SSL)
+
             case NGX_SMTP_STARTTLS:
                 if (c->ssl == NULL) {
                     sslcf = ngx_mail_get_module_srv_conf(s,