changeset 4301:0e10b01960a0 HEAD

IMAP: Reply with tagged BAD if authentication is aborted because client sent "*" or something else that was a client error. If authentication failed for any reason, the error message was always "Authentication failed". In case of client errors or if auth process gave an error message, it should have been that instead.
author Timo Sirainen <tss@iki.fi>
date Mon, 05 Jun 2006 23:25:39 +0300
parents 3eeceb1156ad
children a9498883f44c
files src/imap-login/client-authenticate.c src/login-common/sasl-server.c src/login-common/sasl-server.h src/pop3-login/client-authenticate.c
diffstat 4 files changed, 41 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/src/imap-login/client-authenticate.c	Fri Jun 02 11:39:29 2006 +0300
+++ b/src/imap-login/client-authenticate.c	Mon Jun 05 23:25:39 2006 +0300
@@ -63,16 +63,17 @@
 		return;
 
 	if (strcmp(line, "*") == 0) {
-		sasl_server_auth_cancel(&client->common,
-					"Authentication aborted");
+		sasl_server_auth_client_error(&client->common,
+					      "Authentication aborted");
 		return;
 	}
 
 	if (client->common.auth_request == NULL) {
-		sasl_server_auth_cancel(&client->common,
-					"Don't send unrequested data");
+		sasl_server_auth_client_error(&client->common,
+					      "Don't send unrequested data");
 	} else {
 		auth_client_request_continue(client->common.auth_request, line);
+		client->common.auth_request = NULL;
 	}
 
 	/* clear sensitive data */
@@ -178,6 +179,7 @@
 {
 	struct imap_client *client = (struct imap_client *)_client;
 	struct const_iovec iov[3];
+	const char *msg;
 	size_t data_len;
 
 	switch (reply) {
@@ -191,12 +193,16 @@
 		client_destroy(client, "Login");
 		break;
 	case SASL_SERVER_REPLY_AUTH_FAILED:
+	case SASL_SERVER_REPLY_CLIENT_ERROR:
 		if (args != NULL) {
 			if (client_handle_args(client, args, TRUE))
 				break;
 		}
 
-		client_send_tagline(client, "NO "AUTH_FAILED_MSG);
+		msg = reply == SASL_SERVER_REPLY_AUTH_FAILED ? "NO " : "BAD ";
+		msg = t_strconcat(msg, data != NULL ? data : AUTH_FAILED_MSG,
+				  NULL);
+		client_send_tagline(client, msg);
 
 		/* get back to normal client input. */
 		if (client->io != NULL)
--- a/src/login-common/sasl-server.c	Fri Jun 02 11:39:29 2006 +0300
+++ b/src/login-common/sasl-server.c	Mon Jun 05 23:25:39 2006 +0300
@@ -119,15 +119,15 @@
 
 	mech = auth_client_find_mech(auth_client, mech_name);
 	if (mech == NULL) {
-		sasl_server_auth_cancel(client, 
+		sasl_server_auth_client_error(client,
 			"Unsupported authentication mechanism.");
 		return;
 	}
 
 	if (!client->secured && disable_plaintext_auth &&
 	    (mech->flags & MECH_SEC_PLAINTEXT) != 0) {
-		sasl_server_auth_cancel(client,
-					"Plaintext authentication disabled.");
+		sasl_server_auth_client_error(client,
+			"Plaintext authentication disabled.");
 		return;
 	}
 
@@ -145,12 +145,13 @@
 		auth_client_request_new(auth_client, NULL, &info,
 					authenticate_callback, client, &error);
 	if (client->auth_request == NULL) {
-		sasl_server_auth_cancel(client,
+		sasl_server_auth_failed(client,
 			 t_strconcat("Authentication failed: ", error, NULL));
 	}
 }
 
-void sasl_server_auth_cancel(struct client *client, const char *reason)
+static void sasl_server_auth_cancel(struct client *client, const char *reason,
+				    enum sasl_server_reply reply)
 {
 	if (verbose_auth && reason != NULL) {
 		const char *auth_name =
@@ -167,6 +168,15 @@
 		client->auth_request = NULL;
 	}
 
-	client->sasl_callback(client, SASL_SERVER_REPLY_AUTH_FAILED,
-			      reason, NULL);
+	client->sasl_callback(client, reply, reason, NULL);
 }
+
+void sasl_server_auth_failed(struct client *client, const char *reason)
+{
+	sasl_server_auth_cancel(client, reason, SASL_SERVER_REPLY_AUTH_FAILED);
+}
+
+void sasl_server_auth_client_error(struct client *client, const char *reason)
+{
+	sasl_server_auth_cancel(client, reason, SASL_SERVER_REPLY_CLIENT_ERROR);
+}
--- a/src/login-common/sasl-server.h	Fri Jun 02 11:39:29 2006 +0300
+++ b/src/login-common/sasl-server.h	Mon Jun 05 23:25:39 2006 +0300
@@ -4,6 +4,7 @@
 enum sasl_server_reply {
 	SASL_SERVER_REPLY_SUCCESS,
 	SASL_SERVER_REPLY_AUTH_FAILED,
+	SASL_SERVER_REPLY_CLIENT_ERROR,
 	SASL_SERVER_REPLY_MASTER_FAILED,
 	SASL_SERVER_REPLY_CONTINUE
 };
@@ -16,6 +17,7 @@
 			    const char *service, const char *mech_name,
 			    const char *initial_resp_base64,
 			    sasl_server_callback_t *callback);
-void sasl_server_auth_cancel(struct client *client, const char *reason);
+void sasl_server_auth_failed(struct client *client, const char *reason);
+void sasl_server_auth_client_error(struct client *client, const char *reason);
 
 #endif
--- a/src/pop3-login/client-authenticate.c	Fri Jun 02 11:39:29 2006 +0300
+++ b/src/pop3-login/client-authenticate.c	Mon Jun 05 23:25:39 2006 +0300
@@ -70,16 +70,17 @@
 		return;
 
 	if (strcmp(line, "*") == 0) {
-		sasl_server_auth_cancel(&client->common,
-					"Authentication aborted");
+		sasl_server_auth_client_error(&client->common,
+					      "Authentication aborted");
 		return;
 	}
 
 	if (client->common.auth_request == NULL) {
-		sasl_server_auth_cancel(&client->common,
-					"Don't send unrequested data");
+		sasl_server_auth_client_error(&client->common,
+					      "Don't send unrequested data");
 	} else {
 		auth_client_request_continue(client->common.auth_request, line);
+		client->common.auth_request = NULL;
 	}
 
 	/* clear sensitive data */
@@ -152,6 +153,7 @@
 {
 	struct pop3_client *client = (struct pop3_client *)_client;
 	struct const_iovec iov[3];
+	const char *msg;
 	size_t data_len;
 
 	switch (reply) {
@@ -165,12 +167,15 @@
 		client_destroy(client, "Login");
 		break;
 	case SASL_SERVER_REPLY_AUTH_FAILED:
+	case SASL_SERVER_REPLY_CLIENT_ERROR:
 		if (args != NULL) {
 			if (client_handle_args(client, args, TRUE))
 				break;
 		}
 
-		client_send_line(client, "-ERR "AUTH_FAILED_MSG);
+		msg = t_strconcat("-ERR ", data != NULL ?
+				  data : AUTH_FAILED_MSG, NULL);
+		client_send_line(client, msg);
 
 		/* get back to normal client input. */
 		if (client->io != NULL)