pop3-proxy.c revision 6d24551e169c0808695db35d7a228f1970a84c75
5a580c3a38ced62d4bcc95b8ac7c4f2935b5d294Timo Sirainen/* Copyright (c) 2004-2016 Dovecot authors, see the included COPYING file */
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic void proxy_free_password(struct client *client)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch safe_memset(client->proxy_password, 0, strlen(client->proxy_password));
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainenstatic int proxy_send_login(struct pop3_client *client, struct ostream *output)
6a90041707f1290c8970a3bacb0f8f928aeaaba6Stephan Bosch const unsigned char *sasl_output;
6a90041707f1290c8970a3bacb0f8f928aeaaba6Stephan Bosch unsigned int len;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* remote supports XCLIENT, send it */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch "XCLIENT ADDR=%s PORT=%u SESSION=%s TTL=%u\r\n",
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch client->common.proxy_state = POP3_PROXY_XCLIENT;
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen client->common.proxy_state = POP3_PROXY_LOGIN1;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* send USER command */
6a90041707f1290c8970a3bacb0f8f928aeaaba6Stephan Bosch o_stream_nsend(output, str_data(str), str_len(str));
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch i_assert(client->common.proxy_sasl_client == NULL);
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen sasl_set.authid = client->common.proxy_master_user != NULL ?
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch client->common.proxy_master_user : client->common.proxy_user;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch sasl_set.password = client->common.proxy_password;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch dsasl_client_new(client->common.proxy_mech, &sasl_set);
1bc12a53ddc6696bb209fb79d7cc66262d2ea621Timo Sirainen mech_name = dsasl_client_mech_get_name(client->common.proxy_mech);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (dsasl_client_output(client->common.proxy_sasl_client,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch client_log_err(&client->common, t_strdup_printf(
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch "proxy: SASL mechanism %s init failed: %s",
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen o_stream_nsend(output, str_data(str), str_len(str));
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen if (client->common.proxy_state != POP3_PROXY_XCLIENT)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch client->common.proxy_state = POP3_PROXY_LOGIN2;
7384b4e78eaab44693c985192276e31322155e32Stephan Boschpop3_proxy_continue_sasl_auth(struct client *client, struct ostream *output,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch const unsigned char *data;
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen if (base64_decode(line, strlen(line), NULL, str) < 0) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch client_log_err(client, "proxy: Server sent invalid base64 data in AUTH response");
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch ret = dsasl_client_input(client->proxy_sasl_client,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch ret = dsasl_client_output(client->proxy_sasl_client,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch "proxy: Server sent invalid authentication data: %s",
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch o_stream_nsend(output, str_data(str), str_len(str));
7384b4e78eaab44693c985192276e31322155e32Stephan Boschint pop3_proxy_parse_line(struct client *client, const char *line)
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen struct pop3_client *pop3_client = (struct pop3_client *)client;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch output = login_proxy_get_ostream(client->login_proxy);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* this is a banner */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch "proxy: Remote returned invalid banner: %s",
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch ssl_flags = login_proxy_get_ssl_flags(client->login_proxy);
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen if ((ssl_flags & PROXY_SSL_FLAG_STARTTLS) == 0) {
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen if (proxy_send_login(pop3_client, output) < 0) {
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen "proxy: Remote STLS failed: %s",
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (login_proxy_starttls(client->login_proxy) < 0) {
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen /* i/ostreams changed. */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch output = login_proxy_get_ostream(client->login_proxy);
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen if (proxy_send_login(pop3_client, output) < 0) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch "proxy: Remote XCLIENT failed: %s",
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch client->proxy_state = client->proxy_sasl_client == NULL ?
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* USER successful, send PASS */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* continue SASL authentication */
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen if (pop3_proxy_continue_sasl_auth(client, output,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* Login successful. Send this line to client. */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* Login failed. Pass through the error message to client.
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch If the backend server isn't Dovecot, the error message may
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch be different from Dovecot's "user doesn't exist" error. This
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch would allow an attacker to find out what users exist in the
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch The optimal way to handle this would be to replace the
6a90041707f1290c8970a3bacb0f8f928aeaaba6Stephan Bosch backend's "password failed" error message with Dovecot's
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch AUTH_FAILED_MSG, but this would require a new setting and
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch the sysadmin to actually bother setting it properly.
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch So for now we'll just forward the error message. This
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch shouldn't be a real problem since of course everyone will
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch be using only Dovecot as their backend :) */
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen client_send_reply(client, POP3_CMD_REPLY_ERROR,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch client_send_raw(client, t_strconcat(line, "\r\n", NULL));
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainenvoid pop3_proxy_error(struct client *client, const char *text)