Mercurial > hg > nginx-mail
diff src/mail/ngx_mail_proxy_module.c @ 400:f1e2fab7a46c
Mail: smtp proxy without authentication.
Activated by auth method "unauth" in smtp_auth directive.
Waits for MAIL FROM and first RCPT TO from client, asks auth_http for
backend with additional headers Auth-SMTP-Helo, Auth-SMTP-From,
Auth-SMTP-To, and establishes connection to backend.
Auth-SMTP-From/To currently contain full command (e.g. "mail from: <>"),
this may change in future.
The functionality was designed to take off load from real smtp servers.
Additionally it may be used to implement pop-before-smtp authentication
(but dont do it unless you really need it - use real auth instead).
Current bug-features:
- If only "unauth" method activated in config, other methods (e.g. plain,
login) not advertised but accepted. Make sure your auth server handles
this gracefully.
- If backend server returns error on MAIL FROM / RCPT TO command while
proxy tunnel setup, nginx will close connection to client with 4xx
error. One may use proxy_pass_error_message directive to pass original
error message to client.
- Syntax of MAIL FROM / RCPT TO commands from client isn't checked.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Sun, 22 Jul 2007 23:55:12 +0000 |
parents | 2ceaee987f37 |
children | 481e8f936572 |
line wrap: on
line diff
--- a/src/mail/ngx_mail_proxy_module.c +++ b/src/mail/ngx_mail_proxy_module.c @@ -102,7 +102,8 @@ ngx_module_t ngx_mail_proxy_module = { }; -static u_char smtp_ok[] = "235 2.0.0 OK" CRLF; +static u_char smtp_auth_ok[] = "235 2.0.0 OK" CRLF; +static u_char smtp_ok[] = "250 2.0.0 OK" CRLF; void @@ -516,11 +517,13 @@ ngx_mail_proxy_smtp_handler(ngx_event_t p = ngx_cpymem(p, cscf->server_name.data, cscf->server_name.len); *p++ = CR; *p = LF; - s->mail_state = pcf->xclient ? ngx_smtp_helo: ngx_smtp_noxclient; + s->mail_state = pcf->xclient ? ngx_smtp_helo_xclient : + s->auth_method == NGX_MAIL_AUTH_UNAUTH ? + ngx_smtp_helo_from : ngx_smtp_helo; break; - case ngx_smtp_helo: + case ngx_smtp_helo_xclient: ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy send xclient"); @@ -537,31 +540,77 @@ ngx_mail_proxy_smtp_handler(ngx_event_t return; } - if (s->smtp_helo.len) { - line.len = ngx_sprintf(line.data, - "XCLIENT PROTO=%sSMTP HELO=%V ADDR=%V LOGIN=%V " - "NAME=[UNAVAILABLE]" CRLF, - (s->esmtp ? "E" : ""), &s->smtp_helo, - &s->connection->addr_text, &s->login) - - line.data; - } else { - line.len = ngx_sprintf(line.data, - "XCLIENT PROTO=SMTP ADDR=%V LOGIN=%V " - "NAME=[UNAVAILABLE]" CRLF, - &s->connection->addr_text, &s->login) - - line.data; + line.len = ngx_sprintf(line.data, + "XCLIENT PROTO=%sSMTP%s%V ADDR=%V%s%V " + "NAME=[UNAVAILABLE]" CRLF, + (s->esmtp ? "E" : ""), + (s->smtp_helo.len ? " HELO=" : ""), &s->smtp_helo, + &s->connection->addr_text, + (s->login.len ? " LOGIN=" : ""), &s->login) + - line.data; + + s->mail_state = s->auth_method == NGX_MAIL_AUTH_UNAUTH ? + ngx_smtp_xclient_from : ngx_smtp_xclient; + + break; + + case ngx_smtp_helo_from: + case ngx_smtp_xclient_from: + 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 = s->smtp_from.len + sizeof(CRLF) - 1; + line.data = ngx_palloc(c->pool, line.len); + if (line.data == NULL) { + ngx_mail_proxy_internal_server_error(s); + return; } - s->mail_state = ngx_smtp_xclient; + p = ngx_cpymem(line.data, s->smtp_from.data, s->smtp_from.len); + *p++ = CR; *p = LF; + + s->mail_state = ngx_smtp_from; + break; - case ngx_smtp_noxclient: + case ngx_smtp_from: + 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 = s->smtp_to.len + sizeof(CRLF) - 1; + 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, s->smtp_to.data, s->smtp_to.len); + *p++ = CR; *p = LF; + + s->mail_state = ngx_smtp_to; + + break; + + case ngx_smtp_helo: case ngx_smtp_xclient: + case ngx_smtp_to: - ngx_memcpy(s->proxy->buffer->start, smtp_ok, sizeof(smtp_ok) - 1); + if (s->auth_method == NGX_MAIL_AUTH_UNAUTH) { + ngx_memcpy(s->proxy->buffer->start, smtp_ok, sizeof(smtp_ok) - 1); + s->proxy->buffer->last = s->proxy->buffer->start + + sizeof(smtp_ok) - 1; + } else { + ngx_memcpy(s->proxy->buffer->start, smtp_auth_ok, + sizeof(smtp_auth_ok) - 1); + s->proxy->buffer->last = s->proxy->buffer->start + + sizeof(smtp_auth_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; @@ -701,15 +750,24 @@ ngx_mail_proxy_read_response(ngx_mail_se switch (state) { case ngx_smtp_helo: - case ngx_smtp_noxclient: + case ngx_smtp_helo_from: + case ngx_smtp_helo_xclient: + case ngx_smtp_from: + case ngx_smtp_to: if (p[0] == '2' && p[1] == '5' && p[2] == '0') { return NGX_OK; } break; case ngx_smtp_start: + if (p[0] == '2' && p[1] == '2' && p[2] == '0') { + return NGX_OK; + } + break; + case ngx_smtp_xclient: - if (p[0] == '2' && p[1] == '2' && p[2] == '0') { + case ngx_smtp_xclient_from: + if (p[0] == '2' && (p[1] == '2' || p[1] == '5') && p[2] == '0') { return NGX_OK; } break;