[dovecot-cvs] dovecot/src/imap-login client-authenticate.c, 1.33, 1.34 client.c, 1.32, 1.33 client.h, 1.12, 1.13 imap-proxy.c, 1.1, 1.2 imap-proxy.h, 1.1, 1.2

cras at dovecot.org cras at dovecot.org
Tue Oct 19 02:07:03 EEST 2004


Update of /var/lib/cvs/dovecot/src/imap-login
In directory talvi:/tmp/cvs-serv14845/imap-login

Modified Files:
	client-authenticate.c client.c client.h imap-proxy.c 
	imap-proxy.h 
Log Message:
More smart IMAP and POP3 proxies. Now if remote login fails, it just
destroys the proxy and allows trying another username which can go elsewhere.
Also now replies with the same old "Authentication failed" error message
instead of showing remote server's failure message.



Index: client-authenticate.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/imap-login/client-authenticate.c,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -d -r1.33 -r1.34
--- client-authenticate.c	18 Oct 2004 19:21:47 -0000	1.33
+++ client-authenticate.c	18 Oct 2004 23:07:01 -0000	1.34
@@ -113,10 +113,6 @@
 		   proxy host=.. [port=..] [destuser=..] pass=.. */
 		if (imap_proxy_new(client, host, port, destuser, pass) < 0)
 			client_destroy_internal_failure(client);
-		else {
-			client_destroy(client, t_strconcat(
-				"Proxy: ", client->common.virtual_user, NULL));
-		}
 		return TRUE;
 	} else if (host != NULL) {
 		/* IMAP referral
@@ -151,7 +147,7 @@
 		if (reason != NULL)
 			str_printfa(reply, "NO %s", reason);
 		else
-			str_append(reply, "NO Login not allowed.");
+			str_append(reply, "NO "AUTH_FAILED_MSG);
 		client_send_tagline(client, str_c(reply));
 	} else {
 		/* normal login/failure */
@@ -196,12 +192,7 @@
 				break;
 		}
 
-		if (data == NULL)
-			client_send_tagline(client, "Authentication failed");
-		else {
-			client_send_tagline(client, t_strconcat(
-				"NO Authentication failed: ", data, NULL));
-		}
+		client_send_tagline(client, "NO "AUTH_FAILED_MSG);
 
 		/* get back to normal client input. */
 		if (client->io != NULL)

Index: client.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/imap-login/client.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- client.c	18 Oct 2004 19:21:47 -0000	1.32
+++ client.c	18 Oct 2004 23:07:01 -0000	1.33
@@ -464,8 +464,24 @@
 		client->common.fd = -1;
 	}
 
-	if (client->common.proxy != NULL)
+	if (client->proxy_user != NULL) {
+		safe_memset(client->proxy_password, 0,
+			    strlen(client->proxy_password));
+		i_free(client->proxy_user);
+		i_free(client->proxy_password);
+		client->proxy_user = NULL;
+		client->proxy_password = NULL;
+	}
+
+	if (client->proxy != NULL) {
+		login_proxy_free(client->proxy);
+		client->proxy = NULL;
+	}
+
+	if (client->common.proxy != NULL) {
 		ssl_proxy_free(client->common.proxy);
+		client->common.proxy = NULL;
+	}
 	client_unref(client);
 }
 

Index: client.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/imap-login/client.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- client.h	18 Oct 2004 19:21:47 -0000	1.12
+++ client.h	18 Oct 2004 23:07:01 -0000	1.13
@@ -16,6 +16,9 @@
 	struct ostream *output;
 	struct imap_parser *parser;
 
+	struct login_proxy *proxy;
+	char *proxy_user, *proxy_password;
+
 	time_t last_input;
 	unsigned int bad_counter;
 

Index: imap-proxy.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/imap-login/imap-proxy.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- imap-proxy.c	18 Oct 2004 19:21:47 -0000	1.1
+++ imap-proxy.c	18 Oct 2004 23:07:01 -0000	1.2
@@ -2,17 +2,121 @@
 
 #include "common.h"
 #include "ioloop.h"
+#include "istream.h"
+#include "ostream.h"
 #include "str.h"
+#include "safe-memset.h"
 #include "client.h"
 #include "imap-quote.h"
-#include "login-proxy.h"
 #include "imap-proxy.h"
 
-int imap_proxy_new(struct imap_client *client, const char *host,
-		   unsigned int port, const char *user, const char *password)
+static int proxy_input_line(struct imap_client *client,
+			    struct ostream *output, const char *line)
 {
 	string_t *str;
 
+	if (client->proxy_user != NULL) {
+		/* this is a banner */
+		if (strncmp(line, "* OK ", 5) != 0) {
+			i_error("imap-proxy(%s): "
+				"Remote returned invalid banner: %s",
+				client->common.virtual_user, line);
+			client_destroy_internal_failure(client);
+			return -1;
+		}
+
+		/* send LOGIN command */
+		str = t_str_new(128);
+		str_append(str, "P LOGIN ");
+		imap_quote_append_string(str, client->proxy_user, FALSE);
+		str_append_c(str, ' ');
+		imap_quote_append_string(str, client->proxy_password, FALSE);
+		str_append(str, "\r\n");
+		(void)o_stream_send(output, str_data(str), str_len(str));
+
+		safe_memset(client->proxy_password, 0,
+			    strlen(client->proxy_password));
+		i_free(client->proxy_user);
+		i_free(client->proxy_password);
+		client->proxy_user = NULL;
+		client->proxy_password = NULL;
+		return 0;
+	} else if (strncmp(line, "P OK ", 5) == 0) {
+		/* Login successful. Send this line to client. */
+		(void)o_stream_send_str(client->output, client->cmd_tag);
+		(void)o_stream_send_str(client->output, line + 2);
+		(void)o_stream_send(client->output, "\r\n", 2);
+
+		login_proxy_detach(client->proxy, client->input,
+				   client->output);
+
+		client->proxy = NULL;
+		client->input = NULL;
+		client->output = NULL;
+		client->common.fd = -1;
+		client_destroy(client, t_strconcat(
+			"Proxy: ", client->common.virtual_user, NULL));
+		return -1;
+	} else if (strncmp(line, "P ", 2) == 0) {
+		/* Login failed. Send our own failure reply so client can't
+		   figure out if user exists or not just by looking at the
+		   reply string. */
+		client_send_tagline(client, "NO "AUTH_FAILED_MSG);
+
+		/* allow client input again */
+		i_assert(client->io == NULL);
+		client->io = io_add(client->common.fd, IO_READ,
+				    client_input, client);
+
+		login_proxy_free(client->proxy);
+		client->proxy = NULL;
+		return -1;
+	} else {
+		/* probably some untagged reply */
+		return 0;
+	}
+}
+
+static void proxy_input(struct istream *input, struct ostream *output,
+			void *context)
+{
+	struct imap_client *client = context;
+	const char *line;
+
+	if (input == NULL) {
+		if (client->io != NULL) {
+			/* remote authentication failed, we're just
+			   freeing the proxy */
+			return;
+		}
+
+		/* failed for some reason */
+		client_destroy_internal_failure(client);
+		return;
+	}
+
+	switch (i_stream_read(input)) {
+	case -2:
+		/* buffer full */
+		i_error("imap-proxy(%s): Remote input buffer full",
+			client->common.virtual_user);
+		client_destroy_internal_failure(client);
+		return;
+	case -1:
+		/* disconnected */
+		client_destroy(client, "Proxy: Remote disconnected");
+		return;
+	}
+
+	while ((line = i_stream_next_line(input)) != NULL) {
+		if (proxy_input_line(client, output, line) < 0)
+			break;
+	}
+}
+
+int imap_proxy_new(struct imap_client *client, const char *host,
+		   unsigned int port, const char *user, const char *password)
+{
 	i_assert(user != NULL);
 
 	if (password == NULL) {
@@ -21,17 +125,15 @@
 		return -1;
 	}
 
-	str = t_str_new(128);
-	str_append(str, client->cmd_tag);
-	str_append(str, " LOGIN ");
-	imap_quote_append_string(str, user, FALSE);
-	str_append_c(str, ' ');
-	imap_quote_append_string(str, password, FALSE);
-	str_append(str, "\r\n");
-
-	if (login_proxy_new(&client->common, host, port, str_c(str)) < 0)
+	client->proxy = login_proxy_new(&client->common, host, port,
+					proxy_input, client);
+	if (client->proxy == NULL)
 		return -1;
 
+	client->proxy_user = i_strdup(user);
+	client->proxy_password = i_strdup(password);
+
+	/* disable input until authentication is finished */
 	if (client->io != NULL) {
 		io_remove(client->io);
 		client->io = NULL;

Index: imap-proxy.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/imap-login/imap-proxy.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- imap-proxy.h	18 Oct 2004 19:21:47 -0000	1.1
+++ imap-proxy.h	18 Oct 2004 23:07:01 -0000	1.2
@@ -1,6 +1,8 @@
 #ifndef __IMAP_PROXY_H
 #define __IMAP_PROXY_H
 
+#include "login-proxy.h"
+
 int imap_proxy_new(struct imap_client *client, const char *host,
 		   unsigned int port, const char *user, const char *password);
 



More information about the dovecot-cvs mailing list