]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
auth_debug_passwords: If password is correct but scheme is wrong, try to detect and...
authorTimo Sirainen <tss@iki.fi>
Thu, 31 Dec 2009 20:15:54 +0000 (15:15 -0500)
committerTimo Sirainen <tss@iki.fi>
Thu, 31 Dec 2009 20:15:54 +0000 (15:15 -0500)
--HG--
branch : HEAD

src/auth/auth-request.c
src/auth/password-scheme.c
src/auth/password-scheme.h

index 464a49f43b71ee8fab5b14367f04081f7a03e780..6d1a90d76cbba3598d5304ec459725f722010c50 100644 (file)
@@ -1275,6 +1275,33 @@ void auth_request_proxy_finish(struct auth_request *request, bool success)
        auth_stream_reply_remove(request->extra_fields, "destuser");
 }
 
+static void log_password_failure(struct auth_request *request,
+                                const char *plain_password,
+                                const char *crypted_password,
+                                const char *scheme, const char *user,
+                                const char *subsystem)
+{
+       static bool scheme_ok = FALSE;
+       string_t *str = t_str_new(256);
+       const char *working_scheme;
+
+       str_printfa(str, "%s(%s) != '%s'", scheme,
+                   plain_password, crypted_password);
+
+       if (!scheme_ok) {
+               /* perhaps the scheme is wrong - see if we can find
+                  a working one */
+               working_scheme = password_scheme_detect(plain_password,
+                                                       crypted_password, user);
+               if (working_scheme != NULL) {
+                       str_printfa(str, ", try %s scheme instead",
+                                   working_scheme);
+               }
+       }
+
+       auth_request_log_debug(request, subsystem, "%s", str_c(str));
+}
+
 int auth_request_password_verify(struct auth_request *request,
                                 const char *plain_password,
                                 const char *crypted_password,
@@ -1323,12 +1350,12 @@ int auth_request_password_verify(struct auth_request *request,
        if (ret == 0) {
                auth_request_log_info(request, subsystem,
                                      "Password mismatch");
-               if (request->auth->set->debug_passwords) {
-                       auth_request_log_debug(request, subsystem,
-                                              "%s(%s) != '%s'", scheme,
-                                              plain_password,
-                                              crypted_password);
-               }
+               if (request->auth->set->debug_passwords) T_BEGIN {
+                       log_password_failure(request, plain_password,
+                                            crypted_password, scheme,
+                                            request->original_username,
+                                            subsystem);
+               } T_END;
        }
        return ret;
 }
index 30f6a02e0fa82bef8b1aede7652fd415f1fbe4bb..abdb29c099ff591ca19ac66d66a0a490f3b57463 100644 (file)
@@ -251,6 +251,31 @@ bool password_scheme_is_alias(const char *scheme1, const char *scheme2)
                s1->password_generate == s2->password_generate;
 }
 
+const char *
+password_scheme_detect(const char *plain_password, const char *crypted_password,
+                      const char *user)
+{
+       const struct password_scheme *const *schemes;
+       unsigned int i, count;
+       const unsigned char *raw_password;
+       size_t raw_password_size;
+
+       if (strncmp(crypted_password, "$1$", 3) == 0)
+               return "MD5-CRYPT";
+
+       schemes = array_get(&password_schemes, &count);
+       for (i = 0; i < count; i++) {
+               if (password_decode(crypted_password, schemes[i]->name,
+                                   &raw_password, &raw_password_size) <= 0)
+                       continue;
+
+               if (password_verify(plain_password, user, schemes[i]->name,
+                                   raw_password, raw_password_size) > 0)
+                       return schemes[i]->name;
+       }
+       return NULL;
+}
+
 static bool
 crypt_verify(const char *plaintext, const char *user ATTR_UNUSED,
             const unsigned char *raw_password, size_t size)
index ee40c0ed13f0f3b557de2eb4d1b9f4c5965fa207..8527d874c078d995ac22be4c5fd374ffbf65aa4e 100644 (file)
@@ -53,6 +53,12 @@ bool password_generate_encoded(const char *plaintext, const char *user,
 /* Returns TRUE if schemes are equivalent. */
 bool password_scheme_is_alias(const char *scheme1, const char *scheme2);
 
+/* Try to detect in which scheme crypted password is. Returns the scheme name
+   or NULL if nothing was found. */
+const char *
+password_scheme_detect(const char *plain_password, const char *crypted_password,
+                      const char *user);
+
 void password_scheme_register(const struct password_scheme *scheme);
 void password_scheme_unregister(const struct password_scheme *scheme);