changeset 2776:150f8151c971 HEAD

Added VERSION command and checking to authentication protocol.
author Timo Sirainen <tss@iki.fi>
date Tue, 19 Oct 2004 03:51:21 +0300
parents e6e73d1db27c
children dc309a440bbe
files src/auth/Makefile.am src/auth/auth-client-connection.c src/auth/auth-client-connection.h src/auth/auth-client-interface.h src/auth/auth-master-connection.c src/auth/auth-master-connection.h src/auth/auth-master-interface.h src/lib-auth/auth-server-connection.c src/lib-auth/auth-server-connection.h src/master/auth-process.c
diffstat 10 files changed, 105 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/src/auth/Makefile.am	Tue Oct 19 03:42:07 2004 +0300
+++ b/src/auth/Makefile.am	Tue Oct 19 03:51:21 2004 +0300
@@ -69,6 +69,7 @@
 noinst_HEADERS = \
 	auth-client-connection.h \
 	auth-client-interface.h \
+	auth-master-interface.h \
 	auth-master-connection.h \
 	auth-module.h \
 	db-ldap.h \
--- a/src/auth/auth-client-connection.c	Tue Oct 19 03:42:07 2004 +0300
+++ b/src/auth/auth-client-connection.c	Tue Oct 19 03:51:21 2004 +0300
@@ -361,6 +361,24 @@
 		return;
 	}
 
+	if (!conn->version_received) {
+		line = i_stream_next_line(conn->input);
+		if (line == NULL)
+			return;
+
+		/* make sure the major version matches */
+		if (strncmp(line, "VERSION\t", 8) != 0 ||
+		    atoi(t_strcut(line + 8, '.')) !=
+		    AUTH_CLIENT_PROTOCOL_MAJOR_VERSION) {
+			i_error("Authentication client %u "
+				"not compatible with this server "
+				"(mixed old and new binaries?)", conn->pid);
+			auth_client_connection_destroy(conn);
+			return;
+		}
+		conn->version_received = TRUE;
+	}
+
 	conn->refcount++;
 	while ((line = i_stream_next_line(conn->input)) != NULL) {
 		t_push();
@@ -419,7 +437,9 @@
 	master->clients = conn;
 
 	str = t_str_new(128);
-	str_printfa(str, "SPID\t%u\nCUID\t%u\nDONE\n",
+	str_printfa(str, "VERSION\t%u.%u\nSPID\t%u\nCUID\t%u\nDONE\n",
+                    AUTH_CLIENT_PROTOCOL_MAJOR_VERSION,
+                    AUTH_CLIENT_PROTOCOL_MINOR_VERSION,
 		    master->pid, conn->connect_uid);
 
 	iov[0].iov_base = str_data(mech_handshake);
--- a/src/auth/auth-client-connection.h	Tue Oct 19 03:42:07 2004 +0300
+++ b/src/auth/auth-client-connection.h	Tue Oct 19 03:51:21 2004 +0300
@@ -18,6 +18,7 @@
 
 	unsigned int pid;
 	unsigned int connect_uid;
+	unsigned int version_received:1;
 };
 
 struct auth_client_connection *
--- a/src/auth/auth-client-interface.h	Tue Oct 19 03:42:07 2004 +0300
+++ b/src/auth/auth-client-interface.h	Tue Oct 19 03:51:21 2004 +0300
@@ -1,6 +1,11 @@
 #ifndef __AUTH_CLIENT_INTERFACE_H
 #define __AUTH_CLIENT_INTERFACE_H
 
+/* Major version changes are not backwards compatible,
+   minor version numbers can be ignored. */
+#define AUTH_CLIENT_PROTOCOL_MAJOR_VERSION 1
+#define AUTH_CLIENT_PROTOCOL_MINOR_VERSION 0
+
 #define AUTH_CLIENT_MAX_LINE_LENGTH 8192
 #define AUTH_REQUEST_TIMEOUT 120
 
--- a/src/auth/auth-master-connection.c	Tue Oct 19 03:42:07 2004 +0300
+++ b/src/auth/auth-master-connection.c	Tue Oct 19 03:51:21 2004 +0300
@@ -10,6 +10,7 @@
 #include "network.h"
 #include "mech.h"
 #include "userdb.h"
+#include "auth-master-interface.h"
 #include "auth-client-connection.h"
 #include "auth-master-connection.h"
 
@@ -168,6 +169,23 @@
 		return;
 	}
 
+	if (!conn->version_received) {
+		line = i_stream_next_line(conn->input);
+		if (line == NULL)
+			return;
+
+		/* make sure the major version matches */
+		if (strncmp(line, "VERSION\t", 8) != 0 ||
+		    atoi(t_strcut(line + 8, '.')) !=
+		    AUTH_MASTER_PROTOCOL_MAJOR_VERSION) {
+			i_error("Master not compatible with this server "
+				"(mixed old and new binaries?)");
+			auth_master_connection_close(conn);
+			return;
+		}
+		conn->version_received = TRUE;
+	}
+
 	while ((line = i_stream_next_line(conn->input)) != NULL) {
 		t_push();
 		if (strncmp(line, "REQUEST\t", 8) == 0)
@@ -241,10 +259,11 @@
 
 void auth_master_connection_send_handshake(struct auth_master_connection *conn)
 {
-	/* just a note to master that we're ok. if we die before, it means
-	   we're broken and a simple restart most likely won't help. */
-	if (conn->output != NULL)
-		master_send(conn, "SPID\t%u", conn->pid);
+	if (conn->output != NULL) {
+		master_send(conn, "VERSION\t%u.%u\n",
+			    AUTH_MASTER_PROTOCOL_MAJOR_VERSION,
+                            AUTH_MASTER_PROTOCOL_MINOR_VERSION);
+	}
 }
 
 static void auth_master_connection_close(struct auth_master_connection *conn)
--- a/src/auth/auth-master-connection.h	Tue Oct 19 03:42:07 2004 +0300
+++ b/src/auth/auth-master-connection.h	Tue Oct 19 03:51:21 2004 +0300
@@ -14,6 +14,7 @@
 	struct auth_client_connection *clients;
 	struct timeout *to_clients;
 
+	unsigned int version_received:1;
 	unsigned int destroyed:1;
 };
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/auth/auth-master-interface.h	Tue Oct 19 03:51:21 2004 +0300
@@ -0,0 +1,9 @@
+#ifndef __AUTH_MASTER_INTERFACE_H
+#define __AUTH_MASTER_INTERFACE_H
+
+/* Major version changes are not backwards compatible,
+   minor version numbers can be ignored. */
+#define AUTH_MASTER_PROTOCOL_MAJOR_VERSION 1
+#define AUTH_MASTER_PROTOCOL_MINOR_VERSION 0
+
+#endif
--- a/src/lib-auth/auth-server-connection.c	Tue Oct 19 03:42:07 2004 +0300
+++ b/src/lib-auth/auth-server-connection.c	Tue Oct 19 03:51:21 2004 +0300
@@ -140,6 +140,23 @@
 		return;
 	}
 
+	if (conn->version_received) {
+		line = i_stream_next_line(conn->input);
+		if (line == NULL)
+			return;
+
+		/* make sure the major version matches */
+		if (strncmp(line, "VERSION\t", 8) != 0 ||
+		    atoi(t_strcut(line + 8, '.')) !=
+		    AUTH_CLIENT_PROTOCOL_MAJOR_VERSION) {
+			i_error("Authentication server not compatible with "
+				"this client (mixed old and new binaries?)");
+			auth_server_connection_destroy(conn, FALSE);
+			return;
+		}
+		conn->version_received = TRUE;
+	}
+
 	conn->refcount++;
 	while ((line = i_stream_next_line(conn->input)) != NULL) {
 		if (strncmp(line, "OK\t", 3) == 0)
@@ -173,6 +190,7 @@
 auth_server_connection_new(struct auth_client *client, const char *path)
 {
 	struct auth_server_connection *conn;
+	const char *handshake;
 	pool_t pool;
 	int fd;
 
@@ -209,9 +227,13 @@
 	conn->next = client->connections;
 	client->connections = conn;
 
+	handshake = t_strdup_printf("VERSION\t%u.%u\nCPID\t%u\n",
+				    AUTH_CLIENT_PROTOCOL_MAJOR_VERSION,
+                                    AUTH_CLIENT_PROTOCOL_MINOR_VERSION,
+				    client->pid);
+
         client->conn_waiting_handshake_count++;
-	if (o_stream_send_str(conn->output,
-			      t_strdup_printf("CPID\t%u\n", client->pid)) < 0) {
+	if (o_stream_send_str(conn->output, handshake) < 0) {
 		errno = conn->output->stream_errno;
 		i_warning("Error sending handshake to auth server: %m");
 		auth_server_connection_destroy(conn, TRUE);
--- a/src/lib-auth/auth-server-connection.h	Tue Oct 19 03:42:07 2004 +0300
+++ b/src/lib-auth/auth-server-connection.h	Tue Oct 19 03:51:21 2004 +0300
@@ -46,6 +46,7 @@
 
         struct hash_table *requests;
 
+	unsigned int version_received:1;
 	unsigned int handshake_received:1;
 	unsigned int has_plain_mech:1;
 };
--- a/src/master/auth-process.c	Tue Oct 19 03:42:07 2004 +0300
+++ b/src/master/auth-process.c	Tue Oct 19 03:51:21 2004 +0300
@@ -11,6 +11,7 @@
 #include "restrict-access.h"
 #include "restrict-process-size.h"
 #include "auth-process.h"
+#include "../auth/auth-master-interface.h"
 #include "log.h"
 
 #include <stdlib.h>
@@ -135,27 +136,6 @@
 }
 
 static int
-auth_process_input_spid(struct auth_process *process, const char *args)
-{
-	unsigned int pid;
-
-	if (process->initialized) {
-		i_error("BUG: Authentication server re-handshaking");
-		return FALSE;
-	}
-
-	pid = (unsigned int)strtoul(args, NULL, 10);
-	if (pid == 0) {
-		i_error("BUG: Authentication server said it's PID 0");
-		return FALSE;
-	}
-
-	process->pid = pid;
-	process->initialized = TRUE;
-	return TRUE;
-}
-
-static int
 auth_process_input_fail(struct auth_process *process, const char *args)
 {
 	void *context;
@@ -202,6 +182,24 @@
 		return;
 	}
 
+	if (!process->initialized) {
+		line = i_stream_next_line(process->input);
+		if (line == NULL)
+			return;
+
+		/* make sure the major version matches */
+		if (strncmp(line, "VERSION\t", 8) != 0 ||
+		    atoi(t_strcut(line + 8, '.')) !=
+		    AUTH_MASTER_PROTOCOL_MAJOR_VERSION) {
+			i_error("Auth process %s not compatible with master "
+				"process (mixed old and new binaries?)",
+				dec2str(process->pid));
+			auth_process_destroy(process);
+			return;
+		}
+		process->initialized = TRUE;
+	}
+
 	while ((line = i_stream_next_line(process->input)) != NULL) {
 		t_push();
 		if (strncmp(line, "USER\t", 5) == 0)
@@ -210,8 +208,6 @@
 			ret = auth_process_input_notfound(process, line + 9);
 		else if (strncmp(line, "FAIL\t", 5) == 0)
 			ret = auth_process_input_fail(process, line + 5);
-		else if (strncmp(line, "SPID\t", 5) == 0)
-			ret = auth_process_input_spid(process, line + 5);
 		else
 			ret = TRUE;
 		t_pop();