diff options
author | 2018-08-07 09:08:21 -0400 | |
---|---|---|
committer | 2018-08-07 09:08:21 -0400 | |
commit | 2155203b3e01354c93d7cb68751f520704fcea1e (patch) | |
tree | 4017f17c91faf9c8dd8b2fc6a529601f4e95c4d1 | |
parent | xdg support: split xdg whitelist code in a different module (diff) | |
download | firejail-2155203b3e01354c93d7cb68751f520704fcea1e.tar.gz firejail-2155203b3e01354c93d7cb68751f520704fcea1e.tar.zst firejail-2155203b3e01354c93d7cb68751f520704fcea1e.zip |
xdg macro testing
-rw-r--r-- | src/firejail/fs_whitelist.c | 1 | ||||
-rw-r--r-- | src/firejail/macros.c | 123 | ||||
-rwxr-xr-x | test/fs/fs.sh | 3 | ||||
-rw-r--r-- | test/fs/macro-blacklist.profile | 6 | ||||
-rw-r--r-- | test/fs/macro-readonly.profile | 6 | ||||
-rw-r--r-- | test/fs/macro-whitelist.profile | 6 | ||||
-rwxr-xr-x | test/fs/macro.exp | 174 |
7 files changed, 209 insertions, 110 deletions
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c index a2803ccbc..bfcf9c209 100644 --- a/src/firejail/fs_whitelist.c +++ b/src/firejail/fs_whitelist.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #define EMPTY_STRING ("") | 35 | #define EMPTY_STRING ("") |
36 | #define MAXBUF 4098 | 36 | #define MAXBUF 4098 |
37 | 37 | ||
38 | // returns mallocated memory | ||
38 | char *parse_nowhitelist(int nowhitelist_flag, char *ptr1) { | 39 | char *parse_nowhitelist(int nowhitelist_flag, char *ptr1) { |
39 | char *rv; | 40 | char *rv; |
40 | if (nowhitelist_flag) { | 41 | if (nowhitelist_flag) { |
diff --git a/src/firejail/macros.c b/src/firejail/macros.c index f111802d7..ef8e0cd79 100644 --- a/src/firejail/macros.c +++ b/src/firejail/macros.c | |||
@@ -69,7 +69,7 @@ Macro macro[] = { | |||
69 | }; | 69 | }; |
70 | 70 | ||
71 | // return -1 if not found | 71 | // return -1 if not found |
72 | int macro_id(const char *name) { | 72 | static int macro_id(const char *name) { |
73 | int i = 0; | 73 | int i = 0; |
74 | while (macro[i].name != NULL) { | 74 | while (macro[i].name != NULL) { |
75 | if (strcmp(name, macro[i].name) == 0) | 75 | if (strcmp(name, macro[i].name) == 0) |
@@ -90,6 +90,7 @@ int is_macro(const char *name) { | |||
90 | return 0; | 90 | return 0; |
91 | } | 91 | } |
92 | 92 | ||
93 | // returns mallocated memory | ||
93 | static char *resolve_xdg(const char *var) { | 94 | static char *resolve_xdg(const char *var) { |
94 | char *fname; | 95 | char *fname; |
95 | struct stat s; | 96 | struct stat s; |
@@ -145,6 +146,7 @@ static char *resolve_xdg(const char *var) { | |||
145 | return NULL; | 146 | return NULL; |
146 | } | 147 | } |
147 | 148 | ||
149 | // returns mallocated memory | ||
148 | static char *resolve_hardcoded(char *entries[]) { | 150 | static char *resolve_hardcoded(char *entries[]) { |
149 | char *fname; | 151 | char *fname; |
150 | struct stat s; | 152 | struct stat s; |
@@ -156,7 +158,10 @@ static char *resolve_hardcoded(char *entries[]) { | |||
156 | 158 | ||
157 | if (stat(fname, &s) == 0) { | 159 | if (stat(fname, &s) == 0) { |
158 | free(fname); | 160 | free(fname); |
159 | return entries[i]; | 161 | char *rv = strdup(entries[i]); |
162 | if (!rv) | ||
163 | errExit("strdup"); | ||
164 | return rv; | ||
160 | } | 165 | } |
161 | free(fname); | 166 | free(fname); |
162 | i++; | 167 | i++; |
@@ -165,6 +170,7 @@ static char *resolve_hardcoded(char *entries[]) { | |||
165 | return NULL; | 170 | return NULL; |
166 | } | 171 | } |
167 | 172 | ||
173 | // returns mallocated memory | ||
168 | char *resolve_macro(const char *name) { | 174 | char *resolve_macro(const char *name) { |
169 | char *rv = NULL; | 175 | char *rv = NULL; |
170 | int id = macro_id(name); | 176 | int id = macro_id(name); |
@@ -223,121 +229,18 @@ char *expand_home(const char *path, const char *homedir) { | |||
223 | EUID_ROOT(); | 229 | EUID_ROOT(); |
224 | return new_name; | 230 | return new_name; |
225 | } | 231 | } |
226 | #if 0 | 232 | else { |
227 | else if (strncmp(path, "${DOWNLOADS}", 12) == 0) { | 233 | char *directory = resolve_macro(path); |
228 | char *tmp = resolve_xdg("XDG_DOWNLOAD_DIR=\"$HOME/", 24, "Downloads"); | 234 | if (directory) { |
229 | char *tmp2 = resolve_hardcoded(dentry, "Downloads"); | 235 | if (asprintf(&new_name, "%s/%s", cfg.homedir, directory) == -1) |
230 | if(tmp) { | ||
231 | if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 12) == -1) | ||
232 | errExit("asprintf"); | ||
233 | if(called_as_root) | ||
234 | EUID_ROOT(); | ||
235 | return new_name; | ||
236 | } | ||
237 | else if(tmp2) { | ||
238 | if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 12) == -1) | ||
239 | errExit("asprintf"); | ||
240 | if(called_as_root) | ||
241 | EUID_ROOT(); | ||
242 | return new_name; | ||
243 | } | ||
244 | } | ||
245 | |||
246 | else if (strncmp(path, "${MUSIC}", 8) == 0) { | ||
247 | char *tmp = resolve_xdg("XDG_MUSIC_DIR=\"$HOME/", 21, "Music"); | ||
248 | char *tmp2 = resolve_hardcoded(mentry, "Music"); | ||
249 | if(tmp) { | ||
250 | if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 8) == -1) | ||
251 | errExit("asprintf"); | ||
252 | if(called_as_root) | ||
253 | EUID_ROOT(); | ||
254 | return new_name; | ||
255 | } | ||
256 | else if(tmp2) { | ||
257 | if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 8) == -1) | ||
258 | errExit("asprintf"); | ||
259 | if(called_as_root) | ||
260 | EUID_ROOT(); | ||
261 | return new_name; | ||
262 | } | ||
263 | } | ||
264 | |||
265 | else if (strncmp(path, "${VIDEOS}", 9) == 0) { | ||
266 | char *tmp = resolve_xdg("XDG_VIDEOS_DIR=\"$HOME/", 22, "Videos"); | ||
267 | char *tmp2 = resolve_hardcoded(ventry, "Videos"); | ||
268 | if(tmp) { | ||
269 | if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 9) == -1) | ||
270 | errExit("asprintf"); | ||
271 | if(called_as_root) | ||
272 | EUID_ROOT(); | ||
273 | return new_name; | ||
274 | } | ||
275 | else if(tmp2) { | ||
276 | if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 9) == -1) | ||
277 | errExit("asprintf"); | ||
278 | if(called_as_root) | ||
279 | EUID_ROOT(); | ||
280 | return new_name; | ||
281 | } | ||
282 | } | ||
283 | |||
284 | else if (strncmp(path, "${PICTURES}", 11) == 0) { | ||
285 | char *tmp = resolve_xdg("XDG_PICTURES_DIR=\"$HOME/", 24, "Pictures"); | ||
286 | char *tmp2 = resolve_hardcoded(pentry, "Pictures"); | ||
287 | if(tmp) { | ||
288 | if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 11) == -1) | ||
289 | errExit("asprintf"); | ||
290 | if(called_as_root) | ||
291 | EUID_ROOT(); | ||
292 | return new_name; | ||
293 | } | ||
294 | else if(tmp2) { | ||
295 | if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 11) == -1) | ||
296 | errExit("asprintf"); | ||
297 | if(called_as_root) | ||
298 | EUID_ROOT(); | ||
299 | return new_name; | ||
300 | } | ||
301 | } | ||
302 | |||
303 | else if (strncmp(path, "${DESKTOP}", 10) == 0) { | ||
304 | char *tmp = resolve_xdg("XDG_DESKTOP_DIR=\"$HOME/", 24, "Desktop"); | ||
305 | char *tmp2 = resolve_hardcoded(deentry, "Desktop"); | ||
306 | if(tmp) { | ||
307 | if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 10) == -1) | ||
308 | errExit("asprintf"); | ||
309 | if(called_as_root) | ||
310 | EUID_ROOT(); | ||
311 | return new_name; | ||
312 | } | ||
313 | else if(tmp2) { | ||
314 | if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 10) == -1) | ||
315 | errExit("asprintf"); | 236 | errExit("asprintf"); |
316 | if(called_as_root) | 237 | if(called_as_root) |
317 | EUID_ROOT(); | 238 | EUID_ROOT(); |
239 | free(directory); | ||
318 | return new_name; | 240 | return new_name; |
319 | } | 241 | } |
320 | } | 242 | } |
321 | 243 | ||
322 | else if (strncmp(path, "${DOCUMENTS}", 12) == 0) { | ||
323 | char *tmp = resolve_xdg("XDG_DOCUMENTS_DIR=\"$HOME/", 25, "Documents"); | ||
324 | char *tmp2 = resolve_hardcoded(doentry, "Documents"); | ||
325 | if(tmp) { | ||
326 | if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 12) == -1) | ||
327 | errExit("asprintf"); | ||
328 | if(called_as_root) | ||
329 | EUID_ROOT(); | ||
330 | return new_name; | ||
331 | } | ||
332 | else if(tmp2) { | ||
333 | if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 12) == -1) | ||
334 | errExit("asprintf"); | ||
335 | if(called_as_root) | ||
336 | EUID_ROOT(); | ||
337 | return new_name; | ||
338 | } | ||
339 | } | ||
340 | #endif | ||
341 | char *rv = strdup(path); | 244 | char *rv = strdup(path); |
342 | if (!rv) | 245 | if (!rv) |
343 | errExit("strdup"); | 246 | errExit("strdup"); |
diff --git a/test/fs/fs.sh b/test/fs/fs.sh index 774c61750..c1b589c29 100755 --- a/test/fs/fs.sh +++ b/test/fs/fs.sh | |||
@@ -58,6 +58,9 @@ echo "TESTING: empty private-etc (test/fs/private-etc-empty.exp)" | |||
58 | echo "TESTING: private-bin (test/fs/private-bin.exp)" | 58 | echo "TESTING: private-bin (test/fs/private-bin.exp)" |
59 | ./private-bin.exp | 59 | ./private-bin.exp |
60 | 60 | ||
61 | echo "TESTING: macros (test/fs/macro..exp)" | ||
62 | ./macro.exp | ||
63 | |||
61 | echo "TESTING: whitelist empty (test/fs/whitelist-empty.exp)" | 64 | echo "TESTING: whitelist empty (test/fs/whitelist-empty.exp)" |
62 | ./whitelist-empty.exp | 65 | ./whitelist-empty.exp |
63 | 66 | ||
diff --git a/test/fs/macro-blacklist.profile b/test/fs/macro-blacklist.profile new file mode 100644 index 000000000..2421d1b7c --- /dev/null +++ b/test/fs/macro-blacklist.profile | |||
@@ -0,0 +1,6 @@ | |||
1 | blacklist ${VIDEOS} | ||
2 | blacklist ${DOCUMENTS} | ||
3 | blacklist ${MUSIC} | ||
4 | blacklist ${DOWNLOADS} | ||
5 | blacklist ${PICTURES} | ||
6 | blacklist ${DESKTOP} | ||
diff --git a/test/fs/macro-readonly.profile b/test/fs/macro-readonly.profile new file mode 100644 index 000000000..2f3d5bd78 --- /dev/null +++ b/test/fs/macro-readonly.profile | |||
@@ -0,0 +1,6 @@ | |||
1 | read-only ${VIDEOS} | ||
2 | read-only ${DOCUMENTS} | ||
3 | read-only ${MUSIC} | ||
4 | read-only ${DOWNLOADS} | ||
5 | read-only ${PICTURES} | ||
6 | read-only ${DESKTOP} | ||
diff --git a/test/fs/macro-whitelist.profile b/test/fs/macro-whitelist.profile new file mode 100644 index 000000000..fed7f76fc --- /dev/null +++ b/test/fs/macro-whitelist.profile | |||
@@ -0,0 +1,6 @@ | |||
1 | whitelist ${VIDEOS} | ||
2 | whitelist ${DOCUMENTS} | ||
3 | whitelist ${MUSIC} | ||
4 | whitelist ${DOWNLOADS} | ||
5 | whitelist ${PICTURES} | ||
6 | whitelist ${DESKTOP} | ||
diff --git a/test/fs/macro.exp b/test/fs/macro.exp new file mode 100755 index 000000000..8080a8108 --- /dev/null +++ b/test/fs/macro.exp | |||
@@ -0,0 +1,174 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | # This file is part of Firejail project | ||
3 | # Copyright (C) 2014-2018 Firejail Authors | ||
4 | # License GPL v2 | ||
5 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | |||
11 | send -- "firejail --profile=macro-whitelist.profile ls ~\r" | ||
12 | expect { | ||
13 | timeout {puts "TESTING ERROR 0\n";exit} | ||
14 | "Child process initialized" | ||
15 | } | ||
16 | expect { | ||
17 | timeout {puts "TESTING ERROR 1\n";exit} | ||
18 | "Desktop" | ||
19 | } | ||
20 | expect { | ||
21 | timeout {puts "TESTING ERROR 2\n";exit} | ||
22 | "Documents" | ||
23 | } | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 3\n";exit} | ||
26 | "Downloads" | ||
27 | } | ||
28 | expect { | ||
29 | timeout {puts "TESTING ERROR 4\n";exit} | ||
30 | "Music" | ||
31 | } | ||
32 | expect { | ||
33 | timeout {puts "TESTING ERROR 5\n";exit} | ||
34 | "Pictures" | ||
35 | } | ||
36 | expect { | ||
37 | timeout {puts "TESTING ERROR 6\n";exit} | ||
38 | "Videos" | ||
39 | } | ||
40 | sleep 1 | ||
41 | |||
42 | send -- "firejail --profile=macro-blacklist.profile ls ~/Desktop\r" | ||
43 | expect { | ||
44 | timeout {puts "TESTING ERROR 7\n";exit} | ||
45 | "Child process initialized" | ||
46 | } | ||
47 | expect { | ||
48 | timeout {puts "TESTING ERROR 8\n";exit} | ||
49 | "Permission denied" | ||
50 | } | ||
51 | sleep 1 | ||
52 | |||
53 | send -- "firejail --profile=macro-blacklist.profile ls ~/Documents\r" | ||
54 | expect { | ||
55 | timeout {puts "TESTING ERROR 9n";exit} | ||
56 | "Child process initialized" | ||
57 | } | ||
58 | expect { | ||
59 | timeout {puts "TESTING ERROR 10\n";exit} | ||
60 | "Permission denied" | ||
61 | } | ||
62 | sleep 1 | ||
63 | |||
64 | send -- "firejail --profile=macro-blacklist.profile ls ~/Downloads\r" | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 11n";exit} | ||
67 | "Child process initialized" | ||
68 | } | ||
69 | expect { | ||
70 | timeout {puts "TESTING ERROR 12n";exit} | ||
71 | "Permission denied" | ||
72 | } | ||
73 | sleep 1 | ||
74 | |||
75 | send -- "firejail --profile=macro-blacklist.profile ls ~/Music\r" | ||
76 | expect { | ||
77 | timeout {puts "TESTING ERROR 13\n";exit} | ||
78 | "Child process initialized" | ||
79 | } | ||
80 | expect { | ||
81 | timeout {puts "TESTING ERROR 14\n";exit} | ||
82 | "Permission denied" | ||
83 | } | ||
84 | sleep 1 | ||
85 | |||
86 | send -- "firejail --profile=macro-blacklist.profile ls ~/Pictures\r" | ||
87 | expect { | ||
88 | timeout {puts "TESTING ERROR 15\n";exit} | ||
89 | "Child process initialized" | ||
90 | } | ||
91 | expect { | ||
92 | timeout {puts "TESTING ERROR 16\n";exit} | ||
93 | "Permission denied" | ||
94 | } | ||
95 | sleep 1 | ||
96 | |||
97 | send -- "firejail --profile=macro-blacklist.profile ls ~/Videos\r" | ||
98 | expect { | ||
99 | timeout {puts "TESTING ERROR 17\n";exit} | ||
100 | "Child process initialized" | ||
101 | } | ||
102 | expect { | ||
103 | timeout {puts "TESTING ERROR 18\n";exit} | ||
104 | "Permission denied" | ||
105 | } | ||
106 | sleep 1 | ||
107 | |||
108 | send -- "firejail --profile=macro-readonly.profile touch ~/Desktop/blablabla\r" | ||
109 | expect { | ||
110 | timeout {puts "TESTING ERROR 19\n";exit} | ||
111 | "Child process initialized" | ||
112 | } | ||
113 | expect { | ||
114 | timeout {puts "TESTING ERROR 20\n";exit} | ||
115 | "Read-only file system" | ||
116 | } | ||
117 | sleep 1 | ||
118 | |||
119 | send -- "firejail --profile=macro-readonly.profile touch ~/Documents/blablabla\r" | ||
120 | expect { | ||
121 | timeout {puts "TESTING ERROR 21\n";exit} | ||
122 | "Child process initialized" | ||
123 | } | ||
124 | expect { | ||
125 | timeout {puts "TESTING ERROR 22\n";exit} | ||
126 | "Read-only file system" | ||
127 | } | ||
128 | sleep 1 | ||
129 | |||
130 | send -- "firejail --profile=macro-readonly.profile touch ~/Downloads/blablabla\r" | ||
131 | expect { | ||
132 | timeout {puts "TESTING ERROR 23\n";exit} | ||
133 | "Child process initialized" | ||
134 | } | ||
135 | expect { | ||
136 | timeout {puts "TESTING ERROR 24\n";exit} | ||
137 | "Read-only file system" | ||
138 | } | ||
139 | sleep 1 | ||
140 | |||
141 | send -- "firejail --profile=macro-readonly.profile touch ~/Music/blablabla\r" | ||
142 | expect { | ||
143 | timeout {puts "TESTING ERROR 25\n";exit} | ||
144 | "Child process initialized" | ||
145 | } | ||
146 | expect { | ||
147 | timeout {puts "TESTING ERROR 26\n";exit} | ||
148 | "Read-only file system" | ||
149 | } | ||
150 | sleep 1 | ||
151 | |||
152 | send -- "firejail --profile=macro-readonly.profile touch ~/Pictures/blablabla\r" | ||
153 | expect { | ||
154 | timeout {puts "TESTING ERROR 27\n";exit} | ||
155 | "Child process initialized" | ||
156 | } | ||
157 | expect { | ||
158 | timeout {puts "TESTING ERROR 28\n";exit} | ||
159 | "Read-only file system" | ||
160 | } | ||
161 | sleep 1 | ||
162 | |||
163 | send -- "firejail --profile=macro-readonly.profile touch ~/Videos/blablabla\r" | ||
164 | expect { | ||
165 | timeout {puts "TESTING ERROR 29\n";exit} | ||
166 | "Child process initialized" | ||
167 | } | ||
168 | expect { | ||
169 | timeout {puts "TESTING ERROR 30\n";exit} | ||
170 | "Read-only file system" | ||
171 | } | ||
172 | sleep 1 | ||
173 | |||
174 | puts "\nall done\n" | ||