Ticket #88: max-perm

File max-perm, 7.9 kB (added by matthijs, 14 months ago)

A patch adding a MAX_PERMISSIONS configuration value

Line 
1Index: vuurmuur/libvuurmuur/src/config.c
2===================================================================
3--- vuurmuur.orig/libvuurmuur/src/config.c      2009-06-01 18:09:32.000000000 +0200
4+++ vuurmuur/libvuurmuur/src/config.c   2009-06-02 22:19:32.000000000 +0200
5@@ -393,7 +393,38 @@
6     }
7     fclose(fp);
8 
9-    /* check if we like the configfile */
10+    /* MAX_PERMISSION
11+     * First (even before calling stat_ok to check the config file),
12+     * load the MAX_PERMISSION value. init_pre_config sets max_permission to
13+     * ANY_PERMISSION, so no permission checks occur before here.
14+     */
15+    result = ask_configfile(askconfig_debuglvl, "MAX_PERMISSION", answer, cnf->configfile, sizeof(answer));
16+    if(result == 1)
17+    {
18+        char *endptr;
19+        /* ok, found, parse it as an octal mode */
20+        cnf->max_permission = strtol(answer, &endptr, 8);
21+
22+        /* If strol fails, it will set endptr to answer. Also check that
23+         * there was no trailing garbage at the end of the string. */
24+        if (endptr == answer || *endptr != '\0')
25+        {
26+            (void)vrprint.warning("Warning", "Invalid MAX_PERMISSION setting: %s. It should be an octal permission number. Using default (%o).", answer, DEFAULT_MAX_PERMISSION);
27+            cnf->max_permission = DEFAULT_MAX_PERMISSION;
28+
29+            retval = VR_CNF_W_ILLEGAL_VAR;
30+        }
31+    }
32+    else if(result == 0)
33+    {
34+        /* ignore missing, use default */
35+        cnf->max_permission = DEFAULT_MAX_PERMISSION;
36+    }
37+    else
38+        return(VR_CNF_E_UNKNOWN_ERR);
39+
40+    /* Now that we know the maximum permission a config file can have,
41+     * check if we like the configfile */
42     if(!(stat_ok(debuglvl, cnf->configfile, STATOK_WANT_FILE, STATOK_VERBOSE, STATOK_MUST_EXIST)))
43         return(VR_CNF_E_FILE_PERMISSION);
44 
45@@ -1703,6 +1734,9 @@
46     fprintf(fp, "# Location of the modprobe-command (full path).\n");
47     fprintf(fp, "MODPROBE=\"%s\"\n\n", conf.modprobe_location);
48 
49+    fprintf(fp, "# Maximum permissions for config and log files and directories.\n");
50+    fprintf(fp, "MAX_PERMISSION=\"%o\"\n\n", conf.max_permission);
51+
52     fprintf(fp, "# Load modules if needed? (yes/no)\n");
53     fprintf(fp, "LOAD_MODULES=\"%s\"\n\n", conf.load_modules ? "Yes" : "No");
54     fprintf(fp, "# Wait after loading a module in 1/10th of a second\n");
55@@ -1970,6 +2004,9 @@
56     /* default to yes */
57     cnf->check_iptcaps = TRUE;
58 
59+    /* Don't do any permissin checks until we loaded MAX_PERMISSION from the config file */
60+    cnf->max_permission = ANY_PERMISSION;
61+
62     return(0);
63 }
64 
65Index: vuurmuur/libvuurmuur/src/io.c
66===================================================================
67--- vuurmuur.orig/libvuurmuur/src/io.c  2009-06-01 18:09:32.000000000 +0200
68+++ vuurmuur/libvuurmuur/src/io.c       2009-06-02 22:19:26.000000000 +0200
69@@ -104,7 +104,7 @@
70 stat_ok(const int debuglvl, const char *file_loc, char type, char output, char must_exist)
71 {
72     struct stat stat_buf;
73-    mode_t      mode = 0600;
74+    mode_t max, perm;
75 
76     /* safety */
77     if(file_loc == NULL)
78@@ -160,15 +160,6 @@
79         return(0);
80     }
81 
82-    /* if a file is writable by someone other than root, we refuse to open it */
83-    if(stat_buf.st_mode & S_IWGRP || stat_buf.st_mode & S_IWOTH)
84-    {
85-        if(output == STATOK_VERBOSE)
86-            (void)vrprint.error(-1, "Error", "opening '%s': For security reasons Vuurmuur will not open files that are writable by 'group' or 'other'. Check the file content & permissions.", file_loc);
87-
88-        return(0);
89-    }
90-
91     /* we demand that all files are owned by root */
92     if(stat_buf.st_uid != 0 || stat_buf.st_gid != 0)
93     {
94@@ -178,43 +169,25 @@
95         return(0);
96     }
97 
98-    int fixperm = 0;
99-    /* some warnings about the permissions being too relax */
100-    if(stat_buf.st_mode & S_IRGRP)
101-    {
102-        (void)vrprint.info("Info", "'%s' is readable by 'group'. This is not recommended. ", file_loc);
103-        fixperm = 1;
104-    }
105-    if(stat_buf.st_mode & S_IROTH)
106-    {
107-        (void)vrprint.info("Info", "'%s' is readable by and 'other'. This is not recommended.", file_loc);
108-        fixperm = 1;
109-    }
110-
111-    if(stat_buf.st_mode & S_IXGRP)
112-    {
113-        (void)vrprint.info("Info", "'%s' is executable by 'group'. This is not recommended.", file_loc);
114-        fixperm = 1;
115-    }
116-    if(stat_buf.st_mode & S_IXOTH)
117+    if (conf.max_permission != ANY_PERMISSION)
118     {
119-        (void)vrprint.info("Info", "'%s' is executable by 'other'. This is not recommended.", file_loc);
120-        fixperm = 1;
121-    }
122-
123-    if (fixperm) {
124-        /* for dirs */
125-        if(S_ISDIR(stat_buf.st_mode))
126-            mode = 0700;
127-        /* for files */
128-        else if(S_ISREG(stat_buf.st_mode))
129-            mode = 0600;
130+        /* Extract the permission bits from the mode */
131+        perm = stat_buf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
132+        /* Maximum permissions. Remove +x for files */
133+        max = conf.max_permission;
134+        if (S_ISREG(stat_buf.st_mode) == 1)
135+            max &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
136 
137-        (void)vrprint.info("Info", "Resetting permissions of '%s' to %o.", file_loc, mode);
138-        if(chmod(file_loc, mode) == -1)
139+        /* See if the file mode has more bits set than the maximum allowed */
140+        if(perm & ~max)
141         {
142-            (void)vrprint.error(-1, "Error", "failed to repair permissions for '%s': %s.", file_loc, strerror(errno));
143-            return(0);
144+            (void)vrprint.info("Info", "'%s' has mode %o, which is more than maximum allowed mode %o. Resetting to %o.", file_loc, perm, max, max);
145+
146+            if(chmod(file_loc, max) == -1)
147+            {
148+                (void)vrprint.error(-1, "Error", "failed to repair permissions for '%s': %s.", file_loc, strerror(errno));
149+                return(0);
150+            }
151         }
152     }
153 
154Index: vuurmuur/libvuurmuur/src/vuurmuur.h
155===================================================================
156--- vuurmuur.orig/libvuurmuur/src/vuurmuur.h    2009-05-22 16:07:48.000000000 +0200
157+++ vuurmuur/libvuurmuur/src/vuurmuur.h 2009-06-02 22:19:26.000000000 +0200
158@@ -145,6 +145,8 @@
159 #define DEFAULT_LOAD_MODULES            TRUE                /* default we load modules */
160 #define DEFAULT_MODULES_WAITTIME        0                   /* default we don't wait */
161 
162+#define DEFAULT_MAX_PERMISSION          0700                /* default only allow user rwx */
163+
164 #define MAX_LOGRULE_SIZE                512
165 #define MAX_PIPE_COMMAND                512                 /* maximum lenght of the pipe command */
166 #define MAX_RULECOMMENT_LEN             64                  /* length in characters (for widec) */
167@@ -152,7 +154,9 @@
168 #define PROC_IPCONNTRACK                "/proc/net/ip_conntrack"
169 #define PROC_NFCONNTRACK                "/proc/net/nf_conntrack"
170 
171-
172+/* Special permission value, meaning don't check permissions. The value
173+ * is simply all ones. */
174+#define ANY_PERMISSION                  (~((mode_t)0))
175 /*
176     regexes
177 */
178@@ -427,6 +431,11 @@
179     /* this is detected at runtime */
180     char            use_nfconntrack;
181 
182+       /* Maximum permissions for files and directories used by vuurmuur
183+          (config & log files). This should include x bits, which are
184+          filtered out for files. */
185+       mode_t          max_permission;
186+
187 } conf;
188 
189 
190Index: vuurmuur/vuurmuur/skel/etc/vuurmuur/config.conf.sample
191===================================================================
192--- vuurmuur.orig/vuurmuur/skel/etc/vuurmuur/config.conf.sample 2009-04-16 16:53:27.000000000 +0200
193+++ vuurmuur/vuurmuur/skel/etc/vuurmuur/config.conf.sample      2009-06-01 18:12:51.000000000 +0200
194@@ -75,4 +75,10 @@
195 # Ignore echo-broadcasts? (yes/no)
196 PROTECT_ECHOBROADCAST="Yes"
197 
198+# Don't allow config and log files and directories to be accessable by
199+# anyone but root. For files, the execute bits are automatically
200+# stripped from this value. This should be an octal number describing
201+# the maximum allowable permissions.
202+MAX_PERMISSION="700"
203+
204 # end of file