[PATCH] Mail: allow auth to the proxy without auth to the backend

Arnout Engelen nginx at bzzt.net
Tue Sep 19 10:28:49 UTC 2023


# HG changeset patch
# User Arnout Engelen <arnout at bzzt.net>
# Date 1695027670 -7200
#      Mon Sep 18 11:01:10 2023 +0200
# Node ID 9606e589b9537495c0457383048ac6888be0e7b4
# Parent  daf8f5ba23d8e9955b22782d945f9c065f4b6baa
Mail: allow auth to the proxy without auth to the backend

Currently, when the client authenticates itself to the nginx
mail proxy, the mail proxy also authenticates itself to the
backend.

I encountered a situation where I wanted the proxy to require
authentication, and forward the mail to a (local/firewalled)
mailserver that does not have authentication configured. I
created the patch below to support that.

I'm providing this patch primarily for feedback at this point:
while it does work for my scenario and pass the nginx-tests,
it likely needs additional cleanup and testing. I'd like your
thoughs on whether this change makes sense in the first place,
and whether this is generally a reasonable approach - if so I'll
clean up the patch further.

My approach is to allow the authentication server to return a
'Auth-Method: none' header, in which case the proxy will not
attempt to authenticate to the backend but instead wait for
the 'MAIL FROM' from the client.

You'll notice I've added a 'proxy_auth_method'. The reason I didn't
overwrite 'auth_method' is that 'auth_method' is also used to determine
whether to confirm the authentication to the client. Is that acceptable
from a binary compatibility perspective?

Looking forward to hearing your thoughts!

diff -r daf8f5ba23d8 -r 9606e589b953 src/mail/ngx_mail.h
--- a/src/mail/ngx_mail.h	Fri Sep 01 20:31:46 2023 +0400
+++ b/src/mail/ngx_mail.h	Mon Sep 18 11:01:10 2023 +0200
@@ -212,6 +212,7 @@
     unsigned                starttls:1;
     unsigned                esmtp:1;
     unsigned                auth_method:3;
+    unsigned                proxy_auth_method:3;
     unsigned                auth_wait:1;
 
     ngx_str_t               login;
diff -r daf8f5ba23d8 -r 9606e589b953 src/mail/ngx_mail_auth_http_module.c
--- a/src/mail/ngx_mail_auth_http_module.c	Fri Sep 01 20:31:46 2023 +0400
+++ b/src/mail/ngx_mail_auth_http_module.c	Mon Sep 18 11:01:10 2023 +0200
@@ -677,6 +677,23 @@
                 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 */
 
             continue;
@@ -883,6 +900,7 @@
 
         s->mail_state = 0;
         s->auth_method = NGX_MAIL_AUTH_PLAIN;
+        s->proxy_auth_method = NGX_MAIL_AUTH_PLAIN;
 
         c->log->action = "in auth state";
 
diff -r daf8f5ba23d8 -r 9606e589b953 src/mail/ngx_mail_handler.c
--- a/src/mail/ngx_mail_handler.c	Fri Sep 01 20:31:46 2023 +0400
+++ b/src/mail/ngx_mail_handler.c	Mon Sep 18 11:01:10 2023 +0200
@@ -714,6 +714,7 @@
                    "mail auth cram-md5: \"%V\" \"%V\"", &s->login, &s->passwd);
 
     s->auth_method = NGX_MAIL_AUTH_CRAM_MD5;
+    s->proxy_auth_method = NGX_MAIL_AUTH_CRAM_MD5;
 
     return NGX_DONE;
 }
@@ -748,6 +749,7 @@
                    "mail auth external: \"%V\"", &s->login);
 
     s->auth_method = NGX_MAIL_AUTH_EXTERNAL;
+    s->proxy_auth_method = NGX_MAIL_AUTH_EXTERNAL;
 
     return NGX_DONE;
 }
diff -r daf8f5ba23d8 -r 9606e589b953 src/mail/ngx_mail_pop3_handler.c
--- a/src/mail/ngx_mail_pop3_handler.c	Fri Sep 01 20:31:46 2023 +0400
+++ b/src/mail/ngx_mail_pop3_handler.c	Mon Sep 18 11:01:10 2023 +0200
@@ -464,6 +464,7 @@
                    "pop3 apop: \"%V\" \"%V\"", &s->login, &s->passwd);
 
     s->auth_method = NGX_MAIL_AUTH_APOP;
+    s->proxy_auth_method = NGX_MAIL_AUTH_APOP;
 
     return NGX_DONE;
 }
diff -r daf8f5ba23d8 -r 9606e589b953 src/mail/ngx_mail_proxy_module.c
--- a/src/mail/ngx_mail_proxy_module.c	Fri Sep 01 20:31:46 2023 +0400
+++ b/src/mail/ngx_mail_proxy_module.c	Mon Sep 18 11:01:10 2023 +0200
@@ -605,8 +605,12 @@
         if (pcf->xclient) {
             s->mail_state = ngx_smtp_helo_xclient;
 
-        } else if (s->auth_method == NGX_MAIL_AUTH_NONE) {
-            s->mail_state = ngx_smtp_helo_from;
+        } else if (s->proxy_auth_method == NGX_MAIL_AUTH_NONE) {
+            if (s->smtp_from.len) {
+                s->mail_state = ngx_smtp_helo_from;
+            } else {
+                s->mail_state = ngx_smtp_helo;
+            }
 
         } else if (pcf->smtp_auth) {
             s->mail_state = ngx_smtp_helo_auth;
@@ -667,8 +671,12 @@
         if (s->smtp_helo.len) {
             s->mail_state = ngx_smtp_xclient_helo;
 
-        } else if (s->auth_method == NGX_MAIL_AUTH_NONE) {
-            s->mail_state = ngx_smtp_xclient_from;
+        } else if (s->proxy_auth_method == NGX_MAIL_AUTH_NONE) {
+            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) {
             s->mail_state = ngx_smtp_xclient_auth;
@@ -700,8 +708,12 @@
 
         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;
+        if (s->proxy_auth_method == NGX_MAIL_AUTH_NONE) {
+            if (s->smtp_from.len) {
+                s->mail_state = ngx_smtp_helo_from;
+            } else {
+                s->mail_state = ngx_smtp_helo;
+            }
 
         } else if (pcf->smtp_auth) {
             s->mail_state = ngx_smtp_helo_auth;
diff -r daf8f5ba23d8 -r 9606e589b953 src/mail/ngx_mail_smtp_handler.c
--- a/src/mail/ngx_mail_smtp_handler.c	Fri Sep 01 20:31:46 2023 +0400
+++ b/src/mail/ngx_mail_smtp_handler.c	Mon Sep 18 11:01:10 2023 +0200
@@ -820,6 +820,7 @@
                    "smtp rcpt to:\"%V\"", &s->smtp_to);
 
     s->auth_method = NGX_MAIL_AUTH_NONE;
+    s->proxy_auth_method = NGX_MAIL_AUTH_NONE;
 
     return NGX_DONE;
 }


More information about the nginx-devel mailing list