Skip to content

Commit

Permalink
imapc: Added imapc_max_line_length to limit maximum memory usage.
Browse files Browse the repository at this point in the history
The default is still unlimited, but this should be set to something smaller
for untrusted servers.
  • Loading branch information
sirainen committed Oct 6, 2016
1 parent 7f51e86 commit c23ebb9
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 3 deletions.
2 changes: 2 additions & 0 deletions src/lib-imap-client/imapc-client.c
Expand Up @@ -69,6 +69,8 @@ imapc_client_init(const struct imapc_client_settings *set)
IMAPC_DEFAULT_CONNECT_TIMEOUT_MSECS;
client->set.cmd_timeout_msecs = set->cmd_timeout_msecs != 0 ?
set->cmd_timeout_msecs : IMAPC_DEFAULT_COMMAND_TIMEOUT_MSECS;
client->set.max_line_length = set->max_line_length != 0 ?
set->max_line_length : IMAPC_DEFAULT_MAX_LINE_LENGTH;
client->set.throttle_set = set->throttle_set;

if (client->set.throttle_set.init_msecs == 0)
Expand Down
5 changes: 5 additions & 0 deletions src/lib-imap-client/imapc-client.h
Expand Up @@ -56,6 +56,7 @@ enum imapc_client_ssl_mode {

#define IMAPC_DEFAULT_CONNECT_TIMEOUT_MSECS (1000*30)
#define IMAPC_DEFAULT_COMMAND_TIMEOUT_MSECS (1000*60*5)
#define IMAPC_DEFAULT_MAX_LINE_LENGTH ((size_t)-1)

struct imapc_throttling_settings {
unsigned int init_msecs;
Expand Down Expand Up @@ -93,6 +94,10 @@ struct imapc_client_settings {
sent or received. 0 = default. */
unsigned int cmd_timeout_msecs;

/* Maximum allowed line length (not including literals read as
streams). 0 = unlimited. */
size_t max_line_length;

struct imapc_throttling_settings throttle_set;
};

Expand Down
12 changes: 9 additions & 3 deletions src/lib-imap-client/imapc-connection.c
Expand Up @@ -1437,11 +1437,15 @@ static void imapc_connection_input(struct imapc_connection *conn)
imapc_connection_input_pending(conn);

if (ret < 0) {
/* disconnected */
/* disconnected or buffer full */
str = t_str_new(128);
if (conn->disconnect_reason != NULL) {
str_printfa(str, "Server disconnected with message: %s",
conn->disconnect_reason);
} else if (ret == -2) {
str_printfa(str, "Server sent too large input "
"(buffer full at %"PRIuSIZE_T")",
i_stream_get_data_size(conn->input));
} else if (conn->ssl_iostream == NULL) {
errstr = conn->input->stream_errno == 0 ? "EOF" :
i_stream_get_error(conn->input);
Expand Down Expand Up @@ -1640,7 +1644,8 @@ static void imapc_connection_connect_next_ip(struct imapc_connection *conn)
}
}
conn->fd = fd;
conn->input = conn->raw_input = i_stream_create_fd(fd, (size_t)-1);
conn->input = conn->raw_input =
i_stream_create_fd(fd, conn->client->set.max_line_length);
conn->output = conn->raw_output = o_stream_create_fd(fd, (size_t)-1);
o_stream_set_no_error_handling(conn->output, TRUE);

Expand All @@ -1653,7 +1658,8 @@ static void imapc_connection_connect_next_ip(struct imapc_connection *conn)
o_stream_set_flush_callback(conn->output, imapc_connection_output,
conn);
conn->io = io_add(fd, IO_WRITE, imapc_connection_connected, conn);
conn->parser = imap_parser_create(conn->input, NULL, (size_t)-1);
conn->parser = imap_parser_create(conn->input, NULL,
conn->client->set.max_line_length);
conn->to = timeout_add(conn->client->set.connect_timeout_msecs,
imapc_connection_timeout, conn);
conn->to_output = timeout_add(conn->client->set.max_idle_time*1000,
Expand Down
2 changes: 2 additions & 0 deletions src/lib-storage/index/imapc/imapc-settings.c
Expand Up @@ -30,6 +30,7 @@ static const struct setting_define imapc_setting_defines[] = {
DEF(SET_STR, imapc_list_prefix),
DEF(SET_TIME, imapc_cmd_timeout),
DEF(SET_TIME, imapc_max_idle_time),
DEF(SET_SIZE, imapc_max_line_length),

DEF(SET_STR, pop3_deleted_flag),

Expand All @@ -53,6 +54,7 @@ static const struct imapc_settings imapc_default_settings = {
.imapc_list_prefix = "",
.imapc_cmd_timeout = 5*60,
.imapc_max_idle_time = 60*29,
.imapc_max_line_length = 0,

.pop3_deleted_flag = ""
};
Expand Down
1 change: 1 addition & 0 deletions src/lib-storage/index/imapc/imapc-settings.h
Expand Up @@ -36,6 +36,7 @@ struct imapc_settings {
const char *imapc_list_prefix;
unsigned int imapc_cmd_timeout;
unsigned int imapc_max_idle_time;
uoff_t imapc_max_line_length;

const char *pop3_deleted_flag;

Expand Down
1 change: 1 addition & 0 deletions src/lib-storage/index/imapc/imapc-storage.c
Expand Up @@ -281,6 +281,7 @@ int imapc_storage_client_create(struct mail_namespace *ns,
set.use_proxyauth = (imapc_set->parsed_features & IMAPC_FEATURE_PROXYAUTH) != 0;
set.cmd_timeout_msecs = imapc_set->imapc_cmd_timeout * 1000;
set.max_idle_time = imapc_set->imapc_max_idle_time;
set.max_line_length = imapc_set->imapc_max_line_length;
set.dns_client_socket_path = *ns->user->set->base_dir == '\0' ? "" :
t_strconcat(ns->user->set->base_dir, "/",
DNS_CLIENT_SOCKET_NAME, NULL);
Expand Down

0 comments on commit c23ebb9

Please sign in to comment.