On Sun, 2007-09-09 at 13:26 +0100, Ed W wrote:
> Any suggestions on how this could be done more dynamically, or else 
> could I raise a feature request that the auth process somehow realises 
> when it's being forwarded to an IP address that it's actually listening 
> on already already (ie it's a request which loops back to itself), thus 
> simplifying the config files?  I haven't cracked open the code, but it 
> sounds somewhat possible to check the list of IP addresses we are 
> currently listening on and check that the proxy dest isn't among them?

Try the attached patch. It probably causes the login to fail then. If it
works, I'll continue with a dovecot-auth patch that does the same thing
to make it really work automatically.

diff -r 5c798e920045 src/imap-login/client-authenticate.c
--- a/src/imap-login/client-authenticate.c	Sat Sep 22 18:07:20 2007 +0300
+++ b/src/imap-login/client-authenticate.c	Sat Sep 22 18:21:34 2007 +0300
@@ -107,7 +107,8 @@ static bool client_handle_args(struct im
 	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.
@@ -120,7 +121,7 @@ static bool client_handle_args(struct im
 		return TRUE;
 	}
 
-	if (host != NULL) {
+	if (!proxy && host != NULL) {
 		/* IMAP referral
 
 		   [nologin] referral host=.. [port=..] [destuser=..]
diff -r 5c798e920045 src/login-common/login-proxy.c
--- a/src/login-common/login-proxy.c	Sat Sep 22 18:07:20 2007 +0300
+++ b/src/login-common/login-proxy.c	Sat Sep 22 18:21:34 2007 +0300
@@ -227,6 +227,22 @@ void login_proxy_free(struct login_proxy
 	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;
diff -r 5c798e920045 src/login-common/login-proxy.h
--- a/src/login-common/login-proxy.h	Sat Sep 22 18:07:20 2007 +0300
+++ b/src/login-common/login-proxy.h	Sat Sep 22 18:21:34 2007 +0300
@@ -15,6 +15,11 @@ login_proxy_new(struct client *client, c
 /* 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,
diff -r 5c798e920045 src/pop3-login/client-authenticate.c
--- a/src/pop3-login/client-authenticate.c	Sat Sep 22 18:07:20 2007 +0300
+++ b/src/pop3-login/client-authenticate.c	Sat Sep 22 18:21:34 2007 +0300
@@ -114,7 +114,8 @@ static bool client_handle_args(struct po
 	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.

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to