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