dovecot-2.2: imap/pop3/lmtp proxy: Implemented detection of prox...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Feb 25 06:55:06 EET 2012
details: http://hg.dovecot.org/dovecot-2.2/rev/ba06ea38c722
changeset: 14162:ba06ea38c722
user: Timo Sirainen <tss at iki.fi>
date: Sat Feb 25 06:54:52 2012 +0200
description:
imap/pop3/lmtp proxy: Implemented detection of proxy loops with TTL.
If proxying tries to continue after 5 forward connections, it fails. The
limit of 5 is hard coded currently.
diffstat:
src/imap-login/client.c | 2 ++
src/imap-login/imap-proxy.c | 8 ++++++--
src/lib-lda/lmtp-client.c | 4 ++++
src/lib-lda/lmtp-client.h | 2 ++
src/lmtp/client.c | 1 +
src/lmtp/client.h | 1 +
src/lmtp/commands.c | 19 +++++++++++++++++--
src/lmtp/lmtp-proxy.c | 2 ++
src/lmtp/lmtp-proxy.h | 3 +++
src/login-common/client-common.c | 1 +
src/login-common/client-common.h | 1 +
src/login-common/login-proxy.c | 6 ++++++
src/login-common/login-proxy.h | 7 +++++++
src/pop3-login/client.c | 3 +++
src/pop3-login/pop3-proxy.c | 6 ++++--
15 files changed, 60 insertions(+), 6 deletions(-)
diffs (283 lines):
diff -r f534ed81bce4 -r ba06ea38c722 src/imap-login/client.c
--- a/src/imap-login/client.c Sat Feb 25 06:41:59 2012 +0200
+++ b/src/imap-login/client.c Sat Feb 25 06:54:52 2012 +0200
@@ -121,6 +121,8 @@
(void)net_addr2ip(value, &client->common.local_ip);
else if (strcasecmp(key, "x-connected-port") == 0)
client->common.local_port = atoi(value);
+ else if (strcasecmp(key, "x-proxy-ttl") == 0)
+ client->common.proxy_ttl = atoi(value);
args += 2;
}
}
diff -r f534ed81bce4 -r ba06ea38c722 src/imap-login/imap-proxy.c
--- a/src/imap-login/imap-proxy.c Sat Feb 25 06:41:59 2012 +0200
+++ b/src/imap-login/imap-proxy.c Sat Feb 25 06:54:52 2012 +0200
@@ -29,15 +29,19 @@
static void proxy_write_id(struct imap_client *client, string_t *str)
{
+ i_assert(client->common.proxy_ttl > 0);
+
str_printfa(str, "I ID ("
"\"x-originating-ip\" \"%s\" "
"\"x-originating-port\" \"%u\" "
"\"x-connected-ip\" \"%s\" "
- "\"x-connected-port\" \"%u\")\r\n",
+ "\"x-connected-port\" \"%u\" "
+ "\"x-proxy-ttl\" \"%u\")\r\n",
net_ip2addr(&client->common.ip),
client->common.remote_port,
net_ip2addr(&client->common.local_ip),
- client->common.local_port);
+ client->common.local_port,
+ client->common.proxy_ttl - 1);
}
static void proxy_free_password(struct client *client)
diff -r f534ed81bce4 -r ba06ea38c722 src/lib-lda/lmtp-client.c
--- a/src/lib-lda/lmtp-client.c Sat Feb 25 06:41:59 2012 +0200
+++ b/src/lib-lda/lmtp-client.c Sat Feb 25 06:54:52 2012 +0200
@@ -96,6 +96,7 @@
p_strdup(pool, set->dns_client_socket_path);
client->set.source_ip = set->source_ip;
client->set.source_port = set->source_port;
+ client->set.proxy_ttl_plus_1 = set->proxy_ttl_plus_1;
client->finish_callback = finish_callback;
client->finish_context = context;
client->fd = -1;
@@ -428,6 +429,9 @@
if (client->set.source_port != 0 &&
str_array_icase_find(client->xclient_args, "PORT"))
str_printfa(str, " PORT=%u", client->set.source_port);
+ if (client->set.proxy_ttl_plus_1 != 0 &&
+ str_array_icase_find(client->xclient_args, "TTL"))
+ str_printfa(str, " TTL=%u", client->set.proxy_ttl_plus_1-1);
if (str_len(str) == empty_len)
return FALSE;
diff -r f534ed81bce4 -r ba06ea38c722 src/lib-lda/lmtp-client.h
--- a/src/lib-lda/lmtp-client.h Sat Feb 25 06:41:59 2012 +0200
+++ b/src/lib-lda/lmtp-client.h Sat Feb 25 06:54:52 2012 +0200
@@ -21,6 +21,8 @@
send the these as ADDR/PORT */
struct ip_addr source_ip;
unsigned int source_port;
+ /* send TTL as this -1, so the default 0 means "don't send it" */
+ unsigned int proxy_ttl_plus_1;
};
/* reply contains the reply coming from remote server, or NULL
diff -r f534ed81bce4 -r ba06ea38c722 src/lmtp/client.c
--- a/src/lmtp/client.c Sat Feb 25 06:41:59 2012 +0200
+++ b/src/lmtp/client.c Sat Feb 25 06:54:52 2012 +0200
@@ -227,6 +227,7 @@
client_generate_session_id(client);
client->my_domain = client->set->hostname;
client->lhlo = i_strdup("missing");
+ client->proxy_ttl = LMTP_PROXY_DEFAULT_TTL;
DLLIST_PREPEND(&clients, client);
clients_count++;
diff -r f534ed81bce4 -r ba06ea38c722 src/lmtp/client.h
--- a/src/lmtp/client.h Sat Feb 25 06:41:59 2012 +0200
+++ b/src/lmtp/client.h Sat Feb 25 06:54:52 2012 +0200
@@ -62,6 +62,7 @@
struct client_state state;
struct istream *dot_input;
struct lmtp_proxy *proxy;
+ unsigned int proxy_ttl;
unsigned int disconnected:1;
};
diff -r f534ed81bce4 -r ba06ea38c722 src/lmtp/commands.c
--- a/src/lmtp/commands.c Sat Feb 25 06:41:59 2012 +0200
+++ b/src/lmtp/commands.c Sat Feb 25 06:54:52 2012 +0200
@@ -69,7 +69,7 @@
client_state_reset(client);
client_send_line(client, "250-%s", client->my_domain);
if (client_is_trusted(client))
- client_send_line(client, "250-XCLIENT ADDR PORT");
+ client_send_line(client, "250-XCLIENT ADDR PORT TTL");
client_send_line(client, "250-8BITMIME");
client_send_line(client, "250-ENHANCEDSTATUSCODES");
client_send_line(client, "250 PIPELINING");
@@ -296,6 +296,15 @@
return TRUE;
}
+ if (client->proxy_ttl == 0) {
+ i_error("Proxying to <%s> appears to be looping (TTL=0)",
+ username);
+ client_send_line(client, "554 5.4.6 <%s> "
+ "Proxying appears to be looping (TTL=0)",
+ username);
+ pool_unref(&pool);
+ return TRUE;
+ }
if (array_count(&client->state.rcpt_to) != 0) {
client_send_line(client, "451 4.3.0 <%s> "
"Can't handle mixed proxy/non-proxy destinations",
@@ -311,6 +320,7 @@
proxy_set.dns_client_socket_path = dns_client_socket_path;
proxy_set.source_ip = client->remote_ip;
proxy_set.source_port = client->remote_port;
+ proxy_set.proxy_ttl = client->proxy_ttl-1;
client->proxy = lmtp_proxy_init(&proxy_set, client->output);
if (client->state.mail_body_8bitmime)
@@ -915,7 +925,7 @@
{
const char *const *tmp;
struct ip_addr remote_ip;
- unsigned int remote_port = 0;
+ unsigned int remote_port = 0, ttl = -1U;
bool args_ok = TRUE;
if (!client_is_trusted(client)) {
@@ -931,6 +941,9 @@
if (str_to_uint(*tmp + 5, &remote_port) < 0 ||
remote_port == 0 || remote_port > 65535)
args_ok = FALSE;
+ } else if (strncasecmp(*tmp, "TTL=", 4) == 0) {
+ if (str_to_uint(*tmp + 4, &ttl) < 0)
+ args_ok = FALSE;
}
}
if (!args_ok) {
@@ -944,6 +957,8 @@
client->remote_ip = remote_ip;
if (remote_port != 0)
client->remote_port = remote_port;
+ if (ttl != -1U)
+ client->proxy_ttl = ttl;
client_send_line(client, "220 %s %s", client->my_domain,
client->lmtp_set->login_greeting);
return 0;
diff -r f534ed81bce4 -r ba06ea38c722 src/lmtp/lmtp-proxy.c
--- a/src/lmtp/lmtp-proxy.c Sat Feb 25 06:41:59 2012 +0200
+++ b/src/lmtp/lmtp-proxy.c Sat Feb 25 06:54:52 2012 +0200
@@ -72,6 +72,7 @@
p_strdup(pool, set->dns_client_socket_path);
proxy->set.source_ip = set->source_ip;
proxy->set.source_port = set->source_port;
+ proxy->set.proxy_ttl = set->proxy_ttl;
i_array_init(&proxy->rcpt_to, 32);
i_array_init(&proxy->connections, 32);
return proxy;
@@ -134,6 +135,7 @@
client_set.dns_client_socket_path = proxy->set.dns_client_socket_path;
client_set.source_ip = proxy->set.source_ip;
client_set.source_port = proxy->set.source_port;
+ client_set.proxy_ttl_plus_1 = proxy->set.proxy_ttl+1;
conn = p_new(proxy->pool, struct lmtp_proxy_connection, 1);
conn->proxy = proxy;
diff -r f534ed81bce4 -r ba06ea38c722 src/lmtp/lmtp-proxy.h
--- a/src/lmtp/lmtp-proxy.h Sat Feb 25 06:41:59 2012 +0200
+++ b/src/lmtp/lmtp-proxy.h Sat Feb 25 06:54:52 2012 +0200
@@ -4,6 +4,8 @@
#include "network.h"
#include "lmtp-client.h"
+#define LMTP_PROXY_DEFAULT_TTL 5
+
struct lmtp_proxy_settings {
const char *my_hostname;
const char *dns_client_socket_path;
@@ -11,6 +13,7 @@
/* the original client's IP/port that connected to the proxy */
struct ip_addr source_ip;
unsigned int source_port;
+ unsigned int proxy_ttl;
};
struct lmtp_proxy_rcpt_settings {
diff -r f534ed81bce4 -r ba06ea38c722 src/login-common/client-common.c
--- a/src/login-common/client-common.c Sat Feb 25 06:41:59 2012 +0200
+++ b/src/login-common/client-common.c Sat Feb 25 06:54:52 2012 +0200
@@ -96,6 +96,7 @@
client->trusted = client_is_trusted(client);
client->secured = ssl || client->trusted ||
net_ip_compare(remote_ip, local_ip);
+ client->proxy_ttl = LOGIN_PROXY_TTL;
if (last_client == NULL)
last_client = client;
diff -r f534ed81bce4 -r ba06ea38c722 src/login-common/client-common.h
--- a/src/login-common/client-common.h Sat Feb 25 06:41:59 2012 +0200
+++ b/src/login-common/client-common.h Sat Feb 25 06:54:52 2012 +0200
@@ -117,6 +117,7 @@
struct login_proxy *login_proxy;
char *proxy_user, *proxy_master_user, *proxy_password;
unsigned int proxy_state;
+ unsigned int proxy_ttl;
char *auth_mech_name;
struct auth_client_request *auth_request;
diff -r f534ed81bce4 -r ba06ea38c722 src/login-common/login-proxy.c
--- a/src/login-common/login-proxy.c Sat Feb 25 06:41:59 2012 +0200
+++ b/src/login-common/login-proxy.c Sat Feb 25 06:54:52 2012 +0200
@@ -277,6 +277,12 @@
return -1;
}
+ if (client->proxy_ttl == 0) {
+ i_error("proxy(%s): TTL reached zero - "
+ "proxies appear to be looping?", client->virtual_user);
+ return -1;
+ }
+
proxy = i_new(struct login_proxy, 1);
proxy->client = client;
proxy->client_fd = -1;
diff -r f534ed81bce4 -r ba06ea38c722 src/login-common/login-proxy.h
--- a/src/login-common/login-proxy.h Sat Feb 25 06:41:59 2012 +0200
+++ b/src/login-common/login-proxy.h Sat Feb 25 06:54:52 2012 +0200
@@ -1,6 +1,13 @@
#ifndef LOGIN_PROXY_H
#define LOGIN_PROXY_H
+/* Max. number of embedded proxying connections until proxying fails.
+ This is intended to avoid an accidental configuration where two proxies
+ keep connecting to each others, both thinking the other one is supposed to
+ handle the user. This only works if both proxies support the Dovecot
+ TTL extension feature. */
+#define LOGIN_PROXY_TTL 5
+
struct client;
struct login_proxy;
diff -r f534ed81bce4 -r ba06ea38c722 src/pop3-login/client.c
--- a/src/pop3-login/client.c Sat Feb 25 06:41:59 2012 +0200
+++ b/src/pop3-login/client.c Sat Feb 25 06:54:52 2012 +0200
@@ -56,6 +56,9 @@
args_ok = FALSE;
else
client->common.remote_port = remote_port;
+ } else if (strncasecmp(*tmp, "TTL=", 4) == 0) {
+ if (str_to_uint(*tmp + 4, &client->common.proxy_ttl) < 0)
+ args_ok = FALSE;
}
}
if (!args_ok) {
diff -r f534ed81bce4 -r ba06ea38c722 src/pop3-login/pop3-proxy.c
--- a/src/pop3-login/pop3-proxy.c Sat Feb 25 06:41:59 2012 +0200
+++ b/src/pop3-login/pop3-proxy.c Sat Feb 25 06:54:52 2012 +0200
@@ -37,12 +37,14 @@
{
string_t *str;
+ i_assert(client->common.proxy_ttl > 0);
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",
+ "XCLIENT ADDR=%s PORT=%u TTL=%u\r\n",
net_ip2addr(&client->common.ip),
- client->common.remote_port));
+ client->common.remote_port,
+ client->common.proxy_ttl - 1));
client->common.proxy_state = POP3_PROXY_XCLIENT;
} else {
client->common.proxy_state = POP3_PROXY_LOGIN1;
More information about the dovecot-cvs
mailing list