return TRUE;
}
+static bool cmd_xclient(struct pop3_client *client, const char *args)
+{
+ const char *const *tmp;
+ unsigned int remote_port;
+ bool args_ok = TRUE;
+
+ if (!client->common.trusted) {
+ client_send_line(&client->common, CLIENT_CMD_REPLY_BAD,
+ "You are not from trusted IP");
+ return TRUE;
+ }
+ for (tmp = t_strsplit(args, " "); *tmp != NULL; tmp++) {
+ if (strncasecmp(*tmp, "ADDR=", 5) == 0) {
+ if (net_addr2ip(*tmp + 5, &client->common.ip) < 0)
+ args_ok = FALSE;
+ } else if (strncasecmp(*tmp, "PORT=", 5) == 0) {
+ if (str_to_uint(*tmp + 5, &remote_port) < 0 ||
+ remote_port == 0 || remote_port > 65535)
+ args_ok = FALSE;
+ else
+ client->common.remote_port = remote_port;
+ }
+ }
+ if (!args_ok) {
+ client_send_line(&client->common, CLIENT_CMD_REPLY_BAD,
+ "Invalid parameters");
+ return TRUE;
+ }
+
+ /* args ok, set them and reset the state */
+ client_send_line(&client->common, CLIENT_CMD_REPLY_OK, "Updated");
+ return TRUE;
+}
+
static bool client_command_execute(struct pop3_client *client, const char *cmd,
const char *args)
{
return cmd_stls(client);
if (strcmp(cmd, "QUIT") == 0)
return cmd_quit(client);
+ if (strcmp(cmd, "XCLIENT") == 0)
+ return cmd_xclient(client, args);
client_send_line(&client->common, CLIENT_CMD_REPLY_BAD,
"Unknown command.");
static void pop3_client_send_greeting(struct client *client)
{
struct pop3_client *pop3_client = (struct pop3_client *)client;
+ string_t *str;
client->io = io_add(client->fd, IO_READ, client_input, client);
- pop3_client->apop_challenge = get_apop_challenge(pop3_client);
- if (pop3_client->apop_challenge == NULL) {
- client_send_line(client, CLIENT_CMD_REPLY_OK,
- client->set->login_greeting);
- } else {
- client_send_line(client, CLIENT_CMD_REPLY_OK,
- t_strconcat(client->set->login_greeting, " ",
- pop3_client->apop_challenge, NULL));
+ str = t_str_new(128);
+ if (client->trusted) {
+ /* Dovecot extension to avoid extra roundtrip for CAPA */
+ str_append(str, "[XCLIENT] ");
}
+ str_append(str, client->set->login_greeting);
+ pop3_client->apop_challenge = get_apop_challenge(pop3_client);
+ if (pop3_client->apop_challenge != NULL)
+ str_printfa(str, " %s", pop3_client->apop_challenge);
+ client_send_line(client, CLIENT_CMD_REPLY_OK, str_c(str));
client->greeting_sent = TRUE;
}
{
string_t *str;
+ if (client->proxy_xclient) {
+ /* remote supports XCLIENT, send it */
+ (void)o_stream_send_str(output, t_strdup_printf(
+ "XCLIENT ADDR=%s PORT=%u\r\n",
+ net_ip2addr(&client->common.ip),
+ client->common.remote_port));
+ }
+
str = t_str_new(128);
if (client->common.proxy_master_user == NULL) {
/* send USER command */
client_proxy_failed(client, TRUE);
return -1;
}
+ pop3_client->proxy_xclient =
+ strncmp(line+3, " [XCLIENT]", 10) == 0;
ssl_flags = login_proxy_get_ssl_flags(client->login_proxy);
if ((ssl_flags & PROXY_SSL_FLAG_STARTTLS) == 0) {