diff options
author | netblue30 <netblue30@yahoo.com> | 2016-03-25 08:47:17 -0400 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2016-03-25 08:47:17 -0400 |
commit | e7d1fd9965b42ea8b17a38821140daeac1373d9a (patch) | |
tree | f9937355433349542f87ef92e6160eee1c8cc120 /src/firecfg | |
parent | fix netfilter problem (diff) | |
download | firejail-e7d1fd9965b42ea8b17a38821140daeac1373d9a.tar.gz firejail-e7d1fd9965b42ea8b17a38821140daeac1373d9a.tar.zst firejail-e7d1fd9965b42ea8b17a38821140daeac1373d9a.zip |
added firecfg utility
Diffstat (limited to 'src/firecfg')
-rw-r--r-- | src/firecfg/Makefile.in | 38 | ||||
-rw-r--r-- | src/firecfg/firecfg.config | 7 | ||||
-rw-r--r-- | src/firecfg/main.c | 300 |
3 files changed, 345 insertions, 0 deletions
diff --git a/src/firecfg/Makefile.in b/src/firecfg/Makefile.in new file mode 100644 index 000000000..11f8b1e8d --- /dev/null +++ b/src/firecfg/Makefile.in | |||
@@ -0,0 +1,38 @@ | |||
1 | all: firecfg | ||
2 | |||
3 | prefix=@prefix@ | ||
4 | exec_prefix=@exec_prefix@ | ||
5 | libdir=@libdir@ | ||
6 | sysconfdir=@sysconfdir@ | ||
7 | |||
8 | VERSION=@PACKAGE_VERSION@ | ||
9 | NAME=@PACKAGE_NAME@ | ||
10 | HAVE_SECCOMP_H=@HAVE_SECCOMP_H@ | ||
11 | HAVE_SECCOMP=@HAVE_SECCOMP@ | ||
12 | HAVE_CHROOT=@HAVE_CHROOT@ | ||
13 | HAVE_BIND=@HAVE_BIND@ | ||
14 | HAVE_FATAL_WARNINGS=@HAVE_FATAL_WARNINGS@ | ||
15 | HAVE_NETWORK=@HAVE_NETWORK@ | ||
16 | HAVE_USERNS=@HAVE_USERNS@ | ||
17 | HAVE_X11=@HAVE_X11@ | ||
18 | HAVE_FILE_TRANSFER=@HAVE_FILE_TRANSFER@ | ||
19 | |||
20 | |||
21 | H_FILE_LIST = $(sort $(wildcard *.[h])) | ||
22 | C_FILE_LIST = $(sort $(wildcard *.c)) | ||
23 | OBJS = $(C_FILE_LIST:.c=.o) | ||
24 | BINOBJS = $(foreach file, $(OBJS), $file) | ||
25 | CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' -DPREFIX='"$(prefix)"' -DSYSCONFDIR='"$(sysconfdir)/firejail"' -DLIBDIR='"$(libdir)"' $(HAVE_X11) $(HAVE_SECCOMP) $(HAVE_SECCOMP_H) $(HAVE_CHROOT) $(HAVE_NETWORK) $(HAVE_USERNS) $(HAVE_BIND) $(HAVE_FILE_TRANSFER) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security | ||
26 | LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread | ||
27 | |||
28 | %.o : %.c $(H_FILE_LIST) ../include/common.h ../include/euid_common.h ../include/libnetlink.h ../include/pid.h | ||
29 | $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ | ||
30 | |||
31 | firecfg: $(OBJS) ../lib/common.o | ||
32 | $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/common.o $(LIBS) | ||
33 | |||
34 | clean:; rm -f *.o firecfg firecfg.1 firecfg.1.gz | ||
35 | |||
36 | distclean: clean | ||
37 | rm -fr Makefile | ||
38 | |||
diff --git a/src/firecfg/firecfg.config b/src/firecfg/firecfg.config new file mode 100644 index 000000000..fb996966f --- /dev/null +++ b/src/firecfg/firecfg.config | |||
@@ -0,0 +1,7 @@ | |||
1 | # /etc/firejail/firecfg.config - firecfg utility configuration file | ||
2 | # This is the list of programs handled by firecfg utility | ||
3 | # | ||
4 | firefox | ||
5 | iceweasel | ||
6 | thunderbird | ||
7 | vlc | ||
diff --git a/src/firecfg/main.c b/src/firecfg/main.c new file mode 100644 index 000000000..7465f2d3e --- /dev/null +++ b/src/firecfg/main.c | |||
@@ -0,0 +1,300 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014-2016 netblue30 (netblue30@yahoo.com) | ||
3 | * | ||
4 | * This file is part of firejail project | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | #include <sys/types.h> | ||
22 | #include <dirent.h> | ||
23 | #include <sys/types.h> | ||
24 | #include <sys/stat.h> | ||
25 | #include <unistd.h> | ||
26 | #include "../include/common.h" | ||
27 | |||
28 | static void usage(void) { | ||
29 | printf("firecfg - version %s\n\n", VERSION); | ||
30 | printf("Firecfg is the desktop configuration utility for Firejail software. The utility\n"); | ||
31 | printf("creates several symbolic links to firejail executable. This allows the user to\n"); | ||
32 | printf("sandbox applications automatically, just by clicking on a regular desktop\n"); | ||
33 | printf("menues and icons.\n\n"); | ||
34 | printf("The symbolic links are placed in /usr/local/bin. For more information, see\n"); | ||
35 | printf("DESKTOP INTEGRATION section in man 1 firejail.\n\n"); | ||
36 | printf("Usage: firecfg [OPTIONS]\n\n"); | ||
37 | printf(" --clear - clear all firejail symbolic links\n\n"); | ||
38 | printf(" --help, -? - this help screen.\n\n"); | ||
39 | printf(" --list - list all firejail symbolic links\n\n"); | ||
40 | printf(" --version - print program version and exit.\n\n"); | ||
41 | printf("Example:\n\n"); | ||
42 | printf(" $ sudo firecfg\n"); | ||
43 | printf(" /usr/local/bin/firefox created\n"); | ||
44 | printf(" /usr/local/bin/vlc created\n"); | ||
45 | printf(" [...]\n"); | ||
46 | printf(" $ firecfg --list\n"); | ||
47 | printf(" /usr/local/bin/firefox\n"); | ||
48 | printf(" /usr/local/bin/vlc\n"); | ||
49 | printf(" [...]\n"); | ||
50 | printf(" $ sudo firecfg --clear\n"); | ||
51 | printf(" /usr/local/bin/firefox removed\n"); | ||
52 | printf(" /usr/local/bin/vlc removed\n"); | ||
53 | printf(" [...]\n"); | ||
54 | printf("\n"); | ||
55 | printf("License GPL version 2 or later\n"); | ||
56 | printf("Homepage: http://firejail.wordpress.com\n\n"); | ||
57 | } | ||
58 | |||
59 | // return 1 if the program is found | ||
60 | static int find(const char *program, const char *directory) { | ||
61 | int retval = 0; | ||
62 | |||
63 | char *fname; | ||
64 | if (asprintf(&fname, "/%s/%s", directory, program) == -1) | ||
65 | errExit("asprintf"); | ||
66 | |||
67 | struct stat s; | ||
68 | if (stat(fname, &s) == 0) | ||
69 | retval = 1; | ||
70 | |||
71 | free(fname); | ||
72 | return retval; | ||
73 | } | ||
74 | |||
75 | |||
76 | // return 1 if program is installed on the system | ||
77 | static int which(const char *program) { | ||
78 | // check some well-known paths | ||
79 | if (find(program, "/bin") || find(program, "/usr/bin") || | ||
80 | find(program, "/sbin") || find(program, "/usr/sbin")) | ||
81 | return 1; | ||
82 | |||
83 | // check environment | ||
84 | char *path1 = getenv("PATH"); | ||
85 | if (path1) { | ||
86 | char *path2 = strdup(path1); | ||
87 | if (!path2) | ||
88 | errExit("strdup"); | ||
89 | |||
90 | // use path2 to count the entries | ||
91 | char *ptr = strtok(path2, ":"); | ||
92 | while (ptr) { | ||
93 | if (find(program, ptr)) { | ||
94 | free(path2); | ||
95 | return 1; | ||
96 | } | ||
97 | ptr = strtok(NULL, ":"); | ||
98 | } | ||
99 | free(path2); | ||
100 | } | ||
101 | |||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | // return 1 if the file is a link | ||
106 | static int is_link(const char *fname) { | ||
107 | assert(fname); | ||
108 | if (*fname == '\0') | ||
109 | return 0; | ||
110 | |||
111 | struct stat s; | ||
112 | if (lstat(fname, &s) == 0) { | ||
113 | if (S_ISLNK(s.st_mode)) | ||
114 | return 1; | ||
115 | } | ||
116 | |||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | static void list(void) { | ||
121 | DIR *dir = opendir("/usr/local/bin"); | ||
122 | if (!dir) { | ||
123 | fprintf(stderr, "Error: cannot open /usr/local/bin directory\n"); | ||
124 | exit(1); | ||
125 | } | ||
126 | |||
127 | char *firejail_exec; | ||
128 | if (asprintf(&firejail_exec, "%s/bin/firejail", PREFIX) == -1) | ||
129 | errExit("asprintf"); | ||
130 | |||
131 | struct dirent *entry; | ||
132 | while ((entry = readdir(dir)) != NULL) { | ||
133 | if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) | ||
134 | continue; | ||
135 | |||
136 | char *fullname; | ||
137 | if (asprintf(&fullname, "/usr/local/bin/%s", entry->d_name) == -1) | ||
138 | errExit("asprintf"); | ||
139 | |||
140 | if (is_link(fullname)) { | ||
141 | char* fname = realpath(fullname, NULL); | ||
142 | if (fname) { | ||
143 | if (strcmp(fname, firejail_exec) == 0) | ||
144 | printf("%s\n", fullname); | ||
145 | free(fname); | ||
146 | } | ||
147 | } | ||
148 | free(fullname); | ||
149 | } | ||
150 | |||
151 | closedir(dir); | ||
152 | free(firejail_exec); | ||
153 | } | ||
154 | |||
155 | static void clear(void) { | ||
156 | if (getuid() != 0) { | ||
157 | fprintf(stderr, "Error: you need to be root to run this command\n"); | ||
158 | exit(1); | ||
159 | } | ||
160 | |||
161 | DIR *dir = opendir("/usr/local/bin"); | ||
162 | if (!dir) { | ||
163 | fprintf(stderr, "Error: cannot open /usr/local/bin directory\n"); | ||
164 | exit(1); | ||
165 | } | ||
166 | |||
167 | char *firejail_exec; | ||
168 | if (asprintf(&firejail_exec, "%s/bin/firejail", PREFIX) == -1) | ||
169 | errExit("asprintf"); | ||
170 | |||
171 | struct dirent *entry; | ||
172 | while ((entry = readdir(dir)) != NULL) { | ||
173 | if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) | ||
174 | continue; | ||
175 | |||
176 | char *fullname; | ||
177 | if (asprintf(&fullname, "/usr/local/bin/%s", entry->d_name) == -1) | ||
178 | errExit("asprintf"); | ||
179 | |||
180 | if (is_link(fullname)) { | ||
181 | char* fname = realpath(fullname, NULL); | ||
182 | if (fname) { | ||
183 | if (strcmp(fname, firejail_exec) == 0) { | ||
184 | printf("%s removed\n", fullname); | ||
185 | unlink(fullname); | ||
186 | } | ||
187 | free(fname); | ||
188 | } | ||
189 | } | ||
190 | free(fullname); | ||
191 | } | ||
192 | |||
193 | closedir(dir); | ||
194 | free(firejail_exec); | ||
195 | } | ||
196 | |||
197 | static void set_file(const char *name, const char *firejail_exec) { | ||
198 | if (which(name) == 0) | ||
199 | return; | ||
200 | |||
201 | char *fname; | ||
202 | if (asprintf(&fname, "/usr/local/bin/%s", name) == -1) | ||
203 | errExit("asprintf"); | ||
204 | |||
205 | struct stat s; | ||
206 | if (stat(fname, &s) == 0) | ||
207 | ; //printf("%s already present\n", fname); | ||
208 | else { | ||
209 | int rv = symlink(firejail_exec, fname); | ||
210 | if (rv) { | ||
211 | fprintf(stderr, "Error: cannot create %s symbolic link\n", fname); | ||
212 | perror("symlink"); | ||
213 | } | ||
214 | else | ||
215 | printf("%s created\n", fname); | ||
216 | } | ||
217 | |||
218 | free(fname); | ||
219 | } | ||
220 | |||
221 | #define MAX_BUF 1024 | ||
222 | static void set(void) { | ||
223 | if (getuid() != 0) { | ||
224 | fprintf(stderr, "Error: you need to be root to run this command\n"); | ||
225 | exit(1); | ||
226 | } | ||
227 | |||
228 | char *cfgfile; | ||
229 | if (asprintf(&cfgfile, "%s/firejail/firecfg.config", LIBDIR) == -1) | ||
230 | errExit("asprintf"); | ||
231 | |||
232 | char *firejail_exec; | ||
233 | if (asprintf(&firejail_exec, "%s/bin/firejail", PREFIX) == -1) | ||
234 | errExit("asprintf"); | ||
235 | |||
236 | FILE *fp = fopen(cfgfile, "r"); | ||
237 | if (!fp) { | ||
238 | fprintf(stderr, "Error: cannot open %s\n", cfgfile); | ||
239 | exit(1); | ||
240 | } | ||
241 | |||
242 | char buf[MAX_BUF]; | ||
243 | int lineno = 0; | ||
244 | while (fgets(buf, MAX_BUF,fp)) { | ||
245 | lineno++; | ||
246 | if (*buf == '#') // comments | ||
247 | continue; | ||
248 | |||
249 | // remove \n | ||
250 | char *ptr = strchr(buf, '\n'); | ||
251 | if (ptr) | ||
252 | *ptr = '\0'; | ||
253 | |||
254 | // do not accept .. and/or / in file name | ||
255 | if (strstr(buf, "..") || strchr(buf, '/')) { | ||
256 | fprintf(stderr, "Error: invalid line %d in %s\n", lineno, cfgfile); | ||
257 | exit(1); | ||
258 | } | ||
259 | |||
260 | set_file(buf, firejail_exec); | ||
261 | } | ||
262 | |||
263 | free(cfgfile); | ||
264 | free(firejail_exec); | ||
265 | } | ||
266 | |||
267 | int main(int argc, char **argv) { | ||
268 | int i; | ||
269 | |||
270 | for (i = 1; i < argc; i++) { | ||
271 | // default options | ||
272 | if (strcmp(argv[i], "--help") == 0 || | ||
273 | strcmp(argv[i], "-?") == 0) { | ||
274 | usage(); | ||
275 | return 0; | ||
276 | } | ||
277 | else if (strcmp(argv[i], "--version") == 0) { | ||
278 | printf("firecfg version %s\n\n", VERSION); | ||
279 | return 0; | ||
280 | } | ||
281 | else if (strcmp(argv[i], "--clear") == 0) { | ||
282 | clear(); | ||
283 | return 0; | ||
284 | } | ||
285 | else if (strcmp(argv[i], "--list") == 0) { | ||
286 | list(); | ||
287 | return 0; | ||
288 | } | ||
289 | else { | ||
290 | fprintf(stderr, "Error: invalid command line option\n"); | ||
291 | usage(); | ||
292 | return 1; | ||
293 | } | ||
294 | } | ||
295 | |||
296 | set(); | ||
297 | |||
298 | return 0; | ||
299 | } | ||
300 | |||