Nginx-ru mailing list archive (nginx-ru@sysoev.ru)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: smtp-прокси без авторизации
В сообщении от Tuesday 01 April 2008 00:28:57 Leonid Evdokimov написал(а):
> Maxim Dounin wrote:
> >> Возможно ли использовать smtp-прокси в качестве фронтенда для почтовой
> >> системы без использования авторизации? Устроил бы вариант как с
> >> напильником, так и без него. Почтовый сервер поддерживает xclient.
В аттаче ещё один костыль на эту тему и мануал.
Накладывается на 0.5.35, возможно будет полезен.
Файл конфигурации
mail {
server_name some-mail.com;
auth_http 192.168.0.1:1666/nginxauth.cgi;
proxy_pass 192.168.0.2:25;
server {
listen 25;
protocol mx;
timeout 300s;
}
}
|
Протокол
Для работы nginx в качестве smtp фронтэнда к MX'ам в файле конфигурации необходимо задать протокол "mx"
Хттп-скрипт
URL для хттп-авторизации задается по-прежнему - директивой auth_http
Смтп-бэкенд
В оригинале, nginx получает адрес/порт смтп-сервера в заголовках от хттп-скрипта.
Для протокола mx возможно задавать смтп-бэкенд в конфигурационном файле при помощи знакомой нам по работе с хттп-модулями директивы proxy_pass.
Если бэкенд не задан - он может быть взят из всё тех-же хттп заголовков.
(По правде-говоря - бэкэнд задаётся в конфиге не только для "mx" протокола - он _просто_задаётся_ для любого протокола.)
Если его нет ни в конфиге ни в заголовках - клиенту отдаётся ошибка.
Адрес бэкэнда из заголовков естественным образом имеет приоритет над заданным в конфиге. Т.е. это даёт нам возможность для отдельной сессии переопределить бэкэнд.
Заголовки хттп
На вход хттп-скрипта авторизации даются следующие хттп-заголовки:
Host: 192.168.0.1
|
Client-Helo: test.org
|
Client-Mail: test@xxxxxxxx
|
Client-Rcpt: to@xxxxxxx
|
Client-IP: 192.168.0.3
|
Тут всё понятно.
Ответить скрипт должен как-минимум:
Auth-Status:
Который может быть: OK, WAIT, Или любой фигнёй текстуально описывающей ошибку. В дополнение к последнему варианту статуса может задаваться smtp-код ответа:
Auth-Error-Code: 550
Который будет подставлен перед текстуальным статусом в smtp-ответе клиенту.
В совою очередь Auth-Status: WAIT дополняется заголовком:
Auth-Wait: время
указывающим время таймаута для WAIT
Также, для отдельно взятой смтп-сессии мы можем переопределить заданный в конфиге бэкенд при помощи заголовков:
Auth-Server:
Auth-Port:
для адреса/имени и порта соответственно.
Для передачи произвольной информации смтп-бэкэнду можно использовать заголовок:
Auth-Helo-Addition: что-то там
который через пробел добавится к клиентскому HELO.
Примеры сессий
Входящее соединение говорит нам, а мы ему:
|
220 tset.org ESMTP ready
HELO test.org
250 tset.org
MAIL FROM: test@xxxxxxxx
250 2.0.0 OK
RCPT TO: to@xxxxxxx
|
В этот момент мы начинаем говорить с хттп-сервером так:
|
GET /nginxauth.cgi HTTP/1.0
Host: 192.168.0.1
Client-Helo: test.prg
Client-Mail: test@xxxxxxxx
Client-Rcpt: to@xxxxxxx
Client-IP: 192.168.0.3
Auth-Status: Temporary unavailable
|
И как результат клиенту отдается:
|
535 5.7.0 Temporary unavailable
|
Также, для ошибки задаваемой заголовком Auth-Status: мы можем задать свой код, при помощи заголовка Auth-Error-Code:
То-есть хттп-сессия будет выглядеть так:
|
GET /nginxauth.cgi HTTP/1.0
Host: 192.168.0.1
Client-Helo: test.org
Client-Mail: test@xxxxxxxx
Client-Rcpt: to@xxxxxxx
Client-IP: 192.168.0.3
Auth-Status: Temporary unavailable
Auth-Error-Code: 550
|
А смтп-сессия, соответственно так:
|
220 tset.org ESMTP ready
HELO test.org
250 tset.org
MAIL FROM: test@xxxxxxxx
250 2.0.0 OK
RCPT TO: to@xxxxxxx
550 Temporary unavailable
|
|
Index: src/mail/ngx_mail_smtp_handler.c
===================================================================
--- src/mail/ngx_mail_smtp_handler.c (.../original-0.5.34) (revision 48)
+++ src/mail/ngx_mail_smtp_handler.c (.../nginx-0.5.35_MX_PROXY_2)
(revision 48)
@@ -21,7 +21,7 @@
static ngx_int_t ngx_mail_smtp_starttls(ngx_mail_session_t *s,
ngx_connection_t *c);
-static ngx_int_t ngx_mail_smtp_discard_command(ngx_mail_session_t *s,
+ngx_int_t ngx_mail_smtp_discard_command(ngx_mail_session_t *s,
ngx_connection_t *c, char *err);
static void ngx_mail_smtp_log_rejected_command(ngx_mail_session_t *s,
ngx_connection_t *c, char *err);
@@ -482,7 +482,7 @@
}
-static ngx_int_t
+ngx_int_t
ngx_mail_smtp_discard_command(ngx_mail_session_t *s, ngx_connection_t *c,
char *err)
{
Index: src/mail/ngx_mail_mx_handler.c
===================================================================
--- src/mail/ngx_mail_mx_handler.c (.../original-0.5.34) (revision 0)
+++ src/mail/ngx_mail_mx_handler.c (.../nginx-0.5.35_MX_PROXY_2)
(revision 48)
@@ -0,0 +1,806 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copypaste (M-w, C-y) NomadRain@xxxxxxxxxx
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_event.h>
+#include <ngx_mail.h>
+#include <ngx_mail_smtp_module.h>
+#include <ngx_mail_mx_module.h>
+
+
+static void ngx_mail_mx_invalid_pipelining(ngx_event_t *rev);
+static ngx_int_t ngx_mail_mx_create_buffer(ngx_mail_session_t *s,
+ ngx_connection_t *c);
+
+static ngx_int_t ngx_mail_mx_helo(ngx_mail_session_t *s, ngx_connection_t *c);
+static ngx_int_t ngx_mail_mx_auth(ngx_mail_session_t *s, ngx_connection_t *c);
+static ngx_int_t ngx_mail_mx_mail(ngx_mail_session_t *s, ngx_connection_t *c);
+static ngx_int_t ngx_mail_mx_rcpt(ngx_mail_session_t *s, ngx_connection_t *c);
+static ngx_int_t ngx_mail_smtp_starttls(ngx_mail_session_t *s,
+ ngx_connection_t *c);
+
+extern ngx_int_t ngx_mail_smtp_discard_command(ngx_mail_session_t *s,
+ ngx_connection_t *c, char *err);
+
+static u_char smtp_ok[] = "250 2.0.0 OK" CRLF;
+static u_char smtp_bye[] = "221 2.0.0 Bye" CRLF;
+static u_char smtp_next[] = "334 " CRLF;
+static u_char smtp_username[] = "334 VXNlcm5hbWU6" CRLF;
+static u_char smtp_password[] = "334 UGFzc3dvcmQ6" CRLF;
+static u_char smtp_invalid_command[] = "500 5.5.1 Invalid command" CRLF;
+static u_char smtp_invalid_pipelining[] =
+ "503 5.5.0 Improper use of SMTP command pipelining" CRLF;
+static u_char smtp_invalid_argument[] = "501 5.5.4 Invalid argument" CRLF;
+static u_char smtp_auth_required[] = "530 5.7.1 Authentication required" CRLF;
+static u_char smtp_helo_required[] = "550 HELO/EHLO required by SMTP RFC
[#1001]." CRLF;
+
+
+void
+ngx_mail_mx_init_session(ngx_mail_session_t *s, ngx_connection_t *c)
+{
+ ngx_mail_mx_module_ctx_t *context;
+ ngx_msec_t timeout;
+ ngx_mail_core_srv_conf_t *cscf;
+ ngx_mail_smtp_srv_conf_t *sscf;
+
+ context = ngx_pcalloc(c->pool, sizeof(ngx_mail_mx_module_ctx_t));
+ if(context == NULL) {
+ ngx_mail_close_connection(c);
+ return;
+ }
+
+ ngx_mail_set_ctx(s, context, ngx_mail_mx_module);
+
+ cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
+ sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_mx_module);
+
+ timeout = sscf->greeting_delay ? sscf->greeting_delay : cscf->timeout;
+ ngx_add_timer(c->read, timeout);
+
+ if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) {
+ ngx_mail_close_connection(c);
+ }
+
+ if (sscf->greeting_delay) {
+ c->read->handler = ngx_mail_mx_invalid_pipelining;
+ return;
+ }
+
+ c->read->handler = ngx_mail_mx_init_protocol;
+
+ s->out = sscf->greeting;
+
+ ngx_mail_send(c->write);
+}
+
+
+static void
+ngx_mail_mx_invalid_pipelining(ngx_event_t *rev)
+{
+ ngx_connection_t *c;
+ ngx_mail_session_t *s;
+ ngx_mail_core_srv_conf_t *cscf;
+ ngx_mail_smtp_srv_conf_t *sscf;
+
+ c = rev->data;
+ s = c->data;
+
+ c->log->action = "in delay pipelining state";
+
+ if (rev->timedout) {
+
+ ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "delay greeting");
+
+ rev->timedout = 0;
+
+ cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
+
+ c->read->handler = ngx_mail_mx_init_protocol;
+
+ ngx_add_timer(c->read, cscf->timeout);
+
+ if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) {
+ ngx_mail_close_connection(c);
+ return;
+ }
+
+ sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_mx_module);
+
+ s->out = sscf->greeting;
+
+ } else {
+
+ ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "invalid pipelining");
+
+ if (s->buffer == NULL) {
+ if (ngx_mail_mx_create_buffer(s, c) != NGX_OK) {
+ return;
+ }
+ }
+
+ if (ngx_mail_smtp_discard_command(s, c,
+ "client was rejected before greeting: \"%V\"")
+ != NGX_OK)
+ {
+ return;
+ }
+
+ s->out.len = sizeof(smtp_invalid_pipelining) - 1;
+ s->out.data = smtp_invalid_pipelining;
+ }
+
+ ngx_mail_send(c->write);
+}
+
+
+void
+ngx_mail_mx_init_protocol(ngx_event_t *rev)
+{
+ ngx_connection_t *c;
+ ngx_mail_session_t *s;
+
+ c = rev->data;
+
+ c->log->action = "in auth state";
+
+ if (rev->timedout) {
+ ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
+ c->timedout = 1;
+ ngx_mail_close_connection(c);
+ return;
+ }
+
+ s = c->data;
+
+ if (s->buffer == NULL) {
+ if (ngx_mail_mx_create_buffer(s, c) != NGX_OK) {
+ return;
+ }
+ }
+
+ s->mail_state = ngx_mx_start;
+ c->read->handler = ngx_mail_mx_auth_state;
+
+ ngx_mail_mx_auth_state(rev);
+}
+
+
+static ngx_int_t
+ngx_mail_mx_create_buffer(ngx_mail_session_t *s, ngx_connection_t *c)
+{
+ ngx_mail_smtp_srv_conf_t *sscf;
+
+ if (ngx_array_init(&s->args, c->pool, 2, sizeof(ngx_str_t)) == NGX_ERROR) {
+ ngx_mail_session_internal_server_error(s);
+ return NGX_ERROR;
+ }
+
+ sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_mx_module);
+
+ s->buffer = ngx_create_temp_buf(c->pool, sscf->client_buffer_size);
+ if (s->buffer == NULL) {
+ ngx_mail_session_internal_server_error(s);
+ return NGX_ERROR;
+ }
+
+ return NGX_OK;
+}
+
+
+void
+ngx_mail_mx_auth_state(ngx_event_t *rev)
+{
+ ngx_int_t rc;
+ ngx_connection_t *c;
+ ngx_mail_session_t *s;
+
+ c = rev->data;
+ s = c->data;
+
+ ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "smtp auth state");
+
+ if (rev->timedout) {
+ ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
+ c->timedout = 1;
+ ngx_mail_close_connection(c);
+ return;
+ }
+
+ if (s->out.len) {
+ ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "smtp send handler
busy");
+ s->blocked = 1;
+ return;
+ }
+
+ s->blocked = 0;
+
+ rc = ngx_mail_read_command(s, c);
+
+ if (rc == NGX_AGAIN || rc == NGX_ERROR) {
+ return;
+ }
+
+ s->out.len = sizeof(smtp_ok) - 1;
+ s->out.data = smtp_ok;
+
+ if (rc == NGX_OK) {
+ switch (s->command) {
+
+ case NGX_SMTP_HELO:
+ case NGX_SMTP_EHLO:
+ rc = ngx_mail_mx_helo(s, c);
+ break;
+
+ case NGX_SMTP_QUIT:
+ s->quit = 1;
+ s->out.len = sizeof(smtp_bye) - 1;
+ s->out.data = smtp_bye;
+ break;
+
+ case NGX_SMTP_MAIL:
+ rc = ngx_mail_mx_mail(s, c);
+ break;
+
+ case NGX_SMTP_RCPT:
+ rc = ngx_mail_mx_rcpt(s, c);
+ break;
+
+ case NGX_SMTP_NOOP:
+ case NGX_SMTP_RSET:
+ break;
+
+ case NGX_SMTP_STARTTLS:
+ rc = ngx_mail_smtp_starttls(s, c);
+ break;
+
+ default:
+ rc = NGX_MAIL_PARSE_INVALID_COMMAND;
+ break;
+ }
+ if (s->mail_state == ngx_mx_helo_mail_rcpt) rc = NGX_DONE;
+ }
+
+ switch (rc) {
+
+ case NGX_DONE:
+ ngx_mail_auth(s, c);
+ return;
+
+ case NGX_ERROR:
+ ngx_mail_session_internal_server_error(s);
+ return;
+
+ case NGX_MAIL_PARSE_INVALID_COMMAND:
+ s->mail_state = ngx_mx_start;
+ s->state = 0;
+
+ s->out.len = sizeof(smtp_invalid_command) - 1;
+ s->out.data = smtp_invalid_command;
+
+ /* fall through */
+
+ case NGX_OK:
+ s->args.nelts = 0;
+ s->buffer->pos = s->buffer->start;
+ s->buffer->last = s->buffer->start;
+
+ if (s->state) {
+ s->arg_start = s->buffer->start;
+ }
+
+ ngx_mail_send(c->write);
+ }
+}
+
+
+static ngx_int_t
+ngx_mail_mx_helo(ngx_mail_session_t *s, ngx_connection_t *c)
+{
+ ngx_str_t *arg;
+ ngx_mail_smtp_srv_conf_t *sscf;
+#if (NGX_MAIL_SSL)
+ ngx_mail_ssl_conf_t *sslcf;
+#endif
+ ngx_mail_mx_module_ctx_t *mx_ctx;
+ ngx_str_t *what_free = NULL;
+
+ mx_ctx = ngx_mail_get_module_ctx(s, ngx_mail_mx_module);
+
+ if (s->args.nelts != 1) {
+ s->out.len = sizeof(smtp_invalid_argument) - 1;
+ s->out.data = smtp_invalid_argument;
+ s->state = 0;
+ return NGX_OK;
+ }
+
+ switch(s->mail_state) {
+ case ngx_mx_start: s->mail_state = ngx_mx_helo;
+ break;
+ case ngx_mx_helo_mail:
+ case ngx_mx_helo_rcpt:
+ what_free = (s->mail_state == ngx_mx_helo_mail) ? &mx_ctx->smtp_mail :
&mx_ctx->smtp_rcpt;
+ ngx_pfree(c->pool, what_free->data);
+ what_free->len = 0; /*Pass through...*/
+ case ngx_mx_helo:
+ ngx_pfree(c->pool, mx_ctx->smtp_helo.data);
+ mx_ctx->smtp_helo.len = 0;
+ s->mail_state = ngx_mx_helo;
+ break;
+ default:
+ s->mail_state = ngx_mx_helo;
+ /*
+ * TODO: RFC2881: An EHLO command MAY be issued by a client later in the
session. If
+ * it is issued after the session begins, the SMTP server MUST clear all
+ * buffers and reset the state exactly as if a RSET command had been
+ * issued.
+ */
+ }
+
+ arg = s->args.elts;
+
+ mx_ctx->smtp_helo.len = arg[0].len;
+
+ mx_ctx->smtp_helo.data = ngx_palloc(c->pool, arg[0].len);
+ if (mx_ctx->smtp_helo.data == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(mx_ctx->smtp_helo.data, arg[0].data, arg[0].len);
+
+ sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_mx_module);
+
+ if (s->command == NGX_SMTP_HELO) {
+ s->out = sscf->server_name;
+
+ } 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) {
+ s->out = sscf->starttls_capability;
+ return NGX_OK;
+ }
+
+ if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
+ s->out = sscf->starttls_only_capability;
+ return NGX_OK;
+ }
+ }
+#endif
+
+ s->out = sscf->capability;
+ }
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_mail_mx_mail(ngx_mail_session_t *s, ngx_connection_t *c)
+{
+ ngx_str_t *arg;
+ ngx_mail_mx_module_ctx_t *mx_ctx;
+
+ mx_ctx = ngx_mail_get_module_ctx(s, ngx_mail_mx_module);
+
+ if (s->args.nelts != 2) {
+ s->out.len = sizeof(smtp_invalid_command) - 1;
+ s->out.data = smtp_invalid_command;
+ s->state = 0;
+ return NGX_OK;
+ }
+
+ arg = s->args.elts;
+
+ if(arg[0].len == 5 &&
+ ngx_toupper(arg[0].data[0]) == 'F' &&
+ ngx_toupper(arg[0].data[1]) == 'R' &&
+ ngx_toupper(arg[0].data[2]) == 'O' &&
+ ngx_toupper(arg[0].data[3]) == 'M' &&
+ ngx_toupper(arg[0].data[4]) == ':') {
+
+ switch(s->mail_state) {
+ case ngx_mx_helo: s->mail_state = ngx_mx_helo_mail;
+ break;
+ case ngx_mx_helo_rcpt: s->mail_state = ngx_mx_helo_mail_rcpt;
+ break;
+ case ngx_mx_helo_mail:
+ ngx_pfree(c->pool, mx_ctx->smtp_mail.data);
+ mx_ctx->smtp_mail.len = 0;
+ break;
+ default:
+ s->out.len = sizeof(smtp_helo_required) - 1;
+ s->out.data = smtp_helo_required;
+ s->state = 0;
+ return NGX_OK;
+ }
+
+ mx_ctx->smtp_mail.len = arg[1].len;
+
+ mx_ctx->smtp_mail.data = ngx_palloc(c->pool, arg[1].len);
+ if (mx_ctx->smtp_mail.data == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(mx_ctx->smtp_mail.data, arg[1].data, arg[1].len);
+
+ } else {
+ s->out.len = sizeof(smtp_invalid_command);
+ s->out.data = smtp_invalid_command;
+ s->state = 0;
+ }
+
+ return NGX_OK;
+}
+
+static ngx_int_t
+ngx_mail_mx_rcpt(ngx_mail_session_t *s, ngx_connection_t *c)
+{
+ ngx_str_t *arg;
+ ngx_mail_mx_module_ctx_t *mx_ctx;
+
+ mx_ctx = ngx_mail_get_module_ctx(s, ngx_mail_mx_module);
+
+ if (s->args.nelts != 2) {
+ s->out.len = sizeof(smtp_invalid_command) - 1;
+ s->out.data = smtp_invalid_command;
+ s->state = 0;
+ return NGX_OK;
+ }
+
+ arg = s->args.elts;
+
+ if(arg[0].len == 3 &&
+ ngx_toupper(arg[0].data[0]) == 'T' &&
+ ngx_toupper(arg[0].data[1]) == 'O' &&
+ ngx_toupper(arg[0].data[2]) == ':') {
+
+ switch(s->mail_state) {
+ case ngx_mx_helo: s->mail_state = ngx_mx_helo_rcpt;
+ break;
+ case ngx_mx_helo_mail: s->mail_state = ngx_mx_helo_mail_rcpt;
+ break;
+ case ngx_mx_helo_rcpt:
+ ngx_pfree(c->pool, mx_ctx->smtp_rcpt.data);
+ mx_ctx->smtp_rcpt.len = 0;
+ break;
+ default:
+ s->out.len = sizeof(smtp_helo_required) - 1;
+ s->out.data = smtp_helo_required;
+ s->state = 0;
+ return NGX_OK;
+ }
+
+ mx_ctx->smtp_rcpt.len = arg[1].len;
+
+ mx_ctx->smtp_rcpt.data = ngx_palloc(c->pool, arg[1].len);
+ if (mx_ctx->smtp_rcpt.data == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(mx_ctx->smtp_rcpt.data, arg[1].data, arg[1].len);
+
+ } else {
+ s->out.len = sizeof(smtp_invalid_command);
+ s->out.data = smtp_invalid_command;
+ s->state = 0;
+ }
+
+ return NGX_OK;
+}
+
+static ngx_int_t
+ngx_mail_smtp_starttls(ngx_mail_session_t *s, ngx_connection_t *c)
+{
+#if (NGX_MAIL_SSL)
+ ngx_mail_ssl_conf_t *sslcf;
+
+ if (c->ssl == NULL) {
+ sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
+ if (sslcf->starttls) {
+
+ /*
+ * RFC3207 requires us to discard any knowledge
+ * obtained from client before STARTTLS.
+ */
+
+ s->smtp_helo.len = 0;
+ s->smtp_helo.data = NULL;
+
+ c->read->handler = ngx_mail_starttls_handler;
+ return NGX_OK;
+ }
+ }
+
+#endif
+
+ return NGX_MAIL_PARSE_INVALID_COMMAND;
+}
+
+/*
+static ngx_int_t
+ngx_mail_mx_discard_command(ngx_mail_session_t *s, ngx_connection_t *c,
+ char *err)
+{
+ ssize_t n;
+
+ n = c->recv(c, s->buffer->last, s->buffer->end - s->buffer->last);
+
+ if (n == NGX_ERROR || n == 0) {
+ ngx_mail_close_connection(c);
+ return NGX_ERROR;
+ }
+
+ if (n > 0) {
+ s->buffer->last += n;
+ }
+
+ if (n == NGX_AGAIN) {
+ if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) {
+ ngx_mail_session_internal_server_error(s);
+ return NGX_ERROR;
+ }
+
+ return NGX_AGAIN;
+ }
+
+ ngx_mail_smtp_log_rejected_command(s, c, err);
+
+ s->buffer->pos = s->buffer->start;
+ s->buffer->last = s->buffer->start;
+
+ return NGX_OK;
+}
+
+
+static void
+ngx_mail_smtp_log_rejected_command(ngx_mail_session_t *s, ngx_connection_t *c,
+ char *err)
+{
+ u_char ch;
+ ngx_str_t cmd;
+ ngx_uint_t i;
+
+ if (c->log->log_level < NGX_LOG_INFO) {
+ return;
+ }
+
+ cmd.len = s->buffer->last - s->buffer->start;
+ cmd.data = s->buffer->start;
+
+ for (i = 0; i < cmd.len; i++) {
+ ch = cmd.data[i];
+
+ if (ch != CR && ch != LF) {
+ continue;
+ }
+
+ cmd.data[i] = '_';
+ }
+
+ cmd.len = i;
+
+ ngx_log_error(NGX_LOG_INFO, c->log, 0, err, &cmd);
+}
+*/
+
+ngx_int_t
+ngx_mail_mx_parse_command(ngx_mail_session_t *s)
+{
+ u_char ch, *p, *c, c0, c1, c2, c3;
+ ngx_str_t *arg;
+ enum {
+ sw_start = 0,
+ sw_spaces_before_argument,
+ sw_argument,
+ sw_almost_done
+ } state;
+
+ state = s->state;
+
+ for (p = s->buffer->pos; p < s->buffer->last; p++) {
+ ch = *p;
+
+ switch (state) {
+
+ /* SMTP command */
+ case sw_start:
+ if (ch == ' ' || ch == CR || ch == LF) {
+ c = s->buffer->start;
+
+ if (p - c == 4) {
+
+ c0 = ngx_toupper(c[0]);
+ c1 = ngx_toupper(c[1]);
+ c2 = ngx_toupper(c[2]);
+ c3 = ngx_toupper(c[3]);
+
+ if (c0 == 'H' && c1 == 'E' && c2 == 'L' && c3 == 'O')
+ {
+ s->command = NGX_SMTP_HELO;
+
+ } else if (c0 == 'E' && c1 == 'H' && c2 == 'L' && c3 ==
'O')
+ {
+ s->command = NGX_SMTP_EHLO;
+
+ } else if (c0 == 'Q' && c1 == 'U' && c2 == 'I' && c3 ==
'T')
+ {
+ s->command = NGX_SMTP_QUIT;
+
+ } else if (c0 == 'A' && c1 == 'U' && c2 == 'T' && c3 == 'H')
+ {
+ s->command = NGX_SMTP_AUTH;
+
+ } else if (c0 == 'N' && c1 == 'O' && c2 == 'O' && c3 ==
'P')
+ {
+ s->command = NGX_SMTP_NOOP;
+
+ } else if (c0 == 'M' && c1 == 'A' && c2 == 'I' && c3 ==
'L')
+ {
+ s->command = NGX_SMTP_MAIL;
+
+ } else if (c0 == 'R' && c1 == 'S' && c2 == 'E' && c3 ==
'T')
+ {
+ s->command = NGX_SMTP_RSET;
+
+ } else if (c0 == 'R' && c1 == 'C' && c2 == 'P' && c3 ==
'T')
+ {
+ s->command = NGX_SMTP_RCPT;
+
+ } else if (c0 == 'V' && c1 == 'R' && c2 == 'F' && c3 ==
'Y')
+ {
+ s->command = NGX_SMTP_VRFY;
+
+ } else if (c0 == 'E' && c1 == 'X' && c2 == 'P' && c3 ==
'N')
+ {
+ s->command = NGX_SMTP_EXPN;
+
+ } else if (c0 == 'H' && c1 == 'E' && c2 == 'L' && c3 ==
'P')
+ {
+ s->command = NGX_SMTP_HELP;
+
+ } else {
+ goto invalid;
+ }
+#if (NGX_MAIL_SSL)
+ } else if (p - c == 8) {
+
+ if ((c[0] == 'S'|| c[0] == 's')
+ && (c[1] == 'T'|| c[1] == 't')
+ && (c[2] == 'A'|| c[2] == 'a')
+ && (c[3] == 'R'|| c[3] == 'r')
+ && (c[4] == 'T'|| c[4] == 't')
+ && (c[5] == 'T'|| c[5] == 't')
+ && (c[6] == 'L'|| c[6] == 'l')
+ && (c[7] == 'S'|| c[7] == 's'))
+ {
+ s->command = NGX_SMTP_STARTTLS;
+
+ } else {
+ goto invalid;
+ }
+#endif
+ } else {
+ goto invalid;
+ }
+
+ switch (ch) {
+ case ' ':
+ state = sw_spaces_before_argument;
+ break;
+ case CR:
+ state = sw_almost_done;
+ break;
+ case LF:
+ goto done;
+ }
+ break;
+ }
+
+ if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) {
+ goto invalid;
+ }
+
+ break;
+
+ case sw_spaces_before_argument:
+ switch (ch) {
+ case ' ':
+ break;
+ case CR:
+ state = sw_almost_done;
+ s->arg_end = p;
+ break;
+ case LF:
+ s->arg_end = p;
+ goto done;
+ default:
+ if (s->args.nelts <= 2) {
+ state = sw_argument;
+ s->arg_start = p;
+ break;
+ }
+ goto invalid;
+ }
+ break;
+
+ case sw_argument:
+ switch (ch) {
+ case ' ':
+ case CR:
+ case LF:
+ arg = ngx_array_push(&s->args);
+ if (arg == NULL) {
+ return NGX_ERROR;
+ }
+ arg->len = p - s->arg_start;
+ arg->data = s->arg_start;
+ s->arg_start = NULL;
+
+ switch (ch) {
+ case ' ':
+ state = sw_spaces_before_argument;
+ break;
+ case CR:
+ state = sw_almost_done;
+ break;
+ case LF:
+ goto done;
+ }
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case sw_almost_done:
+ switch (ch) {
+ case LF:
+ goto done;
+ default:
+ goto invalid;
+ }
+ }
+ }
+
+ s->buffer->pos = p;
+ s->state = state;
+
+ return NGX_AGAIN;
+
+done:
+
+ s->buffer->pos = p + 1;
+
+ if (s->arg_start) {
+ arg = ngx_array_push(&s->args);
+ if (arg == NULL) {
+ return NGX_ERROR;
+ }
+ arg->len = s->arg_end - s->arg_start;
+ arg->data = s->arg_start;
+ s->arg_start = NULL;
+ }
+
+ /* s->state = (s->command != NGX_SMTP_AUTH) ? sw_start : sw_argument; */
+ s->state = sw_start;
+
+ return NGX_OK;
+
+invalid:
+
+ s->state = sw_start;
+ s->arg_start = NULL;
+
+ return NGX_MAIL_PARSE_INVALID_COMMAND;
+}
Index: src/mail/ngx_mail.h
===================================================================
--- src/mail/ngx_mail.h (.../original-0.5.34) (revision 48)
+++ src/mail/ngx_mail.h (.../nginx-0.5.35_MX_PROXY_2) (revision 48)
@@ -72,6 +72,7 @@
#define NGX_MAIL_POP3_PROTOCOL 0
#define NGX_MAIL_IMAP_PROTOCOL 1
#define NGX_MAIL_SMTP_PROTOCOL 2
+#define NGX_MAIL_MX_PROTOCOL 3
typedef struct ngx_mail_protocol_s ngx_mail_protocol_t;
Index: src/mail/ngx_mail_proxy_module.c
===================================================================
--- src/mail/ngx_mail_proxy_module.c (.../original-0.5.34) (revision 48)
+++ src/mail/ngx_mail_proxy_module.c (.../nginx-0.5.35_MX_PROXY_2)
(revision 48)
@@ -9,6 +9,7 @@
#include <ngx_event.h>
#include <ngx_event_connect.h>
#include <ngx_mail.h>
+#include <ngx_mail_mx_module.h>
typedef struct {
@@ -17,6 +18,7 @@
ngx_flag_t xclient;
size_t buffer_size;
ngx_msec_t timeout;
+ ngx_peer_addr_t *peer;
} ngx_mail_proxy_conf_t;
@@ -24,6 +26,7 @@
static void ngx_mail_proxy_pop3_handler(ngx_event_t *rev);
static void ngx_mail_proxy_imap_handler(ngx_event_t *rev);
static void ngx_mail_proxy_smtp_handler(ngx_event_t *rev);
+static void ngx_mail_proxy_mx_handler(ngx_event_t *rev);
static void ngx_mail_proxy_dummy_handler(ngx_event_t *ev);
static ngx_int_t ngx_mail_proxy_read_response(ngx_mail_session_t *s,
ngx_uint_t state);
@@ -34,6 +37,8 @@
static void *ngx_mail_proxy_create_conf(ngx_conf_t *cf);
static char *ngx_mail_proxy_merge_conf(ngx_conf_t *cf, void *parent,
void *child);
+static char *
+ngx_mail_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static ngx_command_t ngx_mail_proxy_commands[] = {
@@ -73,6 +78,13 @@
offsetof(ngx_mail_proxy_conf_t, xclient),
NULL },
+ { ngx_string("proxy_pass"),
+ NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
+ ngx_mail_proxy_pass,
+ NGX_MAIL_SRV_CONF_OFFSET,
+ 0,
+ NULL },
+
ngx_null_command
};
@@ -119,7 +131,16 @@
s->connection->log->action = "connecting to upstream";
cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
+ pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module);
+ if(!peer) peer = pcf->peer;
+ if(!peer) {
+ ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
+ "no \"proxy_pass\" defined for server and no one in http
auth response");
+ ngx_mail_session_internal_server_error(s);
+ return;
+ }
+
if (cscf->so_keepalive) {
keepalive = 1;
@@ -162,8 +183,6 @@
s->connection->read->handler = ngx_mail_proxy_block_read;
p->upstream.connection->write->handler = ngx_mail_proxy_dummy_handler;
- pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module);
-
s->proxy->buffer = ngx_create_temp_buf(s->connection->pool,
pcf->buffer_size);
if (s->proxy->buffer == NULL) {
@@ -183,6 +202,11 @@
s->mail_state = ngx_imap_start;
break;
+ case NGX_MAIL_MX_PROTOCOL:
+ p->upstream.connection->read->handler = ngx_mail_proxy_mx_handler;
+ s->mail_state = ngx_mx_start;
+ break;
+
default: /* NGX_MAIL_SMTP_PROTOCOL */
p->upstream.connection->read->handler = ngx_mail_proxy_smtp_handler;
s->mail_state = ngx_smtp_start;
@@ -604,6 +628,161 @@
static void
+ngx_mail_proxy_mx_handler(ngx_event_t *rev)
+{
+ u_char *p;
+ ngx_int_t rc;
+ ngx_str_t line;
+ ngx_connection_t *c;
+ ngx_mail_session_t *s;
+ ngx_mail_proxy_conf_t *pcf;
+ ngx_mail_core_srv_conf_t *cscf;
+ ngx_mail_mx_module_ctx_t *mx_ctx;
+
+ ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0,
+ "mail proxy mx handler");
+
+ c = rev->data;
+ s = c->data;
+
+ if (rev->timedout) {
+ ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
+ "upstream timed out");
+ c->timedout = 1;
+ ngx_mail_proxy_internal_server_error(s);
+ return;
+ }
+
+ rc = ngx_mail_proxy_read_response(s, s->mail_state);
+
+ if (rc == NGX_AGAIN) {
+ return;
+ }
+
+ if (rc == NGX_ERROR) {
+ ngx_mail_proxy_upstream_error(s);
+ return;
+ }
+
+ mx_ctx = ngx_mail_get_module_ctx(s, ngx_mail_mx_module);
+
+ switch (s->mail_state) {
+
+ case ngx_mx_start:
+ ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy send
ehlo");
+
+ s->connection->log->action = "sending HELO/EHLO to upstream";
+
+ line.len = sizeof("HELO " CRLF) - 1 + mx_ctx->smtp_helo.len;
+ if (mx_ctx->smtp_helo_addition.len) line.len +=
mx_ctx->smtp_helo_addition.len + sizeof(" ") - 1;
+
+ line.data = ngx_palloc(c->pool, line.len);
+ if (line.data == NULL) {
+ ngx_mail_proxy_internal_server_error(s);
+ return;
+ }
+
+ pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module);
+
+ p = ngx_cpymem(line.data,
+ ((s->esmtp) ? "EHLO " : "HELO "),
+ sizeof("HELO ") - 1);
+
+ p = ngx_cpymem(p, mx_ctx->smtp_helo.data, mx_ctx->smtp_helo.len);
+
+ if (mx_ctx->smtp_helo_addition.len) {
+ *p++ = ' ';
+ p = ngx_cpymem(p, mx_ctx->smtp_helo_addition.data,
mx_ctx->smtp_helo_addition.len);
+ }
+
+ *p++ = CR; *p = LF;
+
+ s->mail_state = ngx_mx_helo;
+ break;
+
+ case ngx_mx_helo:
+ ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy send mail
from:");
+
+ s->connection->log->action = "sending MAIL FROM: to upstream";
+
+ line.len = sizeof("MAIL FROM: " CRLF) - 1 + mx_ctx->smtp_mail.len;
+ line.data = ngx_palloc(c->pool, line.len);
+ if (line.data == NULL) {
+ ngx_mail_proxy_internal_server_error(s);
+ return;
+ }
+
+ p = ngx_cpymem(line.data, "MAIL FROM: ", sizeof("MAIL FROM: ") - 1);
+ p = ngx_cpymem(p, mx_ctx->smtp_mail.data, mx_ctx->smtp_mail.len);
+ *p++ = CR; *p = LF;
+
+ s->mail_state = ngx_mx_helo_mail;
+ break;
+
+ case ngx_mx_helo_mail:
+ ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy send rcpt
to:");
+
+ s->connection->log->action = "sending RCPT TO: to upstream";
+
+ line.len = sizeof("RCPT TO: " CRLF) - 1 + mx_ctx->smtp_rcpt.len;
+ line.data = ngx_palloc(c->pool, line.len);
+ if (line.data == NULL) {
+ ngx_mail_proxy_internal_server_error(s);
+ return;
+ }
+
+ p = ngx_cpymem(line.data, "RCPT TO: ", sizeof("RCPT TO: ") - 1);
+ p = ngx_cpymem(p, mx_ctx->smtp_rcpt.data, mx_ctx->smtp_rcpt.len);
+ *p++ = CR; *p = LF;
+
+ s->mail_state = ngx_mx_helo_mail_rcpt;
+ break;
+
+ case ngx_mx_helo_mail_rcpt:
+
+ ngx_memcpy(s->proxy->buffer->start, smtp_ok, sizeof(smtp_ok) - 1);
+
+ s->proxy->buffer->pos = s->proxy->buffer->start;
+ s->proxy->buffer->last = s->proxy->buffer->start + sizeof(smtp_ok) - 1;
+
+ s->connection->read->handler = ngx_mail_proxy_handler;
+ s->connection->write->handler = ngx_mail_proxy_handler;
+ rev->handler = ngx_mail_proxy_handler;
+ c->write->handler = ngx_mail_proxy_handler;
+
+ pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module);
+ ngx_add_timer(s->connection->read, pcf->timeout);
+ ngx_del_timer(c->read);
+
+ c->log->action = NULL;
+
+ ngx_mail_proxy_handler(s->connection->write);
+ /*TODO: ngx_mail_delete_ctx(s, ngx_mail_mx_module);*/
+ return;
+
+ default:
+#if (NGX_SUPPRESS_WARN)
+ line.len = 0;
+ line.data = NULL;
+#endif
+ break;
+ }
+
+ if (c->send(c, line.data, line.len) < (ssize_t) line.len) {
+ /*
+ * we treat the incomplete sending as NGX_ERROR
+ * because it is very strange here
+ */
+ ngx_mail_proxy_internal_server_error(s);
+ return;
+ }
+
+ s->proxy->buffer->pos = s->proxy->buffer->start;
+ s->proxy->buffer->last = s->proxy->buffer->start;
+}
+
+
+static void
ngx_mail_proxy_dummy_handler(ngx_event_t *wev)
{
ngx_connection_t *c;
@@ -699,6 +878,29 @@
break;
+ case NGX_MAIL_MX_PROTOCOL:
+ switch (state) {
+
+ case ngx_mx_helo:
+ case ngx_mx_noxclient:
+ case ngx_mx_helo_mail:
+ case ngx_mx_helo_rcpt:
+ case ngx_mx_helo_mail_rcpt:
+ if (p[0] == '2' && p[1] == '5' && p[2] == '0') {
+ return NGX_OK;
+ }
+ break;
+
+ case ngx_mx_start:
+ case ngx_mx_xclient:
+ if (p[0] == '2' && p[1] == '2' && p[2] == '0') {
+ return NGX_OK;
+ }
+ break;
+ }
+
+ break;
+
default: /* NGX_MAIL_SMTP_PROTOCOL */
switch (state) {
@@ -993,6 +1195,58 @@
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);
+ if (conf->peer == NULL) {
+ conf->peer = prev->peer;
+ }
return NGX_CONF_OK;
}
+
+
+static char *
+ngx_mail_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_mail_proxy_conf_t *pcf = conf;
+
+ ngx_str_t *value;
+ ngx_url_t u;
+
+ value = cf->args->elts;
+
+ ngx_memzero(&u, sizeof(ngx_url_t));
+
+ u.url = value[1];
+ u.default_port = 25;
+ u.uri_part = 1;
+ u.one_addr = 1;
+
+ /*
+ if (ngx_strncmp(u.url.data, "http://", 7) == 0) {
+ u.url.len -= 7;
+ u.url.data += 7;
+ }
+
+ */
+ if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
+ if (u.err) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "%s in proxy_pass \"%V\"", u.err, &u.url);
+ }
+
+ return NGX_CONF_ERROR;
+ }
+
+ pcf->peer = u.addrs;
+
+ /*
+ pcf->host_header = u.host;
+ pcf->uri = u.uri;
+
+ if (ahcf->uri.len == 0) {
+ ahcf->uri.len = sizeof("/") - 1;
+ ahcf->uri.data = (u_char *) "/";
+ }
+ */
+
+ return NGX_CONF_OK;
+}
Index: src/mail/ngx_mail_mx_module.c
===================================================================
--- src/mail/ngx_mail_mx_module.c (.../original-0.5.34) (revision 0)
+++ src/mail/ngx_mail_mx_module.c (.../nginx-0.5.35_MX_PROXY_2)
(revision 48)
@@ -0,0 +1,263 @@
+
+/*
+ * Copyright (C) Igor Sysoev,
+ * Copypaste (M-w, C-y) NomadRain@xxxxxxxxxx
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_event.h>
+#include <ngx_mail.h>
+#include <ngx_mail_smtp_module.h>
+#include <ngx_mail_mx_module.h>
+
+
+static void *ngx_mail_mx_create_srv_conf(ngx_conf_t *cf);
+static char *ngx_mail_mx_merge_srv_conf(ngx_conf_t *cf, void *parent,
+ void *child);
+
+static ngx_mail_protocol_t ngx_mail_mx_protocol = {
+ ngx_string("mx"),
+ { 25, 465, 587, 0 },
+ NGX_MAIL_MX_PROTOCOL,
+
+ ngx_mail_mx_init_session,
+ ngx_mail_mx_init_protocol,
+ ngx_mail_mx_parse_command,
+ ngx_mail_mx_auth_state,
+
+ ngx_string("451 4.3.2 Internal server error" CRLF)
+};
+
+
+static ngx_command_t ngx_mail_mx_commands[] = {
+
+ { ngx_string("mx_client_buffer"),
+ NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_size_slot,
+ NGX_MAIL_SRV_CONF_OFFSET,
+ offsetof(ngx_mail_smtp_srv_conf_t, client_buffer_size),
+ NULL },
+
+ { ngx_string("mx_greeting_delay"),
+ NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_msec_slot,
+ NGX_MAIL_SRV_CONF_OFFSET,
+ offsetof(ngx_mail_smtp_srv_conf_t, greeting_delay),
+ NULL },
+
+ { ngx_string("mx_capabilities"),
+ NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
+ ngx_mail_capabilities,
+ NGX_MAIL_SRV_CONF_OFFSET,
+ offsetof(ngx_mail_smtp_srv_conf_t, capabilities),
+ NULL },
+
+ ngx_null_command
+};
+
+
+static ngx_mail_module_t ngx_mail_mx_module_ctx = {
+ &ngx_mail_mx_protocol, /* protocol */
+
+ NULL, /* create main configuration */
+ NULL, /* init main configuration */
+
+ ngx_mail_mx_create_srv_conf, /* create server configuration */
+ ngx_mail_mx_merge_srv_conf /* merge server configuration */
+};
+
+
+ngx_module_t ngx_mail_mx_module = {
+ NGX_MODULE_V1,
+ &ngx_mail_mx_module_ctx, /* module context */
+ ngx_mail_mx_commands, /* module directives */
+ NGX_MAIL_MODULE, /* module type */
+ NULL, /* init master */
+ NULL, /* init module */
+ NULL, /* init process */
+ NULL, /* init thread */
+ NULL, /* exit thread */
+ NULL, /* exit process */
+ NULL, /* exit master */
+ NGX_MODULE_V1_PADDING
+};
+
+
+static void *
+ngx_mail_mx_create_srv_conf(ngx_conf_t *cf)
+{
+ ngx_mail_smtp_srv_conf_t *sscf;
+
+ sscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_smtp_srv_conf_t));
+ if (sscf == NULL) {
+ return NULL;
+ }
+
+ sscf->client_buffer_size = NGX_CONF_UNSET_SIZE;
+ sscf->greeting_delay = NGX_CONF_UNSET_MSEC;
+
+ if (ngx_array_init(&sscf->capabilities, cf->pool, 4, sizeof(ngx_str_t))
+ != NGX_OK)
+ {
+ return NULL;
+ }
+
+ return sscf;
+}
+
+
+static char *
+ngx_mail_mx_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
+{
+ ngx_mail_smtp_srv_conf_t *prev = parent;
+ ngx_mail_smtp_srv_conf_t *conf = child;
+
+ u_char *p, *auth;
+ size_t size;
+ ngx_str_t *c;
+ ngx_uint_t i, m;
+ ngx_mail_core_srv_conf_t *cscf;
+
+ ngx_conf_merge_size_value(conf->client_buffer_size,
+ prev->client_buffer_size,
+ (size_t) ngx_pagesize);
+
+ ngx_conf_merge_msec_value(conf->greeting_delay,
+ prev->greeting_delay, 0);
+
+ ngx_conf_merge_bitmask_value(conf->auth_methods,
+ prev->auth_methods,
+ (NGX_CONF_BITMASK_SET
+ |NGX_MAIL_AUTH_PLAIN_ENABLED
+ |NGX_MAIL_AUTH_LOGIN_ENABLED));
+
+
+ cscf = ngx_mail_conf_get_module_srv_conf(cf, ngx_mail_core_module);
+
+ size = sizeof("220 ESMTP ready" CRLF) - 1 + cscf->server_name.len;
+
+ p = ngx_palloc(cf->pool, size);
+ if (p == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ conf->greeting.len = size;
+ conf->greeting.data = p;
+
+ *p++ = '2'; *p++ = '2'; *p++ = '0'; *p++ = ' ';
+ p = ngx_cpymem(p, cscf->server_name.data, cscf->server_name.len);
+ ngx_memcpy(p, " ESMTP ready" CRLF, sizeof(" ESMTP ready" CRLF) - 1);
+
+
+ size = sizeof("250 " CRLF) - 1 + cscf->server_name.len;
+
+ p = ngx_palloc(cf->pool, size);
+ if (p == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ conf->server_name.len = size;
+ conf->server_name.data = p;
+
+ *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = ' ';
+ p = ngx_cpymem(p, cscf->server_name.data, cscf->server_name.len);
+ *p++ = CR; *p = LF;
+
+
+ if (conf->capabilities.nelts == 0) {
+ conf->capabilities = prev->capabilities;
+ }
+
+ size = sizeof("250-") - 1 + cscf->server_name.len + sizeof(CRLF) - 1
+ + sizeof("250 AUTH") - 1 + sizeof(CRLF) - 1;
+
+ c = conf->capabilities.elts;
+ for (i = 0; i < conf->capabilities.nelts; i++) {
+ size += sizeof("250 ") - 1 + c[i].len + 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 += 1 + ngx_mail_smtp_auth_methods_names[i].len;
+ }
+ } */
+
+ p = ngx_palloc(cf->pool, size);
+ if (p == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ conf->capability.len = size;
+ conf->capability.data = p;
+
+ *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = '-';
+ p = ngx_cpymem(p, cscf->server_name.data, cscf->server_name.len);
+ *p++ = CR; *p++ = LF;
+
+ for (i = 0; i < conf->capabilities.nelts; i++) {
+ *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = '-';
+ p = ngx_cpymem(p, c[i].data, c[i].len);
+ *p++ = CR; *p++ = LF;
+ }
+
+ auth = p;
+
+ *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = ' ';
+ *p++ = 'A'; *p++ = 'U'; *p++ = 'T'; *p++ = 'H';
+
+ /* 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_smtp_auth_methods_names[i].data,
+ ngx_mail_smtp_auth_methods_names[i].len);
+ }
+ } */
+
+ *p++ = CR; *p = LF;
+
+ size += sizeof("250 STARTTLS" CRLF) - 1;
+
+ p = ngx_palloc(cf->pool, size);
+ if (p == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ conf->starttls_capability.len = size;
+ conf->starttls_capability.data = p;
+
+ p = ngx_cpymem(p, conf->capability.data,
+ conf->capability.len);
+
+ p = ngx_cpymem(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1);
+ *p++ = CR; *p = LF;
+
+ p = conf->starttls_capability.data
+ + (auth - conf->capability.data) + 3;
+ *p = '-';
+
+ size = (auth - conf->capability.data)
+ + sizeof("250 STARTTLS" CRLF) - 1;
+
+ p = ngx_palloc(cf->pool, size);
+ if (p == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ conf->starttls_only_capability.len = size;
+ conf->starttls_only_capability.data = p;
+
+ p = ngx_cpymem(p, conf->capability.data,
+ auth - conf->capability.data);
+
+ ngx_memcpy(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1);
+
+ return NGX_CONF_OK;
+}
Index: src/mail/ngx_mail_mx_module.h
===================================================================
--- src/mail/ngx_mail_mx_module.h (.../original-0.5.34) (revision 0)
+++ src/mail/ngx_mail_mx_module.h (.../nginx-0.5.35_MX_PROXY_2)
(revision 48)
@@ -0,0 +1,42 @@
+
+/*
+ * Copyright (C) Igor Sysoev,
+ * Copypaste (M-w, C-y) NomadRain@xxxxxxxxxx
+ */
+
+
+#ifndef _NGX_MAIL_MX_MODULE_H_INCLUDED_
+#define _NGX_MAIL_MX_MODULE_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_mail.h>
+
+
+void ngx_mail_mx_init_session(ngx_mail_session_t *s, ngx_connection_t *c);
+void ngx_mail_mx_init_protocol(ngx_event_t *rev);
+void ngx_mail_mx_auth_state(ngx_event_t *rev);
+ngx_int_t ngx_mail_mx_parse_command(ngx_mail_session_t *s);
+
+typedef enum {
+ ngx_mx_start = 0,
+ ngx_mx_helo,
+ ngx_mx_helo_mail,
+ ngx_mx_helo_rcpt,
+ ngx_mx_helo_mail_rcpt,
+ ngx_mx_noxclient,
+ ngx_mx_xclient
+} ngx_mx_state_e;
+
+typedef struct {
+ ngx_str_t smtp_helo;
+ ngx_str_t smtp_mail;
+ ngx_str_t smtp_rcpt;
+ ngx_str_t smtp_helo_addition;
+} ngx_mail_mx_module_ctx_t;
+
+extern ngx_module_t ngx_mail_mx_module;
+
+
+#endif /* _NGX_MAIL_MX_MODULE_H_INCLUDED_ */
Index: src/mail/ngx_mail_auth_http_module.c
===================================================================
--- src/mail/ngx_mail_auth_http_module.c (.../original-0.5.34)
(revision 48)
+++ src/mail/ngx_mail_auth_http_module.c (.../nginx-0.5.35_MX_PROXY_2)
(revision 48)
@@ -9,6 +9,7 @@
#include <ngx_event.h>
#include <ngx_event_connect.h>
#include <ngx_mail.h>
+#include <ngx_mail_mx_module.h>
typedef struct {
@@ -458,6 +459,7 @@
ngx_int_t rc, port, n;
ngx_peer_addr_t *peer;
struct sockaddr_in *sin;
+ ngx_mail_mx_module_ctx_t *mx_ctx;
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, s->connection->log, 0,
"mail auth http process headers");
@@ -523,7 +525,7 @@
+ sizeof(CRLF) - 1;
break;
- default: /* NGX_MAIL_SMTP_PROTOCOL */
+ default: /* NGX_MAIL_SMTP_PROTOCOL || NGX_MAIL_MX_PROTOCOL*/
ctx->err = ctx->errmsg;
continue;
}
@@ -549,7 +551,7 @@
*p++ = 'N'; *p++ = 'O'; *p++ = ' ';
break;
- default: /* NGX_MAIL_SMTP_PROTOCOL */
+ default: /* NGX_MAIL_SMTP_PROTOCOL || NGX_MAIL_MX_PROTOCOL*/
break;
}
@@ -666,6 +668,30 @@
continue;
}
+
+ if (len == sizeof("Auth-Helo-Addition") - 1
+ && ngx_strncasecmp(ctx->header_name_start,
+ (u_char *) "Auth-Helo-Addition",
+ sizeof("Auth-Helo-Addition") - 1)
+ == 0)
+ {
+ mx_ctx = ngx_mail_get_module_ctx(s, ngx_mail_mx_module);
+ mx_ctx->smtp_helo_addition.len = ctx->header_end -
ctx->header_start;
+ mx_ctx->smtp_helo_addition.data =
ngx_palloc(s->connection->pool,
+
mx_ctx->smtp_helo_addition.len);
+ if (mx_ctx->smtp_helo_addition.data == NULL) {
+ ngx_close_connection(ctx->peer.connection);
+ ngx_destroy_pool(ctx->pool);
+ ngx_mail_session_internal_server_error(s);
+ return;
+ }
+
+ ngx_memcpy(mx_ctx->smtp_helo_addition.data, ctx->header_start,
+ mx_ctx->smtp_helo_addition.len);
+
+ continue;
+ }
+
/* ignore other headers */
continue;
@@ -682,7 +708,7 @@
ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
"client login failed: \"%V\"", &ctx->errmsg);
- if (s->protocol == NGX_MAIL_SMTP_PROTOCOL) {
+ if (s->protocol == NGX_MAIL_SMTP_PROTOCOL ||
NGX_MAIL_MX_PROTOCOL) {
if (ctx->errcode.len == 0) {
ctx->errcode = ngx_mail_smtp_errcode;
@@ -742,44 +768,52 @@
return;
}
- if (ctx->addr.len == 0 || ctx->port.len == 0) {
+/*
+ * TODO: If a backend is not sended in headers - we pass NULL to proxy module.
+ * It will indicate that backend must be taken from config.
+ */
+
+ /* if (ctx->addr.len == 0 || ctx->port.len == 0) {
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
"auth http server %V did not send server or
port",
ctx->peer.name);
ngx_destroy_pool(ctx->pool);
ngx_mail_session_internal_server_error(s);
return;
- }
+ }*/
+
+ if (s->passwd.data == NULL
+ && s->protocol != NGX_MAIL_SMTP_PROTOCOL
+ && s->protocol != NGX_MAIL_MX_PROTOCOL)
+ {
+ ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
+ "auth http server %V did not send password",
+ ctx->peer.name);
+ ngx_destroy_pool(ctx->pool);
+ ngx_mail_session_internal_server_error(s);
+ return;
+ }
- if (s->passwd.data == NULL
- && s->protocol != NGX_MAIL_SMTP_PROTOCOL)
- {
- ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
- "auth http server %V did not send password",
- ctx->peer.name);
- ngx_destroy_pool(ctx->pool);
- ngx_mail_session_internal_server_error(s);
- return;
- }
+ if (ctx->addr.len != 0 && ctx->port.len != 0) {
- peer = ngx_pcalloc(s->connection->pool, sizeof(ngx_peer_addr_t));
- if (peer == NULL) {
+ peer = ngx_pcalloc(s->connection->pool, sizeof(ngx_peer_addr_t));
+ if (peer == NULL) {
ngx_destroy_pool(ctx->pool);
ngx_mail_session_internal_server_error(s);
return;
- }
-
- sin = ngx_pcalloc(s->connection->pool, sizeof(struct sockaddr_in));
- if (sin == NULL) {
+ }
+
+ sin = ngx_pcalloc(s->connection->pool, sizeof(struct
sockaddr_in));
+ if (sin == NULL) {
ngx_destroy_pool(ctx->pool);
ngx_mail_session_internal_server_error(s);
return;
- }
-
- sin->sin_family = AF_INET;
-
- port = ngx_atoi(ctx->port.data, ctx->port.len);
- if (port == NGX_ERROR || port < 1 || port > 65536) {
+ }
+
+ sin->sin_family = AF_INET;
+
+ port = ngx_atoi(ctx->port.data, ctx->port.len);
+ if (port == NGX_ERROR || port < 1 || port > 65536) {
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
"auth http server %V sent invalid server "
"port:\"%V\"",
@@ -787,13 +821,13 @@
ngx_destroy_pool(ctx->pool);
ngx_mail_session_internal_server_error(s);
return;
- }
-
- sin->sin_port = htons((in_port_t) port);
-
- ctx->addr.data[ctx->addr.len] = '\0';
- sin->sin_addr.s_addr = inet_addr((char *) ctx->addr.data);
- if (sin->sin_addr.s_addr == INADDR_NONE) {
+ }
+
+ sin->sin_port = htons((in_port_t) port);
+
+ ctx->addr.data[ctx->addr.len] = '\0';
+ sin->sin_addr.s_addr = inet_addr((char *) ctx->addr.data);
+ if (sin->sin_addr.s_addr == INADDR_NONE) {
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
"auth http server %V sent invalid server "
"address:\"%V\"",
@@ -801,49 +835,55 @@
ngx_destroy_pool(ctx->pool);
ngx_mail_session_internal_server_error(s);
return;
- }
-
- peer->sockaddr = (struct sockaddr *) sin;
- peer->socklen = sizeof(struct sockaddr_in);
-
- len = ctx->addr.len + 1 + ctx->port.len;
-
- peer->name.len = len;
-
- peer->name.data = ngx_palloc(s->connection->pool, len);
- if (peer->name.data == NULL) {
+ }
+
+ peer->sockaddr = (struct sockaddr *) sin;
+ peer->socklen = sizeof(struct sockaddr_in);
+
+ len = ctx->addr.len + 1 + ctx->port.len;
+
+ peer->name.len = len;
+
+ peer->name.data = ngx_palloc(s->connection->pool, len);
+ if (peer->name.data == NULL) {
ngx_destroy_pool(ctx->pool);
ngx_mail_session_internal_server_error(s);
return;
- }
+ }
+
+ len = ctx->addr.len;
+
+ ngx_memcpy(peer->name.data, ctx->addr.data, len);
+
+ peer->name.data[len++] = ':';
+
+ ngx_memcpy(peer->name.data + len, ctx->port.data, ctx->port.len);
+
+ ngx_destroy_pool(ctx->pool);
- len = ctx->addr.len;
+ } else {
+ peer = NULL;
+ ngx_destroy_pool(ctx->pool);
+ }
- ngx_memcpy(peer->name.data, ctx->addr.data, len);
-
- peer->name.data[len++] = ':';
-
- ngx_memcpy(peer->name.data + len, ctx->port.data, ctx->port.len);
-
- ngx_destroy_pool(ctx->pool);
ngx_mail_proxy_init(s, peer);
-
+
return;
}
-
+
if (rc == NGX_AGAIN ) {
- return;
+ return;
}
-
+
/* rc == NGX_ERROR */
-
+
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
"auth http server %V sent invalid header in response",
ctx->peer.name);
ngx_close_connection(ctx->peer.connection);
ngx_destroy_pool(ctx->pool);
ngx_mail_session_internal_server_error(s);
-
+
return;
}
}
@@ -1139,34 +1179,43 @@
ngx_buf_t *b;
ngx_str_t login, passwd;
ngx_mail_core_srv_conf_t *cscf;
+ ngx_mail_mx_module_ctx_t *mx_ctx;
- if (ngx_mail_auth_http_escape(pool, &s->login, &login) != NGX_OK) {
- return NULL;
- }
+ if(s->protocol != NGX_MAIL_MX_PROTOCOL) {
+ if (ngx_mail_auth_http_escape(pool, &s->login, &login) != NGX_OK) {
+ return NULL;
+ }
- if (ngx_mail_auth_http_escape(pool, &s->passwd, &passwd) != NGX_OK) {
- return NULL;
+ if (ngx_mail_auth_http_escape(pool, &s->passwd, &passwd) != NGX_OK) {
+ return NULL;
+ }
+ } else {
+ mx_ctx = ngx_mail_get_module_ctx(s, ngx_mail_mx_module);
}
cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
len = sizeof("GET ") - 1 + ahcf->uri.len + sizeof(" HTTP/1.0" CRLF) - 1
- + sizeof("Host: ") - 1 + ahcf->host_header.len + sizeof(CRLF) - 1
- + sizeof("Auth-Method: ") - 1
- + ngx_mail_auth_http_method[s->auth_method].len
- + sizeof(CRLF) - 1
+ + sizeof("Host: ") - 1 + ahcf->host_header.len + sizeof(CRLF) - 1;
+
+ if(s->protocol != NGX_MAIL_MX_PROTOCOL) {
+ len += sizeof("Auth-Method: ") - 1
+ + ngx_mail_auth_http_method[s->auth_method].len + sizeof(CRLF) - 1
+ sizeof("Auth-User: ") - 1 + login.len + sizeof(CRLF) - 1
+ sizeof("Auth-Pass: ") - 1 + passwd.len + sizeof(CRLF) - 1
+ sizeof("Auth-Salt: ") - 1 + s->salt.len
- + sizeof("Auth-Protocol: ") - 1 + cscf->protocol->name.len
- + sizeof(CRLF) - 1
- + sizeof("Auth-Login-Attempt: ") - 1 + NGX_INT_T_LEN
- + sizeof(CRLF) - 1
- + sizeof("Client-IP: ") - 1 + s->connection->addr_text.len
- + sizeof(CRLF) - 1
- + ahcf->header.len
- + sizeof(CRLF) - 1;
+ + sizeof("Auth-Protocol: ") - 1 + cscf->protocol->name.len +
sizeof(CRLF) - 1
+ + sizeof("Auth-Login-Attempt: ") - 1 + NGX_INT_T_LEN + sizeof(CRLF)
- 1;
+ } else {
+ len += sizeof("Client-Helo: ") - 1 + mx_ctx->smtp_helo.len +
sizeof(CRLF) - 1
+ + sizeof("Client-Mail: ") - 1 + mx_ctx->smtp_mail.len + sizeof(CRLF)
- 1
+ + sizeof("Client-Rcpt: ") - 1 + mx_ctx->smtp_rcpt.len + sizeof(CRLF)
- 1;
+ }
+ len += sizeof("Client-IP: ") - 1 + s->connection->addr_text.len +
sizeof(CRLF) - 1
+ + ahcf->header.len
+ + sizeof(CRLF) - 1;
+
b = ngx_create_temp_buf(pool, len);
if (b == NULL) {
return NULL;
@@ -1182,36 +1231,49 @@
ahcf->host_header.len);
*b->last++ = CR; *b->last++ = LF;
- b->last = ngx_cpymem(b->last, "Auth-Method: ",
- sizeof("Auth-Method: ") - 1);
- b->last = ngx_cpymem(b->last,
- ngx_mail_auth_http_method[s->auth_method].data,
- ngx_mail_auth_http_method[s->auth_method].len);
- *b->last++ = CR; *b->last++ = LF;
+ if(s->protocol != NGX_MAIL_MX_PROTOCOL) {
+ b->last = ngx_cpymem(b->last, "Auth-Method: ",
+ sizeof("Auth-Method: ") - 1);
+ b->last = ngx_cpymem(b->last,
+ ngx_mail_auth_http_method[s->auth_method].data,
+ ngx_mail_auth_http_method[s->auth_method].len);
+ *b->last++ = CR; *b->last++ = LF;
- b->last = ngx_cpymem(b->last, "Auth-User: ", sizeof("Auth-User: ") - 1);
- b->last = ngx_copy(b->last, login.data, login.len);
- *b->last++ = CR; *b->last++ = LF;
+ b->last = ngx_cpymem(b->last, "Auth-User: ", sizeof("Auth-User: ") -
1);
+ b->last = ngx_copy(b->last, login.data, login.len);
+ *b->last++ = CR; *b->last++ = LF;
- b->last = ngx_cpymem(b->last, "Auth-Pass: ", sizeof("Auth-Pass: ") - 1);
- b->last = ngx_copy(b->last, passwd.data, passwd.len);
- *b->last++ = CR; *b->last++ = LF;
+ b->last = ngx_cpymem(b->last, "Auth-Pass: ", sizeof("Auth-Pass: ") -
1);
+ b->last = ngx_copy(b->last, passwd.data, passwd.len);
+ *b->last++ = CR; *b->last++ = LF;
- if (s->auth_method != NGX_MAIL_AUTH_PLAIN && s->salt.len) {
- b->last = ngx_cpymem(b->last, "Auth-Salt: ", sizeof("Auth-Salt: ") -
1);
- b->last = ngx_copy(b->last, s->salt.data, s->salt.len);
+ if (s->auth_method != NGX_MAIL_AUTH_PLAIN && s->salt.len) {
+ b->last = ngx_cpymem(b->last, "Auth-Salt: ", sizeof("Auth-Salt: ")
- 1);
+ b->last = ngx_copy(b->last, s->salt.data, s->salt.len);
- s->passwd.data = NULL;
- }
+ s->passwd.data = NULL;
+ }
- b->last = ngx_cpymem(b->last, "Auth-Protocol: ",
- sizeof("Auth-Protocol: ") - 1);
- b->last = ngx_cpymem(b->last, cscf->protocol->name.data,
- cscf->protocol->name.len);
- *b->last++ = CR; *b->last++ = LF;
+ b->last = ngx_cpymem(b->last, "Auth-Protocol: ",
+ sizeof("Auth-Protocol: ") - 1);
+ b->last = ngx_cpymem(b->last, cscf->protocol->name.data,
+ cscf->protocol->name.len);
+ *b->last++ = CR; *b->last++ = LF;
- b->last = ngx_sprintf(b->last, "Auth-Login-Attempt: %ui" CRLF,
- s->login_attempt);
+ b->last = ngx_sprintf(b->last, "Auth-Login-Attempt: %ui" CRLF,
+ s->login_attempt);
+ } else {
+ b->last = ngx_cpymem(b->last, "Client-Helo: ", sizeof("Client-Helo: ")
- 1);
+ b->last = ngx_copy(b->last, mx_ctx->smtp_helo.data,
mx_ctx->smtp_helo.len);
+ *b->last++ = CR; *b->last++ = LF;
+ b->last = ngx_cpymem(b->last, "Client-Mail: ", sizeof("Client-Mail: ")
- 1);
+ b->last = ngx_copy(b->last, mx_ctx->smtp_mail.data,
mx_ctx->smtp_mail.len);
+ *b->last++ = CR; *b->last++ = LF;
+ b->last = ngx_cpymem(b->last, "Client-Rcpt: ", sizeof("Client-Rcpt: ")
- 1);
+ b->last = ngx_copy(b->last, mx_ctx->smtp_rcpt.data,
mx_ctx->smtp_rcpt.len);
+ *b->last++ = CR; *b->last++ = LF;
+ /*What more???*/
+ }
b->last = ngx_cpymem(b->last, "Client-IP: ", sizeof("Client-IP: ") - 1);
b->last = ngx_copy(b->last, s->connection->addr_text.data,
Index: auto/sources
===================================================================
--- auto/sources (.../original-0.5.34) (revision 48)
+++ auto/sources (.../nginx-0.5.35_MX_PROXY_2) (revision 48)
@@ -440,6 +440,11 @@
MAIL_SMTP_SRCS="src/mail/ngx_mail_smtp_module.c src/mail/ngx_mail_smtp_handler.c"
+MAIL_MX_MODULE="ngx_mail_mx_module"
+MAIL_MX_DEPS="src/mail/ngx_mail_mx_module.h"
+MAIL_MX_SRCS="src/mail/ngx_mail_mx_module.c + src/mail/ngx_mail_mx_handler.c"
+
MAIL_SSL_MODULE="ngx_mail_ssl_module"
MAIL_SSL_DEPS="src/mail/ngx_mail_ssl_module.h"
MAIL_SSL_SRCS="src/mail/ngx_mail_ssl_module.c"
Index: auto/options
===================================================================
--- auto/options (.../original-0.5.34) (revision 48)
+++ auto/options (.../nginx-0.5.35_MX_PROXY_2) (revision 48)
@@ -85,6 +85,7 @@
MAIL_POP3=YES
MAIL_IMAP=YES
MAIL_SMTP=YES
+MAIL_MX=YES
NGX_ADDONS=
@@ -197,6 +198,7 @@
--without-mail_pop3_module) MAIL_POP3=NO ;;
--without-mail_imap_module) MAIL_IMAP=NO ;;
--without-mail_smtp_module) MAIL_SMTP=NO ;;
+ --without-mail_mx_module) MAIL_MX=NO ;;
--add-module=*) NGX_ADDONS="$NGX_ADDONS $value" ;;
@@ -312,6 +314,7 @@
--without-mail_pop3_module disable ngx_mail_pop3_module
--without-mail_imap_module disable ngx_mail_imap_module
--without-mail_smtp_module disable ngx_mail_smtp_module
+ --without-mail_mx_module disable ngx_mail_mx_module
--add-module=PATH enable an external module
Index: auto/modules
===================================================================
--- auto/modules (.../original-0.5.34) (revision 48)
+++ auto/modules (.../nginx-0.5.35_MX_PROXY_2) (revision 48)
@@ -361,6 +361,12 @@
MAIL_SRCS="$MAIL_SRCS $MAIL_SMTP_SRCS"
fi
+ if [ $MAIL_MX = YES ]; then
+ modules="$modules $MAIL_MX_MODULE"
+ MAIL_DEPS="$MAIL_DEPS $MAIL_MX_DEPS"
+ MAIL_SRCS="$MAIL_SRCS $MAIL_MX_SRCS"
+ fi
+
modules="$modules $MAIL_AUTH_HTTP_MODULE"
MAIL_SRCS="$MAIL_SRCS $MAIL_AUTH_HTTP_SRCS"
|