Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 927b2e27eb4d289c88ad87f4a2fdfa8f > files > 5

dovecot-1.0.7-9.el5_11.4.src.rpm

diff -up dovecot-1.0.7/dovecot-example.conf.CVE-2008-4870 dovecot-1.0.7/dovecot-example.conf
--- dovecot-1.0.7/dovecot-example.conf.CVE-2008-4870	2008-11-24 16:39:56.621995519 +0100
+++ dovecot-1.0.7/dovecot-example.conf	2008-11-24 16:39:56.654866148 +0100
@@ -92,7 +92,9 @@
 #ssl_key_file = /etc/pki/dovecot/private/dovecot.pem
 
 # If key file is password protected, give the password here. Alternatively
-# give it when starting dovecot with -p parameter.
+# give it when starting dovecot with -p parameter. Since this file is often
+# world-readable, you may want to place this setting instead to a different
+# root owned 0600 file by using !include_try <path>.
 #ssl_key_password =
 
 # File containing trusted SSL certificate authorities. Usually not needed.
diff -up dovecot-1.0.7/src/deliver/deliver.c.CVE-2008-4870 dovecot-1.0.7/src/deliver/deliver.c
--- dovecot-1.0.7/src/deliver/deliver.c.CVE-2008-4870	2007-10-29 11:42:16.000000000 +0100
+++ dovecot-1.0.7/src/deliver/deliver.c	2008-11-24 16:39:56.655866473 +0100
@@ -258,6 +258,13 @@ static void config_file_init(const char 
 			len--;
 		line[len] = '\0';
 
+		if (strncmp(line, "!include_try ", 13) == 0)
+			continue;
+		if (strncmp(line, "!include ", 9) == 0) {
+			i_fatal_status(EX_CONFIG, "Error in config file %s: "
+				       "deliver doesn't support !include directive", path);
+		}
+
 		value = p = strchr(line, '=');
 		if (value == NULL) {
 			if (strchr(line, '{') != NULL) {
diff -up dovecot-1.0.7/src/lib-settings/settings.c.CVE-2008-4870 dovecot-1.0.7/src/lib-settings/settings.c
--- dovecot-1.0.7/src/lib-settings/settings.c.CVE-2008-4870	2007-10-28 02:09:23.000000000 +0200
+++ dovecot-1.0.7/src/lib-settings/settings.c	2008-11-24 17:30:40.623959537 +0100
@@ -1,6 +1,7 @@
 /* Copyright (C) 2002 Timo Sirainen */
 
 #include "lib.h"
+#include "str.h"
 #include "istream.h"
 #include "strescape.h"
 #include "settings.h"
@@ -8,7 +9,16 @@
 #include <stdio.h>
 #include <fcntl.h>
 
-#define SECTION_ERRORMSG "%s (section changed at line %d)"
+#define SECTION_ERRORMSG "%s (section changed in %s at line %d)"
+
+struct input_stack {
+	struct input_stack *prev;
+
+	struct istream *input;
+	const char *path;
+	unsigned int linenum;
+};
+
 
 static const char *get_bool(const char *value, bool *result)
 {
@@ -65,11 +75,11 @@ bool settings_read(const char *path, con
 		   settings_callback_t *callback,
 		   settings_section_callback_t *sect_callback, void *context)
 {
-	struct istream *input;
-	const char *errormsg, *next_section;
-	char *line, *key, *name, *p, quote;
+	struct input_stack root, *input, *new_input;
+	const char *errormsg, *next_section, *name, *last_section_path = NULL;
+	char *line, *key, *p, quote;
 	size_t len;
-	int fd, linenum, last_section_line = 0, skip, sections, root_section;
+	int fd, last_section_line = 0, skip, sections, root_section;
 
 	fd = open(path, O_RDONLY);
 	if (fd < 0) {
@@ -87,23 +97,29 @@ bool settings_read(const char *path, con
 		next_section = t_strcut(section, '/');
 	}
 
-	linenum = 0; sections = 0; root_section = 0; errormsg = NULL;
-	input = i_stream_create_file(fd, default_pool, 2048, TRUE);
+	memset(&root, 0, sizeof(root));
+	root.path = path;
+	input = &root;
+
+	sections = 0; root_section = 0; errormsg = NULL;
+newfile:
+	input->input = i_stream_create_file(fd, default_pool, 2048, TRUE);
+prevfile:
 	for (;;) {
-		line = i_stream_read_next_line(input);
+		line = i_stream_read_next_line(input->input);
 		if (line == NULL) {
 			/* EOF. Also handle the last line even if it doesn't
 			   contain LF. */
 			const unsigned char *data;
 			size_t size;
 
-			data = i_stream_get_data(input, &size);
+			data = i_stream_get_data(input->input, &size);
 			if (size == 0)
 				break;
 			line = t_strdup_noconst(t_strndup(data, size));
-			i_stream_skip(input, size);
+			i_stream_skip(input->input, size);
 		}
-		linenum++;
+		input->linenum++;
 
 		/* @UNSAFE: line is modified */
 
@@ -148,7 +164,30 @@ bool settings_read(const char *path, con
 			while (IS_WHITE(*line)) line++;
 		}
 
-		if (*line == '=') {
+		if (strcmp(key, "!include_try") == 0 ||
+		    strcmp(key, "!include") == 0) {
+			struct input_stack *tmp;
+
+			for (tmp = input; tmp != NULL; tmp = tmp->prev) {
+				if (strcmp(tmp->path, line) == 0)
+					break;
+			}
+			if (tmp != NULL) {
+				errormsg = "Recursive include";
+			} else if ((fd = open(line, O_RDONLY)) != -1) {
+				new_input = t_new(struct input_stack, 1);
+				new_input->prev = input;
+				new_input->path = t_strdup(line);
+				input = new_input;
+				goto newfile;
+			} else {
+				/* failed, but ignore failures with include_try. */
+				if (strcmp(key, "!include") == 0) {
+					errormsg = t_strdup_printf(
+						"Couldn't open include file %s: %m", line);
+				}
+			}
+		} else if (*line == '=') {
 			/* a) */
 			*line++ = '\0';
 			while (IS_WHITE(*line)) line++;
@@ -184,7 +223,6 @@ bool settings_read(const char *path, con
 			if (*line != '{')
 				errormsg = "Expecting '='";
 			else {
-				last_section_line = linenum;
 				sections++;
 				if (next_section != NULL &&
 				    strcmp(next_section, name) == 0) {
@@ -212,9 +250,13 @@ bool settings_read(const char *path, con
 					    last_section_line != 0) {
 						errormsg = t_strdup_printf(
 							SECTION_ERRORMSG,
-							errormsg, linenum);
+							errormsg,
+							last_section_path,
+							last_section_line);
 					}
 				}
+				last_section_path = input->path;
+				last_section_line = input->linenum;
 			}
 		} else {
 			/* c) */
@@ -233,19 +275,24 @@ bool settings_read(const char *path, con
 						break;
 					}
 				}
-				last_section_line = linenum;
+				last_section_path = input->path;
+				last_section_line = input->linenum;
 				sections--;
 			}
 		}
 
 		if (errormsg != NULL) {
 			i_error("Error in configuration file %s line %d: %s",
-				path, linenum, errormsg);
+				input->path, input->linenum, errormsg);
 			break;
 		}
 	}
 
-	i_stream_destroy(&input);
+	i_stream_destroy(&input->input);
+	input = input->prev;
+	if (line == NULL && input != NULL)
+		goto prevfile;
+
 	t_pop();
 
 	return errormsg == NULL;