client.c revision decb23442f9e6cd5c4845a9cb162029b8c6d5f0f
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen/* Copyright (c) 2002-2011 Dovecot authors, see the included COPYING file */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen/* maximum length for IMAP command line. */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen/* Disconnect client when it sends too many bad commands */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen/* Skip incoming data until newline is found,
c02a056b724abd6578fb8c4e439de0e94eaea6feTimo Sirainen returns TRUE if newline was found. */
c02a056b724abd6578fb8c4e439de0e94eaea6feTimo Sirainenbool client_skip_line(struct imap_client *client)
c02a056b724abd6578fb8c4e439de0e94eaea6feTimo Sirainen const unsigned char *data;
c02a056b724abd6578fb8c4e439de0e94eaea6feTimo Sirainen data = i_stream_get_data(client->common.input, &data_size);
c02a056b724abd6578fb8c4e439de0e94eaea6feTimo Sirainen for (i = 0; i < data_size; i++) {
c02a056b724abd6578fb8c4e439de0e94eaea6feTimo Sirainenstatic const char *get_capability(struct client *client)
c02a056b724abd6578fb8c4e439de0e94eaea6feTimo Sirainen struct imap_client *imap_client = (struct imap_client *)client;
c02a056b724abd6578fb8c4e439de0e94eaea6feTimo Sirainen if (*imap_client->set->imap_capability == '\0')
c02a056b724abd6578fb8c4e439de0e94eaea6feTimo Sirainen str_append(cap_str, CAPABILITY_BANNER_STRING);
c02a056b724abd6578fb8c4e439de0e94eaea6feTimo Sirainen else if (*imap_client->set->imap_capability != '+')
c02a056b724abd6578fb8c4e439de0e94eaea6feTimo Sirainen str_append(cap_str, imap_client->set->imap_capability);
c02a056b724abd6578fb8c4e439de0e94eaea6feTimo Sirainen str_append(cap_str, CAPABILITY_BANNER_STRING);
c02a056b724abd6578fb8c4e439de0e94eaea6feTimo Sirainen str_append(cap_str, imap_client->set->imap_capability + 1);
c02a056b724abd6578fb8c4e439de0e94eaea6feTimo Sirainen if (client->set->disable_plaintext_auth && !client->secured)
c02a056b724abd6578fb8c4e439de0e94eaea6feTimo Sirainen client_authenticate_get_capabilities(client, cap_str);
c02a056b724abd6578fb8c4e439de0e94eaea6feTimo Sirainenstatic int cmd_capability(struct imap_client *imap_client)
c02a056b724abd6578fb8c4e439de0e94eaea6feTimo Sirainen /* Client is required to send CAPABILITY after STARTTLS, so the
c02a056b724abd6578fb8c4e439de0e94eaea6feTimo Sirainen capability resp-code workaround checks only pre-STARTTLS
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen CAPABILITY commands. */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen imap_client->client_ignores_capability_resp_code = TRUE;
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen "* CAPABILITY ", get_capability(client), "\r\n", NULL));
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen "Pre-login capabilities listed, post-login capabilities have more.");
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenstatic int cmd_starttls(struct imap_client *client)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenclient_update_info(struct imap_client *client, const struct imap_arg *args)
c02a056b724abd6578fb8c4e439de0e94eaea6feTimo Sirainen else if (strcasecmp(key, "x-originating-port") == 0)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen else if (strcasecmp(key, "x-connected-ip") == 0)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen (void)net_addr2ip(value, &client->common.local_ip);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen else if (strcasecmp(key, "x-connected-port") == 0)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenstatic int cmd_id(struct imap_client *client, const struct imap_arg *args)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen value = imap_id_args_get_log_reply(args, env);
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen t_strdup_printf("* ID %s\r\n", imap_id_reply_generate(env)));
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen client_send_line(&client->common, CLIENT_CMD_REPLY_OK, "ID completed.");
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenstatic int cmd_noop(struct imap_client *client)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen client_send_line(&client->common, CLIENT_CMD_REPLY_OK,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen "NOOP completed.");
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenstatic int cmd_logout(struct imap_client *client)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen client_send_line(&client->common, CLIENT_CMD_REPLY_BYE, "Logging out");
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen client_send_line(&client->common, CLIENT_CMD_REPLY_OK,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen "Logout completed.");
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen client_destroy(&client->common, "Aborted login");
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenstatic int cmd_enable(struct imap_client *client)
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen client_send_raw(&client->common, "* ENABLED\r\n");
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen client_send_line(&client->common, CLIENT_CMD_REPLY_OK,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen "ENABLE ignored in non-authenticated state.");
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenstatic int client_command_execute(struct imap_client *client, const char *cmd,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen /* atom-specials: */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen /* list-wildcards: */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen /* quoted-specials: */
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainenstatic int client_parse_command(struct imap_client *client,
6c2c5f20760b06bfb4a40b0ee2ef5ab016bc41f0Timo Sirainen const char *msg;
if (fatal) {
return FALSE;
i_unreached();
int ret;
return FALSE;
if (ret == 0)
return FALSE;
if (ret < 0)
return TRUE;
if (ret == 0)
return FALSE;
} else if (ret < 0) {
return FALSE;
const char *text)
switch (reply) {
case CLIENT_CMD_REPLY_OK:
case CLIENT_CMD_REPLY_BAD:
case CLIENT_CMD_REPLY_BYE:
case CLIENT_CMD_REPLY_STATUS:
T_BEGIN {
if (tagged)
} T_END;
static void imap_login_preinit(void)
static void imap_login_init(void)
static void imap_login_deinit(void)
NULL,
NULL,