]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imap-login: Use [resp-codes] to figure out when to replace remote's auth failed messa...
authorTimo Sirainen <tss@iki.fi>
Tue, 7 Apr 2009 20:41:23 +0000 (16:41 -0400)
committerTimo Sirainen <tss@iki.fi>
Tue, 7 Apr 2009 20:41:23 +0000 (16:41 -0400)
--HG--
branch : HEAD

src/imap-login/client-authenticate.c
src/imap-login/client-authenticate.h
src/imap-login/imap-proxy.c
src/pop3-login/pop3-proxy.c

index 995b3abe7115c3dc3128813c641a646ed24825a9..47b95069c8d5278808448aa5ec244feb8ed7efb9 100644 (file)
@@ -21,9 +21,6 @@
 #define AUTH_FAILURE_DELAY_INCREASE_MSECS 5000
 
 #define IMAP_SERVICE_NAME "imap"
-#define IMAP_AUTH_FAILED_MSG "["IMAP_RESP_CODE_AUTHFAILED"] "AUTH_FAILED_MSG
-#define IMAP_AUTHZ_FAILED_MSG \
-       "["IMAP_RESP_CODE_AUTHZFAILED"] Authorization failed"
 
 const char *client_authenticate_get_capabilities(bool secured)
 {
index c18359a51a19f31c55cae06c704007765ddaa699..9932aefa92fd783e22c9f761a2d5d70173bf8c70 100644 (file)
@@ -1,6 +1,13 @@
 #ifndef CLIENT_AUTHENTICATE_H
 #define CLIENT_AUTHENTICATE_H
 
+struct imap_arg;
+
+#define IMAP_AUTH_FAILED_MSG \
+       "["IMAP_RESP_CODE_AUTHFAILED"] "AUTH_FAILED_MSG
+#define IMAP_AUTHZ_FAILED_MSG \
+       "["IMAP_RESP_CODE_AUTHZFAILED"] Authorization failed"
+
 const char *client_authenticate_get_capabilities(bool secured);
 
 int cmd_login(struct imap_client *client, const struct imap_arg *args);
index bfc793f5d85b3b0f68d3f0c02a223cc3aa86326e..2b7667d4431b0f89f437a2c01649ecae3eb01824 100644 (file)
@@ -9,6 +9,7 @@
 #include "str-sanitize.h"
 #include "safe-memset.h"
 #include "client.h"
+#include "client-authenticate.h"
 #include "imap-resp-code.h"
 #include "imap-quote.h"
 #include "imap-proxy.h"
@@ -186,21 +187,7 @@ static int proxy_input_line(struct imap_client *client,
                client_destroy_success(client, str_c(str));
                return 1;
        } else if (strncmp(line, "L ", 2) == 0) {
-               /* If the backend server isn't Dovecot, the error message may
-                  be different from Dovecot's "user doesn't exist" error. This
-                  would allow an attacker to find out what users exist in the
-                  system.
-
-                  The optimal way to handle this would be to replace the
-                  backend's "password failed" error message with Dovecot's
-                  AUTH_FAILED_MSG, but this would require a new setting and
-                  the sysadmin to actually bother setting it properly.
-
-                  So for now we'll just forward the error message. This
-                  shouldn't be a real problem since of course everyone will
-                  be using only Dovecot as their backend :) */
-               client_send_tagline(client, line + 2);
-
+               line += 2;
                if (login_settings->verbose_auth) {
                        str = t_str_new(128);
                        str_printfa(str, "proxy(%s): Login failed to %s:%u",
@@ -218,12 +205,35 @@ static int proxy_input_line(struct imap_client *client,
                                            client->proxy_master_user);
                        }
                        str_append(str, ": ");
-                       if (strncasecmp(line + 2, "NO ", 3) == 0)
-                               str_append(str, line + 2 + 3);
+                       if (strncasecmp(line, "NO ", 3) == 0)
+                               str_append(str, line + 3);
                        else
-                               str_append(str, line + 2);
+                               str_append(str, line);
                        i_info("%s", str_c(str));
                }
+#define STR_NO_IMAP_RESP_CODE_AUTHFAILED "NO ["IMAP_RESP_CODE_AUTHFAILED"]"
+               if (strncmp(line, STR_NO_IMAP_RESP_CODE_AUTHFAILED,
+                           strlen(STR_NO_IMAP_RESP_CODE_AUTHFAILED)) == 0) {
+                       /* the remote sent a generic "authentication failed"
+                          error. replace it with our one, so that in case
+                          the remote is sending a different error message
+                          an attacker can't find out what users exist in
+                          the system. */
+                       line = "NO "IMAP_AUTH_FAILED_MSG;
+               } else if (strncmp(line, "NO [", 4) == 0) {
+                       /* remote sent some other resp-code. forward it. */
+               } else {
+                       /* there was no [resp-code], so remote isn't Dovecot
+                          v1.2+. we could either forward the line as-is and
+                          leak information about what users exist in this
+                          system, or we could hide other errors than password
+                          failures. since other errors are pretty rare,
+                          it's safer to just hide them. they're still
+                          available in logs though. */
+                       line = "NO "IMAP_AUTH_FAILED_MSG;
+               }
+               client_send_tagline(client, line);
+
                proxy_failed(client, FALSE);
                return -1;
        } else {
index 8c2741890f04185a26b13d039881f1dbcfa4283e..9cb77e2026828af4205c96fa91fff43ae7198bc0 100644 (file)
@@ -137,8 +137,21 @@ static int proxy_input_line(struct pop3_client *client,
                return 1;
        }
 
-       /* Login failed. Pass through the error message to client
-          (see imap-proxy code for potential problems with this) */
+       /* Login failed. Pass through the error message to client.
+
+          If the backend server isn't Dovecot, the error message may
+          be different from Dovecot's "user doesn't exist" error. This
+          would allow an attacker to find out what users exist in the
+          system.
+
+          The optimal way to handle this would be to replace the
+          backend's "password failed" error message with Dovecot's
+          AUTH_FAILED_MSG, but this would require a new setting and
+          the sysadmin to actually bother setting it properly.
+
+          So for now we'll just forward the error message. This
+          shouldn't be a real problem since of course everyone will
+          be using only Dovecot as their backend :) */
        if (strncmp(line, "-ERR ", 5) != 0)
                client_send_line(client, "-ERR "AUTH_FAILED_MSG);
        else