Welcome! Log In Create A New Profile

Advanced

[nginx] Mail: proxy_smtp_auth directive.

Maxim Dounin
October 03, 2020 02:06PM
details: https://hg.nginx.org/nginx/rev/d63c5373b5ba
branches:
changeset: 7725:d63c5373b5ba
user: Maxim Dounin <mdounin@mdounin.ru>
date: Sat Oct 03 21:04:57 2020 +0300
description:
Mail: proxy_smtp_auth directive.

The proxy_smtp_auth directive instructs nginx to authenticate users
on backend via the AUTH command (using the PLAIN SASL mechanism),
similar to what is normally done for IMAP and POP3.

If xclient is enabled along with proxy_smtp_auth, the XCLIENT command
won't try to send the LOGIN parameter.

diffstat:

src/mail/ngx_mail.h | 2 +
src/mail/ngx_mail_proxy_module.c | 89 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 87 insertions(+), 4 deletions(-)

diffs (197 lines):

diff -r 64b97c8166b8 -r d63c5373b5ba src/mail/ngx_mail.h
--- a/src/mail/ngx_mail.h Sat Oct 03 21:01:12 2020 +0300
+++ b/src/mail/ngx_mail.h Sat Oct 03 21:04:57 2020 +0300
@@ -162,10 +162,12 @@ typedef enum {
ngx_smtp_auth_external,
ngx_smtp_helo,
ngx_smtp_helo_xclient,
+ ngx_smtp_helo_auth,
ngx_smtp_helo_from,
ngx_smtp_xclient,
ngx_smtp_xclient_from,
ngx_smtp_xclient_helo,
+ ngx_smtp_xclient_auth,
ngx_smtp_from,
ngx_smtp_to
} ngx_smtp_state_e;
diff -r 64b97c8166b8 -r d63c5373b5ba src/mail/ngx_mail_proxy_module.c
--- a/src/mail/ngx_mail_proxy_module.c Sat Oct 03 21:01:12 2020 +0300
+++ b/src/mail/ngx_mail_proxy_module.c Sat Oct 03 21:04:57 2020 +0300
@@ -16,6 +16,7 @@ typedef struct {
ngx_flag_t enable;
ngx_flag_t pass_error_message;
ngx_flag_t xclient;
+ ngx_flag_t smtp_auth;
size_t buffer_size;
ngx_msec_t timeout;
} ngx_mail_proxy_conf_t;
@@ -74,6 +75,13 @@ static ngx_command_t ngx_mail_proxy_com
offsetof(ngx_mail_proxy_conf_t, xclient),
NULL },

+ { ngx_string("proxy_smtp_auth"),
+ NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
+ ngx_conf_set_flag_slot,
+ NGX_MAIL_SRV_CONF_OFFSET,
+ offsetof(ngx_mail_proxy_conf_t, smtp_auth),
+ NULL },
+
ngx_null_command
};

@@ -450,7 +458,7 @@ ngx_mail_proxy_smtp_handler(ngx_event_t
{
u_char *p;
ngx_int_t rc;
- ngx_str_t line;
+ ngx_str_t line, auth, encoded;
ngx_buf_t *b;
ngx_connection_t *c;
ngx_mail_session_t *s;
@@ -513,6 +521,9 @@ ngx_mail_proxy_smtp_handler(ngx_event_t
} else if (s->auth_method == NGX_MAIL_AUTH_NONE) {
s->mail_state = ngx_smtp_helo_from;

+ } else if (pcf->smtp_auth) {
+ s->mail_state = ngx_smtp_helo_auth;
+
} else {
s->mail_state = ngx_smtp_helo;
}
@@ -552,7 +563,9 @@ ngx_mail_proxy_smtp_handler(ngx_event_t
p = ngx_copy(p, s->connection->addr_text.data,
s->connection->addr_text.len);

- if (s->login.len) {
+ pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module);
+
+ if (s->login.len && !pcf->smtp_auth) {
p = ngx_cpymem(p, " LOGIN=", sizeof(" LOGIN=") - 1);
p = ngx_copy(p, s->login.data, s->login.len);
}
@@ -570,6 +583,9 @@ ngx_mail_proxy_smtp_handler(ngx_event_t
} else if (s->auth_method == NGX_MAIL_AUTH_NONE) {
s->mail_state = ngx_smtp_xclient_from;

+ } else if (pcf->smtp_auth) {
+ s->mail_state = ngx_smtp_xclient_auth;
+
} else {
s->mail_state = ngx_smtp_xclient;
}
@@ -595,8 +611,62 @@ ngx_mail_proxy_smtp_handler(ngx_event_t
&s->smtp_helo)
- line.data;

- s->mail_state = (s->auth_method == NGX_MAIL_AUTH_NONE) ?
- ngx_smtp_helo_from : ngx_smtp_helo;
+ pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module);
+
+ if (s->auth_method == NGX_MAIL_AUTH_NONE) {
+ s->mail_state = ngx_smtp_helo_from;
+
+ } else if (pcf->smtp_auth) {
+ s->mail_state = ngx_smtp_helo_auth;
+
+ } else {
+ s->mail_state = ngx_smtp_helo;
+ }
+
+ break;
+
+ case ngx_smtp_helo_auth:
+ case ngx_smtp_xclient_auth:
+ ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0,
+ "mail proxy send auth");
+
+ s->connection->log->action = "sending AUTH to upstream";
+
+ if (s->passwd.data == NULL) {
+ ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
+ "no password available");
+ ngx_mail_proxy_internal_server_error(s);
+ return;
+ }
+
+ auth.len = 1 + s->login.len + 1 + s->passwd.len;
+ auth.data = ngx_pnalloc(c->pool, auth.len);
+ if (auth.data == NULL) {
+ ngx_mail_proxy_internal_server_error(s);
+ return;
+ }
+
+ auth.len = ngx_sprintf(auth.data, "%Z%V%Z%V", &s->login, &s->passwd)
+ - auth.data;
+
+ line.len = sizeof("AUTH PLAIN " CRLF) - 1
+ + ngx_base64_encoded_length(auth.len);
+
+ line.data = ngx_pnalloc(c->pool, line.len);
+ if (line.data == NULL) {
+ ngx_mail_proxy_internal_server_error(s);
+ return;
+ }
+
+ encoded.data = ngx_cpymem(line.data, "AUTH PLAIN ",
+ sizeof("AUTH PLAIN ") - 1);
+
+ ngx_encode_base64(&encoded, &auth);
+
+ p = encoded.data + encoded.len;
+ *p++ = CR; *p = LF;
+
+ s->mail_state = ngx_smtp_auth_plain;

break;

@@ -643,6 +713,7 @@ ngx_mail_proxy_smtp_handler(ngx_event_t

case ngx_smtp_helo:
case ngx_smtp_xclient:
+ case ngx_smtp_auth_plain:
case ngx_smtp_to:

b = s->proxy->buffer;
@@ -824,6 +895,7 @@ ngx_mail_proxy_read_response(ngx_mail_se
case ngx_smtp_helo:
case ngx_smtp_helo_xclient:
case ngx_smtp_helo_from:
+ case ngx_smtp_helo_auth:
case ngx_smtp_from:
if (p[0] == '2' && p[1] == '5' && p[2] == '0') {
return NGX_OK;
@@ -833,11 +905,18 @@ ngx_mail_proxy_read_response(ngx_mail_se
case ngx_smtp_xclient:
case ngx_smtp_xclient_from:
case ngx_smtp_xclient_helo:
+ case ngx_smtp_xclient_auth:
if (p[0] == '2' && (p[1] == '2' || p[1] == '5') && p[2] == '0') {
return NGX_OK;
}
break;

+ case ngx_smtp_auth_plain:
+ if (p[0] == '2' && p[1] == '3' && p[2] == '5') {
+ return NGX_OK;
+ }
+ break;
+
case ngx_smtp_to:
return NGX_OK;
}
@@ -1102,6 +1181,7 @@ ngx_mail_proxy_create_conf(ngx_conf_t *c
pcf->enable = NGX_CONF_UNSET;
pcf->pass_error_message = NGX_CONF_UNSET;
pcf->xclient = NGX_CONF_UNSET;
+ pcf->smtp_auth = NGX_CONF_UNSET;
pcf->buffer_size = NGX_CONF_UNSET_SIZE;
pcf->timeout = NGX_CONF_UNSET_MSEC;

@@ -1118,6 +1198,7 @@ ngx_mail_proxy_merge_conf(ngx_conf_t *cf
ngx_conf_merge_value(conf->enable, prev->enable, 0);
ngx_conf_merge_value(conf->pass_error_message, prev->pass_error_message, 0);
ngx_conf_merge_value(conf->xclient, prev->xclient, 1);
+ ngx_conf_merge_value(conf->smtp_auth, prev->smtp_auth, 0);
ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size,
(size_t) ngx_pagesize);
ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 24 * 60 * 60000);
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[nginx] Mail: proxy_smtp_auth directive.

Maxim Dounin 97 October 03, 2020 02:06PM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 52
Record Number of Users: 6 on February 13, 2018
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready