changeset 6472:6afb29dc9273 HEAD

If proxy points to the same host/port/user combination as we currently have, don't create an infinite connection loop.
author Timo Sirainen <tss@iki.fi>
date Sat, 22 Sep 2007 18:23:52 +0300
parents 910aadd76897
children bd886e12aaa0
files src/imap-login/client-authenticate.c src/login-common/login-proxy.c src/login-common/login-proxy.h src/pop3-login/client-authenticate.c
diffstat 4 files changed, 26 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/imap-login/client-authenticate.c	Sat Sep 22 18:01:37 2007 +0300
+++ b/src/imap-login/client-authenticate.c	Sat Sep 22 18:23:52 2007 +0300
@@ -108,7 +108,8 @@
 	if (destuser == NULL)
 		destuser = client->common.virtual_user;
 
-	if (proxy) {
+	if (proxy &&
+	    !login_proxy_is_ourself(&client->common, host, port, destuser)) {
 		/* we want to proxy the connection to another server.
 		   don't do this unless authentication succeeded. with
 		   master user proxying we can get FAIL with proxy still set.
@@ -121,7 +122,7 @@
 		return TRUE;
 	}
 
-	if (host != NULL) {
+	if (!proxy && host != NULL) {
 		/* IMAP referral
 
 		   [nologin] referral host=.. [port=..] [destuser=..]
--- a/src/login-common/login-proxy.c	Sat Sep 22 18:01:37 2007 +0300
+++ b/src/login-common/login-proxy.c	Sat Sep 22 18:23:52 2007 +0300
@@ -218,6 +218,22 @@
 	main_listen_start();
 }
 
+bool login_proxy_is_ourself(struct client *client, const char *host,
+			    unsigned int port, const char *destuser)
+{
+	struct ip_addr ip;
+
+	if (port != client->local_port)
+		return FALSE;
+
+	if (net_addr2ip(host, &ip) < 0)
+		return FALSE;
+	if (!net_ip_compare(&ip, &client->local_ip))
+		return FALSE;
+
+	return strcmp(client->virtual_user, destuser) == 0;
+}
+
 const char *login_proxy_get_host(struct login_proxy *proxy)
 {
 	return proxy->host;
--- a/src/login-common/login-proxy.h	Sat Sep 22 18:01:37 2007 +0300
+++ b/src/login-common/login-proxy.h	Sat Sep 22 18:23:52 2007 +0300
@@ -26,6 +26,11 @@
 /* Free the proxy. This should be called if authentication fails. */
 void login_proxy_free(struct login_proxy *proxy);
 
+/* Return TRUE if host/port/destuser combination points to same as current
+   connection. */
+bool login_proxy_is_ourself(struct client *client, const char *host,
+			    unsigned int port, const char *destuser);
+
 /* Detach proxy from client. This is done after the authentication is
    successful and all that is left is the dummy proxying. */
 void login_proxy_detach(struct login_proxy *proxy, struct istream *client_input,
--- a/src/pop3-login/client-authenticate.c	Sat Sep 22 18:01:37 2007 +0300
+++ b/src/pop3-login/client-authenticate.c	Sat Sep 22 18:23:52 2007 +0300
@@ -115,7 +115,8 @@
 	if (destuser == NULL)
 		destuser = client->common.virtual_user;
 
-	if (proxy) {
+	if (proxy &&
+	    !login_proxy_is_ourself(&client->common, host, port, destuser)) {
 		/* we want to proxy the connection to another server.
 		   don't do this unless authentication succeeded. with
 		   master user proxying we can get FAIL with proxy still set.