From bf27c70b784ed67e324ddfe1ad4f46bf571d3a09 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Wed, 2 Jun 2010 18:45:02 +0100 Subject: [PATCH] script-login: Added version check to the protocol. --HG-- branch : HEAD --- src/lib-master/master-login.c | 3 ++- src/util/script-login.c | 28 +++++++++++++++++++++++++--- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/lib-master/master-login.c b/src/lib-master/master-login.c index bd7fbf8c98..4c135fd6b4 100644 --- a/src/lib-master/master-login.c +++ b/src/lib-master/master-login.c @@ -301,7 +301,8 @@ static int master_login_postlogin(struct master_login_client *client, } str = t_str_new(256); - str_printfa(str, "%s\t%s", net_ip2addr(&client->auth_req.local_ip), + str_printfa(str, "VERSION\tscript-login\t1\t0\n" + "%s\t%s", net_ip2addr(&client->auth_req.local_ip), net_ip2addr(&client->auth_req.remote_ip)); for (i = 0; auth_args[i] != NULL; i++) { str_append_c(str, '\t'); diff --git a/src/util/script-login.c b/src/util/script-login.c index 383c023d4b..b57eac7fa9 100644 --- a/src/util/script-login.c +++ b/src/util/script-login.c @@ -16,6 +16,8 @@ #include #include +#define SCRIPT_LOGIN_PROTOCOL_VERSION_MAJOR 1 +#define SCRIPT_LOGIN_READ_TIMEOUT_SECS 10 #define ENV_USERDB_KEYS "USERDB_KEYS" #define SCRIPT_COMM_FD 3 @@ -27,7 +29,7 @@ static void client_connected(struct master_service_connection *conn) enum mail_storage_service_flags flags = MAIL_STORAGE_SERVICE_FLAG_NO_PLUGINS; string_t *instr, *keys; - const char **args, *key, *value, *error; + const char **args, *key, *value, *error, *version_line, *data_line; struct mail_storage_service_ctx *service_ctx; struct mail_storage_service_input input; struct mail_storage_service_user *user; @@ -36,18 +38,38 @@ static void client_connected(struct master_service_connection *conn) int fd = -1; ssize_t ret; + alarm(SCRIPT_LOGIN_READ_TIMEOUT_SECS); + net_set_nonblock(conn->fd, FALSE); instr = t_str_new(1024); ret = fd_read(conn->fd, buf, sizeof(buf), &fd); while (ret > 0) { str_append_n(instr, buf, ret); - if (buf[ret-1] == '\n') { + if (buf[ret-1] == '\n' && + strchr(str_c(instr), '\n')[1] != '\0') { str_truncate(instr, str_len(instr)-1); break; } ret = read(conn->fd, buf, sizeof(buf)); } + + version_line = str_c(instr); + data_line = strchr(version_line, '\n'); + if (data_line != NULL) + version_line = t_strdup_until(version_line, data_line++); + else + version_line = NULL; + + if (ret > 0 || version_line != NULL) { + if (version_line == NULL || + !version_string_verify(version_line, "script-login", + SCRIPT_LOGIN_PROTOCOL_VERSION_MAJOR)) { + i_fatal("Client not compatible with this binary " + "(connecting to wrong socket?)"); + } + } + if (ret <= 0) { if (ret < 0) i_fatal("read() failed: %m"); @@ -60,7 +82,7 @@ static void client_connected(struct master_service_connection *conn) /* put everything to environment */ env_clean(); keys = t_str_new(256); - args = t_strsplit(str_c(instr), "\t"); + args = t_strsplit(data_line, "\t"); if (str_array_length(args) < 3) i_fatal("Missing input fields"); -- 2.47.3