imap-proxy.c revision 4b6ddd3770c8484da7308032b75fc93b91aa1b49
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (c) 2004-2008 Dovecot authors, see the included COPYING file */
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainenstatic int proxy_input_line(struct imap_client *client,
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen const char *msg;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* this is a banner */
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen client_syslog(&client->common, t_strdup_printf(
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen "proxy: Remote returned invalid banner: %s",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* send LOGIN command */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen imap_quote_append_string(str, client->proxy_user, FALSE);
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen imap_quote_append_string(str, client->proxy_password, FALSE);
8fa41238067c854435884c459963fde6f8c6436bTimo Sirainen (void)o_stream_send(output, str_data(str), str_len(str));
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen /* Login successful. Send this line to client. */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen (void)o_stream_send_str(client->output, client->cmd_tag);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen (void)o_stream_send_str(client->output, line + 1);
5aeb15e5817fbd4b1d8de540aa7673e3819a8030Timo Sirainen (void)o_stream_send(client->output, "\r\n", 2);
41e1c7380edda701719d8ce1fb4d465d2ec4c84dTimo Sirainen msg = t_strdup_printf("proxy(%s): started proxying to %s:%u",
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen login_proxy_detach(client->proxy, client->input,
9f32b9444d2a6db8f556d2c49ffceab1a59791ffTimo Sirainen /* If the backend server isn't Dovecot, the error message may
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen be different from Dovecot's "user doesn't exist" error. This
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen would allow an attacker to find out what users exist in the
648d24583c1574441c4fa0331a90bd4d6e7996c5Timo Sirainen The optimal way to handle this would be to replace the
ee246b46953e4b94b2f22e093373674fa9155500Timo Sirainen backend's "password failed" error message with Dovecot's
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen AUTH_FAILED_MSG, but this would require a new setting and
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen the sysadmin to actually bother setting it properly.
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen So for now we'll just forward the error message. This
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen shouldn't be a real problem since of course everyone will
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen be using only Dovecot as their backend :) */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* allow client input again */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client->io = io_add(client->common.fd, IO_READ,
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen /* probably some untagged reply */
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainenstatic void proxy_input(struct istream *input, struct ostream *output,
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen /* remote authentication failed, we're just
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen freeing the proxy */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* we came here from client_destroy() */
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen /* failed for some reason, probably server disconnected */
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen client_send_line(client, "* BYE Temporary login failure.");
d161e3c2cde2bd8d5917840f68823a2259ed426eTimo Sirainen /* buffer full */
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen "proxy: Remote input buffer full");
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen /* disconnected */
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen client_destroy(client, "Proxy: Remote disconnected");
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen while ((line = i_stream_next_line(input)) != NULL) {
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen if (proxy_input_line(client, output, line) < 0)
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainenint imap_proxy_new(struct imap_client *client, const char *host,
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen unsigned int port, const char *user, const char *password)
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen client_syslog(&client->common, "proxy: password not given");
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen /* connection_queue_add() decided that we were the oldest
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen connection and killed us. */
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen client->proxy = login_proxy_new(&client->common, host, port,
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen /* disable input until authentication is finished */