Mercurial > dovecot > core-2.2
changeset 10243:9c4740670030 HEAD
imap proxy: Always send post-login capability to client.
The original code did it only when client had used CAPABILITY command. Now
it's also sent in tagged reply to login/authenticate command if the remote
server didn't already add it.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 02 Nov 2009 13:39:54 -0500 |
parents | 2a00f1d762b0 |
children | a5e545002bf5 |
files | src/imap-login/imap-proxy.c |
diffstat | 1 files changed, 37 insertions(+), 28 deletions(-) [+] |
line wrap: on
line diff
--- a/src/imap-login/imap-proxy.c Fri Oct 30 15:36:12 2009 -0400 +++ b/src/imap-login/imap-proxy.c Mon Nov 02 13:39:54 2009 -0500 @@ -52,27 +52,9 @@ base64_encode(str_data(str), str_len(str), dest); } -static void -client_send_capability_if_needed(struct imap_client *client, string_t *str, - const char *capability) -{ - if (!client->client_ignores_capability_resp_code || capability == NULL) - return; - - /* reset this so that we don't re-send the CAPABILITY in case server - sends it multiple times */ - client->client_ignores_capability_resp_code = FALSE; - - /* client has used CAPABILITY command, so it didn't understand the - capabilities in the banner. send the backend's untagged CAPABILITY - reply and hope that the client understands it */ - str_printfa(str, "* CAPABILITY %s\r\n", capability); -} - static void proxy_write_login(struct imap_client *client, string_t *str) { - if (client->client_ignores_capability_resp_code) - str_append(str, "C CAPABILITY\r\n"); + str_append(str, "C CAPABILITY\r\n"); if (client->common.proxy_master_user == NULL) { /* logging in normally - use LOGIN command */ @@ -136,11 +118,45 @@ return 0; } +static void +client_send_login_reply(struct imap_client *client, string_t *str, + const char *line) +{ + const char *capability; + bool tagged_capability; + + capability = client->proxy_backend_capability; + tagged_capability = strncasecmp(line, "[CAPABILITY ", 12) == 0; + if (tagged_capability) + capability = t_strcut(line + 12, ']'); + + if (client->client_ignores_capability_resp_code && capability != NULL) { + /* client has used CAPABILITY command, so it didn't understand + the capabilities in the banner. send the backend's untagged + CAPABILITY reply and hope that the client understands it */ + str_printfa(str, "* CAPABILITY %s\r\n", capability); + } + str_append(str, client->cmd_tag); + str_append(str, " OK "); + if (!client->client_ignores_capability_resp_code && + !tagged_capability && capability != NULL) { + str_printfa(str, "[CAPABILITY %s] ", capability); + if (*line == '[') { + /* we need to send the capability. + skip over this resp-code */ + while (*line != ']' && *line != '\0') + line++; + if (*line == ' ') line++; + } + } + str_append(str, line); + str_append(str, "\r\n"); +} + int imap_proxy_parse_line(struct client *client, const char *line) { struct imap_client *imap_client = (struct imap_client *)client; struct ostream *output; - const char *capability; string_t *str; i_assert(!client->destroyed); @@ -191,15 +207,8 @@ return 1; } else if (strncmp(line, "L OK ", 5) == 0) { /* Login successful. Send this line to client. */ - capability = imap_client->proxy_backend_capability; - if (strncmp(line + 5, "[CAPABILITY ", 12) == 0) - capability = t_strcut(line + 5 + 12, ']'); - str = t_str_new(128); - client_send_capability_if_needed(imap_client, str, capability); - str_append(str, imap_client->cmd_tag); - str_append(str, line + 1); - str_append(str, "\r\n"); + client_send_login_reply(imap_client, str, line + 5); (void)o_stream_send(client->output, str_data(str), str_len(str));