Mercurial > dovecot > core-2.2
changeset 20758:70b3c35378e1
imap-login: Honor nopipelining during preauth
author | Aki Tuomi <aki.tuomi@dovecot.fi> |
---|---|
date | Tue, 20 Sep 2016 15:02:42 +0300 |
parents | d06029ae9816 |
children | d891cab81b16 |
files | src/imap-login/imap-proxy.c |
diffstat | 1 files changed, 47 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/src/imap-login/imap-proxy.c Tue Sep 20 12:47:32 2016 +0300 +++ b/src/imap-login/imap-proxy.c Tue Sep 20 15:02:42 2016 +0300 @@ -55,6 +55,22 @@ i_free_and_null(client->proxy_password); } +static int proxy_write_starttls(struct imap_client *client, string_t *str) +{ + enum login_proxy_ssl_flags ssl_flags = login_proxy_get_ssl_flags(client->common.login_proxy); + if ((ssl_flags & PROXY_SSL_FLAG_STARTTLS) != 0) { + if (client->proxy_backend_capability != NULL && + !str_array_icase_find(t_strsplit(client->proxy_backend_capability, " "), "STARTTLS")) { + client_log_err(&client->common, + "proxy: Remote doesn't support STARTTLS"); + return -1; + } + str_append(str, "S STARTTLS\r\n"); + return 1; + } + return 0; +} + static int proxy_write_login(struct imap_client *client, string_t *str) { struct dsasl_client_settings sasl_set; @@ -131,9 +147,9 @@ static int proxy_input_banner(struct imap_client *client, struct ostream *output, const char *line) { - enum login_proxy_ssl_flags ssl_flags; const char *const *capabilities = NULL; string_t *str; + int ret; if (strncmp(line, "* OK ", 5) != 0) { client_log_err(&client->common, t_strdup_printf( @@ -145,8 +161,6 @@ str = t_str_new(128); if (strncmp(line + 5, "[CAPABILITY ", 12) == 0) { capabilities = t_strsplit(t_strcut(line + 5 + 12, ']'), " "); - if (str_array_icase_find(capabilities, "ID")) - proxy_write_id(client, str); if (str_array_icase_find(capabilities, "SASL-IR")) client->proxy_sasl_ir = TRUE; if (str_array_icase_find(capabilities, "LOGINDISABLED")) @@ -154,18 +168,19 @@ i_free(client->proxy_backend_capability); client->proxy_backend_capability = i_strdup(t_strcut(line + 5 + 12, ']')); + if (str_array_icase_find(capabilities, "ID")) { + proxy_write_id(client, str); + if (client->common.proxy_nopipelining) { + /* write login or starttls after I OK */ + o_stream_nsend(output, str_data(str), str_len(str)); + return 0; + } + } } - ssl_flags = login_proxy_get_ssl_flags(client->common.login_proxy); - if ((ssl_flags & PROXY_SSL_FLAG_STARTTLS) != 0) { - if (capabilities != NULL && - !str_array_icase_find(capabilities, "STARTTLS")) { - client_log_err(&client->common, - "proxy: Remote doesn't support STARTTLS"); - return -1; - } - str_append(str, "S STARTTLS\r\n"); - } else { + if ((ret = proxy_write_starttls(client, str)) < 0) { + return -1; + } else if (ret == 0) { if (proxy_write_login(client, str) < 0) return -1; } @@ -359,10 +374,26 @@ return 1; } return 0; - } else if (strncasecmp(line, "I ", 2) == 0 || - strncasecmp(line, "* ID ", 5) == 0) { + } else if (strncasecmp(line, "I ", 2) == 0) { + /* Reply to ID command we sent, ignore it unless + pipelining is disabled, in which case send + either STARTTLS or login */ + client->proxy_state = IMAP_PROXY_STATE_ID; + + if (client->proxy_nopipelining) + str = t_str_new(128); + if ((ret = proxy_write_starttls(imap_client, str)) < 0) { + return -1; + } else if (ret == 0) { + if (proxy_write_login(imap_client, str) < 0) + return -1; + } + o_stream_nsend(output, str_data(str), str_len(str)); + return 1; + } + return 0; + } else if (strncasecmp(line, "* ID ", 5) == 0) { /* Reply to ID command we sent, ignore it */ - client->proxy_state = IMAP_PROXY_STATE_ID; return 0; } else if (strncmp(line, "* ", 2) == 0) { /* untagged reply. just foward it. */