diff src/imap-login/client-authenticate.c @ 2766:26a091f3add6 HEAD

Implemented support for LOGIN-REFERRALS using "referral" and "reason" parameters from auth server.
author Timo Sirainen <tss@iki.fi>
date Mon, 18 Oct 2004 04:13:25 +0300
parents 0f31778d3c34
children d344be0bb70f
line wrap: on
line diff
--- a/src/imap-login/client-authenticate.c	Mon Oct 18 04:00:42 2004 +0300
+++ b/src/imap-login/client-authenticate.c	Mon Oct 18 04:13:25 2004 +0300
@@ -76,8 +76,54 @@
 	safe_memset(line, 0, strlen(line));
 }
 
+static int client_handle_success_args(struct imap_client *client,
+				      const char *const *args, int nologin)
+{
+	const char *reason = NULL, *referral = NULL;
+	string_t *reply;
+
+	for (; *args != NULL; args++) {
+		if (strcmp(*args, "nologin") == 0)
+			nologin = TRUE;
+		else if (strncmp(*args, "reason=", 7) == 0)
+			reason = *args + 7;
+		else  if (strncmp(*args, "referral=", 9) == 0)
+			referral = *args + 9;
+	}
+
+	if (!nologin && referral == NULL)
+		return FALSE;
+
+	reply = t_str_new(128);
+	str_append(reply, nologin ? "NO " : "OK ");
+	if (referral != NULL)
+		str_printfa(reply, "[REFERRAL %s] ", referral);
+
+	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.");
+
+	client_send_tagline(client, str_c(reply));
+	if (!nologin) {
+		client_destroy(client, t_strconcat(
+			"Login: ", client->common.virtual_user, NULL));
+	} else {
+		/* get back to normal client input. */
+		if (client->io != NULL)
+			io_remove(client->io);
+		client->io = io_add(client->common.fd, IO_READ,
+				    client_input, client);
+	}
+	return TRUE;
+}
+
 static void sasl_callback(struct client *_client, enum sasl_server_reply reply,
-			  const char *data)
+			  const char *data, const char *const *args)
 {
 	struct imap_client *client = (struct imap_client *)_client;
 	struct const_iovec iov[3];
@@ -86,11 +132,21 @@
 
 	switch (reply) {
 	case SASL_SERVER_REPLY_SUCCESS:
+		if (args != NULL) {
+			if (client_handle_success_args(client, args, FALSE))
+				break;
+		}
+
 		client_send_tagline(client, "OK Logged in.");
 		client_destroy(client, t_strconcat(
 			"Login: ", client->common.virtual_user, NULL));
 		break;
 	case SASL_SERVER_REPLY_AUTH_FAILED:
+		if (args != NULL) {
+			if (client_handle_success_args(client, args, TRUE))
+				break;
+		}
+
 		if (data == NULL)
 			client_send_tagline(client, "Authentication failed");
 		else {