]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
script-login: Added version check to the protocol.
authorTimo Sirainen <tss@iki.fi>
Wed, 2 Jun 2010 17:45:02 +0000 (18:45 +0100)
committerTimo Sirainen <tss@iki.fi>
Wed, 2 Jun 2010 17:45:02 +0000 (18:45 +0100)
--HG--
branch : HEAD

src/lib-master/master-login.c
src/util/script-login.c

index bd7fbf8c9835834410cc1210047d8a8cf05728e9..4c135fd6b4d989dc786c135ec15c164cc412f023 100644 (file)
@@ -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');
index 383c023d4be20549a1396c238857b6e526a66d9a..b57eac7fa9be79568a76161702f0eb2f23b927ad 100644 (file)
@@ -16,6 +16,8 @@
 #include <stdlib.h>
 #include <unistd.h>
 
+#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");