pop3-proxy.c revision 45312f52ff3a3d4c137447be4c7556500c2f8bf2
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter/* Copyright (c) 2004-2009 Dovecot authors, see the included COPYING file */
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter#include "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 "client.h"
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter#include "pop3-proxy.h"
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter#define PROXY_FAILURE_MSG "-ERR [IN-USE] "AUTH_TEMP_FAILED_MSG
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walterstatic void proxy_free_password(struct pop3_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
8dc21698c4ed699801d2b6f9135b3d6cb8512917Lukas Slebodnikstatic void proxy_failed(struct pop3_client *client, bool send_line)
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter{
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter if (send_line)
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter client_send_line(client, PROXY_FAILURE_MSG);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter login_proxy_free(&client->proxy);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter proxy_free_password(client);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter i_free_and_null(client->proxy_user);
1203e462650f035b0df2304075d60b9a99e36715Stef Walter i_free_and_null(client->proxy_master_user);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
1203e462650f035b0df2304075d60b9a99e36715Stef Walter /* call this last - it may destroy the client */
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter client_auth_failed(client, TRUE);
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik}
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnikstatic void get_plain_auth(struct pop3_client *client, string_t *dest)
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik{
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik string_t *str;
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik str = t_str_new(128);
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik str_append(str, client->proxy_user);
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik str_append_c(str, '\0');
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik str_append(str, client->proxy_master_user);
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik str_append_c(str, '\0');
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik str_append(str, client->proxy_password);
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik base64_encode(str_data(str), str_len(str), dest);
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik}
1a94716209e40a9ccaedc7e70f9de961d1cced48Lukas Slebodnik
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walterstatic int proxy_input_line(struct pop3_client *client,
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter struct ostream *output, const char *line)
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter{
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter string_t *str;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter i_assert(!client->destroyed);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter switch (client->proxy_state) {
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter case 0:
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter /* this is a banner */
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter if (strncmp(line, "+OK", 3) != 0) {
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter client_syslog_err(&client->common, t_strdup_printf(
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter "proxy: Remote returned invalid banner: %s",
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter str_sanitize(line, 160)));
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter proxy_failed(client, TRUE);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter return -1;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter }
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter str = t_str_new(128);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter if (client->proxy_master_user == NULL) {
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter /* send USER command */
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter str_append(str, "USER ");
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter str_append(str, client->proxy_user);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter str_append(str, "\r\n");
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter } else {
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter /* master user login - use AUTH PLAIN. */
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter str_append(str, "AUTH PLAIN\r\n");
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter }
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter (void)o_stream_send(output, str_data(str), str_len(str));
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter client->proxy_state++;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter return 0;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter case 1:
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter str = t_str_new(128);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter if (client->proxy_master_user == NULL) {
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter if (strncmp(line, "+OK", 3) != 0)
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter break;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter /* USER successful, send PASS */
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter str_append(str, "PASS ");
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter str_append(str, client->proxy_password);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter str_append(str, "\r\n");
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter } else {
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter if (*line != '+')
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter break;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter /* AUTH successful, send the authentication data */
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter get_plain_auth(client, str);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter str_append(str, "\r\n");
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter }
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter (void)o_stream_send(output, str_data(str), str_len(str));
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter proxy_free_password(client);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter client->proxy_state++;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter return 0;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter case 2:
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 (void)o_stream_send_str(client->output, line);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter str = t_str_new(128);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter str_printfa(str, "proxy(%s): started proxying to %s:%u",
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter client->common.virtual_user,
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter login_proxy_get_host(client->proxy),
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter login_proxy_get_port(client->proxy));
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter if (strcmp(client->common.virtual_user,
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter client->proxy_user) != 0) {
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter /* remote username is different, log it */
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter str_append_c(str, '/');
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter str_append(str, client->proxy_user);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter }
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter if (client->proxy_master_user != NULL) {
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter str_printfa(str, " (master %s)",
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter client->proxy_master_user);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter }
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter login_proxy_detach(client->proxy, client->common.input,
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter client->output);
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter client->proxy = NULL;
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter client->common.input = NULL;
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter client->output = NULL;
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter client->common.fd = -1;
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter client_destroy_success(client, str_c(str));
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter return 0;
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter }
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter /* Login failed. Pass through the error message to client
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter (see imap-proxy code for potential problems with this) */
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter if (strncmp(line, "-ERR ", 5) != 0)
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter client_send_line(client, "-ERR "AUTH_FAILED_MSG);
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter else
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter client_send_line(client, line);
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter if (verbose_auth) {
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter str = t_str_new(128);
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter str_printfa(str, "proxy(%s): Login failed to %s:%u",
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter client->common.virtual_user,
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter login_proxy_get_host(client->proxy),
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter login_proxy_get_port(client->proxy));
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter if (strcmp(client->common.virtual_user,
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter client->proxy_user) != 0) {
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter /* remote username is different, log it */
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter str_append_c(str, '/');
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter str_append(str, client->proxy_user);
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter }
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter if (client->proxy_master_user != NULL) {
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter str_printfa(str, " (master %s)",
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter client->proxy_master_user);
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter }
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter str_append(str, ": ");
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter if (strncmp(line, "-ERR ", 5) == 0)
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter str_append(str, line + 5);
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter else
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter str_append(str, line);
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter i_info("%s", str_c(str));
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter }
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter proxy_failed(client, FALSE);
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter return -1;
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter}
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walterstatic void proxy_input(struct istream *input, struct ostream *output,
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter struct pop3_client *client)
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter{
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter const char *line;
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter if (input == NULL) {
c3c6eb141d6a288b3da20ad6a2e5718844b2d4adPavel Reichl if (client->proxy == NULL) {
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter /* we're just freeing the proxy */
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter return;
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter }
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter if (client->destroyed) {
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter /* we came here from client_destroy() */
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter return;
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter }
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter /* failed for some reason, probably server disconnected */
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter proxy_failed(client, TRUE);
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter return;
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter }
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter i_assert(!client->destroyed);
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter switch (i_stream_read(input)) {
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter case -2:
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter client_syslog_err(&client->common,
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter "proxy: Remote input buffer full");
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter proxy_failed(client, TRUE);
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter return;
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter case -1:
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter client_syslog_err(&client->common,
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter "proxy: Remote disconnected");
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter proxy_failed(client, TRUE);
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter return;
1203e462650f035b0df2304075d60b9a99e36715Stef Walter }
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter while ((line = i_stream_next_line(input)) != NULL) {
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter if (proxy_input_line(client, output, line) < 0)
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter break;
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter }
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter}
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walterint pop3_proxy_new(struct pop3_client *client, const char *host,
fcd8093c58638dc7c4f9cddfc97f273b94ce2eadStef Walter unsigned int port, const char *user, const char *master_user,
c2cc119de8eac712c040b3993f41c967ff2278deStef Walter const char *password)
b699c4d7f85a5404be1d1ee9450331aea869b886Stef Walter{
1203e462650f035b0df2304075d60b9a99e36715Stef Walter i_assert(user != NULL);
1203e462650f035b0df2304075d60b9a99e36715Stef Walter i_assert(!client->destroyed);
1203e462650f035b0df2304075d60b9a99e36715Stef Walter
1203e462650f035b0df2304075d60b9a99e36715Stef Walter if (password == NULL) {
1203e462650f035b0df2304075d60b9a99e36715Stef Walter client_syslog_err(&client->common, "proxy: password not given");
1203e462650f035b0df2304075d60b9a99e36715Stef Walter client_send_line(client, PROXY_FAILURE_MSG);
1203e462650f035b0df2304075d60b9a99e36715Stef Walter return -1;
1203e462650f035b0df2304075d60b9a99e36715Stef Walter }
1203e462650f035b0df2304075d60b9a99e36715Stef Walter
1203e462650f035b0df2304075d60b9a99e36715Stef Walter i_assert(client->refcount > 1);
1203e462650f035b0df2304075d60b9a99e36715Stef Walter connection_queue_add(1);
1203e462650f035b0df2304075d60b9a99e36715Stef Walter
1203e462650f035b0df2304075d60b9a99e36715Stef Walter if (client->destroyed) {
1203e462650f035b0df2304075d60b9a99e36715Stef Walter /* connection_queue_add() decided that we were the oldest
1203e462650f035b0df2304075d60b9a99e36715Stef Walter connection and killed us. */
1203e462650f035b0df2304075d60b9a99e36715Stef Walter return -1;
1203e462650f035b0df2304075d60b9a99e36715Stef Walter }
1203e462650f035b0df2304075d60b9a99e36715Stef Walter if (login_proxy_is_ourself(&client->common, host, port, user)) {
1203e462650f035b0df2304075d60b9a99e36715Stef Walter client_syslog_err(&client->common, "Proxying loops to itself");
1203e462650f035b0df2304075d60b9a99e36715Stef Walter client_send_line(client, PROXY_FAILURE_MSG);
1203e462650f035b0df2304075d60b9a99e36715Stef Walter return -1;
1203e462650f035b0df2304075d60b9a99e36715Stef Walter }
1203e462650f035b0df2304075d60b9a99e36715Stef Walter
1203e462650f035b0df2304075d60b9a99e36715Stef Walter client->proxy = login_proxy_new(&client->common, host, port,
1203e462650f035b0df2304075d60b9a99e36715Stef Walter proxy_input, client);
1203e462650f035b0df2304075d60b9a99e36715Stef Walter if (client->proxy == NULL) {
1203e462650f035b0df2304075d60b9a99e36715Stef Walter client_send_line(client, PROXY_FAILURE_MSG);
1203e462650f035b0df2304075d60b9a99e36715Stef Walter return -1;
1203e462650f035b0df2304075d60b9a99e36715Stef Walter }
1203e462650f035b0df2304075d60b9a99e36715Stef Walter
1203e462650f035b0df2304075d60b9a99e36715Stef Walter client->proxy_state = 0;
1203e462650f035b0df2304075d60b9a99e36715Stef Walter client->proxy_user = i_strdup(user);
1203e462650f035b0df2304075d60b9a99e36715Stef Walter client->proxy_master_user = i_strdup(master_user);
1203e462650f035b0df2304075d60b9a99e36715Stef Walter client->proxy_password = i_strdup(password);
1203e462650f035b0df2304075d60b9a99e36715Stef Walter
1203e462650f035b0df2304075d60b9a99e36715Stef Walter /* disable input until authentication is finished */
1203e462650f035b0df2304075d60b9a99e36715Stef Walter if (client->io != NULL)
1203e462650f035b0df2304075d60b9a99e36715Stef Walter io_remove(&client->io);
8dc21698c4ed699801d2b6f9135b3d6cb8512917Lukas Slebodnik return 0;
1203e462650f035b0df2304075d60b9a99e36715Stef Walter}
8dc21698c4ed699801d2b6f9135b3d6cb8512917Lukas Slebodnik