# HG changeset patch # User Timo Sirainen # Date 1044181002 -7200 # Node ID f6ec2868351286b8c5d08febcceacca1b6ca6b22 # Parent c62416017121f6df23f29a9acc52018ba20fe917 auth: kill login connection if it leaves requests hanging too long. diff -r c62416017121 -r f6ec28683512 src/auth/auth-login-interface.h --- a/src/auth/auth-login-interface.h Sun Feb 02 11:45:07 2003 +0200 +++ b/src/auth/auth-login-interface.h Sun Feb 02 12:16:42 2003 +0200 @@ -4,6 +4,10 @@ /* max. size for auth_login_request_continue.data[] */ #define AUTH_LOGIN_MAX_REQUEST_DATA_SIZE 4096 +/* Login process must finish with single authentication requests in this time, + or the whole connection will be killed. */ +#define AUTH_REQUEST_TIMEOUT 120 + enum auth_mech { AUTH_MECH_PLAIN = 0x01, AUTH_MECH_DIGEST_MD5 = 0x02, diff -r c62416017121 -r f6ec28683512 src/auth/login-connection.c --- a/src/auth/login-connection.c Sun Feb 02 11:45:07 2003 +0200 +++ b/src/auth/login-connection.c Sun Feb 02 12:16:42 2003 +0200 @@ -18,6 +18,7 @@ AUTH_LOGIN_MAX_REQUEST_DATA_SIZE) #define MAX_OUTBUF_SIZE (1024*50) +static struct timeout *to; static struct auth_login_handshake_output handshake_output; static struct login_connection *connections; @@ -254,6 +255,32 @@ i_free(conn); } +static void auth_request_hash_timeout_check(void *key __attr_unused__, + void *value, void *context) +{ + struct login_connection *conn = context; + struct auth_request *auth_request = value; + + if (auth_request->created + AUTH_REQUEST_TIMEOUT < ioloop_time) { + i_warning("Login process has too old (%us) requests, " + "killing it.", + (unsigned int)(ioloop_time - auth_request->created)); + + login_connection_destroy(conn); + hash_foreach_stop(); + } +} + +static void request_timeout(void *context __attr_unused__) +{ + struct login_connection *conn; + + for (conn = connections; conn != NULL; conn = conn->next) { + hash_foreach(conn->auth_requests, + auth_request_hash_timeout_check, conn); + } +} + void login_connections_init(void) { const char *env; @@ -267,6 +294,7 @@ handshake_output.auth_mechanisms = auth_mechanisms; connections = NULL; + to = timeout_add(5000, request_timeout, NULL); } void login_connections_deinit(void) @@ -278,4 +306,6 @@ login_connection_destroy(connections); connections = next; } + + timeout_remove(to); } diff -r c62416017121 -r f6ec28683512 src/auth/mech-digest-md5.c --- a/src/auth/mech-digest-md5.c Sun Feb 02 11:45:07 2003 +0200 +++ b/src/auth/mech-digest-md5.c Sun Feb 02 12:16:42 2003 +0200 @@ -543,8 +543,7 @@ } static int -mech_digest_md5_auth_continue(struct login_connection *conn, - struct auth_request *auth_request, +mech_digest_md5_auth_continue(struct auth_request *auth_request, struct auth_login_request_continue *request, const unsigned char *data, mech_callback_t *callback) @@ -588,7 +587,7 @@ /* failed */ reply.result = AUTH_LOGIN_RESULT_FAILURE; reply.data_size = strlen(error)+1; - callback(&reply, error, conn); + callback(&reply, error, auth_request->conn); return FALSE; } diff -r c62416017121 -r f6ec28683512 src/auth/mech-plain.c --- a/src/auth/mech-plain.c Sun Feb 02 11:45:07 2003 +0200 +++ b/src/auth/mech-plain.c Sun Feb 02 12:16:42 2003 +0200 @@ -13,8 +13,7 @@ } static int -mech_plain_auth_continue(struct login_connection *conn, - struct auth_request *auth_request, +mech_plain_auth_continue(struct auth_request *auth_request, struct auth_login_request_continue *request, const unsigned char *data, mech_callback_t *callback) { diff -r c62416017121 -r f6ec28683512 src/auth/mech.c --- a/src/auth/mech.c Sun Feb 02 11:45:07 2003 +0200 +++ b/src/auth/mech.c Sun Feb 02 12:16:42 2003 +0200 @@ -1,6 +1,7 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "common.h" +#include "ioloop.h" #include "buffer.h" #include "hash.h" #include "mech.h" @@ -90,6 +91,7 @@ } if (auth_request != NULL) { + auth_request->created = ioloop_time; auth_request->conn = conn; auth_request->id = request->id; auth_request->protocol = request->protocol; @@ -113,7 +115,7 @@ failure_reply.id = request->id; callback(&failure_reply, NULL, conn); } else { - if (!auth_request->auth_continue(conn, auth_request, + if (!auth_request->auth_continue(auth_request, request, data, callback)) mech_request_free(conn, auth_request, request->id); } diff -r c62416017121 -r f6ec28683512 src/auth/mech.h --- a/src/auth/mech.h Sun Feb 02 11:45:07 2003 +0200 +++ b/src/auth/mech.h Sun Feb 02 12:16:42 2003 +0200 @@ -14,11 +14,12 @@ struct login_connection *conn; unsigned int id; + time_t created; + enum auth_protocol protocol; mech_callback_t *callback; - int (*auth_continue)(struct login_connection *conn, - struct auth_request *auth_request, + int (*auth_continue)(struct auth_request *auth_request, struct auth_login_request_continue *request, const unsigned char *data, mech_callback_t *callback); diff -r c62416017121 -r f6ec28683512 src/imap-login/client-authenticate.c --- a/src/imap-login/client-authenticate.c Sun Feb 02 11:45:07 2003 +0200 +++ b/src/imap-login/client-authenticate.c Sun Feb 02 12:16:42 2003 +0200 @@ -61,6 +61,7 @@ { if (client->auth_request != NULL) { auth_abort_request(client->auth_request); + auth_request_unref(client->auth_request); client->auth_request = NULL; } @@ -136,6 +137,7 @@ if (reply == NULL) { /* failed */ + auth_request_unref(client->auth_request); client->auth_request = NULL; client_auth_abort(client, "NO Authentication process died."); return FALSE; @@ -143,10 +145,14 @@ switch (reply->result) { case AUTH_LOGIN_RESULT_CONTINUE: + i_assert(client->auth_request == NULL); + client->auth_request = request; + auth_request_ref(client->auth_request); return TRUE; case AUTH_LOGIN_RESULT_SUCCESS: + auth_request_unref(client->auth_request); client->auth_request = NULL; user = auth_login_get_str(reply, data, reply->username_idx); @@ -172,6 +178,7 @@ case AUTH_LOGIN_RESULT_FAILURE: /* see if we have error message */ + auth_request_unref(client->auth_request); client->auth_request = NULL; if (reply->data_size > 0 && data[reply->data_size-1] == '\0') { diff -r c62416017121 -r f6ec28683512 src/imap-login/client.c --- a/src/imap-login/client.c Sun Feb 02 11:45:07 2003 +0200 +++ b/src/imap-login/client.c Sun Feb 02 12:16:42 2003 +0200 @@ -34,6 +34,10 @@ client hash, it's faster if we disconnect multiple clients. */ #define CLIENT_DESTROY_OLDEST_COUNT 16 +#if CLIENT_LOGIN_IDLE_TIMEOUT >= AUTH_REQUEST_TIMEOUT +# error client idle timeout must be smaller than authentication timeout +#endif + static struct hash_table *clients; static struct timeout *to_idle; diff -r c62416017121 -r f6ec28683512 src/pop3-login/client.c --- a/src/pop3-login/client.c Sun Feb 02 11:45:07 2003 +0200 +++ b/src/pop3-login/client.c Sun Feb 02 12:16:42 2003 +0200 @@ -27,6 +27,10 @@ client hash, it's faster if we disconnect multiple clients. */ #define CLIENT_DESTROY_OLDEST_COUNT 16 +#if CLIENT_LOGIN_IDLE_TIMEOUT >= AUTH_REQUEST_TIMEOUT +# error client idle timeout must be smaller than authentication timeout +#endif + static struct hash_table *clients; static struct timeout *to_idle;