#include <stdlib.h>
+enum imap_proxy_state {
+ IMAP_PROXY_STATE_NONE,
+ IMAP_PROXY_STATE_BANNER,
+ IMAP_PROXY_STATE_ID,
+ IMAP_PROXY_STATE_STARTTLS,
+ IMAP_PROXY_STATE_CAPABILITY,
+ IMAP_PROXY_STATE_AUTH_CONTINUE,
+ IMAP_PROXY_STATE_LOGIN
+};
+
static void proxy_write_id(struct imap_client *client, string_t *str)
{
str_printfa(str, "I ID ("
output = login_proxy_get_ostream(client->login_proxy);
if (!imap_client->proxy_seen_banner) {
/* this is a banner */
+ client->proxy_state = IMAP_PROXY_STATE_BANNER;
imap_client->proxy_seen_banner = TRUE;
if (proxy_input_banner(imap_client, output, line) < 0) {
client_proxy_failed(client, TRUE);
/* used literals with LOGIN command, just ignore. */
return 0;
}
+ client->proxy_state = IMAP_PROXY_STATE_AUTH_CONTINUE;
imap_client->proxy_wait_auth_continue = FALSE;
str = t_str_new(128);
return -1;
}
/* STARTTLS successful, begin TLS negotiation. */
+ client->proxy_state = IMAP_PROXY_STATE_STARTTLS;
if (login_proxy_starttls(client->login_proxy) < 0) {
client_proxy_failed(client, TRUE);
return -1;
return 1;
} else if (strncmp(line, "L OK ", 5) == 0) {
/* Login successful. Send this line to client. */
+ client->proxy_state = IMAP_PROXY_STATE_LOGIN;
str = t_str_new(128);
client_send_login_reply(imap_client, str, line + 5);
(void)o_stream_send(client->output,
return 0;
} else if (strncmp(line, "C ", 2) == 0) {
/* Reply to CAPABILITY command we sent, ignore it */
+ client->proxy_state = IMAP_PROXY_STATE_CAPABILITY;
return 0;
} else if (strncasecmp(line, "I ", 2) == 0 ||
strncasecmp(line, "* ID ", 5) == 0) {
/* Reply to ID command we sent, ignore it */
+ client->proxy_state = IMAP_PROXY_STATE_ID;
return 0;
} else if (strncmp(line, "* ", 2) == 0) {
/* untagged reply. just foward it. */
imap_client->proxy_sasl_ir = FALSE;
imap_client->proxy_seen_banner = FALSE;
imap_client->proxy_wait_auth_continue = FALSE;
+ client->proxy_state = IMAP_PROXY_STATE_NONE;
}
return;
case -1:
client_log_err(client, t_strdup_printf(
- "proxy: Remote %s:%u disconnected: %s",
+ "proxy: Remote %s:%u disconnected: %s (state=%u)",
login_proxy_get_host(client->login_proxy),
login_proxy_get_port(client->login_proxy),
- get_disconnect_reason(input)));
+ get_disconnect_reason(input), client->proxy_state));
client_proxy_failed(client, TRUE);
return;
}
str_append(str, "AUTH PLAIN\r\n");
}
(void)o_stream_send(output, str_data(str), str_len(str));
- client->proxy_state = POP3_PROXY_LOGIN1;
+ client->common.proxy_state = POP3_PROXY_LOGIN1;
}
int pop3_proxy_parse_line(struct client *client, const char *line)
i_assert(!client->destroyed);
output = login_proxy_get_ostream(client->login_proxy);
- switch (pop3_client->proxy_state) {
+ switch (client->proxy_state) {
case POP3_PROXY_BANNER:
/* this is a banner */
if (strncmp(line, "+OK", 3) != 0) {
proxy_send_login(pop3_client, output);
} else {
(void)o_stream_send_str(output, "STLS\r\n");
- pop3_client->proxy_state = POP3_PROXY_STARTTLS;
+ client->proxy_state = POP3_PROXY_STARTTLS;
}
return 0;
case POP3_PROXY_STARTTLS:
}
(void)o_stream_send(output, str_data(str), str_len(str));
proxy_free_password(client);
- pop3_client->proxy_state = POP3_PROXY_LOGIN2;
+ client->proxy_state = POP3_PROXY_LOGIN2;
return 0;
case POP3_PROXY_LOGIN2:
if (strncmp(line, "+OK", 3) != 0)
void pop3_proxy_reset(struct client *client)
{
- struct pop3_client *pop3_client = (struct pop3_client *)client;
-
- pop3_client->proxy_state = POP3_PROXY_BANNER;
+ client->proxy_state = POP3_PROXY_BANNER;
}