Mercurial > dovecot > original-hg > dovecot-1.2
changeset 8574:1b744c38bcac HEAD
Increase failed login's reply delay by 5 seconds for each failure.
Don't add any delays if passdb returned nodelay extra field.
Based on patch by Apple.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 19 Dec 2008 09:31:18 +0200 |
parents | f9166a09423a |
children | 52417406a50c |
files | src/auth/auth-request-handler.c src/imap-login/client-authenticate.c src/imap-login/client.c src/imap-login/client.h src/pop3-login/client-authenticate.c src/pop3-login/client.c src/pop3-login/client.h |
diffstat | 7 files changed, 109 insertions(+), 36 deletions(-) [+] |
line wrap: on
line diff
--- a/src/auth/auth-request-handler.c Fri Dec 19 09:06:38 2008 +0200 +++ b/src/auth/auth-request-handler.c Fri Dec 19 09:31:18 2008 +0200 @@ -254,6 +254,8 @@ as the wanted user */ auth_stream_reply_add(reply, "authz", NULL); } + if (request->no_failure_delay) + auth_stream_reply_add(reply, "nodelay", NULL); get_client_extra_fields(request, reply); auth_request_handle_failure(request, reply);
--- a/src/imap-login/client-authenticate.c Fri Dec 19 09:06:38 2008 +0200 +++ b/src/imap-login/client-authenticate.c Fri Dec 19 09:31:18 2008 +0200 @@ -18,6 +18,8 @@ #include <stdlib.h> +#define AUTH_FAILURE_DELAY_INCREASE_MSECS 5000 + #define IMAP_SERVICE_NAME "imap" #define IMAP_AUTH_FAILED_MSG "["IMAP_RESP_CODE_AUTHFAILED"] "AUTH_FAILED_MSG #define IMAP_AUTHZ_FAILED_MSG \ @@ -79,23 +81,50 @@ } } -static void client_auth_failed(struct imap_client *client) +static void client_authfail_delay_timeout(struct imap_client *client) { + timeout_remove(&client->to_authfail_delay); + + /* get back to normal client input. */ + i_assert(client->io == NULL); + client->io = io_add(client->common.fd, IO_READ, client_input, client); + client_input(client); +} + +static void client_auth_failed(struct imap_client *client, bool nodelay) +{ + unsigned int delay_msecs; + client->common.auth_command_tag = NULL; if (client->auth_initializing) return; - /* get back to normal client input. */ if (client->io != NULL) io_remove(&client->io); - client->io = io_add(client->common.fd, IO_READ, - client_input, client); - client_input(client); + if (nodelay) { + client->io = io_add(client->common.fd, IO_READ, + client_input, client); + client_input(client); + return; + } + + /* increase the timeout after each unsuccessful attempt, but don't + increase it so high that the idle timeout would be triggered */ + delay_msecs = client->common.auth_attempts * + AUTH_FAILURE_DELAY_INCREASE_MSECS; + if (delay_msecs > CLIENT_LOGIN_IDLE_TIMEOUT_MSECS) + delay_msecs = CLIENT_LOGIN_IDLE_TIMEOUT_MSECS - 1000; + timeout_reset(client->to_idle_disconnect); + + i_assert(client->to_authfail_delay == NULL); + client->to_authfail_delay = + timeout_add(delay_msecs, client_authfail_delay_timeout, client); } static bool client_handle_args(struct imap_client *client, - const char *const *args, bool success) + const char *const *args, bool success, + bool *nodelay_r) { const char *reason = NULL, *host = NULL, *destuser = NULL, *pass = NULL; const char *master_user = NULL; @@ -104,9 +133,12 @@ bool proxy = FALSE, temp = FALSE, nologin = !success, proxy_self; bool authz_failure = FALSE; + *nodelay_r = FALSE; for (; *args != NULL; args++) { if (strcmp(*args, "nologin") == 0) nologin = TRUE; + else if (strcmp(*args, "nodelay") == 0) + *nodelay_r = TRUE; else if (strcmp(*args, "proxy") == 0) proxy = TRUE; else if (strcmp(*args, "temp") == 0) @@ -210,7 +242,7 @@ i_assert(nologin || proxy_self); if (!client->destroyed) - client_auth_failed(client); + client_auth_failed(client, *nodelay_r); return TRUE; } @@ -221,6 +253,7 @@ struct const_iovec iov[3]; const char *msg; size_t data_len; + bool nodelay; i_assert(!client->destroyed || reply == SASL_SERVER_REPLY_CLIENT_ERROR || @@ -231,7 +264,7 @@ if (client->to_auth_waiting != NULL) timeout_remove(&client->to_auth_waiting); if (args != NULL) { - if (client_handle_args(client, args, TRUE)) + if (client_handle_args(client, args, TRUE, &nodelay)) break; } client_destroy_success(client, "Login"); @@ -241,7 +274,7 @@ if (client->to_auth_waiting != NULL) timeout_remove(&client->to_auth_waiting); if (args != NULL) { - if (client_handle_args(client, args, FALSE)) + if (client_handle_args(client, args, FALSE, &nodelay)) break; } @@ -251,7 +284,7 @@ client_send_tagline(client, msg); if (!client->destroyed) - client_auth_failed(client); + client_auth_failed(client, nodelay); break; case SASL_SERVER_REPLY_MASTER_FAILED: if (data == NULL)
--- a/src/imap-login/client.c Fri Dec 19 09:06:38 2008 +0200 +++ b/src/imap-login/client.c Fri Dec 19 09:31:18 2008 +0200 @@ -26,9 +26,6 @@ /* maximum length for IMAP command line. */ #define MAX_IMAP_LINE 8192 -/* Disconnect client after idling this many milliseconds */ -#define CLIENT_LOGIN_IDLE_TIMEOUT_MSECS (3*60*1000) - /* Disconnect client when it sends too many bad commands */ #define CLIENT_MAX_BAD_COMMANDS 10 @@ -572,6 +569,8 @@ timeout_remove(&client->to_idle_disconnect); if (client->to_auth_waiting != NULL) timeout_remove(&client->to_auth_waiting); + if (client->to_authfail_delay != NULL) + timeout_remove(&client->to_authfail_delay); if (client->common.fd != -1) { net_disconnect(client->common.fd);
--- a/src/imap-login/client.h Fri Dec 19 09:06:38 2008 +0200 +++ b/src/imap-login/client.h Fri Dec 19 09:31:18 2008 +0200 @@ -5,6 +5,9 @@ #include "master.h" #include "client-common.h" +/* Disconnect client after idling this many milliseconds */ +#define CLIENT_LOGIN_IDLE_TIMEOUT_MSECS (3*60*1000) + struct imap_client { struct client common; @@ -15,6 +18,7 @@ struct ostream *output; struct imap_parser *parser; struct timeout *to_idle_disconnect, *to_auth_waiting; + struct timeout *to_authfail_delay; struct login_proxy *proxy; char *proxy_user, *proxy_master_user, *proxy_password;
--- a/src/pop3-login/client-authenticate.c Fri Dec 19 09:06:38 2008 +0200 +++ b/src/pop3-login/client-authenticate.c Fri Dec 19 09:31:18 2008 +0200 @@ -20,6 +20,7 @@ #include <stdlib.h> #define POP3_SERVICE_NAME "pop3" +#define AUTH_FAILURE_DELAY_INCREASE_MSECS 5000 const char *capability_string = POP3_CAPABILITY_REPLY; @@ -82,8 +83,48 @@ } } +static void client_authfail_delay_timeout(struct pop3_client *client) +{ + timeout_remove(&client->to_authfail_delay); + + /* get back to normal client input. */ + i_assert(client->io == NULL); + client->io = io_add(client->common.fd, IO_READ, client_input, client); + client_input(client); +} + +static void client_auth_failed(struct pop3_client *client, bool nodelay) +{ + unsigned int delay_msecs; + + if (client->auth_initializing) + return; + + if (client->io != NULL) + io_remove(&client->io); + if (nodelay) { + client->io = io_add(client->common.fd, IO_READ, + client_input, client); + client_input(client); + return; + } + + /* increase the timeout after each unsuccessful attempt, but don't + increase it so high that the idle timeout would be triggered */ + delay_msecs = client->common.auth_attempts * + AUTH_FAILURE_DELAY_INCREASE_MSECS; + if (delay_msecs > CLIENT_LOGIN_IDLE_TIMEOUT_MSECS) + delay_msecs = CLIENT_LOGIN_IDLE_TIMEOUT_MSECS - 1000; + timeout_reset(client->to_idle_disconnect); + + i_assert(client->to_authfail_delay == NULL); + client->to_authfail_delay = + timeout_add(delay_msecs, client_authfail_delay_timeout, client); +} + static bool client_handle_args(struct pop3_client *client, - const char *const *args, bool success) + const char *const *args, bool success, + bool *nodelay_r) { const char *reason = NULL, *host = NULL, *destuser = NULL, *pass = NULL; const char *master_user = NULL; @@ -91,9 +132,12 @@ unsigned int port = 110; bool proxy = FALSE, temp = FALSE, nologin = !success; + *nodelay_r = FALSE; for (; *args != NULL; args++) { if (strcmp(*args, "nologin") == 0) nologin = TRUE; + else if (strcmp(*args, "nodelay") == 0) + *nodelay_r = TRUE; else if (strcmp(*args, "proxy") == 0) proxy = TRUE; else if (strcmp(*args, "temp") == 0) @@ -150,14 +194,8 @@ client_send_line(client, str_c(reply)); - if (!client->destroyed) { - /* get back to normal client input. */ - if (client->io != NULL) - io_remove(&client->io); - client->io = io_add(client->common.fd, IO_READ, - client_input, client); - client_input(client); - } + if (!client->destroyed) + client_auth_failed(client, *nodelay_r); return TRUE; } @@ -168,6 +206,7 @@ struct const_iovec iov[3]; const char *msg; size_t data_len; + bool nodelay; i_assert(!client->destroyed || reply == SASL_SERVER_REPLY_CLIENT_ERROR || @@ -176,7 +215,7 @@ switch (reply) { case SASL_SERVER_REPLY_SUCCESS: if (args != NULL) { - if (client_handle_args(client, args, TRUE)) + if (client_handle_args(client, args, TRUE, &nodelay)) break; } @@ -185,7 +224,7 @@ case SASL_SERVER_REPLY_AUTH_FAILED: case SASL_SERVER_REPLY_CLIENT_ERROR: if (args != NULL) { - if (client_handle_args(client, args, FALSE)) + if (client_handle_args(client, args, FALSE, &nodelay)) break; } @@ -193,14 +232,8 @@ data : AUTH_FAILED_MSG, NULL); client_send_line(client, msg); - if (!client->destroyed && !client->auth_initializing) { - /* get back to normal client input. */ - if (client->io != NULL) - io_remove(&client->io); - client->io = io_add(client->common.fd, IO_READ, - client_input, client); - client_input(client); - } + if (!client->destroyed) + client_auth_failed(client, nodelay); break; case SASL_SERVER_REPLY_MASTER_FAILED: if (data == NULL)
--- a/src/pop3-login/client.c Fri Dec 19 09:06:38 2008 +0200 +++ b/src/pop3-login/client.c Fri Dec 19 09:31:18 2008 +0200 @@ -21,9 +21,6 @@ SASL authentication gives the largest output. */ #define MAX_OUTBUF_SIZE 4096 -/* Disconnect client after idling this many milliseconds */ -#define CLIENT_LOGIN_IDLE_TIMEOUT_MSECS (3*60*1000) - /* Disconnect client when it sends too many bad commands */ #define CLIENT_MAX_BAD_COMMANDS 10 @@ -378,6 +375,8 @@ io_remove(&client->io); if (client->to_idle_disconnect != NULL) timeout_remove(&client->to_idle_disconnect); + if (client->to_authfail_delay != NULL) + timeout_remove(&client->to_authfail_delay); if (client->common.fd != -1) { net_disconnect(client->common.fd);
--- a/src/pop3-login/client.h Fri Dec 19 09:06:38 2008 +0200 +++ b/src/pop3-login/client.h Fri Dec 19 09:31:18 2008 +0200 @@ -6,6 +6,9 @@ #include "client-common.h" #include "auth-client.h" +/* Disconnect client after idling this many milliseconds */ +#define CLIENT_LOGIN_IDLE_TIMEOUT_MSECS (3*60*1000) + struct pop3_client { struct client common; @@ -14,7 +17,7 @@ struct io *io; struct ostream *output; - struct timeout *to_idle_disconnect; + struct timeout *to_idle_disconnect, *to_authfail_delay; struct login_proxy *proxy; char *proxy_user, *proxy_master_user, *proxy_password;