mail proxy: allow dynamically deciding whether to use SMTP authentication to the backend

Adds a `Auth-Method` as a valid response header for the HTTP
authentication server. When set to 'None', the proxy will not
attempt to perform SMTP authentication to the backend, even
when `proxy_smtp_auth` is `on`. This is useful when some backends
require authentication, while others don't allow it.

While this has been tested and works, the patch was created with an
incomplete understanding of the `proxy_smtp_auth` option, so it might
not be the cleanest implementation. Sharing as 'draft' for now until
I find the time to set up a better test environment and revise the
patch. Any feedback/pointers/etc welcome :)

Fixes #155
This commit is contained in:
Arnout Engelen 2024-09-10 18:27:49 +02:00
parent 00637cce36
commit 501435f6cd
No known key found for this signature in database
GPG Key ID: 061107B0F74A6DAA
6 changed files with 41 additions and 6 deletions

View File

@ -212,6 +212,7 @@ typedef struct {
unsigned starttls:1; unsigned starttls:1;
unsigned esmtp:1; unsigned esmtp:1;
unsigned auth_method:3; unsigned auth_method:3;
unsigned proxy_auth_method:3;
unsigned auth_wait:1; unsigned auth_wait:1;
ngx_str_t login; ngx_str_t login;

View File

@ -677,6 +677,23 @@ ngx_mail_auth_http_process_headers(ngx_mail_session_t *s,
continue; continue;
} }
if (len == sizeof("Auth-Method") - 1
&& ngx_strncasecmp(ctx->header_name_start,
(u_char *) "Auth-Method",
sizeof("Auth-Method") - 1)
== 0)
{
int value_len = ctx->header_end - ctx->header_start;
if (value_len == sizeof("none") - 1
&& ngx_strncasecmp(ctx->header_start,
(u_char *) "none",
sizeof("none") - 1)
== 0)
{
s->proxy_auth_method = NGX_MAIL_AUTH_NONE;
}
}
/* ignore other headers */ /* ignore other headers */
continue; continue;
@ -883,6 +900,7 @@ ngx_mail_auth_sleep_handler(ngx_event_t *rev)
s->mail_state = 0; s->mail_state = 0;
s->auth_method = NGX_MAIL_AUTH_PLAIN; s->auth_method = NGX_MAIL_AUTH_PLAIN;
s->proxy_auth_method = NGX_MAIL_AUTH_PLAIN;
c->log->action = "in auth state"; c->log->action = "in auth state";

View File

@ -714,6 +714,7 @@ ngx_mail_auth_cram_md5(ngx_mail_session_t *s, ngx_connection_t *c)
"mail auth cram-md5: \"%V\" \"%V\"", &s->login, &s->passwd); "mail auth cram-md5: \"%V\" \"%V\"", &s->login, &s->passwd);
s->auth_method = NGX_MAIL_AUTH_CRAM_MD5; s->auth_method = NGX_MAIL_AUTH_CRAM_MD5;
s->proxy_auth_method = NGX_MAIL_AUTH_CRAM_MD5;
return NGX_DONE; return NGX_DONE;
} }
@ -748,6 +749,7 @@ ngx_mail_auth_external(ngx_mail_session_t *s, ngx_connection_t *c,
"mail auth external: \"%V\"", &s->login); "mail auth external: \"%V\"", &s->login);
s->auth_method = NGX_MAIL_AUTH_EXTERNAL; s->auth_method = NGX_MAIL_AUTH_EXTERNAL;
s->proxy_auth_method = NGX_MAIL_AUTH_EXTERNAL;
return NGX_DONE; return NGX_DONE;
} }

View File

@ -464,6 +464,7 @@ ngx_mail_pop3_apop(ngx_mail_session_t *s, ngx_connection_t *c)
"pop3 apop: \"%V\" \"%V\"", &s->login, &s->passwd); "pop3 apop: \"%V\" \"%V\"", &s->login, &s->passwd);
s->auth_method = NGX_MAIL_AUTH_APOP; s->auth_method = NGX_MAIL_AUTH_APOP;
s->proxy_auth_method = NGX_MAIL_AUTH_APOP;
return NGX_DONE; return NGX_DONE;
} }

View File

@ -605,8 +605,12 @@ ngx_mail_proxy_smtp_handler(ngx_event_t *rev)
if (pcf->xclient) { if (pcf->xclient) {
s->mail_state = ngx_smtp_helo_xclient; s->mail_state = ngx_smtp_helo_xclient;
} else if (s->auth_method == NGX_MAIL_AUTH_NONE) { } else if (s->proxy_auth_method == NGX_MAIL_AUTH_NONE) {
s->mail_state = ngx_smtp_helo_from; if (s->smtp_from.len) {
s->mail_state = ngx_smtp_helo_from;
} else {
s->mail_state = ngx_smtp_helo;
}
} else if (pcf->smtp_auth) { } else if (pcf->smtp_auth) {
s->mail_state = ngx_smtp_helo_auth; s->mail_state = ngx_smtp_helo_auth;
@ -667,8 +671,12 @@ ngx_mail_proxy_smtp_handler(ngx_event_t *rev)
if (s->smtp_helo.len) { if (s->smtp_helo.len) {
s->mail_state = ngx_smtp_xclient_helo; s->mail_state = ngx_smtp_xclient_helo;
} else if (s->auth_method == NGX_MAIL_AUTH_NONE) { } else if (s->proxy_auth_method == NGX_MAIL_AUTH_NONE) {
s->mail_state = ngx_smtp_xclient_from; if (s->smtp_from.len) {
s->mail_state = ngx_smtp_xclient_from;
} else {
s->mail_state = ngx_smtp_xclient_helo;
}
} else if (pcf->smtp_auth) { } else if (pcf->smtp_auth) {
s->mail_state = ngx_smtp_xclient_auth; s->mail_state = ngx_smtp_xclient_auth;
@ -700,8 +708,12 @@ ngx_mail_proxy_smtp_handler(ngx_event_t *rev)
pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module);
if (s->auth_method == NGX_MAIL_AUTH_NONE) { if (s->proxy_auth_method == NGX_MAIL_AUTH_NONE) {
s->mail_state = ngx_smtp_helo_from; if (s->smtp_from.len) {
s->mail_state = ngx_smtp_helo_from;
} else {
s->mail_state = ngx_smtp_helo;
}
} else if (pcf->smtp_auth) { } else if (pcf->smtp_auth) {
s->mail_state = ngx_smtp_helo_auth; s->mail_state = ngx_smtp_helo_auth;

View File

@ -820,6 +820,7 @@ ngx_mail_smtp_rcpt(ngx_mail_session_t *s, ngx_connection_t *c)
"smtp rcpt to:\"%V\"", &s->smtp_to); "smtp rcpt to:\"%V\"", &s->smtp_to);
s->auth_method = NGX_MAIL_AUTH_NONE; s->auth_method = NGX_MAIL_AUTH_NONE;
s->proxy_auth_method = NGX_MAIL_AUTH_NONE;
return NGX_DONE; return NGX_DONE;
} }