changeset 1083:f6ec28683512 HEAD

auth: kill login connection if it leaves requests hanging too long.
author Timo Sirainen <tss@iki.fi>
date Sun, 02 Feb 2003 12:16:42 +0200
parents c62416017121
children 86b8c9cb7ac0
files src/auth/auth-login-interface.h src/auth/login-connection.c src/auth/mech-digest-md5.c src/auth/mech-plain.c src/auth/mech.c src/auth/mech.h src/imap-login/client-authenticate.c src/imap-login/client.c src/pop3-login/client.c
diffstat 9 files changed, 58 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- 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,
--- 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);
 }
--- 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;
 }
 
--- 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)
 {
--- 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);
 	}
--- 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);
--- 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') {
--- 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;
 
--- 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;