diff options
Diffstat (limited to 'src/fbuilder')
-rw-r--r-- | src/fbuilder/build_bin.c | 10 | ||||
-rw-r--r-- | src/fbuilder/build_fs.c | 52 | ||||
-rw-r--r-- | src/fbuilder/build_home.c | 8 | ||||
-rw-r--r-- | src/fbuilder/build_profile.c | 74 | ||||
-rw-r--r-- | src/fbuilder/build_seccomp.c | 47 | ||||
-rw-r--r-- | src/fbuilder/fbuilder.h | 22 | ||||
-rw-r--r-- | src/fbuilder/filedb.c | 4 | ||||
-rw-r--r-- | src/fbuilder/main.c | 26 |
8 files changed, 133 insertions, 110 deletions
diff --git a/src/fbuilder/build_bin.c b/src/fbuilder/build_bin.c index 6c173bfcc..fb92fb630 100644 --- a/src/fbuilder/build_bin.c +++ b/src/fbuilder/build_bin.c | |||
@@ -95,7 +95,7 @@ static void process_bin(const char *fname) { | |||
95 | 95 | ||
96 | 96 | ||
97 | // process fname, fname.1, fname.2, fname.3, fname.4, fname.5 | 97 | // process fname, fname.1, fname.2, fname.3, fname.4, fname.5 |
98 | void build_bin(const char *fname) { | 98 | void build_bin(const char *fname, FILE *fp) { |
99 | assert(fname); | 99 | assert(fname); |
100 | 100 | ||
101 | // run fname | 101 | // run fname |
@@ -114,13 +114,13 @@ void build_bin(const char *fname) { | |||
114 | } | 114 | } |
115 | 115 | ||
116 | if (bin_out) { | 116 | if (bin_out) { |
117 | printf("private-bin "); | 117 | fprintf(fp, "private-bin "); |
118 | FileDB *ptr = bin_out; | 118 | FileDB *ptr = bin_out; |
119 | while (ptr) { | 119 | while (ptr) { |
120 | printf("%s,", ptr->fname); | 120 | fprintf(fp, "%s,", ptr->fname); |
121 | ptr = ptr->next; | 121 | ptr = ptr->next; |
122 | } | 122 | } |
123 | printf("\n"); | 123 | fprintf(fp, "\n"); |
124 | printf("# private-lib\n"); | 124 | fprintf(fp, "# private-lib\n"); |
125 | } | 125 | } |
126 | } | 126 | } |
diff --git a/src/fbuilder/build_fs.c b/src/fbuilder/build_fs.c index 01104edb1..f1a27a35a 100644 --- a/src/fbuilder/build_fs.c +++ b/src/fbuilder/build_fs.c | |||
@@ -125,21 +125,21 @@ static void etc_callback(char *ptr) { | |||
125 | etc_out = filedb_add(etc_out, ptr); | 125 | etc_out = filedb_add(etc_out, ptr); |
126 | } | 126 | } |
127 | 127 | ||
128 | void build_etc(const char *fname) { | 128 | void build_etc(const char *fname, FILE *fp) { |
129 | assert(fname); | 129 | assert(fname); |
130 | 130 | ||
131 | process_files(fname, "/etc", etc_callback); | 131 | process_files(fname, "/etc", etc_callback); |
132 | 132 | ||
133 | printf("private-etc "); | 133 | fprintf(fp, "private-etc "); |
134 | if (etc_out == NULL) | 134 | if (etc_out == NULL) |
135 | printf("none\n"); | 135 | fprintf(fp, "none\n"); |
136 | else { | 136 | else { |
137 | FileDB *ptr = etc_out; | 137 | FileDB *ptr = etc_out; |
138 | while (ptr) { | 138 | while (ptr) { |
139 | printf("%s,", ptr->fname); | 139 | fprintf(fp, "%s,", ptr->fname); |
140 | ptr = ptr->next; | 140 | ptr = ptr->next; |
141 | } | 141 | } |
142 | printf("\n"); | 142 | fprintf(fp, "\n"); |
143 | } | 143 | } |
144 | } | 144 | } |
145 | 145 | ||
@@ -160,15 +160,15 @@ static void var_callback(char *ptr) { | |||
160 | var_out = filedb_add(var_out, ptr); | 160 | var_out = filedb_add(var_out, ptr); |
161 | } | 161 | } |
162 | 162 | ||
163 | void build_var(const char *fname) { | 163 | void build_var(const char *fname, FILE *fp) { |
164 | assert(fname); | 164 | assert(fname); |
165 | 165 | ||
166 | process_files(fname, "/var", var_callback); | 166 | process_files(fname, "/var", var_callback); |
167 | 167 | ||
168 | if (var_out == NULL) | 168 | if (var_out == NULL) |
169 | printf("blacklist /var\n"); | 169 | fprintf(fp, "blacklist /var\n"); |
170 | else | 170 | else |
171 | filedb_print(var_out, "whitelist "); | 171 | filedb_print(var_out, "whitelist ", fp); |
172 | } | 172 | } |
173 | 173 | ||
174 | 174 | ||
@@ -197,15 +197,15 @@ static void share_callback(char *ptr) { | |||
197 | share_out = filedb_add(share_out, ptr); | 197 | share_out = filedb_add(share_out, ptr); |
198 | } | 198 | } |
199 | 199 | ||
200 | void build_share(const char *fname) { | 200 | void build_share(const char *fname, FILE *fp) { |
201 | assert(fname); | 201 | assert(fname); |
202 | 202 | ||
203 | process_files(fname, "/usr/share", share_callback); | 203 | process_files(fname, "/usr/share", share_callback); |
204 | 204 | ||
205 | if (share_out == NULL) | 205 | if (share_out == NULL) |
206 | printf("blacklist /usr/share\n"); | 206 | fprintf(fp, "blacklist /usr/share\n"); |
207 | else | 207 | else |
208 | filedb_print(share_out, "whitelist "); | 208 | filedb_print(share_out, "whitelist ", fp); |
209 | } | 209 | } |
210 | 210 | ||
211 | //******************************************* | 211 | //******************************************* |
@@ -216,21 +216,21 @@ static void tmp_callback(char *ptr) { | |||
216 | filedb_add(tmp_out, ptr); | 216 | filedb_add(tmp_out, ptr); |
217 | } | 217 | } |
218 | 218 | ||
219 | void build_tmp(const char *fname) { | 219 | void build_tmp(const char *fname, FILE *fp) { |
220 | assert(fname); | 220 | assert(fname); |
221 | 221 | ||
222 | process_files(fname, "/tmp", tmp_callback); | 222 | process_files(fname, "/tmp", tmp_callback); |
223 | 223 | ||
224 | if (tmp_out == NULL) | 224 | if (tmp_out == NULL) |
225 | printf("private-tmp\n"); | 225 | fprintf(fp, "private-tmp\n"); |
226 | else { | 226 | else { |
227 | printf("\n"); | 227 | fprintf(fp, "\n"); |
228 | printf("# private-tmp\n"); | 228 | fprintf(fp, "# private-tmp\n"); |
229 | printf("# File accessed in /tmp directory:\n"); | 229 | fprintf(fp, "# File accessed in /tmp directory:\n"); |
230 | printf("# "); | 230 | fprintf(fp, "# "); |
231 | FileDB *ptr = tmp_out; | 231 | FileDB *ptr = tmp_out; |
232 | while (ptr) { | 232 | while (ptr) { |
233 | printf("%s,", ptr->fname); | 233 | fprintf(fp, "%s,", ptr->fname); |
234 | ptr = ptr->next; | 234 | ptr = ptr->next; |
235 | } | 235 | } |
236 | printf("\n"); | 236 | printf("\n"); |
@@ -294,24 +294,24 @@ static void dev_callback(char *ptr) { | |||
294 | filedb_add(dev_out, ptr); | 294 | filedb_add(dev_out, ptr); |
295 | } | 295 | } |
296 | 296 | ||
297 | void build_dev(const char *fname) { | 297 | void build_dev(const char *fname, FILE *fp) { |
298 | assert(fname); | 298 | assert(fname); |
299 | 299 | ||
300 | process_files(fname, "/dev", dev_callback); | 300 | process_files(fname, "/dev", dev_callback); |
301 | 301 | ||
302 | if (dev_out == NULL) | 302 | if (dev_out == NULL) |
303 | printf("private-dev\n"); | 303 | fprintf(fp, "private-dev\n"); |
304 | else { | 304 | else { |
305 | printf("\n"); | 305 | fprintf(fp, "\n"); |
306 | printf("# private-dev\n"); | 306 | fprintf(fp, "# private-dev\n"); |
307 | printf("# This is the list of devices accessed (on top of regular private-dev devices:\n"); | 307 | fprintf(fp, "# This is the list of devices accessed (on top of regular private-dev devices:\n"); |
308 | printf("# "); | 308 | fprintf(fp, "# "); |
309 | FileDB *ptr = dev_out; | 309 | FileDB *ptr = dev_out; |
310 | while (ptr) { | 310 | while (ptr) { |
311 | printf("%s,", ptr->fname); | 311 | fprintf(fp, "%s,", ptr->fname); |
312 | ptr = ptr->next; | 312 | ptr = ptr->next; |
313 | } | 313 | } |
314 | printf("\n"); | 314 | fprintf(fp, "\n"); |
315 | } | 315 | } |
316 | } | 316 | } |
317 | 317 | ||
diff --git a/src/fbuilder/build_home.c b/src/fbuilder/build_home.c index 947f172d8..9bbd2c258 100644 --- a/src/fbuilder/build_home.c +++ b/src/fbuilder/build_home.c | |||
@@ -158,7 +158,7 @@ void process_home(const char *fname, char *home, int home_len) { | |||
158 | 158 | ||
159 | 159 | ||
160 | // process fname, fname.1, fname.2, fname.3, fname.4, fname.5 | 160 | // process fname, fname.1, fname.2, fname.3, fname.4, fname.5 |
161 | void build_home(const char *fname) { | 161 | void build_home(const char *fname, FILE *fp) { |
162 | assert(fname); | 162 | assert(fname); |
163 | 163 | ||
164 | // load whitelist common | 164 | // load whitelist common |
@@ -190,10 +190,10 @@ void build_home(const char *fname) { | |||
190 | 190 | ||
191 | // print the out list if any | 191 | // print the out list if any |
192 | if (db_out) { | 192 | if (db_out) { |
193 | filedb_print(db_out, "whitelist ~/"); | 193 | filedb_print(db_out, "whitelist ~/", fp); |
194 | printf("include /etc/firejail/whitelist-common.inc\n"); | 194 | fprintf(fp, "include /etc/firejail/whitelist-common.inc\n"); |
195 | } | 195 | } |
196 | else | 196 | else |
197 | printf("private\n"); | 197 | fprintf(fp, "private\n"); |
198 | 198 | ||
199 | } \ No newline at end of file | 199 | } \ No newline at end of file |
diff --git a/src/fbuilder/build_profile.c b/src/fbuilder/build_profile.c index 6d6263035..de9f79232 100644 --- a/src/fbuilder/build_profile.c +++ b/src/fbuilder/build_profile.c | |||
@@ -56,7 +56,7 @@ static void clear_tmp_files(void) { | |||
56 | 56 | ||
57 | } | 57 | } |
58 | 58 | ||
59 | void build_profile(int argc, char **argv, int index) { | 59 | void build_profile(int argc, char **argv, int index, FILE *fp) { |
60 | // next index is the application name | 60 | // next index is the application name |
61 | if (index >= argc) { | 61 | if (index >= argc) { |
62 | fprintf(stderr, "Error: application name missing\n"); | 62 | fprintf(stderr, "Error: application name missing\n"); |
@@ -116,51 +116,51 @@ void build_profile(int argc, char **argv, int index) { | |||
116 | 116 | ||
117 | if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { | 117 | if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { |
118 | printf("\n\n\n"); | 118 | printf("\n\n\n"); |
119 | printf("############################################\n"); | 119 | fprintf(fp, "############################################\n"); |
120 | printf("# %s profile\n", argv[index]); | 120 | fprintf(fp, "# %s profile\n", argv[index]); |
121 | printf("############################################\n"); | 121 | fprintf(fp, "############################################\n"); |
122 | printf("# Persistent global definitions\n"); | 122 | fprintf(fp, "# Persistent global definitions\n"); |
123 | printf("# include /etc/firejail/globals.local\n"); | 123 | fprintf(fp, "# include /etc/firejail/globals.local\n"); |
124 | printf("\n"); | 124 | fprintf(fp, "\n"); |
125 | 125 | ||
126 | printf("### basic blacklisting\n"); | 126 | fprintf(fp, "### basic blacklisting\n"); |
127 | printf("include /etc/firejail/disable-common.inc\n"); | 127 | fprintf(fp, "include /etc/firejail/disable-common.inc\n"); |
128 | printf("# include /etc/firejail/disable-devel.inc\n"); | 128 | fprintf(fp, "# include /etc/firejail/disable-devel.inc\n"); |
129 | printf("include /etc/firejail/disable-passwdmgr.inc\n"); | 129 | fprintf(fp, "include /etc/firejail/disable-passwdmgr.inc\n"); |
130 | printf("# include /etc/firejail/disable-programs.inc\n"); | 130 | fprintf(fp, "# include /etc/firejail/disable-programs.inc\n"); |
131 | printf("\n"); | 131 | fprintf(fp, "\n"); |
132 | 132 | ||
133 | printf("### home directory whitelisting\n"); | 133 | fprintf(fp, "### home directory whitelisting\n"); |
134 | build_home(TRACE_OUTPUT); | 134 | build_home(TRACE_OUTPUT, fp); |
135 | printf("\n"); | 135 | fprintf(fp, "\n"); |
136 | 136 | ||
137 | printf("### filesystem\n"); | 137 | fprintf(fp, "### filesystem\n"); |
138 | build_tmp(TRACE_OUTPUT); | 138 | build_tmp(TRACE_OUTPUT, fp); |
139 | build_dev(TRACE_OUTPUT); | 139 | build_dev(TRACE_OUTPUT, fp); |
140 | build_etc(TRACE_OUTPUT); | 140 | build_etc(TRACE_OUTPUT, fp); |
141 | build_var(TRACE_OUTPUT); | 141 | build_var(TRACE_OUTPUT, fp); |
142 | build_bin(TRACE_OUTPUT); | 142 | build_bin(TRACE_OUTPUT, fp); |
143 | build_share(TRACE_OUTPUT); | 143 | build_share(TRACE_OUTPUT, fp); |
144 | printf("\n"); | 144 | fprintf(fp, "\n"); |
145 | 145 | ||
146 | printf("### security filters\n"); | 146 | fprintf(fp, "### security filters\n"); |
147 | printf("caps.drop all\n"); | 147 | fprintf(fp, "caps.drop all\n"); |
148 | printf("nonewprivs\n"); | 148 | fprintf(fp, "nonewprivs\n"); |
149 | printf("seccomp\n"); | 149 | fprintf(fp, "seccomp\n"); |
150 | if (have_strace) | 150 | if (have_strace) |
151 | build_seccomp(STRACE_OUTPUT); | 151 | build_seccomp(STRACE_OUTPUT, fp); |
152 | else { | 152 | else { |
153 | printf("# If you install strace on your system, Firejail will also create a\n"); | 153 | fprintf(fp, "# If you install strace on your system, Firejail will also create a\n"); |
154 | printf("# whitelisted seccomp filter.\n"); | 154 | fprintf(fp, "# whitelisted seccomp filter.\n"); |
155 | } | 155 | } |
156 | printf("\n"); | 156 | fprintf(fp, "\n"); |
157 | 157 | ||
158 | printf("### network\n"); | 158 | fprintf(fp, "### network\n"); |
159 | build_protocol(TRACE_OUTPUT); | 159 | build_protocol(TRACE_OUTPUT, fp); |
160 | printf("\n"); | 160 | fprintf(fp, "\n"); |
161 | 161 | ||
162 | printf("### environment\n"); | 162 | fprintf(fp, "### environment\n"); |
163 | printf("shell none\n"); | 163 | fprintf(fp, "shell none\n"); |
164 | 164 | ||
165 | } | 165 | } |
166 | else { | 166 | else { |
diff --git a/src/fbuilder/build_seccomp.c b/src/fbuilder/build_seccomp.c index 18a767518..63f37e34a 100644 --- a/src/fbuilder/build_seccomp.c +++ b/src/fbuilder/build_seccomp.c | |||
@@ -20,11 +20,12 @@ | |||
20 | 20 | ||
21 | #include "fbuilder.h" | 21 | #include "fbuilder.h" |
22 | 22 | ||
23 | void build_seccomp(const char *fname) { | 23 | void build_seccomp(const char *fname, FILE *fp) { |
24 | assert(fname); | 24 | assert(fname); |
25 | assert(fp); | ||
25 | 26 | ||
26 | FILE *fp = fopen(fname, "r"); | 27 | FILE *fp2 = fopen(fname, "r"); |
27 | if (!fp) { | 28 | if (!fp2) { |
28 | fprintf(stderr, "Error: cannot open %s\n", fname); | 29 | fprintf(stderr, "Error: cannot open %s\n", fname); |
29 | exit(1); | 30 | exit(1); |
30 | } | 31 | } |
@@ -33,7 +34,7 @@ void build_seccomp(const char *fname) { | |||
33 | int line = 1; | 34 | int line = 1; |
34 | int position = 0; | 35 | int position = 0; |
35 | int cnt = 0; | 36 | int cnt = 0; |
36 | while (fgets(buf, MAX_BUF, fp)) { | 37 | while (fgets(buf, MAX_BUF, fp2)) { |
37 | // remove \n | 38 | // remove \n |
38 | char *ptr = strchr(buf, '\n'); | 39 | char *ptr = strchr(buf, '\n'); |
39 | if (ptr) | 40 | if (ptr) |
@@ -62,20 +63,20 @@ void build_seccomp(const char *fname) { | |||
62 | break; | 63 | break; |
63 | 64 | ||
64 | if (line == 3) | 65 | if (line == 3) |
65 | printf("# seccomp.keep %s", buf + position); | 66 | fprintf(fp, "# seccomp.keep %s", buf + position); |
66 | else | 67 | else |
67 | printf(",%s", buf + position); | 68 | fprintf(fp, ",%s", buf + position); |
68 | cnt++; | 69 | cnt++; |
69 | } | 70 | } |
70 | line++; | 71 | line++; |
71 | } | 72 | } |
72 | printf("\n"); | 73 | fprintf(fp, "\n"); |
73 | printf("# %d syscalls total\n", cnt); | 74 | fprintf(fp, "# %d syscalls total\n", cnt); |
74 | printf("# Probably you will need to add more syscalls to seccomp.keep. Look for\n"); | 75 | fprintf(fp, "# Probably you will need to add more syscalls to seccomp.keep. Look for\n"); |
75 | printf("# seccomp errors in /var/log/syslog or /var/log/audit/audit.log while\n"); | 76 | fprintf(fp, "# seccomp errors in /var/log/syslog or /var/log/audit/audit.log while\n"); |
76 | printf("# running your sandbox.\n"); | 77 | fprintf(fp, "# running your sandbox.\n"); |
77 | 78 | ||
78 | fclose(fp); | 79 | fclose(fp2); |
79 | } | 80 | } |
80 | 81 | ||
81 | //*************************************** | 82 | //*************************************** |
@@ -141,7 +142,7 @@ static void process_protocol(const char *fname) { | |||
141 | 142 | ||
142 | 143 | ||
143 | // process fname, fname.1, fname.2, fname.3, fname.4, fname.5 | 144 | // process fname, fname.1, fname.2, fname.3, fname.4, fname.5 |
144 | void build_protocol(const char *fname) { | 145 | void build_protocol(const char *fname, FILE *fp) { |
145 | assert(fname); | 146 | assert(fname); |
146 | 147 | ||
147 | // run fname | 148 | // run fname |
@@ -161,31 +162,31 @@ void build_protocol(const char *fname) { | |||
161 | 162 | ||
162 | int net = 0; | 163 | int net = 0; |
163 | if (unix_s || inet || inet6 || netlink || packet) { | 164 | if (unix_s || inet || inet6 || netlink || packet) { |
164 | printf("protocol "); | 165 | fprintf(fp, "protocol "); |
165 | if (unix_s) | 166 | if (unix_s) |
166 | printf("unix,"); | 167 | fprintf(fp, "unix,"); |
167 | if (inet) { | 168 | if (inet) { |
168 | printf("inet,"); | 169 | fprintf(fp, "inet,"); |
169 | net = 1; | 170 | net = 1; |
170 | } | 171 | } |
171 | if (inet6) { | 172 | if (inet6) { |
172 | printf("inet6,"); | 173 | fprintf(fp, "inet6,"); |
173 | net = 1; | 174 | net = 1; |
174 | } | 175 | } |
175 | if (netlink) | 176 | if (netlink) |
176 | printf("netlink,"); | 177 | fprintf(fp, "netlink,"); |
177 | if (packet) { | 178 | if (packet) { |
178 | printf("packet"); | 179 | fprintf(fp, "packet"); |
179 | net = 1; | 180 | net = 1; |
180 | } | 181 | } |
181 | printf("\n"); | 182 | fprintf(fp, "\n"); |
182 | } | 183 | } |
183 | 184 | ||
184 | if (net == 0) | 185 | if (net == 0) |
185 | printf("net none\n"); | 186 | fprintf(fp, "net none\n"); |
186 | else { | 187 | else { |
187 | printf("# net eth0\n"); | 188 | fprintf(fp, "# net eth0\n"); |
188 | printf("netfilter\n"); | 189 | fprintf(fp, "netfilter\n"); |
189 | } | 190 | } |
190 | } | 191 | } |
191 | 192 | ||
diff --git a/src/fbuilder/fbuilder.h b/src/fbuilder/fbuilder.h index 401ae908e..81dc951ec 100644 --- a/src/fbuilder/fbuilder.h +++ b/src/fbuilder/fbuilder.h | |||
@@ -32,24 +32,24 @@ | |||
32 | extern int arg_debug; | 32 | extern int arg_debug; |
33 | 33 | ||
34 | // build_profile.c | 34 | // build_profile.c |
35 | void build_profile(int argc, char **argv, int index); | 35 | void build_profile(int argc, char **argv, int index, FILE *fp); |
36 | 36 | ||
37 | // build_seccomp.c | 37 | // build_seccomp.c |
38 | void build_seccomp(const char *fname); | 38 | void build_seccomp(const char *fname, FILE *fp); |
39 | void build_protocol(const char *fname); | 39 | void build_protocol(const char *fname, FILE *fp); |
40 | 40 | ||
41 | // build_fs.c | 41 | // build_fs.c |
42 | void build_etc(const char *fname); | 42 | void build_etc(const char *fname, FILE *fp); |
43 | void build_var(const char *fname); | 43 | void build_var(const char *fname, FILE *fp); |
44 | void build_tmp(const char *fname); | 44 | void build_tmp(const char *fname, FILE *fp); |
45 | void build_dev(const char *fname); | 45 | void build_dev(const char *fname, FILE *fp); |
46 | void build_share(const char *fname); | 46 | void build_share(const char *fname, FILE *fp); |
47 | 47 | ||
48 | // build_bin.c | 48 | // build_bin.c |
49 | void build_bin(const char *fname); | 49 | void build_bin(const char *fname, FILE *fp); |
50 | 50 | ||
51 | // build_home.c | 51 | // build_home.c |
52 | void build_home(const char *fname); | 52 | void build_home(const char *fname, FILE *fp); |
53 | 53 | ||
54 | // utils.c | 54 | // utils.c |
55 | int is_dir(const char *fname); | 55 | int is_dir(const char *fname); |
@@ -64,6 +64,6 @@ typedef struct filedb_t { | |||
64 | 64 | ||
65 | FileDB *filedb_add(FileDB *head, const char *fname); | 65 | FileDB *filedb_add(FileDB *head, const char *fname); |
66 | FileDB *filedb_find(FileDB *head, const char *fname); | 66 | FileDB *filedb_find(FileDB *head, const char *fname); |
67 | void filedb_print(FileDB *head, const char *prefix); | 67 | void filedb_print(FileDB *head, const char *prefix, FILE *fp); |
68 | 68 | ||
69 | #endif \ No newline at end of file | 69 | #endif \ No newline at end of file |
diff --git a/src/fbuilder/filedb.c b/src/fbuilder/filedb.c index a76fbc961..b7162c2d6 100644 --- a/src/fbuilder/filedb.c +++ b/src/fbuilder/filedb.c | |||
@@ -69,10 +69,10 @@ FileDB *filedb_add(FileDB *head, const char *fname) { | |||
69 | return entry; | 69 | return entry; |
70 | }; | 70 | }; |
71 | 71 | ||
72 | void filedb_print(FileDB *head, const char *prefix) { | 72 | void filedb_print(FileDB *head, const char *prefix, FILE *fp) { |
73 | FileDB *ptr = head; | 73 | FileDB *ptr = head; |
74 | while (ptr) { | 74 | while (ptr) { |
75 | printf("%s%s\n", prefix, ptr->fname); | 75 | fprintf(fp, "%s%s\n", prefix, ptr->fname); |
76 | ptr = ptr->next; | 76 | ptr = ptr->next; |
77 | } | 77 | } |
78 | } | 78 | } |
diff --git a/src/fbuilder/main.c b/src/fbuilder/main.c index 83217ef98..1b997ccdb 100644 --- a/src/fbuilder/main.c +++ b/src/fbuilder/main.c | |||
@@ -22,7 +22,7 @@ int arg_debug = 0; | |||
22 | 22 | ||
23 | static void usage(void) { | 23 | static void usage(void) { |
24 | printf("Firejail profile builder\n"); | 24 | printf("Firejail profile builder\n"); |
25 | printf("Usage: firejail [--debug] --build program-and-arguments\n"); | 25 | printf("Usage: firejail [--debug] --build[=profile-file] program-and-arguments\n"); |
26 | } | 26 | } |
27 | 27 | ||
28 | int main(int argc, char **argv) { | 28 | int main(int argc, char **argv) { |
@@ -38,6 +38,8 @@ printf("\n"); | |||
38 | 38 | ||
39 | int i; | 39 | int i; |
40 | int prog_index = 0; | 40 | int prog_index = 0; |
41 | FILE *fp = stdout; | ||
42 | int prof_file = 0; | ||
41 | 43 | ||
42 | // parse arguments and extract program index | 44 | // parse arguments and extract program index |
43 | for (i = 1; i < argc; i++) { | 45 | for (i = 1; i < argc; i++) { |
@@ -49,6 +51,22 @@ printf("\n"); | |||
49 | arg_debug = 1; | 51 | arg_debug = 1; |
50 | else if (strcmp(argv[i], "--build") == 0) | 52 | else if (strcmp(argv[i], "--build") == 0) |
51 | ; // do nothing, this is passed down from firejail | 53 | ; // do nothing, this is passed down from firejail |
54 | else if (strncmp(argv[i], "--build=", 8) == 0) { | ||
55 | // this option is only supported for non-root users | ||
56 | if (getuid() == 0) { | ||
57 | fprintf(stderr, "Error fbuild: --build=profile-name is not supported for root user.\n"); | ||
58 | exit(1); | ||
59 | } | ||
60 | |||
61 | // check file access | ||
62 | fp = fopen(argv[i] + 8, "w"); | ||
63 | if (!fp) { | ||
64 | fprintf(stderr, "Error fbuild: cannot open profile file.\n"); | ||
65 | exit(1); | ||
66 | } | ||
67 | prof_file = 1; | ||
68 | // do nothing, this is passed down from firejail | ||
69 | } | ||
52 | else { | 70 | else { |
53 | if (*argv[i] == '-') { | 71 | if (*argv[i] == '-') { |
54 | fprintf(stderr, "Error fbuilder: invalid program\n"); | 72 | fprintf(stderr, "Error fbuilder: invalid program\n"); |
@@ -63,9 +81,13 @@ printf("\n"); | |||
63 | if (prog_index == 0) { | 81 | if (prog_index == 0) { |
64 | fprintf(stderr, "Error fbuilder: program and arguments required\n"); | 82 | fprintf(stderr, "Error fbuilder: program and arguments required\n"); |
65 | usage(); | 83 | usage(); |
84 | if (prof_file) | ||
85 | fclose(fp); | ||
66 | exit(1); | 86 | exit(1); |
67 | } | 87 | } |
68 | 88 | ||
69 | build_profile(argc, argv, prog_index); | 89 | build_profile(argc, argv, prog_index, fp); |
90 | if (prof_file) | ||
91 | fclose(fp); | ||
70 | return 0; | 92 | return 0; |
71 | } | 93 | } |