dovecot-2.1: pop3-login: Implemented XCLIENT command for forward...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Feb 25 05:21:12 EET 2012
details: http://hg.dovecot.org/dovecot-2.1/rev/35ed77dd500e
changeset: 14190:35ed77dd500e
user: Timo Sirainen <tss at iki.fi>
date: Sat Feb 25 05:20:47 2012 +0200
description:
pop3-login: Implemented XCLIENT command for forwarding client ip/port from proxy.
diffstat:
src/pop3-login/client.c | 54 ++++++++++++++++++++++++++++++++++++++------
src/pop3-login/client.h | 1 +
src/pop3-login/pop3-proxy.c | 10 ++++++++
3 files changed, 57 insertions(+), 8 deletions(-)
diffs (120 lines):
diff -r 970809a9f9bd -r 35ed77dd500e src/pop3-login/client.c
--- a/src/pop3-login/client.c Sat Feb 25 04:38:01 2012 +0200
+++ b/src/pop3-login/client.c Sat Feb 25 05:20:47 2012 +0200
@@ -35,6 +35,40 @@
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)
{
@@ -53,6 +87,8 @@
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.");
@@ -149,18 +185,20 @@
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);
+ 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) {
- 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));
- }
+ 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;
}
diff -r 970809a9f9bd -r 35ed77dd500e src/pop3-login/client.h
--- a/src/pop3-login/client.h Sat Feb 25 04:38:01 2012 +0200
+++ b/src/pop3-login/client.h Sat Feb 25 05:20:47 2012 +0200
@@ -18,6 +18,7 @@
char *last_user;
char *apop_challenge;
unsigned int apop_server_pid, apop_connect_uid;
+ bool proxy_xclient;
};
#endif
diff -r 970809a9f9bd -r 35ed77dd500e src/pop3-login/pop3-proxy.c
--- a/src/pop3-login/pop3-proxy.c Sat Feb 25 04:38:01 2012 +0200
+++ b/src/pop3-login/pop3-proxy.c Sat Feb 25 05:20:47 2012 +0200
@@ -37,6 +37,14 @@
{
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 */
@@ -71,6 +79,8 @@
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) {
More information about the dovecot-cvs
mailing list