dovecot-2.0: auth worker: Verify that both client and server see...
dovecot at dovecot.org
dovecot at dovecot.org
Tue Mar 16 18:26:28 EET 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/91ae9577aca9
changeset: 10924:91ae9577aca9
user: Timo Sirainen <tss at iki.fi>
date: Tue Mar 16 18:26:25 2010 +0200
description:
auth worker: Verify that both client and server see the same passdb/userdb IDs.
diffstat:
src/auth/auth-worker-client.c | 52 ++++++++++++++++++++++++++
src/auth/auth-worker-client.h | 2 +
src/auth/auth-worker-server.c | 24 +++++++++++-
src/auth/passdb.c | 17 ++++++++
src/auth/passdb.h | 4 ++
src/auth/userdb.c | 17 ++++++++
src/auth/userdb.h | 3 +
7 files changed, 118 insertions(+), 1 deletions(-)
diffs (233 lines):
diff -r bf26a6ec3389 -r 91ae9577aca9 src/auth/auth-worker-client.c
--- a/src/auth/auth-worker-client.c Tue Mar 16 18:08:27 2010 +0200
+++ b/src/auth/auth-worker-client.c Tue Mar 16 18:26:25 2010 +0200
@@ -6,6 +6,7 @@
#include "network.h"
#include "istream.h"
#include "ostream.h"
+#include "hex-binary.h"
#include "str.h"
#include "master-service.h"
#include "auth-request.h"
@@ -23,6 +24,9 @@
struct io *io;
struct istream *input;
struct ostream *output;
+
+ unsigned int version_received:1;
+ unsigned int dbhash_received:1;
};
struct auth_worker_list_context {
@@ -550,6 +554,24 @@
return ret;
}
+static bool auth_worker_verify_db_hash(const char *line)
+{
+ string_t *str;
+ unsigned char passdb_md5[MD5_RESULTLEN];
+ unsigned char userdb_md5[MD5_RESULTLEN];
+
+ passdbs_generate_md5(passdb_md5);
+ userdbs_generate_md5(userdb_md5);
+
+ str = t_str_new(128);
+ str_append(str, "DBHASH\t");
+ binary_to_hex_append(str, passdb_md5, sizeof(passdb_md5));
+ str_append_c(str, '\t');
+ binary_to_hex_append(str, userdb_md5, sizeof(userdb_md5));
+
+ return strcmp(line, str_c(str)) == 0;
+}
+
static void auth_worker_input(struct auth_worker_client *client)
{
char *line;
@@ -570,6 +592,36 @@
return;
}
+ if (!client->version_received) {
+ line = i_stream_next_line(client->input);
+ if (line == NULL)
+ return;
+
+ if (strncmp(line, "VERSION\tauth-worker\t", 20) != 0 ||
+ atoi(t_strcut(line + 20, '\t')) !=
+ AUTH_WORKER_PROTOCOL_MAJOR_VERSION) {
+ i_error("Auth worker not compatible with this server "
+ "(mixed old and new binaries?)");
+ auth_worker_client_destroy(&client);
+ return;
+ }
+ client->version_received = TRUE;
+ }
+ if (!client->dbhash_received) {
+ line = i_stream_next_line(client->input);
+ if (line == NULL)
+ return;
+
+ if (!auth_worker_verify_db_hash(line)) {
+ i_error("Auth worker sees different passdbs/userdbs "
+ "than auth server. Maybe config just changed "
+ "and this goes away automatically?");
+ auth_worker_client_destroy(&client);
+ return;
+ }
+ client->dbhash_received = TRUE;
+ }
+
client->refcount++;
while ((line = i_stream_next_line(client->input)) != NULL) {
T_BEGIN {
diff -r bf26a6ec3389 -r 91ae9577aca9 src/auth/auth-worker-client.h
--- a/src/auth/auth-worker-client.h Tue Mar 16 18:08:27 2010 +0200
+++ b/src/auth/auth-worker-client.h Tue Mar 16 18:26:25 2010 +0200
@@ -1,6 +1,8 @@
#ifndef AUTH_WORKER_CLIENT_H
#define AUTH_WORKER_CLIENT_H
+#define AUTH_WORKER_PROTOCOL_MAJOR_VERSION 1
+#define AUTH_WORKER_PROTOCOL_MINOR_VERSION 0
#define AUTH_WORKER_MAX_LINE_LENGTH 8192
extern struct auth_worker_client *auth_worker_client;
diff -r bf26a6ec3389 -r 91ae9577aca9 src/auth/auth-worker-server.c
--- a/src/auth/auth-worker-server.c Tue Mar 16 18:08:27 2010 +0200
+++ b/src/auth/auth-worker-server.c Tue Mar 16 18:26:25 2010 +0200
@@ -119,6 +119,28 @@
auth_worker_request_send(conn, request);
}
+static void auth_worker_send_handshake(struct auth_worker_connection *conn)
+{
+ string_t *str;
+ unsigned char passdb_md5[MD5_RESULTLEN];
+ unsigned char userdb_md5[MD5_RESULTLEN];
+
+ str = t_str_new(128);
+ str_printfa(str, "VERSION\tauth-worker\t%u\t%u\n",
+ AUTH_WORKER_PROTOCOL_MAJOR_VERSION,
+ AUTH_WORKER_PROTOCOL_MINOR_VERSION);
+
+ passdbs_generate_md5(passdb_md5);
+ userdbs_generate_md5(userdb_md5);
+ str_append(str, "DBHASH\t");
+ binary_to_hex_append(str, passdb_md5, sizeof(passdb_md5));
+ str_append_c(str, '\t');
+ binary_to_hex_append(str, userdb_md5, sizeof(userdb_md5));
+ str_append_c(str, '\n');
+
+ o_stream_send(conn->output, str_data(str), str_len(str));
+}
+
static struct auth_worker_connection *auth_worker_create(void)
{
struct auth_worker_connection *conn;
@@ -141,9 +163,9 @@
conn->io = io_add(fd, IO_READ, worker_input, conn);
conn->to = timeout_add(AUTH_WORKER_MAX_IDLE_SECS * 1000,
auth_worker_idle_timeout, conn);
+ auth_worker_send_handshake(conn);
idle_count++;
-
array_append(&connections, &conn, 1);
return conn;
}
diff -r bf26a6ec3389 -r 91ae9577aca9 src/auth/passdb.c
--- a/src/auth/passdb.c Tue Mar 16 18:08:27 2010 +0200
+++ b/src/auth/passdb.c Tue Mar 16 18:26:25 2010 +0200
@@ -232,6 +232,23 @@
passdb->iface.deinit(passdb);
}
+void passdbs_generate_md5(unsigned char md5[MD5_RESULTLEN])
+{
+ struct md5_context ctx;
+ struct passdb_module *const *passdbs;
+ unsigned int i, count;
+
+ md5_init(&ctx);
+ passdbs = array_get(&passdb_modules, &count);
+ for (i = 0; i < count; i++) {
+ md5_update(&ctx, &passdbs[i]->id, sizeof(passdbs[i]->id));
+ md5_update(&ctx, passdbs[i]->iface.name,
+ strlen(passdbs[i]->iface.name));
+ md5_update(&ctx, passdbs[i]->args, strlen(passdbs[i]->args));
+ }
+ md5_final(&ctx, md5);
+}
+
extern struct passdb_module_interface passdb_passwd;
extern struct passdb_module_interface passdb_bsdauth;
extern struct passdb_module_interface passdb_shadow;
diff -r bf26a6ec3389 -r 91ae9577aca9 src/auth/passdb.h
--- a/src/auth/passdb.h Tue Mar 16 18:08:27 2010 +0200
+++ b/src/auth/passdb.h Tue Mar 16 18:26:25 2010 +0200
@@ -1,6 +1,8 @@
#ifndef PASSDB_H
#define PASSDB_H
+#include "md5.h"
+
#define IS_VALID_PASSWD(pass) \
((pass)[0] != '\0' && (pass)[0] != '*' && (pass)[0] != '!')
@@ -93,6 +95,8 @@
void passdb_register_module(struct passdb_module_interface *iface);
void passdb_unregister_module(struct passdb_module_interface *iface);
+void passdbs_generate_md5(unsigned char md5[MD5_RESULTLEN]);
+
void passdbs_init(void);
void passdbs_deinit(void);
diff -r bf26a6ec3389 -r 91ae9577aca9 src/auth/userdb.c
--- a/src/auth/userdb.c Tue Mar 16 18:08:27 2010 +0200
+++ b/src/auth/userdb.c Tue Mar 16 18:26:25 2010 +0200
@@ -181,6 +181,23 @@
userdb->iface->deinit(userdb);
}
+void userdbs_generate_md5(unsigned char md5[MD5_RESULTLEN])
+{
+ struct md5_context ctx;
+ struct userdb_module *const *userdbs;
+ unsigned int i, count;
+
+ md5_init(&ctx);
+ userdbs = array_get(&userdb_modules, &count);
+ for (i = 0; i < count; i++) {
+ md5_update(&ctx, &userdbs[i]->id, sizeof(userdbs[i]->id));
+ md5_update(&ctx, userdbs[i]->iface->name,
+ strlen(userdbs[i]->iface->name));
+ md5_update(&ctx, userdbs[i]->args, strlen(userdbs[i]->args));
+ }
+ md5_final(&ctx, md5);
+}
+
extern struct userdb_module_interface userdb_prefetch;
extern struct userdb_module_interface userdb_static;
extern struct userdb_module_interface userdb_passwd;
diff -r bf26a6ec3389 -r 91ae9577aca9 src/auth/userdb.h
--- a/src/auth/userdb.h Tue Mar 16 18:08:27 2010 +0200
+++ b/src/auth/userdb.h Tue Mar 16 18:26:25 2010 +0200
@@ -1,6 +1,7 @@
#ifndef USERDB_H
#define USERDB_H
+#include "md5.h"
#include "auth-stream.h"
struct auth;
@@ -71,6 +72,8 @@
void userdb_register_module(struct userdb_module_interface *iface);
void userdb_unregister_module(struct userdb_module_interface *iface);
+void userdbs_generate_md5(unsigned char md5[MD5_RESULTLEN]);
+
void userdbs_init(void);
void userdbs_deinit(void);
More information about the dovecot-cvs
mailing list