diff -up dovecot-2.3.8/src/auth/Makefile.am.CVE_2020_12674prereq dovecot-2.3.8/src/auth/Makefile.am --- dovecot-2.3.8/src/auth/Makefile.am.CVE_2020_12674prereq 2019-10-08 10:46:18.000000000 +0200 +++ dovecot-2.3.8/src/auth/Makefile.am 2020-08-07 20:46:56.095295825 +0200 @@ -38,6 +38,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib-oauth2 \ -I$(top_srcdir)/src/lib-ssl-iostream \ -I$(top_srcdir)/src/lib-lua \ + -I$(top_srcdir)/src/lib-dcrypt \ -DAUTH_MODULE_DIR=\""$(auth_moduledir)"\" \ -DPKG_LIBEXECDIR=\""$(pkglibexecdir)"\" \ -DPKG_RUNDIR=\""$(rundir)"\" \ @@ -248,7 +249,8 @@ libstats_auth_la_SOURCES = auth-stats.c test_programs = \ test-libpassword \ test-auth-cache \ - test-auth + test-auth \ + test-mech noinst_PROGRAMS = $(test_programs) @@ -288,6 +290,13 @@ test_auth_SOURCES = \ test_auth_LDADD = $(test_libs) $(auth_libs) $(AUTH_LIBS) test_auth_DEPENDENCIES = $(pkglibexec_PROGRAMS) $(test_libs) +test_mech_SOURCES = \ + test-mock.c \ + test-mech.c + +test_mech_LDADD = $(test_libs) $(auth_libs) $(AUTH_LIBS) +test_mech_DEPENDENCIES = $(pkglibexec_PROGRAMS) $(test_libs) + check-local: for bin in $(test_programs); do \ if ! $(RUN_TEST) ./$$bin; then exit 1; fi; \ diff -up dovecot-2.3.8/src/auth/passdb.h.CVE_2020_12674prereq dovecot-2.3.8/src/auth/passdb.h --- dovecot-2.3.8/src/auth/passdb.h.CVE_2020_12674prereq 2019-10-08 10:46:18.000000000 +0200 +++ dovecot-2.3.8/src/auth/passdb.h 2020-08-07 20:35:16.295684287 +0200 @@ -24,6 +24,8 @@ enum passdb_result { typedef void verify_plain_callback_t(enum passdb_result result, struct auth_request *request); +typedef void verify_plain_continue_callback_t(struct auth_request *request, + verify_plain_callback_t *callback); typedef void lookup_credentials_callback_t(enum passdb_result result, const unsigned char *credentials, size_t size, diff -up dovecot-2.3.8/src/auth/auth-request-handler-private.h.CVE_2020_12674prereq dovecot-2.3.8/src/auth/auth-request-handler-private.h --- dovecot-2.3.8/src/auth/auth-request-handler-private.h.CVE_2020_12674prereq 2020-08-07 20:35:16.295684287 +0200 +++ dovecot-2.3.8/src/auth/auth-request-handler-private.h 2020-08-07 20:35:16.295684287 +0200 @@ -0,0 +1,27 @@ +#ifndef AUTH_REQUEST_HANDLER_PRIVATE_H +#define AUTH_REQUEST_HANDLER_PRIVATE_H + +struct auth_request; +struct auth_client_connection; + +struct auth_request_handler { + int refcount; + pool_t pool; + HASH_TABLE(void *, struct auth_request *) requests; + + unsigned int connect_uid, client_pid; + + auth_client_request_callback_t *callback; + struct auth_client_connection *conn; + + auth_master_request_callback_t *master_callback; + auth_request_handler_reply_callback_t *reply_callback; + auth_request_handler_reply_continue_callback_t *reply_continue_callback; + verify_plain_continue_callback_t *verify_plain_continue_callback; + + bool destroyed:1; + bool token_auth:1; +}; + + +#endif diff -up dovecot-2.3.8/src/auth/auth-request-handler.h.CVE_2020_12674prereq dovecot-2.3.8/src/auth/auth-request-handler.h --- dovecot-2.3.8/src/auth/auth-request-handler.h.CVE_2020_12674prereq 2019-10-08 10:46:18.000000000 +0200 +++ dovecot-2.3.8/src/auth/auth-request-handler.h 2020-08-07 20:35:16.295684287 +0200 @@ -17,6 +17,17 @@ auth_client_request_callback_t(const cha typedef void auth_master_request_callback_t(const char *reply, struct auth_master_connection *conn); +typedef void +auth_request_handler_reply_callback_t(struct auth_request *request, + enum auth_client_result result, + const void *auth_reply, + size_t reply_size); +typedef void +auth_request_handler_reply_continue_callback_t(struct auth_request *request, + const void *reply, + size_t reply_size); + + struct auth_request_handler * auth_request_handler_create(bool token_auth, auth_client_request_callback_t *callback, struct auth_client_connection *conn, diff -up dovecot-2.3.8/src/auth/test-mock.c.CVE_2020_12674prereq dovecot-2.3.8/src/auth/test-mock.c --- dovecot-2.3.8/src/auth/test-mock.c.CVE_2020_12674prereq 2019-10-08 10:46:18.000000000 +0200 +++ dovecot-2.3.8/src/auth/test-mock.c 2020-08-07 20:35:16.296684273 +0200 @@ -28,14 +28,22 @@ static void passdb_mock_verify_plain(str callback(PASSDB_RESULT_OK, request); } +static void passdb_mock_lookup_credentials(struct auth_request *request, + lookup_credentials_callback_t *callback) +{ + passdb_handle_credentials(PASSDB_RESULT_OK, "password", "PLAIN", + callback, request); +} + static struct passdb_module_interface mock_interface = { .name = "mock", .init = passdb_mock_init, .deinit = passdb_mock_deinit, .verify_plain = passdb_mock_verify_plain, + .lookup_credentials = passdb_mock_lookup_credentials, }; -static struct auth_passdb_settings set = { +struct auth_passdb_settings mock_passdb_set = { .name = "mock", .driver = "mock", .args = "", @@ -95,7 +103,7 @@ void passdb_mock_mod_deinit(void) struct auth_passdb *passdb_mock(void) { struct auth_passdb *ret = i_new(struct auth_passdb, 1); - ret->set = &set; + ret->set = &mock_passdb_set; ret->passdb = mock_passdb_mod; return ret; } diff -up dovecot-2.3.8/src/auth/test-auth.h.CVE_2020_12674prereq dovecot-2.3.8/src/auth/test-auth.h --- dovecot-2.3.8/src/auth/test-auth.h.CVE_2020_12674prereq 2019-10-08 10:46:18.000000000 +0200 +++ dovecot-2.3.8/src/auth/test-auth.h 2020-08-07 20:35:16.296684273 +0200 @@ -8,6 +8,8 @@ struct auth_passdb; +extern struct auth_passdb_settings mock_passdb_set; + void test_auth_request_var_expand(void); void test_db_dict_parse_cache_key(void); void test_username_filter(void); diff -up dovecot-2.3.8/src/auth/auth-request.c.CVE_2020_12674prereq dovecot-2.3.8/src/auth/auth-request.c --- dovecot-2.3.8/src/auth/auth-request.c.CVE_2020_12674prereq 2019-10-08 10:46:18.000000000 +0200 +++ dovecot-2.3.8/src/auth/auth-request.c 2020-08-07 20:35:16.295684287 +0200 @@ -16,6 +16,7 @@ #include "auth-cache.h" #include "auth-request.h" #include "auth-request-handler.h" +#include "auth-request-handler-private.h" #include "auth-request-stats.h" #include "auth-client-connection.h" #include "auth-master-connection.h" @@ -67,9 +68,6 @@ static void auth_request_userdb_import(struct auth_request *request, const char *args); static -void auth_request_verify_plain_continue(struct auth_request *request, - verify_plain_callback_t *callback); -static void auth_request_lookup_credentials_policy_continue(struct auth_request *request, lookup_credentials_callback_t *callback); static @@ -307,10 +307,12 @@ void auth_request_success_continue(struct auth_policy_check_ctx *ctx) return; } - stats = auth_request_stats_get(request); - stats->auth_success_count++; - if (request->master_user != NULL) - stats->auth_master_success_count++; + if (request->set->stats) { + stats = auth_request_stats_get(request); + stats->auth_success_count++; + if (request->master_user != NULL) + stats->auth_master_success_count++; + } auth_request_set_state(request, AUTH_REQUEST_STATE_FINISHED); auth_request_refresh_last_access(request); @@ -324,8 +326,10 @@ void auth_request_fail(struct auth_request *request) i_assert(request->state == AUTH_REQUEST_STATE_MECH_CONTINUE); - stats = auth_request_stats_get(request); - stats->auth_failure_count++; + if (request->set->stats) { + stats = auth_request_stats_get(request); + stats->auth_failure_count++; + } auth_request_set_state(request, AUTH_REQUEST_STATE_FINISHED); auth_request_refresh_last_access(request); @@ -1233,7 +1231,7 @@ void auth_request_policy_penalty_finish( switch(ctx->type) { case AUTH_POLICY_CHECK_TYPE_PLAIN: - auth_request_verify_plain_continue(ctx->request, ctx->callback_plain); + ctx->request->handler->verify_plain_continue_callback(ctx->request, ctx->callback_plain); return; case AUTH_POLICY_CHECK_TYPE_LOOKUP: auth_request_lookup_credentials_policy_continue(ctx->request, ctx->callback_lookup); @@ -1284,7 +1282,8 @@ void auth_request_verify_plain(struct au request->user_changed_by_lookup = FALSE; if (request->policy_processed || !request->set->policy_check_before_auth) { - auth_request_verify_plain_continue(request, callback); + request->handler->verify_plain_continue_callback(request, + callback); } else { ctx = p_new(request->pool, struct auth_policy_check_ctx, 1); ctx->request = request; @@ -1294,10 +1293,9 @@ void auth_request_verify_plain(struct au } } -static -void auth_request_verify_plain_continue(struct auth_request *request, - verify_plain_callback_t *callback) { - +void auth_request_default_verify_plain_continue(struct auth_request *request, + verify_plain_callback_t *callback) +{ struct auth_passdb *passdb; enum passdb_result result; const char *cache_key, *error; diff -up dovecot-2.3.8/src/auth/auth-request-handler.c.CVE_2020_12674prereq dovecot-2.3.8/src/auth/auth-request-handler.c --- dovecot-2.3.8/src/auth/auth-request-handler.c.CVE_2020_12674prereq 2019-10-08 10:46:18.000000000 +0200 +++ dovecot-2.3.8/src/auth/auth-request-handler.c 2020-08-07 20:35:16.295684287 +0200 @@ -17,32 +17,28 @@ #include "auth-client-connection.h" #include "auth-master-connection.h" #include "auth-request-handler.h" +#include "auth-request-handler-private.h" #include "auth-policy.h" #define AUTH_FAILURE_DELAY_CHECK_MSECS 500 - -struct auth_request_handler { - int refcount; - pool_t pool; - HASH_TABLE(void *, struct auth_request *) requests; - - unsigned int connect_uid, client_pid; - - auth_client_request_callback_t *callback; - struct auth_client_connection *conn; - - auth_master_request_callback_t *master_callback; - - bool destroyed:1; - bool token_auth:1; -}; - static ARRAY(struct auth_request *) auth_failures_arr; static struct aqueue *auth_failures; static struct timeout *to_auth_failures; static void auth_failure_timeout(void *context) ATTR_NULL(1); + +static void +auth_request_handler_default_reply_callback(struct auth_request *request, + enum auth_client_result result, + const void *auth_reply, + size_t reply_size); + +static void +auth_request_handler_default_reply_continue(struct auth_request *request, + const void *reply, + size_t reply_size); + struct auth_request_handler * auth_request_handler_create(bool token_auth, auth_client_request_callback_t *callback, struct auth_client_connection *conn, @@ -61,6 +57,12 @@ auth_request_handler_create(bool token_a handler->conn = conn; handler->master_callback = master_callback; handler->token_auth = token_auth; + handler->reply_callback = + auth_request_handler_default_reply_callback; + handler->reply_continue_callback = + auth_request_handler_default_reply_continue; + handler->verify_plain_continue_callback = + auth_request_default_verify_plain_continue; return handler; } @@ -355,6 +363,16 @@ void auth_request_handler_reply(struct a enum auth_client_result result, const void *auth_reply, size_t reply_size) { + struct auth_request_handler *handler = request->handler; + handler->reply_callback(request, result, auth_reply, reply_size); +} + +static void +auth_request_handler_default_reply_callback(struct auth_request *request, + enum auth_client_result result, + const void *auth_reply, + size_t reply_size) +{ struct auth_request_handler *handler = request->handler; string_t *str; int ret; @@ -407,6 +425,14 @@ void auth_request_handler_reply(struct a void auth_request_handler_reply_continue(struct auth_request *request, const void *reply, size_t reply_size) { + request->handler->reply_continue_callback(request, reply, reply_size); +} + +static void +auth_request_handler_default_reply_continue(struct auth_request *request, + const void *reply, + size_t reply_size) +{ auth_request_handler_reply(request, AUTH_CLIENT_RESULT_CONTINUE, reply, reply_size); } @@ -703,6 +729,7 @@ static void auth_str_append_userdb_extra auth_str_add_keyvalue(dest, "master_user", request->master_user); } + auth_str_add_keyvalue(dest, "auth_mech", request->mech->mech_name); if (*request->set->anonymous_username != '\0' && strcmp(request->user, request->set->anonymous_username) == 0) { /* this is an anonymous login, either via ANONYMOUS diff -up dovecot-2.3.8/src/auth/auth-request.h.CVE_2020_12674prereq dovecot-2.3.8/src/auth/auth-request.h --- dovecot-2.3.8/src/auth/auth-request.h.CVE_2020_12674prereq 2019-10-08 10:46:18.000000000 +0200 +++ dovecot-2.3.8/src/auth/auth-request.h 2020-08-07 20:35:16.295684287 +0200 @@ -295,6 +295,8 @@ void auth_request_set_credentials(struct set_credentials_callback_t *callback); void auth_request_userdb_callback(enum userdb_result result, struct auth_request *request); +void auth_request_default_verify_plain_continue(struct auth_request *request, + verify_plain_callback_t *callback); void auth_request_refresh_last_access(struct auth_request *request); void auth_str_append(string_t *dest, const char *key, const char *value);