diff options
author | 2021-05-06 15:39:36 -0400 | |
---|---|---|
committer | 2021-05-06 15:39:36 -0400 | |
commit | 43e47483ff94753655ade1e633e973725d8fb505 (patch) | |
tree | f4f69043bcb37fd62c6d60da57cad5b6027f46c5 /src/fbuilder | |
parent | some wireshark hardening (#4245) (diff) | |
download | firejail-43e47483ff94753655ade1e633e973725d8fb505.tar.gz firejail-43e47483ff94753655ade1e633e973725d8fb505.tar.zst firejail-43e47483ff94753655ade1e633e973725d8fb505.zip |
more --build
Diffstat (limited to 'src/fbuilder')
-rw-r--r-- | src/fbuilder/build_bin.c | 9 | ||||
-rw-r--r-- | src/fbuilder/build_fs.c | 145 | ||||
-rw-r--r-- | src/fbuilder/build_home.c | 26 | ||||
-rw-r--r-- | src/fbuilder/build_profile.c | 53 | ||||
-rw-r--r-- | src/fbuilder/fbuilder.h | 1 | ||||
-rw-r--r-- | src/fbuilder/filedb.c | 49 |
6 files changed, 130 insertions, 153 deletions
diff --git a/src/fbuilder/build_bin.c b/src/fbuilder/build_bin.c index 431aebee6..9577042c4 100644 --- a/src/fbuilder/build_bin.c +++ b/src/fbuilder/build_bin.c | |||
@@ -83,11 +83,9 @@ static void process_bin(const char *fname) { | |||
83 | continue; | 83 | continue; |
84 | *ptr2 = '\0'; | 84 | *ptr2 = '\0'; |
85 | 85 | ||
86 | // skip strace | 86 | // skip strace and firejail (in case we hit a symlink in /usr/local/bin) |
87 | if (strcmp(ptr, "strace") == 0) | 87 | if (strcmp(ptr, "strace") && strcmp(ptr, "firejail")) |
88 | continue; | 88 | bin_out = filedb_add(bin_out, ptr); |
89 | |||
90 | bin_out = filedb_add(bin_out, ptr); | ||
91 | } | 89 | } |
92 | 90 | ||
93 | fclose(fp); | 91 | fclose(fp); |
@@ -121,6 +119,5 @@ void build_bin(const char *fname, FILE *fp) { | |||
121 | ptr = ptr->next; | 119 | ptr = ptr->next; |
122 | } | 120 | } |
123 | fprintf(fp, "\n"); | 121 | fprintf(fp, "\n"); |
124 | fprintf(fp, "#private-lib\n"); | ||
125 | } | 122 | } |
126 | } | 123 | } |
diff --git a/src/fbuilder/build_fs.c b/src/fbuilder/build_fs.c index b35380b96..8700e0ba1 100644 --- a/src/fbuilder/build_fs.c +++ b/src/fbuilder/build_fs.c | |||
@@ -146,106 +146,57 @@ void build_etc(const char *fname, FILE *fp) { | |||
146 | //******************************************* | 146 | //******************************************* |
147 | // var directory | 147 | // var directory |
148 | //******************************************* | 148 | //******************************************* |
149 | #if 0 | ||
150 | // todo: load the list from whitelist-var-common.inc | ||
151 | static char *var_skip[] = { | ||
152 | "/var/lib/ca-certificates", | ||
153 | "/var/lib/dbus", | ||
154 | "/var/lib/menu-xdg", | ||
155 | "/var/lib/uim", | ||
156 | "/var/cache/fontconfig", | ||
157 | "/var/tmp", | ||
158 | "/var/run", | ||
159 | "/var/lock", | ||
160 | NULL | ||
161 | }; | ||
162 | #endif | ||
149 | static FileDB *var_out = NULL; | 163 | static FileDB *var_out = NULL; |
164 | static FileDB *var_skip = NULL; | ||
150 | static void var_callback(char *ptr) { | 165 | static void var_callback(char *ptr) { |
151 | if (strcmp(ptr, "/var/lib") == 0) | 166 | // extract the directory: |
152 | ; | 167 | assert(strncmp(ptr, "/var", 4) == 0); |
153 | else if (strcmp(ptr, "/var/cache") == 0) | 168 | char *p1 = ptr + 4; |
154 | ; | 169 | if (*p1 != '/') |
155 | else if (strncmp(ptr, "/var/lib/menu-xdg", 17) == 0) | 170 | return; |
156 | var_out = filedb_add(var_out, "/var/lib/menu-xdg"); | 171 | p1++; |
157 | else if (strncmp(ptr, "/var/cache/fontconfig", 21) == 0) | 172 | |
158 | var_out = filedb_add(var_out, "/var/cache/fontconfig"); | 173 | if (*p1 == '/') // double '/' |
159 | else | 174 | p1++; |
160 | var_out = filedb_add(var_out, ptr); | 175 | if (*p1 == '\0') |
176 | return; | ||
177 | |||
178 | if (!filedb_find(var_skip, p1)) | ||
179 | var_out = filedb_add(var_out, p1); | ||
161 | } | 180 | } |
162 | 181 | ||
163 | void build_var(const char *fname, FILE *fp) { | 182 | void build_var(const char *fname, FILE *fp) { |
164 | assert(fname); | 183 | assert(fname); |
165 | 184 | ||
185 | var_skip = filedb_load_whitelist(var_skip, "whitelist-var-common.inc", "whitelist /var/"); | ||
166 | process_files(fname, "/var", var_callback); | 186 | process_files(fname, "/var", var_callback); |
167 | 187 | ||
168 | if (var_out == NULL) { | 188 | // always whitelist /var |
169 | fprintf(fp, "blacklist /var\n"); | 189 | if (var_out) |
170 | } else { | 190 | filedb_print(var_out, "whitelist /var/", fp); |
171 | filedb_print(var_out, "whitelist ", fp); | 191 | fprintf(fp, "include whitelist-var-common.inc\n"); |
172 | fprintf(fp, "include whitelist-var-common.inc\n"); | ||
173 | } | ||
174 | } | 192 | } |
175 | 193 | ||
176 | 194 | ||
177 | //******************************************* | 195 | //******************************************* |
178 | // usr/share directory | 196 | // usr/share directory |
179 | //******************************************* | 197 | //******************************************* |
180 | // todo: load the list from whitelist-usr-share-common.inc | ||
181 | static char *share_skip[] = { | ||
182 | "/usr/share/alsa", | ||
183 | "/usr/share/applications", | ||
184 | "/usr/share/ca-certificates", | ||
185 | "/usr/share/crypto-policies", | ||
186 | "/usr/share/cursors", | ||
187 | "/usr/share/dconf", | ||
188 | "/usr/share/distro-info", | ||
189 | "/usr/share/drirc.d", | ||
190 | "/usr/share/enchant", | ||
191 | "/usr/share/enchant-2", | ||
192 | "/usr/share/file", | ||
193 | "/usr/share/fontconfig", | ||
194 | "/usr/share/fonts", | ||
195 | "/usr/share/fonts-config", | ||
196 | "/usr/share/gir-1.0", | ||
197 | "/usr/share/gjs-1.0", | ||
198 | "/usr/share/glib-2.0", | ||
199 | "/usr/share/glvnd", | ||
200 | "/usr/share/gtk-2.0", | ||
201 | "/usr/share/gtk-3.0", | ||
202 | "/usr/share/gtk-engines", | ||
203 | "/usr/share/gtksourceview-3.0", | ||
204 | "/usr/share/gtksourceview-4", | ||
205 | "/usr/share/hunspell", | ||
206 | "/usr/share/hwdata", | ||
207 | "/usr/share/icons", | ||
208 | "/usr/share/icu", | ||
209 | "/usr/share/knotifications5", | ||
210 | "/usr/share/kservices5", | ||
211 | "/usr/share/Kvantum", | ||
212 | "/usr/share/kxmlgui5", | ||
213 | "/usr/share/libdrm", | ||
214 | "/usr/share/libthai", | ||
215 | "/usr/share/locale", | ||
216 | "/usr/share/mime", | ||
217 | "/usr/share/misc", | ||
218 | "/usr/share/Modules", | ||
219 | "/usr/share/myspell", | ||
220 | "/usr/share/p11-kit", | ||
221 | "/usr/share/perl", | ||
222 | "/usr/share/perl5", | ||
223 | "/usr/share/pixmaps", | ||
224 | "/usr/share/pki", | ||
225 | "/usr/share/plasma", | ||
226 | "/usr/share/publicsuffix", | ||
227 | "/usr/share/qt", | ||
228 | "/usr/share/qt4", | ||
229 | "/usr/share/qt5", | ||
230 | "/usr/share/qt5ct", | ||
231 | "/usr/share/sounds", | ||
232 | "/usr/share/tcl8.6", | ||
233 | "/usr/share/tcltk", | ||
234 | "/usr/share/terminfo", | ||
235 | "/usr/share/texlive", | ||
236 | "/usr/share/texmf", | ||
237 | "/usr/share/themes", | ||
238 | "/usr/share/thumbnail.so", | ||
239 | "/usr/share/uim", | ||
240 | "/usr/share/vulkan", | ||
241 | "/usr/share/X11", | ||
242 | "/usr/share/xml", | ||
243 | "/usr/share/zenity", | ||
244 | "/usr/share/zoneinfo", | ||
245 | NULL | ||
246 | }; | ||
247 | |||
248 | static FileDB *share_out = NULL; | 198 | static FileDB *share_out = NULL; |
199 | static FileDB *share_skip = NULL; | ||
249 | static void share_callback(char *ptr) { | 200 | static void share_callback(char *ptr) { |
250 | // extract the directory: | 201 | // extract the directory: |
251 | assert(strncmp(ptr, "/usr/share", 10) == 0); | 202 | assert(strncmp(ptr, "/usr/share", 10) == 0); |
@@ -263,30 +214,21 @@ static void share_callback(char *ptr) { | |||
263 | if (p2) | 214 | if (p2) |
264 | *p2 = '\0'; | 215 | *p2 = '\0'; |
265 | 216 | ||
266 | int i = 0; | 217 | |
267 | int found = 0; | 218 | if (!filedb_find(share_skip, p1)) |
268 | while (share_skip[i]) { | 219 | share_out = filedb_add(share_out, p1); |
269 | if (strncmp(ptr, share_skip[i], strlen(share_skip[i])) == 0) { | ||
270 | found = 1; | ||
271 | break; | ||
272 | } | ||
273 | i++; | ||
274 | } | ||
275 | if (!found) | ||
276 | share_out = filedb_add(share_out, ptr); | ||
277 | } | 220 | } |
278 | 221 | ||
279 | void build_share(const char *fname, FILE *fp) { | 222 | void build_share(const char *fname, FILE *fp) { |
280 | assert(fname); | 223 | assert(fname); |
281 | 224 | ||
225 | share_skip = filedb_load_whitelist(share_skip, "whitelist-usr-share-common.inc", "whitelist /usr/share/"); | ||
282 | process_files(fname, "/usr/share", share_callback); | 226 | process_files(fname, "/usr/share", share_callback); |
283 | 227 | ||
284 | if (share_out == NULL) { | 228 | // always whitelist /usr/share |
285 | fprintf(fp, "blacklist /usr/share\n"); | 229 | if (share_out) |
286 | } else { | 230 | filedb_print(share_out, "whitelist /usr/share/", fp); |
287 | filedb_print(share_out, "whitelist ", fp); | 231 | fprintf(fp, "include whitelist-usr-share-common.inc\n"); |
288 | fprintf(fp, "include whitelist-usr-share-common.inc\n"); | ||
289 | } | ||
290 | } | 232 | } |
291 | 233 | ||
292 | //******************************************* | 234 | //******************************************* |
@@ -336,6 +278,7 @@ static char *dev_skip[] = { | |||
336 | "/dev/null", | 278 | "/dev/null", |
337 | "/dev/full", | 279 | "/dev/full", |
338 | "/dev/random", | 280 | "/dev/random", |
281 | "/dev/srandom", | ||
339 | "/dev/urandom", | 282 | "/dev/urandom", |
340 | "/dev/sr0", | 283 | "/dev/sr0", |
341 | "/dev/cdrom", | 284 | "/dev/cdrom", |
diff --git a/src/fbuilder/build_home.c b/src/fbuilder/build_home.c index d7706282a..b3ec6cffd 100644 --- a/src/fbuilder/build_home.c +++ b/src/fbuilder/build_home.c | |||
@@ -23,30 +23,6 @@ | |||
23 | static FileDB *db_skip = NULL; | 23 | static FileDB *db_skip = NULL; |
24 | static FileDB *db_out = NULL; | 24 | static FileDB *db_out = NULL; |
25 | 25 | ||
26 | static void load_whitelist_common(void) { | ||
27 | FILE *fp = fopen(SYSCONFDIR "/whitelist-common.inc", "r"); | ||
28 | if (!fp) { | ||
29 | fprintf(stderr, "Error: cannot open whitelist-common.inc\n"); | ||
30 | exit(1); | ||
31 | } | ||
32 | |||
33 | char buf[MAX_BUF]; | ||
34 | while (fgets(buf, MAX_BUF, fp)) { | ||
35 | if (strncmp(buf, "whitelist ${HOME}/", 18) != 0) | ||
36 | continue; | ||
37 | char *fn = buf + 18; | ||
38 | char *ptr = strchr(buf, '\n'); | ||
39 | if (!ptr) | ||
40 | continue; | ||
41 | *ptr = '\0'; | ||
42 | |||
43 | // add the file to skip list | ||
44 | db_skip = filedb_add(db_skip, fn); | ||
45 | } | ||
46 | |||
47 | fclose(fp); | ||
48 | } | ||
49 | |||
50 | void process_home(const char *fname, char *home, int home_len) { | 26 | void process_home(const char *fname, char *home, int home_len) { |
51 | assert(fname); | 27 | assert(fname); |
52 | assert(home); | 28 | assert(home); |
@@ -162,7 +138,7 @@ void build_home(const char *fname, FILE *fp) { | |||
162 | assert(fname); | 138 | assert(fname); |
163 | 139 | ||
164 | // load whitelist common | 140 | // load whitelist common |
165 | load_whitelist_common(); | 141 | db_skip = filedb_load_whitelist(db_skip, "whitelist-common.inc", "whitelist ${HOME}/"); |
166 | 142 | ||
167 | // find user home directory | 143 | // find user home directory |
168 | struct passwd *pw = getpwuid(getuid()); | 144 | struct passwd *pw = getpwuid(getuid()); |
diff --git a/src/fbuilder/build_profile.c b/src/fbuilder/build_profile.c index 100630eb9..fb53f70a6 100644 --- a/src/fbuilder/build_profile.c +++ b/src/fbuilder/build_profile.c | |||
@@ -141,57 +141,70 @@ void build_profile(int argc, char **argv, int index, FILE *fp) { | |||
141 | if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { | 141 | if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { |
142 | if (fp == stdout) | 142 | if (fp == stdout) |
143 | printf("--- Built profile beings after this line ---\n"); | 143 | printf("--- Built profile beings after this line ---\n"); |
144 | fprintf(fp, "# Firejail profile for %s\n", argv[index]); | 144 | fprintf(fp, "# Save this file as \"application.profile\" (change \"application\" with the\n"); |
145 | fprintf(fp, "# program name) in ~/.config/firejail directory. Firejail will find it\n"); | ||
146 | fprintf(fp, "# automatically every time you sandbox your application.\n#\n"); | ||
147 | fprintf(fp, "# Run \"firejail application\" to test it. In the file there are\n"); | ||
148 | fprintf(fp, "# some other commands you can try. Enable them by removing the \"#\".\n"); | ||
149 | |||
150 | fprintf(fp, "\n# Firejail profile for %s\n", argv[index]); | ||
145 | fprintf(fp, "# Persistent local customizations\n"); | 151 | fprintf(fp, "# Persistent local customizations\n"); |
146 | fprintf(fp, "#include %s.local\n", argv[index]); | 152 | fprintf(fp, "#include %s.local\n", argv[index]); |
147 | fprintf(fp, "# Persistent global definitions\n"); | 153 | fprintf(fp, "# Persistent global definitions\n"); |
148 | fprintf(fp, "#include globals.local\n"); | 154 | fprintf(fp, "#include globals.local\n"); |
149 | fprintf(fp, "\n"); | 155 | fprintf(fp, "\n"); |
150 | 156 | ||
151 | fprintf(fp, "### basic blacklisting\n"); | 157 | fprintf(fp, "### Basic Blacklisting ###\n"); |
158 | fprintf(fp, "### Enable as many of them as you can! A very important one is\n"); | ||
159 | fprintf(fp, "### \"disable-exec.inc\". This will make among other things your home\n"); | ||
160 | fprintf(fp, "### and /tmp directories non-executable.\n"); | ||
152 | fprintf(fp, "include disable-common.inc\n"); | 161 | fprintf(fp, "include disable-common.inc\n"); |
153 | fprintf(fp, "#include disable-devel.inc\n"); | 162 | fprintf(fp, "#include disable-devel.inc\n"); |
154 | fprintf(fp, "#include disable-exec.inc\n"); | 163 | fprintf(fp, "#include disable-exec.inc\n"); |
155 | fprintf(fp, "#include disable-interpreters.inc\n"); | 164 | fprintf(fp, "#include disable-interpreters.inc\n"); |
156 | fprintf(fp, "include disable-passwdmgr.inc\n"); | 165 | fprintf(fp, "include disable-passwdmgr.inc\n"); |
157 | fprintf(fp, "#include disable-programs.inc\n"); | 166 | fprintf(fp, "include disable-programs.inc\n"); |
158 | fprintf(fp, "#include disable-xdg.inc\n"); | 167 | fprintf(fp, "#include disable-xdg.inc\n"); |
159 | fprintf(fp, "\n"); | 168 | fprintf(fp, "\n"); |
160 | 169 | ||
161 | fprintf(fp, "### home directory whitelisting\n"); | 170 | fprintf(fp, "### Home Directory Whitelisting ###\n"); |
171 | fprintf(fp, "### If something goes wrong, this section is the first one to comment out.\n"); | ||
172 | fprintf(fp, "### Instead, you'll have to relay on the basic blacklisting above.\n"); | ||
162 | build_home(trace_output, fp); | 173 | build_home(trace_output, fp); |
163 | 174 | ||
164 | fprintf(fp, "\n### /usr/share:\n"); | 175 | fprintf(fp, "\n### The Rest of the Filesystem ###\n"); |
165 | build_share(trace_output, fp); | 176 | build_share(trace_output, fp); |
166 | fprintf(fp, "\n### /var:\n"); | ||
167 | build_var(trace_output, fp); | 177 | build_var(trace_output, fp); |
168 | fprintf(fp, "\n### /bin:\n"); | ||
169 | build_bin(trace_output, fp); | 178 | build_bin(trace_output, fp); |
170 | fprintf(fp, "\n### /dev:\n"); | ||
171 | build_dev(trace_output, fp); | 179 | build_dev(trace_output, fp); |
172 | fprintf(fp, "\n### /etc:\n"); | 180 | fprintf(fp, "#nodvd\n"); |
181 | fprintf(fp, "#noinput\n"); | ||
182 | fprintf(fp, "#notv\n"); | ||
183 | fprintf(fp, "#nou2f\n"); | ||
184 | fprintf(fp, "#novideo\n"); | ||
173 | build_etc(trace_output, fp); | 185 | build_etc(trace_output, fp); |
174 | fprintf(fp, "\n### /tmp:\n"); | ||
175 | build_tmp(trace_output, fp); | 186 | build_tmp(trace_output, fp); |
176 | 187 | ||
177 | fprintf(fp, "\n### security filters\n"); | 188 | fprintf(fp, "\n### Security Filters ###\n"); |
189 | fprintf(fp, "#apparmor\n"); | ||
178 | fprintf(fp, "caps.drop all\n"); | 190 | fprintf(fp, "caps.drop all\n"); |
191 | fprintf(fp, "netfilter\n"); | ||
192 | fprintf(fp, "#nogroups\n"); | ||
193 | fprintf(fp, "#noroot\n"); | ||
179 | fprintf(fp, "nonewprivs\n"); | 194 | fprintf(fp, "nonewprivs\n"); |
195 | build_protocol(trace_output, fp); | ||
196 | |||
180 | fprintf(fp, "seccomp\n"); | 197 | fprintf(fp, "seccomp\n"); |
181 | if (!have_strace) { | 198 | if (!have_strace) { |
182 | fprintf(fp, "# If you install strace on your system, Firejail will also create a\n"); | 199 | fprintf(fp, "### If you install strace on your system, Firejail will also create a\n"); |
183 | fprintf(fp, "# whitelisted seccomp filter.\n"); | 200 | fprintf(fp, "### whitelisted seccomp filter.\n"); |
184 | } | 201 | } |
185 | else if (!have_yama_permission) | 202 | else if (!have_yama_permission) |
186 | fprintf(fp, "# Yama security module prevents creation of a whitelisted seccomp filter\n"); | 203 | fprintf(fp, "### Yama security module prevents creation of a whitelisted seccomp filter\n"); |
187 | else | 204 | else |
188 | build_seccomp(strace_output, fp); | 205 | build_seccomp(strace_output, fp); |
189 | 206 | fprintf(fp, "#shell none\n"); | |
190 | fprintf(fp, "\n### network\n"); | 207 | fprintf(fp, "#tracelog\n"); |
191 | build_protocol(trace_output, fp); | ||
192 | |||
193 | fprintf(fp, "\n### environment\n"); | ||
194 | fprintf(fp, "shell none\n"); | ||
195 | 208 | ||
196 | if (!arg_debug) { | 209 | if (!arg_debug) { |
197 | unlink(trace_output); | 210 | unlink(trace_output); |
diff --git a/src/fbuilder/fbuilder.h b/src/fbuilder/fbuilder.h index 8d3621c02..08dd35e10 100644 --- a/src/fbuilder/fbuilder.h +++ b/src/fbuilder/fbuilder.h | |||
@@ -66,5 +66,6 @@ typedef struct filedb_t { | |||
66 | FileDB *filedb_add(FileDB *head, const char *fname); | 66 | FileDB *filedb_add(FileDB *head, const char *fname); |
67 | FileDB *filedb_find(FileDB *head, const char *fname); | 67 | FileDB *filedb_find(FileDB *head, const char *fname); |
68 | void filedb_print(FileDB *head, const char *prefix, FILE *fp); | 68 | void filedb_print(FileDB *head, const char *prefix, FILE *fp); |
69 | FileDB *filedb_load_whitelist(FileDB *head, const char *fname, const char *prefix); | ||
69 | 70 | ||
70 | #endif | 71 | #endif |
diff --git a/src/fbuilder/filedb.c b/src/fbuilder/filedb.c index 6e302a606..94a226cb7 100644 --- a/src/fbuilder/filedb.c +++ b/src/fbuilder/filedb.c | |||
@@ -20,7 +20,9 @@ | |||
20 | 20 | ||
21 | #include "fbuilder.h" | 21 | #include "fbuilder.h" |
22 | 22 | ||
23 | // find exact name or an exact name in a parent directory | ||
23 | FileDB *filedb_find(FileDB *head, const char *fname) { | 24 | FileDB *filedb_find(FileDB *head, const char *fname) { |
25 | assert(fname); | ||
24 | FileDB *ptr = head; | 26 | FileDB *ptr = head; |
25 | int found = 0; | 27 | int found = 0; |
26 | int len = strlen(fname); | 28 | int len = strlen(fname); |
@@ -52,6 +54,8 @@ FileDB *filedb_find(FileDB *head, const char *fname) { | |||
52 | FileDB *filedb_add(FileDB *head, const char *fname) { | 54 | FileDB *filedb_add(FileDB *head, const char *fname) { |
53 | assert(fname); | 55 | assert(fname); |
54 | 56 | ||
57 | // todo: support fnames such as ${RUNUSER}/.mutter-Xwaylandauth.* | ||
58 | |||
55 | // don't add it if it is already there or if the parent directory is already in the list | 59 | // don't add it if it is already there or if the parent directory is already in the list |
56 | if (filedb_find(head, fname)) | 60 | if (filedb_find(head, fname)) |
57 | return head; | 61 | return head; |
@@ -70,9 +74,52 @@ FileDB *filedb_add(FileDB *head, const char *fname) { | |||
70 | }; | 74 | }; |
71 | 75 | ||
72 | void filedb_print(FileDB *head, const char *prefix, FILE *fp) { | 76 | void filedb_print(FileDB *head, const char *prefix, FILE *fp) { |
77 | assert(head); | ||
78 | assert(prefix); | ||
79 | |||
73 | FileDB *ptr = head; | 80 | FileDB *ptr = head; |
74 | while (ptr) { | 81 | while (ptr) { |
75 | fprintf(fp, "%s%s\n", prefix, ptr->fname); | 82 | if (fp) |
83 | fprintf(fp, "%s%s\n", prefix, ptr->fname); | ||
84 | else | ||
85 | printf("%s%s\n", prefix, ptr->fname); | ||
76 | ptr = ptr->next; | 86 | ptr = ptr->next; |
77 | } | 87 | } |
78 | } | 88 | } |
89 | |||
90 | FileDB *filedb_load_whitelist(FileDB *head, const char *fname, const char *prefix) { | ||
91 | assert(fname); | ||
92 | assert(prefix); | ||
93 | int len = strlen(prefix); | ||
94 | char *f; | ||
95 | if (asprintf(&f, "%s/%s", SYSCONFDIR, fname) == -1) | ||
96 | errExit("asprintf"); | ||
97 | FILE *fp = fopen(f, "r"); | ||
98 | if (!fp) { | ||
99 | fprintf(stderr, "Error: cannot open whitelist-common.inc\n"); | ||
100 | free(f); | ||
101 | exit(1); | ||
102 | } | ||
103 | |||
104 | char buf[MAX_BUF]; | ||
105 | while (fgets(buf, MAX_BUF, fp)) { | ||
106 | if (strncmp(buf, prefix, len) != 0) | ||
107 | continue; | ||
108 | |||
109 | char *fn = buf + len; | ||
110 | char *ptr = strchr(buf, '\n'); | ||
111 | if (!ptr) | ||
112 | continue; | ||
113 | *ptr = '\0'; | ||
114 | |||
115 | // add the file to skip list | ||
116 | head = filedb_add(head, fn); | ||
117 | } | ||
118 | |||
119 | fclose(fp); | ||
120 | free(f); | ||
121 | //printf("***************************************************\n"); | ||
122 | //filedb_print(head, prefix, NULL); | ||
123 | //printf("***************************************************\n"); | ||
124 | return head; | ||
125 | } | ||