pop3-proxy.c revision 26681e71837ebbb3eb92455ec4e3cadefa710f82
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter/* Copyright (c) 2004-2013 Dovecot authors, see the included COPYING file */
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter#include "login-common.h"
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter#include "ioloop.h"
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter#include "istream.h"
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter#include "ostream.h"
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter#include "base64.h"
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter#include "safe-memset.h"
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter#include "str.h"
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter#include "str-sanitize.h"
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter#include "sasl-client.h"
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter#include "client.h"
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter#include "pop3-proxy.h"
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walterstatic void proxy_free_password(struct client *client)
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter{
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter if (client->proxy_password == NULL)
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter return;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter safe_memset(client->proxy_password, 0, strlen(client->proxy_password));
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter i_free_and_null(client->proxy_password);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter}
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walterstatic int proxy_send_login(struct pop3_client *client, struct ostream *output)
8dc21698c4ed699801d2b6f9135b3d6cb8512917Lukas Slebodnik{
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter struct sasl_client_settings sasl_set;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter const unsigned char *sasl_output;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter unsigned int len;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter const char *mech_name, *error;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter string_t *str;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter i_assert(client->common.proxy_ttl > 1);
1203e462650f035b0df2304075d60b9a99e36715Stef Walter if (client->proxy_xclient) {
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter /* remote supports XCLIENT, send it */
1203e462650f035b0df2304075d60b9a99e36715Stef Walter o_stream_nsend_str(output, t_strdup_printf(
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter "XCLIENT ADDR=%s PORT=%u SESSION=%s TTL=%u\r\n",
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik net_ip2addr(&client->common.ip),
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik client->common.remote_port,
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik client_get_session_id(&client->common),
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik client->common.proxy_ttl - 1));
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik client->common.proxy_state = POP3_PROXY_XCLIENT;
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik } else {
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik client->common.proxy_state = POP3_PROXY_LOGIN1;
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik }
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik str = t_str_new(128);
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik if (client->common.proxy_mech == NULL) {
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik /* send USER command */
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik str_append(str, "USER ");
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik str_append(str, client->common.proxy_user);
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik str_append(str, "\r\n");
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter o_stream_nsend(output, str_data(str), str_len(str));
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter return 0;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter }
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter i_assert(client->common.proxy_sasl_client == NULL);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter memset(&sasl_set, 0, sizeof(sasl_set));
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter sasl_set.authid = client->common.proxy_master_user != NULL ?
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter client->common.proxy_master_user : client->common.proxy_user;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter sasl_set.authzid = client->common.proxy_user;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter sasl_set.password = client->common.proxy_password;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter client->common.proxy_sasl_client =
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter sasl_client_new(client->common.proxy_mech, &sasl_set);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter mech_name = sasl_client_mech_get_name(client->common.proxy_mech);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter str_printfa(str, "AUTH %s ", mech_name);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter if (sasl_client_output(client->common.proxy_sasl_client,
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter &sasl_output, &len, &error) < 0) {
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter client_log_err(&client->common, t_strdup_printf(
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter "proxy: SASL mechanism %s init failed: %s",
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter mech_name, error));
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter return -1;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter }
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter if (len == 0)
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter str_append_c(str, '=');
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter else
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter base64_encode(sasl_output, len, str);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter str_append(str, "\r\n");
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter o_stream_nsend(output, str_data(str), str_len(str));
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter proxy_free_password(&client->common);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter if (client->common.proxy_state != POP3_PROXY_XCLIENT)
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter client->common.proxy_state = POP3_PROXY_LOGIN2;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter return 0;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter}
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walterstatic int
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walterpop3_proxy_continue_sasl_auth(struct client *client, struct ostream *output,
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter const char *line)
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter{
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter string_t *str;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter const unsigned char *data;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter unsigned int data_len;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter const char *error;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter int ret;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter str = t_str_new(128);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter if (base64_decode(line, strlen(line), NULL, str) < 0) {
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter client_log_err(client, "proxy: Server sent invalid base64 data in AUTH response");
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter return -1;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter }
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter ret = sasl_client_input(client->proxy_sasl_client,
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter str_data(str), str_len(str), &error);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter if (ret == 0) {
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter ret = sasl_client_output(client->proxy_sasl_client,
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter &data, &data_len, &error);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter }
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter if (ret < 0) {
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter client_log_err(client, t_strdup_printf(
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter "proxy: Server sent invalid authentication data: %s",
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter error));
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter return -1;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter }
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter i_assert(ret == 0);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter str_truncate(str, 0);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter base64_encode(data, data_len, str);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter str_append(str, "\r\n");
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter o_stream_nsend(output, str_data(str), str_len(str));
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter return 0;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter}
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walterint pop3_proxy_parse_line(struct client *client, const char *line)
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter{
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter struct pop3_client *pop3_client = (struct pop3_client *)client;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter struct ostream *output;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter enum login_proxy_ssl_flags ssl_flags;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter i_assert(!client->destroyed);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter output = login_proxy_get_ostream(client->login_proxy);
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter switch (client->proxy_state) {
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter case POP3_PROXY_BANNER:
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter /* this is a banner */
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter if (strncmp(line, "+OK", 3) != 0) {
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter client_log_err(client, t_strdup_printf(
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter "proxy: Remote returned invalid banner: %s",
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter str_sanitize(line, 160)));
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter client_proxy_failed(client, TRUE);
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter return -1;
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter }
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter pop3_client->proxy_xclient =
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter strncmp(line+3, " [XCLIENT]", 10) == 0;
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter ssl_flags = login_proxy_get_ssl_flags(client->login_proxy);
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter if ((ssl_flags & PROXY_SSL_FLAG_STARTTLS) == 0) {
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter if (proxy_send_login(pop3_client, output) < 0) {
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter client_proxy_failed(client, TRUE);
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter return -1;
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter }
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter } else {
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter o_stream_nsend_str(output, "STLS\r\n");
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter client->proxy_state = POP3_PROXY_STARTTLS;
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter }
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter return 0;
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter case POP3_PROXY_STARTTLS:
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter if (strncmp(line, "+OK", 3) != 0) {
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter client_log_err(client, t_strdup_printf(
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter "proxy: Remote STLS failed: %s",
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter str_sanitize(line, 160)));
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter client_proxy_failed(client, TRUE);
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter return -1;
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter }
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter if (login_proxy_starttls(client->login_proxy) < 0) {
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter client_proxy_failed(client, TRUE);
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter return -1;
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter }
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter /* i/ostreams changed. */
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter output = login_proxy_get_ostream(client->login_proxy);
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter if (proxy_send_login(pop3_client, output) < 0) {
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter client_proxy_failed(client, TRUE);
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter return -1;
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter }
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter return 1;
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter case POP3_PROXY_XCLIENT:
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter if (strncmp(line, "+OK", 3) != 0) {
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter client_log_err(client, t_strdup_printf(
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter "proxy: Remote XCLIENT failed: %s",
c3c6eb141d6a288b3da20ad6a2e5718844b2d4adPavel Reichl str_sanitize(line, 160)));
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter client_proxy_failed(client, TRUE);
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter return -1;
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter }
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter client->proxy_state = client->proxy_sasl_client == NULL ?
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter POP3_PROXY_LOGIN1 : POP3_PROXY_LOGIN2;
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter return 0;
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter case POP3_PROXY_LOGIN1:
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter i_assert(client->proxy_sasl_client == NULL);
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter if (strncmp(line, "+OK", 3) != 0)
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter break;
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter /* USER successful, send PASS */
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter o_stream_nsend_str(output, t_strdup_printf(
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter "PASS %s\r\n", client->proxy_password));
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter proxy_free_password(client);
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter client->proxy_state = POP3_PROXY_LOGIN2;
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter return 0;
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter case POP3_PROXY_LOGIN2:
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter if (strncmp(line, "+ ", 2) == 0 &&
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter client->proxy_sasl_client != NULL) {
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter /* continue SASL authentication */
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter if (pop3_proxy_continue_sasl_auth(client, output,
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter line+2) < 0) {
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter client_proxy_failed(client, TRUE);
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter return -1;
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter }
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter return 0;
1203e462650f035b0df2304075d60b9a99e36715Stef Walter }
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter if (strncmp(line, "+OK", 3) != 0)
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter break;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter /* Login successful. Send this line to client. */
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter line = t_strconcat(line, "\r\n", NULL);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter o_stream_nsend_str(client->output, line);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter client_proxy_finish_destroy_client(client);
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter return 1;
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter }
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
1203e462650f035b0df2304075d60b9a99e36715Stef Walter /* Login failed. Pass through the error message to client.
1203e462650f035b0df2304075d60b9a99e36715Stef Walter
1203e462650f035b0df2304075d60b9a99e36715Stef Walter If the backend server isn't Dovecot, the error message may
1203e462650f035b0df2304075d60b9a99e36715Stef Walter be different from Dovecot's "user doesn't exist" error. This
1203e462650f035b0df2304075d60b9a99e36715Stef Walter would allow an attacker to find out what users exist in the
1203e462650f035b0df2304075d60b9a99e36715Stef Walter system.
1203e462650f035b0df2304075d60b9a99e36715Stef Walter
1203e462650f035b0df2304075d60b9a99e36715Stef Walter The optimal way to handle this would be to replace the
1203e462650f035b0df2304075d60b9a99e36715Stef Walter backend's "password failed" error message with Dovecot's
1203e462650f035b0df2304075d60b9a99e36715Stef Walter AUTH_FAILED_MSG, but this would require a new setting and
1203e462650f035b0df2304075d60b9a99e36715Stef Walter the sysadmin to actually bother setting it properly.
1203e462650f035b0df2304075d60b9a99e36715Stef Walter
1203e462650f035b0df2304075d60b9a99e36715Stef Walter So for now we'll just forward the error message. This
1203e462650f035b0df2304075d60b9a99e36715Stef Walter shouldn't be a real problem since of course everyone will
1203e462650f035b0df2304075d60b9a99e36715Stef Walter be using only Dovecot as their backend :) */
1203e462650f035b0df2304075d60b9a99e36715Stef Walter if (strncmp(line, "-ERR ", 5) != 0) {
1203e462650f035b0df2304075d60b9a99e36715Stef Walter client_send_reply(client, POP3_CMD_REPLY_ERROR,
1203e462650f035b0df2304075d60b9a99e36715Stef Walter AUTH_FAILED_MSG);
1203e462650f035b0df2304075d60b9a99e36715Stef Walter } else {
1203e462650f035b0df2304075d60b9a99e36715Stef Walter client_send_raw(client, t_strconcat(line, "\r\n", NULL));
1203e462650f035b0df2304075d60b9a99e36715Stef Walter }
1203e462650f035b0df2304075d60b9a99e36715Stef Walter
1203e462650f035b0df2304075d60b9a99e36715Stef Walter if (client->set->auth_verbose) {
1203e462650f035b0df2304075d60b9a99e36715Stef Walter if (strncmp(line, "-ERR ", 5) == 0)
1203e462650f035b0df2304075d60b9a99e36715Stef Walter line += 5;
1203e462650f035b0df2304075d60b9a99e36715Stef Walter client_proxy_log_failure(client, line);
1203e462650f035b0df2304075d60b9a99e36715Stef Walter }
1203e462650f035b0df2304075d60b9a99e36715Stef Walter client->proxy_auth_failed = TRUE;
1203e462650f035b0df2304075d60b9a99e36715Stef Walter client_proxy_failed(client, FALSE);
1203e462650f035b0df2304075d60b9a99e36715Stef Walter return -1;
1203e462650f035b0df2304075d60b9a99e36715Stef Walter}
1203e462650f035b0df2304075d60b9a99e36715Stef Walter
1203e462650f035b0df2304075d60b9a99e36715Stef Waltervoid pop3_proxy_reset(struct client *client)
1203e462650f035b0df2304075d60b9a99e36715Stef Walter{
1203e462650f035b0df2304075d60b9a99e36715Stef Walter client->proxy_state = POP3_PROXY_BANNER;
1203e462650f035b0df2304075d60b9a99e36715Stef Walter}
1203e462650f035b0df2304075d60b9a99e36715Stef Walter
1203e462650f035b0df2304075d60b9a99e36715Stef Waltervoid pop3_proxy_error(struct client *client, const char *text)
8dc21698c4ed699801d2b6f9135b3d6cb8512917Lukas Slebodnik{
1203e462650f035b0df2304075d60b9a99e36715Stef Walter client_send_reply(client, POP3_CMD_REPLY_ERROR, text);
8dc21698c4ed699801d2b6f9135b3d6cb8512917Lukas Slebodnik}
1203e462650f035b0df2304075d60b9a99e36715Stef Walter