From: Timo Sirainen Date: Mon, 23 Dec 2013 13:30:31 +0000 (+0200) Subject: imap proxy: Added proxy_nopipelining passdb setting to work around other servers... X-Git-Tag: 2.2.11~53 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ab281fc992907b6cf6c730f672dc3aa4c6685015;p=thirdparty%2Fdovecot%2Fcore.git imap proxy: Added proxy_nopipelining passdb setting to work around other servers' bugs. --- diff --git a/src/imap-login/imap-proxy.c b/src/imap-login/imap-proxy.c index 5423f68be2..3d911560ba 100644 --- a/src/imap-login/imap-proxy.c +++ b/src/imap-login/imap-proxy.c @@ -63,8 +63,13 @@ static int proxy_write_login(struct imap_client *client, string_t *str) unsigned int len; const char *mech_name, *error; - if (client->proxy_backend_capability == NULL) + if (client->proxy_backend_capability == NULL) { str_append(str, "C CAPABILITY\r\n"); + if (client->common.proxy_nopipelining) { + /* authenticate only after receiving C OK reply. */ + return 0; + } + } if (client->common.proxy_mech == NULL) { /* logging in normally - use LOGIN command */ @@ -271,6 +276,14 @@ int imap_proxy_parse_line(struct client *client, const char *line) } o_stream_nsend(output, str_data(str), str_len(str)); return 1; + } else if (strncmp(line, "C OK ", 5) == 0 && + client->proxy_password != NULL) { + /* pipelining was disabled, send the login now. */ + str = t_str_new(128); + if (proxy_write_login(imap_client, str) < 0) + return -1; + o_stream_nsend(output, str_data(str), str_len(str)); + return 1; } else if (strncmp(line, "L OK ", 5) == 0) { /* Login successful. Send this line to client. */ client->proxy_state = IMAP_PROXY_STATE_LOGIN; diff --git a/src/login-common/client-common-auth.c b/src/login-common/client-common-auth.c index bf80d379ce..bc44a4f6b0 100644 --- a/src/login-common/client-common-auth.c +++ b/src/login-common/client-common-auth.c @@ -107,6 +107,8 @@ static void client_auth_parse_args(struct client *client, reply_r->proxy_refresh_secs = atoi(value); else if (strcmp(key, "proxy_mech") == 0) reply_r->proxy_mech = value; + else if (strcmp(key, "proxy_nopipelining") == 0) + reply_r->proxy_nopipelining = TRUE; else if (strcmp(key, "master") == 0) reply_r->master_user = value; else if (strcmp(key, "ssl") == 0) { @@ -350,6 +352,7 @@ static int proxy_start(struct client *client, client->proxy_user = i_strdup(reply->destuser); client->proxy_master_user = i_strdup(reply->master_user); client->proxy_password = i_strdup(reply->password); + client->proxy_nopipelining = reply->proxy_nopipelining; /* disable input until authentication is finished */ if (client->io != NULL) diff --git a/src/login-common/client-common.h b/src/login-common/client-common.h index 49def5c753..89ee4c69d1 100644 --- a/src/login-common/client-common.h +++ b/src/login-common/client-common.h @@ -62,6 +62,7 @@ struct client_auth_reply { enum login_proxy_ssl_flags ssl_flags; unsigned int proxy:1; + unsigned int proxy_nopipelining:1; unsigned int temp:1; unsigned int nologin:1; unsigned int authz_failure:1; @@ -157,6 +158,7 @@ struct client { unsigned int auth_initializing:1; unsigned int auth_process_comm_fail:1; unsigned int proxy_auth_failed:1; + unsigned int proxy_nopipelining:1; unsigned int auth_waiting:1; unsigned int auth_user_disabled:1; unsigned int auth_pass_expired:1;