dovecot-2.0: *-login: Moved most of the common code to login-com...

dovecot at dovecot.org dovecot at dovecot.org
Mon Aug 10 04:53:25 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/e30495ae11de
changeset: 9756:e30495ae11de
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Aug 09 21:53:14 2009 -0400
description:
*-login: Moved most of the common code to login-common.

diffstat:

24 files changed, 1373 insertions(+), 1995 deletions(-)
src/imap-login/client-authenticate.c  |  365 +++------------------
src/imap-login/client-authenticate.h  |    5 
src/imap-login/client.c               |  548 +++++----------------------------
src/imap-login/client.h               |   34 --
src/imap-login/imap-proxy.c           |  247 +++-----------
src/imap-login/imap-proxy.h           |    7 
src/login-common/Makefile.am          |    1 
src/login-common/client-common-auth.c |  480 ++++++++++++++++++++++++++++
src/login-common/client-common.c      |  406 +++++++++++++++++++++++-
src/login-common/client-common.h      |  100 +++++-
src/login-common/common.h             |    1 
src/login-common/login-proxy.c        |    8 
src/login-common/login-proxy.h        |    1 
src/login-common/main.c               |    2 
src/login-common/sasl-server.c        |   13 
src/login-common/ssl-proxy-openssl.c  |    7 
src/login-common/ssl-proxy.c          |    2 
src/login-common/ssl-proxy.h          |    2 
src/pop3-login/client-authenticate.c  |  414 ++++--------------------
src/pop3-login/client-authenticate.h  |    3 
src/pop3-login/client.c               |  475 +++-------------------------
src/pop3-login/client.h               |   34 --
src/pop3-login/pop3-proxy.c           |  206 +-----------
src/pop3-login/pop3-proxy.h           |    7 

diffs (truncated from 4357 to 300 lines):

diff -r c2037505a66b -r e30495ae11de src/imap-login/client-authenticate.c
--- a/src/imap-login/client-authenticate.c	Sun Aug 09 21:48:45 2009 -0400
+++ b/src/imap-login/client-authenticate.c	Sun Aug 09 21:53:14 2009 -0400
@@ -18,18 +18,14 @@
 
 #include <stdlib.h>
 
-#define AUTH_FAILURE_DELAY_INCREASE_MSECS 5000
-
-#define IMAP_SERVICE_NAME "imap"
-
-const char *client_authenticate_get_capabilities(struct imap_client *client)
+const char *client_authenticate_get_capabilities(struct client *client)
 {
 	const struct auth_mech_desc *mech;
 	unsigned int i, count;
 	string_t *str;
 
 	str = t_str_new(128);
-	mech = sasl_server_get_advertised_mechs(&client->common, &count);
+	mech = sasl_server_get_advertised_mechs(client, &count);
 	for (i = 0; i < count; i++) {
 		str_append_c(str, ' ');
 		str_append(str, "AUTH=");
@@ -39,146 +35,13 @@ const char *client_authenticate_get_capa
 	return str_c(str);
 }
 
-static void client_auth_input(struct imap_client *client)
+bool imap_client_auth_handle_reply(struct client *client,
+				   const struct client_auth_reply *reply)
 {
-	char *line;
+	struct imap_client *imap_client = (struct imap_client *)client;
+	string_t *str;
 
-	if (!client_read(client))
-		return;
-
-	if (client->skip_line) {
-		if (i_stream_next_line(client->common.input) == NULL)
-			return;
-
-		client->skip_line = FALSE;
-	}
-
-	/* @UNSAFE */
-	line = i_stream_next_line(client->common.input);
-	if (line == NULL)
-		return;
-
-	if (strcmp(line, "*") == 0)
-		sasl_server_auth_abort(&client->common);
-	else {
-		client_set_auth_waiting(client);
-		auth_client_request_continue(client->common.auth_request, line);
-		io_remove(&client->io);
-
-		/* clear sensitive data */
-		safe_memset(line, 0, strlen(line));
-	}
-}
-
-static void client_authfail_delay_timeout(struct imap_client *client)
-{
-	timeout_remove(&client->to_authfail_delay);
-
-	/* get back to normal client input. */
-	i_assert(client->io == NULL);
-	client->io = io_add(client->common.fd, IO_READ, client_input, client);
-	client_input(client);
-}
-
-void client_auth_failed(struct imap_client *client, bool nodelay)
-{
-	unsigned int delay_msecs;
-
-	i_free_and_null(client->common.master_data_prefix);
-
-	if (client->auth_initializing)
-		return;
-
-	if (client->io != NULL)
-		io_remove(&client->io);
-	if (nodelay) {
-		client->io = io_add(client->common.fd, IO_READ,
-				    client_input, client);
-		client_input(client);
-		return;
-	}
-
-	/* increase the timeout after each unsuccessful attempt, but don't
-	   increase it so high that the idle timeout would be triggered */
-	delay_msecs = client->common.auth_attempts *
-		AUTH_FAILURE_DELAY_INCREASE_MSECS;
-	if (delay_msecs > CLIENT_LOGIN_IDLE_TIMEOUT_MSECS)
-		delay_msecs = CLIENT_LOGIN_IDLE_TIMEOUT_MSECS - 1000;
-
-	i_assert(client->to_authfail_delay == NULL);
-	client->to_authfail_delay =
-		timeout_add(delay_msecs, client_authfail_delay_timeout, client);
-}
-
-static bool client_handle_args(struct imap_client *client,
-			       const char *const *args, bool success,
-			       bool *nodelay_r)
-{
-	const char *reason = NULL, *host = NULL, *destuser = NULL, *pass = NULL;
-	const char *master_user = NULL;
-	const char *key, *value, *p;
-	enum login_proxy_ssl_flags ssl_flags = 0;
-	string_t *reply;
-	unsigned int port = 143;
-	bool proxy = FALSE, temp = FALSE, nologin = !success;
-	bool authz_failure = FALSE;
-
-	*nodelay_r = FALSE;
-	for (; *args != NULL; args++) {
-		p = strchr(*args, '=');
-		if (p == NULL) {
-			key = *args;
-			value = "";
-		} else {
-			key = t_strdup_until(*args, p);
-			value = p + 1;
-		}
-		if (strcmp(key, "nologin") == 0)
-			nologin = TRUE;
-		else if (strcmp(key, "nodelay") == 0)
-			*nodelay_r = TRUE;
-		else if (strcmp(key, "proxy") == 0)
-			proxy = TRUE;
-		else if (strcmp(key, "temp") == 0)
-			temp = TRUE;
-		else if (strcmp(key, "authz") == 0)
-			authz_failure = TRUE;
-		else if (strcmp(key, "reason") == 0)
-			reason = value;
-		else if (strcmp(key, "host") == 0)
-			host = value;
-		else if (strcmp(key, "port") == 0)
-			port = atoi(value);
-		else if (strcmp(key, "destuser") == 0)
-			destuser = value;
-		else if (strcmp(key, "pass") == 0)
-			pass = value;
-		else if (strcmp(key, "master") == 0)
-			master_user = value;
-		else if (strcmp(key, "user") == 0) {
-			/* already handled in login-common */
-		} else if (client->common.set->auth_debug)
-			i_info("Ignoring unknown passdb extra field: %s", key);
-	}
-
-	if (destuser == NULL)
-		destuser = client->common.virtual_user;
-
-	if (proxy) {
-		/* 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.
-
-		   proxy host=.. [port=..] [destuser=..] pass=.. */
-		if (!success)
-			return FALSE;
-		if (imap_proxy_new(client, host, port, destuser, master_user,
-				   pass, ssl_flags) < 0)
-			client_auth_failed(client, TRUE);
-		return TRUE;
-	}
-
-	if (host != NULL) {
+	if (reply->host != NULL) {
 		/* IMAP referral
 
 		   [nologin] referral host=.. [port=..] [destuser=..]
@@ -188,47 +51,46 @@ static bool client_handle_args(struct im
 		   OK [...] Logged in, but you should use this server instead.
 		   .. [REFERRAL ..] (Reason from auth server)
 		*/
-		reply = t_str_new(128);
-		str_append(reply, client->cmd_tag);
-		str_append_c(reply, ' ');
-		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.");
+		str = t_str_new(128);
+		str_append(str, imap_client->cmd_tag);
+		str_append_c(str, ' ');
+		str_append(str, reply->nologin ? "NO " : "OK ");
+		str_printfa(str, "[REFERRAL imap://%s;AUTH=%s@%s",
+			    reply->destuser, client->auth_mech_name,
+			    reply->host);
+		if (reply->port != 143)
+			str_printfa(str, ":%u", reply->port);
+		str_append(str, "/] ");
+		if (reply->reason != NULL)
+			str_append(str, reply->reason);
+		else if (reply->nologin)
+			str_append(str, "Try this server instead.");
 		else {
-			str_append(reply, "Logged in, but you should use "
+			str_append(str, "Logged in, but you should use "
 				   "this server instead.");
 		}
-		str_append(reply, "\r\n");
-		client_send_raw(client, str_c(reply));
-		if (!nologin) {
+		str_append(str, "\r\n");
+		client_send_raw(client, str_c(str));
+		if (!reply->nologin) {
 			client_destroy_success(client, "Login with referral");
 			return TRUE;
 		}
-	} else if (nologin) {
+	} else if (reply->nologin) {
 		/* Authentication went ok, but for some reason user isn't
 		   allowed to log in. Shouldn't probably happen. */
-		if (reason != NULL) {
-			client_send_line(&client->common,
+		if (reply->reason != NULL) {
+			client_send_line(client,
 					 CLIENT_CMD_REPLY_AUTH_FAIL_REASON,
-					 reason);
-		} else if (temp) {
-			client_send_line(&client->common,
+					 reply->reason);
+		} else if (reply->temp) {
+			client_send_line(client,
 					 CLIENT_CMD_REPLY_AUTH_FAIL_TEMP,
 					 AUTH_TEMP_FAILED_MSG);
-		} else if (authz_failure) {
-			client_send_line(&client->common,
-					 CLIENT_CMD_REPLY_AUTHZ_FAILED,
+		} else if (reply->authz_failure) {
+			client_send_line(client, CLIENT_CMD_REPLY_AUTHZ_FAILED,
 					 "Authorization failed");
 		} else {
-			client_send_line(&client->common,
-					 CLIENT_CMD_REPLY_AUTH_FAILED,
+			client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAILED,
 					 AUTH_FAILED_MSG);
 		}
 	} else {
@@ -236,127 +98,34 @@ static bool client_handle_args(struct im
 		return FALSE;
 	}
 
-	i_assert(nologin);
+	i_assert(reply->nologin);
 
 	if (!client->destroyed)
-		client_auth_failed(client, *nodelay_r);
+		client_auth_failed(client, reply->nodelay);
 	return TRUE;
 }
 
-static void sasl_callback(struct client *_client, enum sasl_server_reply reply,
-			  const char *data, const char *const *args)
-{
-	struct imap_client *client = (struct imap_client *)_client;
-	struct const_iovec iov[3];
-	size_t data_len;
-	bool nodelay;
-
-	i_assert(!client->destroyed ||
-		 reply == SASL_SERVER_REPLY_AUTH_ABORTED ||
-		 reply == SASL_SERVER_REPLY_MASTER_FAILED);
-
-	switch (reply) {
-	case SASL_SERVER_REPLY_SUCCESS:
-		if (client->to_auth_waiting != NULL)
-			timeout_remove(&client->to_auth_waiting);
-		if (args != NULL) {
-			if (client_handle_args(client, args, TRUE, &nodelay))
-				break;
-		}
-		client_destroy_success(client, "Login");
-		break;
-	case SASL_SERVER_REPLY_AUTH_FAILED:
-	case SASL_SERVER_REPLY_AUTH_ABORTED:
-		if (client->to_auth_waiting != NULL)
-			timeout_remove(&client->to_auth_waiting);
-		if (args != NULL) {
-			if (client_handle_args(client, args, FALSE, &nodelay))
-				break;
-		}
-
-		if (reply == SASL_SERVER_REPLY_AUTH_ABORTED) {
-			client_send_line(&client->common, CLIENT_CMD_REPLY_BAD,
-					 "Authentication aborted by client.");
-		} else if (data == NULL) {
-			client_send_line(&client->common,


More information about the dovecot-cvs mailing list