]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Added auth_verbose_passwords = no|plain|sha1.
authorTimo Sirainen <tss@iki.fi>
Tue, 26 Jan 2010 11:40:01 +0000 (13:40 +0200)
committerTimo Sirainen <tss@iki.fi>
Tue, 26 Jan 2010 11:40:01 +0000 (13:40 +0200)
--HG--
branch : HEAD

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

index 8ae8918cb91f958c877ff5867fa415e53931b642..75505ffa4b61b11cf9fc60f8003d22cf18dadd68 100644 (file)
 # 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
index 4d9211d5ed74fc619b4e0c50c55ab64f12fe091a..7f66e04fecf2d016c60b394a7016f84ecb7f15e6 100644 (file)
@@ -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 @@ static void log_password_failure(struct auth_request *request,
        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 @@ int auth_request_password_verify(struct auth_request *request,
                              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 @@ auth_request_get_var_expand_table(const struct auth_request *auth_request,
        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 @@ get_log_str(struct auth_request *auth_request, const char *subsystem,
        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);
 }
index 9821759e76f4a2b47d1b026af75363aaec475481..c9e011009180e079a8f34a4e7dc2b1ef766091f3 100644 (file)
@@ -160,6 +160,8 @@ void auth_request_set_userdb_field_values(struct auth_request *request,
                                          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,
index a4f4aa67339fcaf9a0e17418c3394203ca3587b5..98a4f185f215600a26b5eace7681d5905892d8f8 100644 (file)
@@ -171,6 +171,7 @@ static const struct setting_define auth_setting_defines[] = {
        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 @@ static const struct auth_settings auth_default_settings = {
        .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,
index 86853b08843572a50ef17d7537da6d84358ce411..ca144870b3d34cff6ced3f74458f3143dfc1c29c 100644 (file)
@@ -34,6 +34,7 @@ struct auth_settings {
        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;
index 4fa69a5c709339f6fee106cb2ae110ec98d052ba..801927f6705cd5af330332eed495130298806045 100644 (file)
@@ -37,7 +37,7 @@ bsdauth_verify_plain(struct auth_request *request, const char *password,
        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;
        }
index 9aeb68a58ebd72809cebd8cdfa1772c624303560..79c3a4996f0ba5b6bf98d6f37d294444ca7abb88 100644 (file)
@@ -41,7 +41,7 @@ local_sia_verify_plain(struct auth_request *request, const char *password,
        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);