dovecot-1.2: auth_debug_passwords: If password is correct but sc...

dovecot at dovecot.org dovecot at dovecot.org
Thu Dec 31 22:13:21 EET 2009


details:   http://hg.dovecot.org/dovecot-1.2/rev/b48a4af4248d
changeset: 9523:b48a4af4248d
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Dec 31 15:13:15 2009 -0500
description:
auth_debug_passwords: If password is correct but scheme is wrong, try to detect and log it.

diffstat:

3 files changed, 64 insertions(+), 6 deletions(-)
src/auth/auth-request.c    |   39 +++++++++++++++++++++++++++++++++------
src/auth/password-scheme.c |   25 +++++++++++++++++++++++++
src/auth/password-scheme.h |    6 ++++++

diffs (107 lines):

diff -r 029c3afcfbd0 -r b48a4af4248d src/auth/auth-request.c
--- a/src/auth/auth-request.c	Tue Dec 29 17:19:16 2009 -0500
+++ b/src/auth/auth-request.c	Thu Dec 31 15:13:15 2009 -0500
@@ -1272,6 +1272,33 @@ void auth_request_proxy_finish(struct au
 	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,
@@ -1320,12 +1347,12 @@ int auth_request_password_verify(struct 
 	if (ret == 0) {
 		auth_request_log_info(request, subsystem,
 				      "Password mismatch");
-		if (request->auth->verbose_debug_passwords) {
-			auth_request_log_debug(request, subsystem,
-					       "%s(%s) != '%s'", scheme,
-					       plain_password,
-					       crypted_password);
-		}
+		if (request->auth->verbose_debug_passwords) T_BEGIN {
+			log_password_failure(request, plain_password,
+					     crypted_password, scheme,
+					     request->original_username,
+					     subsystem);
+		} T_END;
 	}
 	return ret;
 }
diff -r 029c3afcfbd0 -r b48a4af4248d src/auth/password-scheme.c
--- a/src/auth/password-scheme.c	Tue Dec 29 17:19:16 2009 -0500
+++ b/src/auth/password-scheme.c	Thu Dec 31 15:13:15 2009 -0500
@@ -249,6 +249,31 @@ bool password_scheme_is_alias(const char
 	/* if they've the same generate function, they're equivalent */
 	return s1 != NULL && s2 != NULL &&
 		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
diff -r 029c3afcfbd0 -r b48a4af4248d src/auth/password-scheme.h
--- a/src/auth/password-scheme.h	Tue Dec 29 17:19:16 2009 -0500
+++ b/src/auth/password-scheme.h	Thu Dec 31 15:13:15 2009 -0500
@@ -53,6 +53,12 @@ bool password_generate_encoded(const cha
 /* 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);
 


More information about the dovecot-cvs mailing list