[dovecot-cvs] dovecot/src/imap-login Makefile.am, 1.3, 1.4 client-authenticate.c, 1.32, 1.33 client.c, 1.31, 1.32 client.h, 1.11, 1.12 imap-proxy.c, NONE, 1.1 imap-proxy.h, NONE, 1.1

cras at dovecot.org cras at dovecot.org
Mon Oct 18 22:21:49 EEST 2004


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

Modified Files:
	Makefile.am client-authenticate.c client.c client.h 
Added Files:
	imap-proxy.c imap-proxy.h 
Log Message:
Added IMAP and POP3 proxying support.



Index: Makefile.am
===================================================================
RCS file: /var/lib/cvs/dovecot/src/imap-login/Makefile.am,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- Makefile.am	22 Aug 2003 02:42:13 -0000	1.3
+++ Makefile.am	18 Oct 2004 19:21:47 -0000	1.4
@@ -10,15 +10,17 @@
 
 imap_login_LDADD = \
 	../login-common/liblogin-common.a \
-	../lib-imap/imap-parser.o \
+	../lib-imap/libimap.a \
 	../lib-auth/libauth.a \
 	../lib/liblib.a \
 	$(SSL_LIBS)
 
 imap_login_SOURCES = \
 	client.c \
-	client-authenticate.c
+	client-authenticate.c \
+	imap-proxy.c
 
 noinst_HEADERS = \
 	client.h \
-	client-authenticate.h
+	client-authenticate.h \
+	imap-proxy.h

Index: client-authenticate.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/imap-login/client-authenticate.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- client-authenticate.c	18 Oct 2004 01:13:25 -0000	1.32
+++ client-authenticate.c	18 Oct 2004 19:21:47 -0000	1.33
@@ -13,6 +13,9 @@
 #include "auth-client.h"
 #include "client.h"
 #include "client-authenticate.h"
+#include "imap-proxy.h"
+
+#include <stdlib.h>
 
 const char *client_authenticate_get_capabilities(int secured)
 {
@@ -76,39 +79,85 @@
 	safe_memset(line, 0, strlen(line));
 }
 
-static int client_handle_success_args(struct imap_client *client,
-				      const char *const *args, int nologin)
+static int client_handle_args(struct imap_client *client,
+			      const char *const *args, int nologin)
 {
-	const char *reason = NULL, *referral = NULL;
+	const char *reason = NULL, *host = NULL, *destuser = NULL, *pass = NULL;
 	string_t *reply;
+	unsigned int port = 143;
+	int proxy = FALSE;
 
 	for (; *args != NULL; args++) {
 		if (strcmp(*args, "nologin") == 0)
 			nologin = TRUE;
+		else if (strcmp(*args, "proxy") == 0)
+			proxy = TRUE;
 		else if (strncmp(*args, "reason=", 7) == 0)
 			reason = *args + 7;
-		else  if (strncmp(*args, "referral=", 9) == 0)
-			referral = *args + 9;
+		else if (strncmp(*args, "host=", 5) == 0)
+			host = *args + 5;
+		else if (strncmp(*args, "port=", 5) == 0)
+			port = atoi(*args + 5);
+		else if (strncmp(*args, "destuser=", 9) == 0)
+			destuser = *args + 9;
+		else if (strncmp(*args, "pass=", 5) == 0)
+			pass = *args + 5;
 	}
 
-	if (!nologin && referral == NULL)
-		return FALSE;
+	if (destuser == NULL)
+		destuser = client->common.virtual_user;
 
-	reply = t_str_new(128);
-	str_append(reply, nologin ? "NO " : "OK ");
-	if (referral != NULL)
-		str_printfa(reply, "[REFERRAL %s] ", referral);
+	if (proxy) {
+		/* we want to proxy the connection to another server.
 
-	if (reason != NULL)
-		str_append(reply, reason);
-	else if (!nologin)
-		str_append(reply, "Logged in.");
-	else if (referral != NULL)
-		str_append(reply, "Try this server instead.");
-	else
-		str_append(reply, "Login disabled.");
+		   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
+
+		   [nologin] referral host=.. [port=..] [destuser=..]
+		   [reason=..]
+
+		   NO [REFERRAL imap://destuser;AUTH=..@host:port/] Can't login.
+		   OK [...] Logged in, but you should use this server instead.
+		   .. [REFERRAL ..] (Reason from auth server)
+		*/
+		reply = t_str_new(128);
+		str_append(reply, nologin ? "NO " : "OK ");
+		str_printfa(reply, "[REFERRAL imap://%s;AUTH=%s@%s",
+			    destuser, client->common.auth_mech_name, host);
+		if (port != 143)
+			str_printfa(reply, ":%u", port);
+		str_append(reply, "/] ");
+		if (reason != NULL)
+			str_append(reply, reason);
+		else if (nologin)
+			str_append(reply, "Try this server instead.");
+		else {
+			str_append(reply, "Logged in, but you should use "
+				   "this server instead.");
+		}
+		client_send_tagline(client, str_c(reply));
+	} else if (nologin) {
+		/* Authentication went ok, but for some reason user isn't
+		   allowed to log in. Shouldn't probably happen. */
+		reply = t_str_new(128);
+		if (reason != NULL)
+			str_printfa(reply, "NO %s", reason);
+		else
+			str_append(reply, "NO Login not allowed.");
+		client_send_tagline(client, str_c(reply));
+	} else {
+		/* normal login/failure */
+		return FALSE;
+	}
 
-	client_send_tagline(client, str_c(reply));
 	if (!nologin) {
 		client_destroy(client, t_strconcat(
 			"Login: ", client->common.virtual_user, NULL));
@@ -133,7 +182,7 @@
 	switch (reply) {
 	case SASL_SERVER_REPLY_SUCCESS:
 		if (args != NULL) {
-			if (client_handle_success_args(client, args, FALSE))
+			if (client_handle_args(client, args, FALSE))
 				break;
 		}
 
@@ -143,7 +192,7 @@
 		break;
 	case SASL_SERVER_REPLY_AUTH_FAILED:
 		if (args != NULL) {
-			if (client_handle_success_args(client, args, TRUE))
+			if (client_handle_args(client, args, TRUE))
 				break;
 		}
 
@@ -161,11 +210,7 @@
 				    client_input, client);
 		break;
 	case SASL_SERVER_REPLY_MASTER_FAILED:
-		client_send_line(client, "* BYE Internal login failure. "
-				 "Refer to server log for more information.");
-		client_destroy(client, t_strconcat("Internal login failure: ",
-						   client->common.virtual_user,
-						   NULL));
+		client_destroy_internal_failure(client);
 		break;
 	case SASL_SERVER_REPLY_CONTINUE:
 		data_len = strlen(data);

Index: client.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/imap-login/client.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -d -r1.31 -r1.32
--- client.c	18 Oct 2004 01:13:25 -0000	1.31
+++ client.c	18 Oct 2004 19:21:47 -0000	1.32
@@ -15,6 +15,7 @@
 #include "client-authenticate.h"
 #include "auth-client.h"
 #include "ssl-proxy.h"
+#include "imap-proxy.h"
 
 /* max. size of one parameter in line, or max reply length in SASL
    authentication */
@@ -442,7 +443,8 @@
 	hash_remove(clients, client);
 
 	i_stream_close(client->input);
-	o_stream_close(client->output);
+	if (client->output != NULL)
+		o_stream_close(client->output);
 
 	if (client->common.auth_request != NULL) {
 		auth_client_request_abort(client->common.auth_request);
@@ -467,6 +469,14 @@
 	client_unref(client);
 }
 
+void client_destroy_internal_failure(struct imap_client *client)
+{
+	client_send_line(client, "* BYE Internal login failure. "
+			 "Refer to server log for more information.");
+	client_destroy(client, t_strconcat("Internal login failure: ",
+					   client->common.virtual_user, NULL));
+}
+
 void client_ref(struct imap_client *client)
 {
 	client->refcount++;
@@ -480,7 +490,8 @@
 	imap_parser_destroy(client->parser);
 
 	i_stream_unref(client->input);
-	o_stream_unref(client->output);
+	if (client->output != NULL)
+		o_stream_unref(client->output);
 
 	i_free(client->common.virtual_user);
 	i_free(client->common.auth_mech_name);

Index: client.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/imap-login/client.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- client.h	11 Oct 2004 17:14:26 -0000	1.11
+++ client.h	18 Oct 2004 19:21:47 -0000	1.12
@@ -28,6 +28,7 @@
 };
 
 void client_destroy(struct imap_client *client, const char *reason);
+void client_destroy_internal_failure(struct imap_client *client);
 
 void client_send_line(struct imap_client *client, const char *line);
 void client_send_tagline(struct imap_client *client, const char *line);

--- NEW FILE: imap-proxy.c ---
/* Copyright (C) 2004 Timo Sirainen */

#include "common.h"
#include "ioloop.h"
#include "str.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)
{
	string_t *str;

	i_assert(user != NULL);

	if (password == NULL) {
		i_error("proxy(%s): password not given",
			client->common.virtual_user);
		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)
		return -1;

	if (client->io != NULL) {
		io_remove(client->io);
		client->io = NULL;
	}

	return 0;
}

--- NEW FILE: imap-proxy.h ---
#ifndef __IMAP_PROXY_H
#define __IMAP_PROXY_H

int imap_proxy_new(struct imap_client *client, const char *host,
		   unsigned int port, const char *user, const char *password);

#endif



More information about the dovecot-cvs mailing list