dovecot-2.0: *-login: Allow auth input to be larger than the res...

dovecot at dovecot.org dovecot at dovecot.org
Thu Aug 13 20:31:35 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/e4235adb3044
changeset: 9782:e4235adb3044
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Aug 13 13:31:27 2009 -0400
description:
*-login: Allow auth input to be larger than the rest of the input.

diffstat:

4 files changed, 58 insertions(+), 21 deletions(-)
src/lib-master/master-interface.h     |    2 
src/login-common/client-common-auth.c |   67 +++++++++++++++++++++++++--------
src/login-common/client-common.c      |    2 
src/login-common/client-common.h      |    8 +--

diffs (178 lines):

diff -r 19912e4a2fb3 -r e4235adb3044 src/lib-master/master-interface.h
--- a/src/lib-master/master-interface.h	Thu Aug 13 13:00:43 2009 -0400
+++ b/src/lib-master/master-interface.h	Thu Aug 13 13:31:27 2009 -0400
@@ -35,7 +35,7 @@ struct log_service_handshake {
 
 /* This should be kept in sync with LOGIN_MAX_INBUF_SIZE. Multiply it by two
    to make sure there's space to transfer the command tag  */
-#define MASTER_AUTH_MAX_DATA_SIZE (4096*2)
+#define MASTER_AUTH_MAX_DATA_SIZE (1024*2)
 
 /* Authentication request. File descriptor may be sent along with the
    request. */
diff -r 19912e4a2fb3 -r e4235adb3044 src/login-common/client-common-auth.c
--- a/src/login-common/client-common-auth.c	Thu Aug 13 13:00:43 2009 -0400
+++ b/src/login-common/client-common-auth.c	Thu Aug 13 13:31:27 2009 -0400
@@ -21,6 +21,8 @@
 #if CLIENT_LOGIN_IDLE_TIMEOUT_MSECS < AUTH_REQUEST_TIMEOUT*1000
 #  error client idle timeout must be larger than authentication timeout
 #endif
+
+#define CLIENT_AUTH_BUF_MAX_SIZE 8192
 
 static void client_authfail_delay_timeout(struct client *client)
 {
@@ -324,17 +326,45 @@ client_auth_handle_reply(struct client *
 	return client->v.auth_handle_reply(client, reply);
 }
 
-int client_auth_parse_response(struct client *client, char **data_r)
-{
-	if (!client_read(client))
-		return 0;
-
-	/* @UNSAFE */
-	*data_r = i_stream_next_line(client->input);
-	if (*data_r == NULL)
-		return 0;
-
-	if (strcmp(*data_r, "*") == 0) {
+static int client_auth_read_line(struct client *client)
+{
+	const unsigned char *data;
+	size_t i, size;
+	unsigned int len;
+
+	if (i_stream_read_data(client->input, &data, &size, 0) == -1) {
+		client_destroy(client, "Disconnected");
+		return -1;
+	}
+
+	/* see if we have a full line */
+	for (i = 0; i < size; i++) {
+		if (data[i] == '\n')
+			break;
+	}
+	if (str_len(client->auth_response) + i > CLIENT_AUTH_BUF_MAX_SIZE) {
+		client_destroy(client, "Authentication response too large");
+		return -1;
+	}
+	str_append_n(client->auth_response, data, i);
+	i_stream_skip(client->input, i == size ? size : i+1);
+
+	/* drop trailing \r */
+	len = str_len(client->auth_response);
+	if (len > 0 && str_c(client->auth_response)[len-1] == '\r')
+		str_truncate(client->auth_response, len-1);
+
+	return i < size;
+}
+
+int client_auth_parse_response(struct client *client)
+{
+	int ret;
+
+	if ((ret = client_auth_read_line(client)) <= 0)
+		return ret;
+
+	if (strcmp(str_c(client->auth_response), "*") == 0) {
 		sasl_server_auth_abort(client);
 		return -1;
 	}
@@ -343,18 +373,18 @@ int client_auth_parse_response(struct cl
 
 static void client_auth_input(struct client *client)
 {
-	char *line;
 	int ret;
 
-	if ((ret = client->v.auth_parse_response(client, &line)) <= 0)
+	if ((ret = client->v.auth_parse_response(client)) <= 0)
 		return;
 
 	client_set_auth_waiting(client);
-	auth_client_request_continue(client->auth_request, line);
+	auth_client_request_continue(client->auth_request,
+				     str_c(client->auth_response));
 	io_remove(&client->io);
 
-	/* clear sensitive data */
-	safe_memset(line, 0, strlen(line));
+	memset(str_c_modifiable(client->auth_response), 0,
+	       str_len(client->auth_response));
 }
 
 void client_auth_send_challenge(struct client *client, const char *data)
@@ -435,6 +465,8 @@ sasl_callback(struct client *client, enu
 		if (client->to_auth_waiting != NULL)
 			timeout_remove(&client->to_auth_waiting);
 
+		str_truncate(client->auth_response, 0);
+
 		i_assert(client->io == NULL);
 		client->io = io_add(client->fd, IO_READ,
 				    client_auth_input, client);
@@ -459,6 +491,9 @@ int client_auth_begin(struct client *cli
 		return 1;
 	}
 
+
+	if (client->auth_response == NULL)
+		client->auth_response = str_new(default_pool, 256);
 
 	client_ref(client);
 	client->auth_initializing = TRUE;
diff -r 19912e4a2fb3 -r e4235adb3044 src/login-common/client-common.c
--- a/src/login-common/client-common.c	Thu Aug 13 13:00:43 2009 -0400
+++ b/src/login-common/client-common.c	Thu Aug 13 13:31:27 2009 -0400
@@ -140,6 +140,8 @@ void client_destroy(struct client *clien
 		timeout_remove(&client->to_auth_waiting);
 	if (client->to_authfail_delay != NULL)
 		timeout_remove(&client->to_authfail_delay);
+	if (client->auth_response != NULL)
+		str_free(&client->auth_response);
 
 	if (client->fd != -1) {
 		net_disconnect(client->fd);
diff -r 19912e4a2fb3 -r e4235adb3044 src/login-common/client-common.h
--- a/src/login-common/client-common.h	Thu Aug 13 13:00:43 2009 -0400
+++ b/src/login-common/client-common.h	Thu Aug 13 13:31:27 2009 -0400
@@ -7,11 +7,10 @@
 
 /* max. size of input buffer. this means:
 
-   SASL: Max SASL request length from client
    IMAP: Max. length of a single parameter
    POP3: Max. length of a command line (spec says 512 would be enough)
 */
-#define LOGIN_MAX_INBUF_SIZE 4096
+#define LOGIN_MAX_INBUF_SIZE 1024
 /* max. size of output buffer. if it gets full, the client is disconnected.
    SASL authentication gives the largest output. */
 #define LOGIN_MAX_OUTBUF_SIZE 4096
@@ -64,7 +63,7 @@ struct client_vfuncs {
 	bool (*auth_handle_reply)(struct client *client,
 				  const struct client_auth_reply *reply);
 	void (*auth_send_challenge)(struct client *client, const char *data);
-	int (*auth_parse_response)(struct client *client, char **data_r);
+	int (*auth_parse_response)(struct client *client);
 	void (*proxy_reset)(struct client *client);
 	int (*proxy_parse_line)(struct client *client, const char *line);
 };
@@ -98,6 +97,7 @@ struct client {
 
 	char *auth_mech_name;
 	struct auth_request *auth_request;
+	string_t *auth_response;
 
 	unsigned int master_tag;
 	sasl_server_callback_t *sasl_callback;
@@ -157,7 +157,7 @@ void client_send_raw(struct client *clie
 
 void client_set_auth_waiting(struct client *client);
 void client_auth_send_challenge(struct client *client, const char *data);
-int client_auth_parse_response(struct client *client, char **data_r);
+int client_auth_parse_response(struct client *client);
 int client_auth_begin(struct client *client, const char *mech_name,
 		      const char *init_resp);
 bool client_check_plaintext_auth(struct client *client, bool pass_sent);


More information about the dovecot-cvs mailing list