changeset 10585:941511db13c3 HEAD

Added auth_verbose_passwords = no|plain|sha1.
author Timo Sirainen <tss@iki.fi>
date Tue, 26 Jan 2010 13:40:01 +0200
parents 667fea930ec3
children e1d112ef2e4c
files doc/example-config/conf.d/logging.conf src/auth/auth-request.c src/auth/auth-request.h src/auth/auth-settings.c src/auth/auth-settings.h src/auth/passdb-bsdauth.c src/auth/passdb-sia.c
diffstat 7 files changed, 61 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/doc/example-config/conf.d/logging.conf	Mon Jan 25 20:40:25 2010 +0200
+++ b/doc/example-config/conf.d/logging.conf	Tue Jan 26 13:40:01 2010 +0200
@@ -23,6 +23,11 @@
 # Log unsuccessful authentication attempts and the reasons why they failed.
 #auth_verbose = no
 
+# In case of password mismatches, log the attempted password. Valid values are
+# no, plain and sha1. sha1 can be useful for detecting brute force password
+# attempts vs. user simply trying the same password over and over again.
+#auth_verbose_passwords = no
+
 # Even more verbose logging for debugging purposes. Shows for example SQL
 # queries.
 #auth_debug = no
--- a/src/auth/auth-request.c	Mon Jan 25 20:40:25 2010 +0200
+++ b/src/auth/auth-request.c	Tue Jan 26 13:40:01 2010 +0200
@@ -4,6 +4,7 @@
 #include "ioloop.h"
 #include "buffer.h"
 #include "hash.h"
+#include "sha1.h"
 #include "hex-binary.h"
 #include "str.h"
 #include "safe-memset.h"
@@ -23,6 +24,9 @@
 #include <stdlib.h>
 #include <sys/stat.h>
 
+static void get_log_prefix(string_t *str, struct auth_request *auth_request,
+			   const char *subsystem);
+
 struct auth_request *
 auth_request_new(struct auth *auth, const struct mech_module *mech,
 		 mech_callback_t *callback, void *context)
@@ -1302,6 +1306,38 @@
 	auth_request_log_debug(request, subsystem, "%s", str_c(str));
 }
 
+void auth_request_log_password_mismatch(struct auth_request *request,
+					const char *subsystem)
+{
+	string_t *str;
+	const char *log_type = request->auth->set->verbose_passwords;
+
+	if (strcmp(log_type, "no") == 0) {
+		auth_request_log_info(request, subsystem, "Password mismatch");
+		return;
+	}
+
+	str = t_str_new(128);
+	get_log_prefix(str, request, subsystem);
+	str_append(str, "Password mismatch ");
+
+	if (strcmp(log_type, "plain") == 0) {
+		str_printfa(str, "(given password: %s)",
+			    request->mech_password);
+	} else if (strcmp(log_type, "sha1") == 0) {
+		unsigned char sha1[SHA1_RESULTLEN];
+
+		sha1_get_digest(request->mech_password,
+				strlen(request->mech_password), sha1);
+		str_printfa(str, "(SHA1 of given password: %s)",
+			    binary_to_hex(sha1, sizeof(sha1)));
+	} else {
+		i_unreached();
+	}
+
+	i_info("%s", str_c(str));
+}
+
 int auth_request_password_verify(struct auth_request *request,
 				 const char *plain_password,
 				 const char *crypted_password,
@@ -1348,8 +1384,7 @@
 			      scheme, raw_password, raw_password_size);
 	i_assert(ret >= 0);
 	if (ret == 0) {
-		auth_request_log_info(request, subsystem,
-				      "Password mismatch");
+		auth_request_log_password_mismatch(request, subsystem);
 		if (request->auth->set->debug_passwords) T_BEGIN {
 			log_password_failure(request, plain_password,
 					     crypted_password, scheme,
@@ -1437,15 +1472,12 @@
 	return tab;
 }
 
-static const char * ATTR_FORMAT(3, 0)
-get_log_str(struct auth_request *auth_request, const char *subsystem,
-	    const char *format, va_list va)
+static void get_log_prefix(string_t *str, struct auth_request *auth_request,
+			   const char *subsystem)
 {
 #define MAX_LOG_USERNAME_LEN 64
 	const char *ip;
-	string_t *str;
 
-	str = t_str_new(128);
 	str_append(str, subsystem);
 	str_append_c(str, '(');
 
@@ -1464,6 +1496,16 @@
 	if (auth_request->requested_login_user != NULL)
 		str_append(str, ",master");
 	str_append(str, "): ");
+}
+
+static const char * ATTR_FORMAT(3, 0)
+get_log_str(struct auth_request *auth_request, const char *subsystem,
+	    const char *format, va_list va)
+{
+	string_t *str;
+
+	str = t_str_new(128);
+	get_log_prefix(str, auth_request, subsystem);
 	str_vprintfa(str, format, va);
 	return str_c(str);
 }
--- a/src/auth/auth-request.h	Mon Jan 25 20:40:25 2010 +0200
+++ b/src/auth/auth-request.h	Tue Jan 26 13:40:01 2010 +0200
@@ -160,6 +160,8 @@
 					  const char *const *values);
 void auth_request_proxy_finish(struct auth_request *request, bool success);
 
+void auth_request_log_password_mismatch(struct auth_request *request,
+					const char *subsystem);
 int auth_request_password_verify(struct auth_request *request,
 				 const char *plain_password,
 				 const char *crypted_password,
--- a/src/auth/auth-settings.c	Mon Jan 25 20:40:25 2010 +0200
+++ b/src/auth/auth-settings.c	Tue Jan 26 13:40:01 2010 +0200
@@ -171,6 +171,7 @@
 	DEF(SET_BOOL, verbose),
 	DEF(SET_BOOL, debug),
 	DEF(SET_BOOL, debug_passwords),
+	DEF(SET_ENUM, verbose_passwords),
 	DEF(SET_BOOL, ssl_require_client_cert),
 	DEF(SET_BOOL, ssl_username_from_cert),
 	DEF(SET_BOOL, use_winbind),
@@ -203,6 +204,7 @@
 	.verbose = FALSE,
 	.debug = FALSE,
 	.debug_passwords = FALSE,
+	.verbose_passwords = "no:plain:sha1",
 	.ssl_require_client_cert = FALSE,
 	.ssl_username_from_cert = FALSE,
 	.use_winbind = FALSE,
--- a/src/auth/auth-settings.h	Mon Jan 25 20:40:25 2010 +0200
+++ b/src/auth/auth-settings.h	Tue Jan 26 13:40:01 2010 +0200
@@ -34,6 +34,7 @@
 	unsigned int failure_delay;
 
 	bool verbose, debug, debug_passwords;
+	const char *verbose_passwords;
 	bool ssl_require_client_cert;
 	bool ssl_username_from_cert;
 	bool use_winbind;
--- a/src/auth/passdb-bsdauth.c	Mon Jan 25 20:40:25 2010 +0200
+++ b/src/auth/passdb-bsdauth.c	Tue Jan 26 13:40:01 2010 +0200
@@ -37,7 +37,7 @@
 	safe_memset(pw->pw_passwd, 0, strlen(pw->pw_passwd));
 
 	if (result == 0) {
-		auth_request_log_info(request, "bsdauth", "password mismatch");
+		auth_request_log_password_mismatch(request, "bsdauth");
 		callback(PASSDB_RESULT_PASSWORD_MISMATCH, request);
 		return;
 	}
--- a/src/auth/passdb-sia.c	Mon Jan 25 20:40:25 2010 +0200
+++ b/src/auth/passdb-sia.c	Tue Jan 26 13:40:01 2010 +0200
@@ -41,7 +41,7 @@
 	if (sia_validate_user(checkpw_collect, 1, &argutility, NULL,
 			      (char *)request->user, NULL, NULL, NULL,
 			      (char *)password) != SIASUCCESS) {
-		auth_request_log_info(request, "sia", "password mismatch");
+		auth_request_log_password_mismatch(request, "sia");
                 callback(PASSDB_RESULT_PASSWORD_MISMATCH, request);
 	} else {
 		callback(PASSDB_RESULT_OK, request);