[dovecot-cvs] dovecot/src/lib-auth auth-client.h, 1.7, 1.8 auth-server-connection.c, 1.8, 1.9 auth-server-connection.h, 1.5, 1.6 auth-server-request.c, 1.14, 1.15 auth-server-request.h, 1.1, 1.2

cras at dovecot.org cras at dovecot.org
Wed Oct 13 19:38:37 EEST 2004


Update of /var/lib/cvs/dovecot/src/lib-auth
In directory talvi:/tmp/cvs-serv8894/lib-auth

Modified Files:
	auth-client.h auth-server-connection.c 
	auth-server-connection.h auth-server-request.c 
	auth-server-request.h 
Log Message:
Changed dovecot-auth protocol to ASCII based. Should be easier now to write
replacement server if needed by someone. Also cleaned up/made more
consistent auth code. The new code could still use some cleaning though..



Index: auth-client.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-auth/auth-client.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- auth-client.h	2 Jul 2004 22:03:37 -0000	1.7
+++ auth-client.h	13 Oct 2004 16:38:34 -0000	1.8
@@ -7,10 +7,14 @@
 struct auth_client;
 struct auth_request;
 
+enum auth_request_flags {
+	AUTH_REQUEST_FLAG_SECURED		= 0x01,
+	AUTH_REQUEST_FLAG_VALID_CLIENT_CERT	= 0x02,
+};
+
 struct auth_mech_desc {
 	char *name;
-	unsigned int plaintext:1;
-	unsigned int advertise:1;
+        enum mech_security_flags flags;
 };
 
 struct auth_connect_id {
@@ -21,18 +25,16 @@
 struct auth_request_info {
 	const char *mech;
 	const char *protocol;
-	enum auth_client_request_new_flags flags;
+	enum auth_request_flags flags;
 
 	struct ip_addr local_ip, remote_ip;
 
-	const unsigned char *initial_resp_data;
-	size_t initial_resp_size;
+	const char *initial_resp_base64;
 };
 
-/* reply is NULL if auth connection died */
-typedef void auth_request_callback_t(struct auth_request *request,
-				     struct auth_client_request_reply *reply,
-				     const unsigned char *data, void *context);
+typedef void auth_request_callback_t(struct auth_request *request, int status,
+				     const char *data_base64,
+				     const char *const *args, void *context);
 
 typedef void auth_connect_notify_callback_t(struct auth_client *client,
 					    int connected, void *context);
@@ -69,7 +71,7 @@
 /* Continue authentication. Call when
    reply->result == AUTH_CLIENT_REQUEST_CONTINUE */
 void auth_client_request_continue(struct auth_request *request,
-				  const unsigned char *data, size_t data_size);
+				  const char *data_base64);
 
 /* Abort ongoing authentication request. */
 void auth_client_request_abort(struct auth_request *request);

Index: auth-server-connection.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-auth/auth-server-connection.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- auth-server-connection.c	8 Oct 2004 17:51:48 -0000	1.8
+++ auth-server-connection.c	13 Oct 2004 16:38:34 -0000	1.9
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Timo Sirainen */
+/* Copyright (C) 2003-2004 Timo Sirainen */
 
 #include "lib.h"
 #include "buffer.h"
@@ -12,13 +12,7 @@
 #include "auth-server-request.h"
 
 #include <unistd.h>
-
-/* Maximum size for an auth reply. 50kB should be more than enough. */
-#define MAX_INBUF_SIZE (1024*50)
-
-#define MAX_OUTBUF_SIZE \
-	(sizeof(struct auth_client_request_continue) + \
-	 AUTH_CLIENT_MAX_REQUEST_DATA_SIZE)
+#include <stdlib.h>
 
 static void auth_server_connection_unref(struct auth_server_connection *conn);
 
@@ -40,54 +34,81 @@
 	}
 }
 
-static void auth_handle_handshake(struct auth_server_connection *conn,
-				  struct auth_client_handshake_reply *handshake,
-				  const unsigned char *data)
+static int
+auth_client_input_mech(struct auth_server_connection *conn, const char *args)
 {
-	struct auth_client_handshake_mech_desc handshake_mech_desc;
+	const char *const *list;
 	struct auth_mech_desc mech_desc;
-	buffer_t *buf;
-	unsigned int i;
 
-	if (handshake->data_size == 0 || data[handshake->data_size-1] != '\0' ||
-	    handshake->mech_count * sizeof(handshake_mech_desc) >=
-	    handshake->data_size)  {
-		i_error("BUG: Auth server sent corrupted handshake");
-		auth_server_connection_destroy(conn, FALSE);
-		return;
+	if (conn->handshake_received) {
+		i_error("BUG: Authentication server already sent handshake");
+		return FALSE;
 	}
 
-	buf = buffer_create_dynamic(conn->pool, sizeof(mech_desc) *
-				    handshake->mech_count);
-	for (i = 0; i < handshake->mech_count; i++) {
-		memcpy(&handshake_mech_desc,
-		       data + sizeof(handshake_mech_desc) * i,
-		       sizeof(handshake_mech_desc));
+	list = t_strsplit(args, "\t");
+	if (list[0] == NULL) {
+		i_error("BUG: Authentication server sent broken MECH line");
+		return FALSE;
+	}
 
-		if (handshake_mech_desc.name_idx >= handshake->data_size) {
-			i_error("BUG: Auth server sent corrupted handshake");
-			auth_server_connection_destroy(conn, FALSE);
-			return;
-		}
+	memset(&mech_desc, 0, sizeof(mech_desc));
+	mech_desc.name = p_strdup(conn->pool, list[0]);
 
-		mech_desc.name = p_strdup(conn->pool, (const char *)data +
-					  handshake_mech_desc.name_idx);
-		mech_desc.plaintext = handshake_mech_desc.plaintext;
-		mech_desc.advertise = handshake_mech_desc.advertise;
-		buffer_append(buf, &mech_desc, sizeof(mech_desc));
+	if (strcmp(mech_desc.name, "PLAIN") == 0)
+		conn->has_plain_mech = TRUE;
 
-		if (strcmp(mech_desc.name, "PLAIN") == 0)
-			conn->has_plain_mech = TRUE;
+	for (list++; *list != NULL; list++) {
+		if (strcmp(*list, "private") == 0)
+			mech_desc.flags |= MECH_SEC_PRIVATE;
+		else if (strcmp(*list, "anonymous") == 0)
+			mech_desc.flags |= MECH_SEC_ANONYMOUS;
+		else if (strcmp(*list, "plaintext") == 0)
+			mech_desc.flags |= MECH_SEC_PLAINTEXT;
+		else if (strcmp(*list, "dictionary") == 0)
+			mech_desc.flags |= MECH_SEC_DICTIONARY;
+		else if (strcmp(*list, "active") == 0)
+			mech_desc.flags |= MECH_SEC_ACTIVE;
+		else if (strcmp(*list, "forward-secrecy") == 0)
+			mech_desc.flags |= MECH_SEC_FORWARD_SECRECY;
+		else if (strcmp(*list, "mutual-auth") == 0)
+			mech_desc.flags |= MECH_SEC_MUTUAL_AUTH;
+	}
+	buffer_append(conn->auth_mechs_buf, &mech_desc, sizeof(mech_desc));
+	return TRUE;
+}
+
+static int
+auth_client_input_spid(struct auth_server_connection *conn, const char *args)
+{
+	if (conn->handshake_received) {
+		i_error("BUG: Authentication server already sent handshake");
+		return FALSE;
 	}
 
-	conn->server_pid = handshake->server_pid;
-	conn->connect_uid = handshake->connect_uid;
+	conn->server_pid = (unsigned int)strtoul(args, NULL, 10);
+	return TRUE;
+}
+
+static int
+auth_client_input_cuid(struct auth_server_connection *conn, const char *args)
+{
+	if (conn->handshake_received) {
+		i_error("BUG: Authentication server already sent handshake");
+		return FALSE;
+	}
+
+	conn->connect_uid = (unsigned int)strtoul(args, NULL, 10);
+	return TRUE;
+}
+
+static int auth_client_input_done(struct auth_server_connection *conn)
+{
+	conn->available_auth_mechs = conn->auth_mechs_buf->data;
 	conn->available_auth_mechs_count =
-		buffer_get_used_size(buf) / sizeof(mech_desc);
-	conn->available_auth_mechs = buffer_free_without_data(buf);
-	conn->handshake_received = TRUE;
+		conn->auth_mechs_buf->used / sizeof(struct auth_mech_desc);
 
-        conn->client->conn_waiting_handshake_count--;
+	conn->handshake_received = TRUE;
+	conn->client->conn_waiting_handshake_count--;
 	update_available_auth_mechs(conn);
 
 	if (conn->client->connect_notify_callback != NULL &&
@@ -95,14 +116,14 @@
 		conn->client->connect_notify_callback(conn->client, TRUE,
 				conn->client->connect_notify_context);
 	}
+	return TRUE;
 }
 
 static void auth_client_input(void *context)
 {
 	struct auth_server_connection *conn = context;
-	struct auth_client_handshake_reply handshake;
-	const unsigned char *data;
-	size_t size;
+	const char *line;
+	int ret;
 
 	switch (i_stream_read(conn->input)) {
 	case 0:
@@ -114,50 +135,37 @@
 	case -2:
 		/* buffer full - can't happen unless auth is buggy */
 		i_error("BUG: Auth server sent us more than %d bytes of data",
-			MAX_INBUF_SIZE);
+			AUTH_CLIENT_MAX_LINE_LENGTH);
 		auth_server_connection_destroy(conn, FALSE);
 		return;
 	}
 
-	if (!conn->handshake_received) {
-		data = i_stream_get_data(conn->input, &size);
-		if (size < sizeof(handshake))
-			return;
-
-		memcpy(&handshake, data, sizeof(handshake));
-		if (size < sizeof(handshake) + handshake.data_size)
-			return;
-
-		conn->refcount++;
-		auth_handle_handshake(conn, &handshake,
-				      data + sizeof(handshake));
-		i_stream_skip(conn->input, sizeof(handshake) +
-			      handshake.data_size);
-		auth_server_connection_unref(conn);
-		return;
-	}
-
-	if (!conn->reply_received) {
-		data = i_stream_get_data(conn->input, &size);
-		if (size < sizeof(conn->reply))
-			return;
-
-		memcpy(&conn->reply, data, sizeof(conn->reply));
-		i_stream_skip(conn->input, sizeof(conn->reply));
-		conn->reply_received = TRUE;
-	}
-
-	data = i_stream_get_data(conn->input, &size);
-	if (size < conn->reply.data_size)
-		return;
-
-	/* we've got a full reply */
 	conn->refcount++;
-	conn->reply_received = FALSE;
-
-	auth_server_request_handle_reply(conn, &conn->reply, data);
-	i_stream_skip(conn->input, conn->reply.data_size);
+	while ((line = i_stream_next_line(conn->input)) != NULL) {
+		if (strncmp(line, "OK\t", 3) == 0)
+			ret = auth_client_input_ok(conn, line + 3);
+		else if (strncmp(line, "CONT\t", 5) == 0)
+			ret = auth_client_input_cont(conn, line + 5);
+        	else if (strncmp(line, "FAIL\t", 5) == 0)
+			ret = auth_client_input_fail(conn, line + 5);
+		else if (strncmp(line, "MECH\t", 5) == 0)
+			ret = auth_client_input_mech(conn, line + 5);
+		else if (strncmp(line, "SPID\t", 5) == 0)
+			ret = auth_client_input_spid(conn, line + 5);
+		else if (strncmp(line, "CUID\t", 5) == 0)
+			ret = auth_client_input_cuid(conn, line + 5);
+		else if (strcmp(line, "DONE") == 0)
+			ret = auth_client_input_done(conn);
+		else {
+			/* ignore unknown command */
+			ret = TRUE;
+		}
 
+		if (!ret) {
+			auth_server_connection_destroy(conn, FALSE);
+			break;
+		}
+	}
 	auth_server_connection_unref(conn);
 }
 
@@ -165,7 +173,6 @@
 auth_server_connection_new(struct auth_client *client, const char *path)
 {
 	struct auth_server_connection *conn;
-	struct auth_client_handshake_request handshake;
 	pool_t pool;
 	int fd;
 
@@ -192,21 +199,19 @@
 		conn->ext_input_io =
 			client->ext_input_add(fd, auth_client_input, conn);
 	}
-	conn->input = i_stream_create_file(fd, default_pool, MAX_INBUF_SIZE,
-					   FALSE);
+	conn->input = i_stream_create_file(fd, default_pool,
+					   AUTH_CLIENT_MAX_LINE_LENGTH, FALSE);
 	conn->output = o_stream_create_file(fd, default_pool, (size_t)-1,
 					    FALSE);
 	conn->requests = hash_create(default_pool, pool, 100, NULL, NULL);
+	conn->auth_mechs_buf = buffer_create_dynamic(default_pool, 256);
 
 	conn->next = client->connections;
 	client->connections = conn;
 
-	/* send our handshake */
-	memset(&handshake, 0, sizeof(handshake));
-	handshake.client_pid = client->pid;
-
         client->conn_waiting_handshake_count++;
-	if (o_stream_send(conn->output, &handshake, sizeof(handshake)) < 0) {
+	if (o_stream_send_str(conn->output,
+			      t_strdup_printf("CPID\t%u\n", client->pid)) < 0) {
 		errno = conn->output->stream_errno;
 		i_warning("Error sending handshake to auth server: %m");
 		auth_server_connection_destroy(conn, TRUE);
@@ -252,7 +257,7 @@
 	conn->fd = -1;
 
 	auth_server_requests_remove_all(conn);
-        auth_server_connection_unref(conn);
+	auth_server_connection_unref(conn);
 
 	if (reconnect)
 		auth_client_connect_missing_servers(client);
@@ -270,6 +275,7 @@
 	i_assert(conn->refcount == 0);
 
 	hash_destroy(conn->requests);
+	buffer_free(conn->auth_mechs_buf);
 
 	i_stream_unref(conn->input);
 	o_stream_unref(conn->output);

Index: auth-server-connection.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-auth/auth-server-connection.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- auth-server-connection.h	2 Jul 2004 22:03:37 -0000	1.5
+++ auth-server-connection.h	13 Oct 2004 16:38:34 -0000	1.6
@@ -40,14 +40,13 @@
 	unsigned int server_pid;
 	unsigned int connect_uid;
 
+	buffer_t *auth_mechs_buf;
 	const struct auth_mech_desc *available_auth_mechs;
 	unsigned int available_auth_mechs_count;
-        struct auth_client_request_reply reply;
 
         struct hash_table *requests;
 
 	unsigned int handshake_received:1;
-	unsigned int reply_received:1;
 	unsigned int has_plain_mech:1;
 };
 

Index: auth-server-request.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-auth/auth-server-request.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- auth-server-request.c	8 Oct 2004 17:51:48 -0000	1.14
+++ auth-server-request.c	13 Oct 2004 16:38:34 -0000	1.15
@@ -1,31 +1,31 @@
-/* Copyright (C) 2003 Timo Sirainen */
+/* Copyright (C) 2003-2004 Timo Sirainen */
 
 #include "lib.h"
-#include "buffer.h"
+#include "str.h"
 #include "hash.h"
 #include "ostream.h"
 #include "auth-client.h"
 #include "auth-server-connection.h"
 #include "auth-server-request.h"
 
+#include <stdlib.h>
+
 struct auth_request {
         struct auth_server_connection *conn;
 
 	unsigned int id;
 
 	char *mech, *protocol;
-	enum auth_client_request_new_flags flags;
+        enum auth_request_flags flags;
 	struct ip_addr local_ip, remote_ip;
 
-	unsigned char *initial_resp_data;
-	size_t initial_resp_size;
+	char *initial_resp_base64;
 
 	auth_request_callback_t *callback;
 	void *context;
 
         struct auth_server_connection *next_conn;
-	unsigned char *plaintext_data; /* for resending to other servers */
-        size_t plaintext_data_size;
+	char *plaintext_data; /* for resending to other servers */
 
 	unsigned int init_sent:1;
 	unsigned int retrying:1;
@@ -33,6 +33,7 @@
 
 static int auth_server_send_new_request(struct auth_server_connection *conn,
 					struct auth_request *request);
+static void auth_client_request_free(struct auth_request *request);
 
 static struct auth_server_connection *
 get_next_plain_server(struct auth_server_connection *conn)
@@ -47,8 +48,7 @@
 }
 
 static void
-auth_server_request_check_retry(struct auth_request *request,
-				const unsigned char *data, size_t data_size)
+auth_server_request_check_retry(struct auth_request *request, const char *data)
 {
 	if (strcmp(request->mech, "PLAIN") == 0 &&
 	    request->plaintext_data == NULL && request->conn != NULL) {
@@ -56,9 +56,7 @@
 		if (request->next_conn != NULL) {
 			/* plaintext authentication - save the data so we can
 			   try it for the next */
-			request->plaintext_data = i_malloc(data_size);
-			memcpy(request->plaintext_data, data, data_size);
-			request->plaintext_data_size = data_size;
+			request->plaintext_data = i_strdup(data);
 
 			hash_insert(request->next_conn->requests,
 				    POINTER_CAST(request->id), request);
@@ -72,51 +70,28 @@
 static int auth_server_send_new_request(struct auth_server_connection *conn,
 					struct auth_request *request)
 {
-	struct auth_client_request_new auth_request;
-	buffer_t *buf;
-	size_t size;
+	string_t *str;
 	ssize_t ret;
 
-	memset(&auth_request, 0, sizeof(auth_request));
-	auth_request.type = AUTH_CLIENT_REQUEST_NEW;
-	auth_request.id = request->id;
-	auth_request.flags = request->flags;
-
-	if (request->local_ip.family == request->remote_ip.family)
-		auth_request.ip_family = request->local_ip.family;
-
 	t_push();
-	buf = buffer_create_dynamic(pool_datastack_create(), 256);
-	buffer_set_used_size(buf, sizeof(auth_request));
-
-	if (auth_request.ip_family != 0) {
-		size = IPADDR_IS_V4(&request->local_ip) ? 4 :
-			sizeof(request->local_ip.ip);
-		buffer_append(buf, &request->local_ip.ip, size);
-		buffer_append(buf, &request->remote_ip.ip, size);
-	}
-
-	auth_request.mech_idx =
-		buffer_get_used_size(buf) - sizeof(auth_request);
-	buffer_append(buf, request->mech, strlen(request->mech)+1);
-
-	auth_request.protocol_idx =
-		buffer_get_used_size(buf) - sizeof(auth_request);
-	buffer_append(buf, request->protocol, strlen(request->protocol)+1);
-
-	auth_request.initial_resp_idx =
-		buffer_get_used_size(buf) - sizeof(auth_request);
-	buffer_append(buf, request->initial_resp_data,
-		      request->initial_resp_size);
+	str = t_str_new(512);
 
-	auth_request.data_size =
-		buffer_get_used_size(buf) - sizeof(auth_request);
+	str_printfa(str, "AUTH\t%u\t%s\tproto=%s",
+		    request->id, request->mech, request->protocol);
+	if ((request->flags & AUTH_REQUEST_FLAG_SECURED) != 0)
+		str_append(str, "\tsecured");
+	if ((request->flags & AUTH_REQUEST_FLAG_VALID_CLIENT_CERT) != 0)
+		str_append(str, "\tvalid-client-cert");
 
-	memcpy(buffer_get_space_unsafe(buf, 0, sizeof(auth_request)),
-	       &auth_request, sizeof(auth_request));
+	if (request->local_ip.family != 0)
+		str_printfa(str, "\tlip=%s", net_ip2addr(&request->local_ip));
+	if (request->remote_ip.family != 0)
+		str_printfa(str, "\trip=%s", net_ip2addr(&request->remote_ip));
+	if (request->initial_resp_base64 != NULL)
+		str_printfa(str, "\tresp=%s", request->initial_resp_base64);
+	str_append_c(str, '\n');
 
-	ret = o_stream_send(conn->output, buffer_get_data(buf, NULL),
-			    buffer_get_used_size(buf));
+	ret = o_stream_send(conn->output, str_data(str), str_len(str));
 	t_pop();
 
 	if (ret < 0) {
@@ -126,63 +101,123 @@
 		return FALSE;
 	}
 
-	auth_server_request_check_retry(request, request->initial_resp_data,
-					request->initial_resp_size);
+	auth_server_request_check_retry(request, request->initial_resp_base64);
 	return TRUE;
 }
 
 static void auth_server_send_continue(struct auth_server_connection *conn,
 				      struct auth_request *request,
-				      const unsigned char *data, size_t size)
+				      const char *data_base64)
 {
-	struct auth_client_request_continue auth_request;
-        struct const_iovec iov[2];
+	struct const_iovec iov[3];
+	const char *prefix;
 
-	/* send continued request to auth */
-	auth_request.type = AUTH_CLIENT_REQUEST_CONTINUE;
-	auth_request.id = request->id;
-	auth_request.data_size = size;
+	prefix = t_strdup_printf("CONT\t%u\t", request->id);
 
-	iov[0].iov_base = &auth_request;
-	iov[0].iov_len = sizeof(auth_request);
-	iov[1].iov_base = data;
-	iov[1].iov_len = size;
+	iov[0].iov_base = prefix;
+	iov[0].iov_len = strlen(prefix);
+	iov[1].iov_base = data_base64;
+	iov[1].iov_len = strlen(data_base64);
+	iov[2].iov_base = "\n";
+	iov[2].iov_len = 1;
 
-	if (o_stream_sendv(conn->output, iov, 2) < 0) {
+	if (o_stream_sendv(conn->output, iov, 3) < 0) {
 		errno = conn->output->stream_errno;
 		i_warning("Error sending continue request to auth server: %m");
 		auth_server_connection_destroy(conn, TRUE);
 	}
 }
 
-void auth_server_request_handle_reply(struct auth_server_connection *conn,
-				      struct auth_client_request_reply *reply,
-				      const unsigned char *data)
+int auth_client_input_ok(struct auth_server_connection *conn, const char *args)
 {
+	const char *const *list, *const *args_list, *data_base64;
 	struct auth_request *request;
-        struct auth_server_connection *next;
+	unsigned int id;
 
-	request = hash_lookup(conn->requests, POINTER_CAST(reply->id));
+	list = t_strsplit(args, "\t");
+	if (list[0] == NULL) {
+		i_error("BUG: Authentication server sent broken OK line");
+		return FALSE;
+	}
+
+	id = (unsigned int)strtoul(list[0], NULL, 10);
+
+	request = hash_lookup(conn->requests, POINTER_CAST(id));
 	if (request == NULL) {
 		/* We've already destroyed the request */
-		return;
+		return TRUE;
 	}
 
-	switch (reply->result) {
-	case AUTH_CLIENT_RESULT_SUCCESS:
-		hash_remove(request->conn->requests, POINTER_CAST(request->id));
-		if (request->next_conn != NULL) {
-			hash_remove(request->next_conn->requests,
-				    POINTER_CAST(request->id));
-		}
-		request->conn = conn;
-		request->next_conn = NULL;
-		break;
-	case AUTH_CLIENT_RESULT_FAILURE:
-		hash_remove(conn->requests, POINTER_CAST(request->id));
-		if (!request->retrying)
+	hash_remove(request->conn->requests, POINTER_CAST(id));
+	if (request->next_conn != NULL)
+		hash_remove(request->next_conn->requests, POINTER_CAST(id));
+	request->conn = conn;
+	request->next_conn = NULL;
+
+	data_base64 = NULL;
+	for (args_list = ++list; *list != NULL; list++) {
+		if (strncmp(*list, "resp=", 5) == 0) {
+			data_base64 = *list + 5;
 			break;
+		}
+	}
+
+	request->callback(request, 1, data_base64, args_list, request->context);
+	auth_client_request_free(request);
+	return TRUE;
+}
+
+int auth_client_input_cont(struct auth_server_connection *conn,
+			   const char *args)
+{
+	struct auth_request *request;
+	const char *data;
+	unsigned int id;
+
+	data = strchr(args, '\t');
+	if (data++ == NULL) {
+		i_error("BUG: Authentication server sent broken CONT line");
+		return FALSE;
+	}
+
+	id = (unsigned int)strtoul(args, NULL, 10);
+
+	request = hash_lookup(conn->requests, POINTER_CAST(id));
+	if (request == NULL) {
+		/* We've already destroyed the request */
+		return TRUE;
+	}
+
+	if (request->retrying) {
+		auth_server_send_continue(conn, request,
+					  request->plaintext_data);
+	}
+	request->callback(request, 0, data, NULL, request->context);
+	return TRUE;
+}
+
+int auth_client_input_fail(struct auth_server_connection *conn,
+			   const char *args)
+{
+	struct auth_request *request;
+        struct auth_server_connection *next;
+	const char *error;
+	unsigned int id;
 
+	error = strchr(args, '\t');
+	if (error != NULL)
+		error++;
+
+	id = (unsigned int)strtoul(args, NULL, 10);
+
+	request = hash_lookup(conn->requests, POINTER_CAST(id));
+	if (request == NULL) {
+		/* We've already destroyed the request */
+		return TRUE;
+	}
+
+	hash_remove(conn->requests, POINTER_CAST(request->id));
+	if (request->retrying) {
 		next = request->next_conn == NULL ? NULL :
 			get_next_plain_server(request->next_conn);
 
@@ -193,33 +228,22 @@
 		if (next == NULL) {
 			if (request->conn != NULL) {
 				/* the other one hasn't replied yet */
-				return;
+				return TRUE;
 			}
 			request->conn = conn;
-			break;
-		}
-
-		hash_insert(next->requests, POINTER_CAST(request->id), request);
-		request->next_conn = next;
-
-		auth_server_send_new_request(next, request);
-		return;
-	case AUTH_CLIENT_RESULT_CONTINUE:
-		if (!request->retrying)
-			break;
+		} else {
+			hash_insert(next->requests, POINTER_CAST(request->id),
+				    request);
+			request->next_conn = next;
 
-		auth_server_send_continue(conn, request,
-					  request->plaintext_data,
-					  request->plaintext_data_size);
-		return;
+			auth_server_send_new_request(next, request);
+			return TRUE;
+		}
 	}
 
-	request->callback(request, reply, data, request->context);
-
-	if (reply->result != AUTH_CLIENT_RESULT_CONTINUE) {
-		i_free(request->plaintext_data);
-		i_free(request);
-	}
+	request->callback(request, -1, error, NULL, request->context);
+	auth_client_request_free(request);
+	return TRUE;
 }
 
 static void request_hash_remove(struct auth_server_connection *conn,
@@ -227,7 +251,7 @@
 {
 	if (request->conn == conn) {
 		if (request->next_conn == NULL) {
-			request->callback(request, NULL, NULL,
+			request->callback(request, -1, NULL, NULL,
 					  request->context);
 			request->conn = NULL;
 		} else {
@@ -285,13 +309,9 @@
 	request->remote_ip = request_info->remote_ip;
 	request->id = ++client->request_id_counter;
 
-	if (request_info->initial_resp_size != 0) {
-		request->initial_resp_size = request_info->initial_resp_size;
-		request->initial_resp_data =
-			i_malloc(request_info->initial_resp_size);
-		memcpy(request->initial_resp_data,
-		       request_info->initial_resp_data,
-		       request_info->initial_resp_size);
+	if (request_info->initial_resp_base64 != NULL) {
+		request->initial_resp_base64 =
+			i_strdup(request_info->initial_resp_base64);
 	}
 	
 	if (request->id == 0) {
@@ -309,11 +329,19 @@
 }
 
 void auth_client_request_continue(struct auth_request *request,
-				  const unsigned char *data, size_t data_size)
+                                  const char *data_base64)
 {
-	auth_server_send_continue(request->conn, request, data, data_size);
+	auth_server_send_continue(request->conn, request, data_base64);
+	auth_server_request_check_retry(request, data_base64);
+}
 
-	auth_server_request_check_retry(request, data, data_size);
+static void auth_client_request_free(struct auth_request *request)
+{
+	i_free(request->initial_resp_base64);
+	i_free(request->plaintext_data);
+	i_free(request->mech);
+	i_free(request->protocol);
+	i_free(request);
 }
 
 void auth_client_request_abort(struct auth_request *request)
@@ -324,13 +352,8 @@
 	if (request->next_conn != NULL)
 		hash_remove(request->next_conn->requests, id);
 
-	request->callback(request, NULL, NULL, request->context);
-
-	i_free(request->initial_resp_data);
-	i_free(request->plaintext_data);
-	i_free(request->mech);
-	i_free(request->protocol);
-	i_free(request);
+	request->callback(request, -1, NULL, NULL, request->context);
+	auth_client_request_free(request);
 }
 
 unsigned int auth_client_request_get_id(struct auth_request *request)

Index: auth-server-request.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-auth/auth-server-request.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- auth-server-request.h	22 Aug 2003 02:42:13 -0000	1.1
+++ auth-server-request.h	13 Oct 2004 16:38:34 -0000	1.2
@@ -1,9 +1,11 @@
 #ifndef __AUTH_SERVER_REQUEST_H
 #define __AUTH_SERVER_REQUEST_H
 
-void auth_server_request_handle_reply(struct auth_server_connection *conn,
-				      struct auth_client_request_reply *reply,
-				      const unsigned char *data);
+int auth_client_input_ok(struct auth_server_connection *conn, const char *args);
+int auth_client_input_cont(struct auth_server_connection *conn,
+			   const char *args);
+int auth_client_input_fail(struct auth_server_connection *conn,
+			   const char *args);
 
 void auth_server_requests_remove_all(struct auth_server_connection *conn);
 



More information about the dovecot-cvs mailing list