[dovecot-cvs] dovecot/src/pop3-login client-authenticate.c, 1.37, 1.38 client.c, 1.32, 1.33 client.h, 1.14, 1.15 pop3-proxy.c, 1.1, 1.2 pop3-proxy.h, 1.1, 1.2

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


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

Modified Files:
	client-authenticate.c client.c client.h pop3-proxy.c 
	pop3-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/pop3-login/client-authenticate.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -d -r1.37 -r1.38
--- client-authenticate.c	18 Oct 2004 19:21:48 -0000	1.37
+++ client-authenticate.c	18 Oct 2004 23:07:02 -0000	1.38
@@ -114,10 +114,6 @@
 		   proxy host=.. [port=..] [destuser=..] pass=.. */
 		if (pop3_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;
 	}
 
@@ -129,7 +125,7 @@
 	if (reason != NULL)
 		str_append(reply, reason);
 	else
-		str_append(reply, "Login disabled.");
+		str_append(reply, AUTH_FAILED_MSG);
 
 	client_send_line(client, str_c(reply));
 
@@ -166,12 +162,7 @@
 				break;
 		}
 
-		if (data == NULL)
-			client_send_line(client, "-ERR Authentication failed");
-		else {
-			client_send_line(client, t_strconcat(
-				"-ERR Authentication failed: ", data, NULL));
-		}
+		client_send_line(client, "-ERR "AUTH_FAILED_MSG);
 
 		/* get back to normal client input. */
 		if (client->io != NULL)

Index: client.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/pop3-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:48 -0000	1.32
+++ client.c	18 Oct 2004 23:07:02 -0000	1.33
@@ -15,6 +15,7 @@
 #include "client-authenticate.h"
 #include "auth-client.h"
 #include "ssl-proxy.h"
+#include "pop3-proxy.h"
 #include "hostpid.h"
 
 /* max. length of input command line (spec says 512), or max reply length in
@@ -358,8 +359,24 @@
 		client->io = NULL;
 	}
 
-	net_disconnect(client->common.fd);
-	client->common.fd = -1;
+	if (client->common.fd != -1) {
+		net_disconnect(client->common.fd);
+		client->common.fd = -1;
+	}
+
+	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);

Index: client.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/pop3-login/client.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- client.h	18 Oct 2004 19:21:48 -0000	1.14
+++ client.h	18 Oct 2004 23:07:02 -0000	1.15
@@ -16,6 +16,9 @@
 	struct istream *input;
 	struct ostream *output;
 
+	struct login_proxy *proxy;
+	char *proxy_user, *proxy_password;
+
 	time_t last_input;
 	unsigned int bad_counter;
 

Index: pop3-proxy.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/pop3-login/pop3-proxy.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- pop3-proxy.c	18 Oct 2004 19:21:48 -0000	1.1
+++ pop3-proxy.c	18 Oct 2004 23:07:02 -0000	1.2
@@ -2,17 +2,112 @@
 
 #include "common.h"
 #include "ioloop.h"
+#include "istream.h"
+#include "ostream.h"
 #include "base64.h"
+#include "safe-memset.h"
 #include "str.h"
 #include "client.h"
-#include "login-proxy.h"
 #include "pop3-proxy.h"
 
-int pop3_proxy_new(struct pop3_client *client, const char *host,
-		   unsigned int port, const char *user, const char *password)
+static void proxy_input(struct istream *input, struct ostream *output,
+			void *context)
 {
+	struct pop3_client *client = context;
 	string_t *auth, *str;
+	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("pop-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;
+	}
+
+	line = i_stream_next_line(input);
+	if (line == NULL)
+		return;
+
+	if (client->proxy_user != NULL) {
+		/* this is a banner */
+		if (strncmp(line, "+OK ", 4) != 0) {
+			i_error("pop3-proxy(%s): "
+				"Remote returned invalid banner: %s",
+				client->common.virtual_user, line);
+			client_destroy_internal_failure(client);
+			return;
+		}
+
+		/* send AUTH command */
+		auth = t_str_new(128);
+		str_append_c(auth, '\0');
+		str_append(auth, client->proxy_user);
+		str_append_c(auth, '\0');
+		str_append(auth, client->proxy_password);
+
+		str = t_str_new(128);
+		str_append(str, "AUTH ");
+		base64_encode(str_data(auth), str_len(auth), str);
+		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;
+	} else if (strncmp(line, "+OK ", 4) == 0) {
+		/* Login successful. Send this line to client. */
+		(void)o_stream_send_str(client->output, line);
+		(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));
+	} else {
+		/* 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_line(client, "-ERR "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;
+	}
+}
 
+int pop3_proxy_new(struct pop3_client *client, const char *host,
+		   unsigned int port, const char *user, const char *password)
+{
 	i_assert(user != NULL);
 
 	if (password == NULL) {
@@ -21,20 +116,15 @@
 		return -1;
 	}
 
-	auth = t_str_new(128);
-	str_append_c(auth, '\0');
-	str_append(auth, user);
-	str_append_c(auth, '\0');
-	str_append(auth, password);
-
-	str = t_str_new(128);
-	str_append(str, "AUTH ");
-	base64_encode(str_data(auth), str_len(auth), str);
-	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: pop3-proxy.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/pop3-login/pop3-proxy.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- pop3-proxy.h	18 Oct 2004 19:21:48 -0000	1.1
+++ pop3-proxy.h	18 Oct 2004 23:07:02 -0000	1.2
@@ -1,6 +1,8 @@
 #ifndef __POP3_PROXY_H
 #define __POP3_PROXY_H
 
+#include "login-proxy.h"
+
 int pop3_proxy_new(struct pop3_client *client, const char *host,
 		   unsigned int port, const char *user, const char *password);
 



More information about the dovecot-cvs mailing list