Codebase list firetools / 134a4c6
New upstream version 0.9.52 Reiner Herrmann 6 years ago
65 changed file(s) with 602 addition(s) and 376 deletion(s). Raw diff Collapse all Expand all
1010
1111 firetools_config_extras.h:
1212 echo "#define PACKAGE_LIBDIR \"$(DESTDIR)/$(PREFIX)/lib/firetools\"" > firetools_config_extras.h
13
13
1414 .PHONY: src
1515 src: firetools_config_extras.h
1616 $(MAKE) -C $@ $(MFLAGS)
3434 rm -fr autom4te.cache
3535 rm -f sanitizer.sh
3636
37
37
3838 realinstall:
3939 mkdir -p $(DESTDIR)/$(PREFIX)/bin
4040 mkdir -p $(DESTDIR)/$(PREFIX)/share/applications
5151 install -c -m 0644 src/firetools/firetools.desktop $(DESTDIR)/$(PREFIX)/share/applications/.
5252 install -c -m 0644 src/firejail-ui/firejail-ui.desktop $(DESTDIR)/$(PREFIX)/share/applications/.
5353 install -c -m 0644 src/firetools/resources/firetools.png $(DESTDIR)/$(PREFIX)/share/pixmaps/.
54 install -c -m 0644 src/firetools/resources/firetools-minimal.png $(DESTDIR)/$(PREFIX)/share/pixmaps/.
5455 install -c -m 0644 src/firejail-ui/resources/firejail-ui.png $(DESTDIR)/$(PREFIX)/share/pixmaps/.
5556 install -c -m 0644 COPYING $(DESTDIR)/$(DOCDIR)/.
5657 install -c -m 0644 README $(DESTDIR)/$(DOCDIR)/.
7374 rm -f $(DESTDIR)/$(PREFIX)/bin/firetools
7475 rm -f $(DESTDIR)/$(PREFIX)/bin/firejail-ui
7576 rm -f $(DESTDIR)/$(PREFIX)/share/pixmaps/firetools.png
77 rm -f $(DESTDIR)/$(PREFIX)/share/pixmaps/firetools-minimal.png
7678 rm -f $(DESTDIR)/$(PREFIX)/share/pixmaps/firejail-ui.png
7779 rm -f $(DESTDIR)/$(PREFIX)/share/applications/firetools.desktop
7880 rm -f $(DESTDIR)/$(PREFIX)/share/applications/firejail-ui.desktop
8789 mv config.status.old config.status
8890 rm -fr $(NAME)-$(VERSION) $(NAME)-$(VERSION).tar.xz
8991 mkdir $(NAME)-$(VERSION)
90 cd $(NAME)-$(VERSION); cp -a ../src .; cp -a ../platform .;
92 cd $(NAME)-$(VERSION); cp -a ../src .; rm -fr src/profile_editor; cp -a ../platform .;
9193 cd $(NAME)-$(VERSION); cp -a ../configure .; cp -a ../configure.ac .; cp -a ../Makefile.in .; cp -a ../install.sh .; cp -a ../mkdeb.sh .;cp -a ../mkask.sh .; cp -a ../mkman.sh .;cd ..
9294 cd $(NAME)-$(VERSION); cp -a ../COPYING .; cp -a ../README .; cp -a ../RELNOTES .; cd ..
9395 cd $(NAME)-$(VERSION); rm -fr `find . -name .svn`; rm -fr $(NAME)-$(VERSION); cd ..
1717 Firetools Authors:
1818
1919 netblue30 (netblue30@yahoo.com)
20 Daniel Schildt (https://github.com/d2s)
21 - ignore built packages in .gitignore
22 - grayscale icon for launcher
23 - fix/add comments throughout the code
24 - add more auto-detected apps
25 - improve visual style
26 - reduce margins, improve usability
27 - add signal-desktop icon
2028 Reiner Herrmann
2129 - Debian and Ubuntu integration
2230 - various fixes
2331 Warren Togami (https://github.com/wtogami)
2432 - rewrite of mkrpm.sh, Fedora packaging cleanup
2533 Piraty (https://github.com/Piraty)
26 - use system's icons when available
34 - use system's icons when available
2735 Topi Miettinen (https://github.com/topimiettinen)
2836 - change labels to black to be visible with dark themes and various other fixes
2937 dmio (https://github.com/dmio)
3139
3240 Terminal icon (gnome-terminal.png) taken from Gnome project, license LGPL v3 or CC BY-SA 3.0.
3341
34 Libreoffice-writer (libreoffice-writer.png) taken from Gnome project, license LGPL v3 or CC BY-SA 3.0.
42 Libreoffice-writer (libreoffice-writer.png) taken from LibreOffice project, license LGPL v3 (or later) or CC BY-SA 3.0 or MPL 1.1.
3543
3644 Icedove icon (icedove.png) taken from Debian project, license MPL 1.1 or GPL v2 or LGPL v2.1.
3745
3846 Firefox icon (firefox.png) taken from Firefox project, license MPL 2.0.
3947
4048 fmgr and firejail-ui icons (go_top.png, go_up.png, user-home.png, gnome-fs-directory.png, empty.png)
41 take from nuoveXT 2 project (http://gnome-look.org/content/show.php/nuoveXT+2?content=56625)
49 take from nuoveXT 2 project (http://gnome-look.org/content/show.php/nuoveXT+2?content=56625),
4250 license LGPL
4351
4452 fmgr and firejail-ui icons (emblem-symbolic-link.png, view-refresh.png) taken from Adwaita project
4553 (http://gnome-look.org/content/show.php/?content=144237), license GPL
4654
55
4756 Copyright (C) 2015 Firetools Authors
0 firetools (0.9.52) baseline; urgency=low
1 * modif: moving to a grayscale color scheme
2 * feature: firewall support in stats window
3 * feature: AppArmor support in stats window
4 * feature: adding Signal to the default list of applications
5 * bugfixes and various user interface improvements
6 -- netblue30 <netblue30@yahoo.com> Thu, 1 Mar 2018 13:00:00 -0500
7
08 firetools (0.9.50) baseline; urgency=low
19 * modif: removed the periodic window update for seccomp, caps,
210 and dns
3 * feature: memory deny exec stats support
11 * feature: memory deny exec stats support
412 * feature: print security profile name in stats window
513 * feature: protocol support in firejail-ui
614 * feature: nodvd support in firejail-ui
00 #! /bin/sh
11 # Guess values for system-dependent variables and create Makefiles.
2 # Generated by GNU Autoconf 2.69 for firetools 0.9.50.
2 # Generated by GNU Autoconf 2.69 for firetools 0.9.52.
33 #
44 # Report bugs to <netblue30@yahoo.com>.
55 #
579579 # Identity of this package.
580580 PACKAGE_NAME='firetools'
581581 PACKAGE_TARNAME='firetools'
582 PACKAGE_VERSION='0.9.50'
583 PACKAGE_STRING='firetools 0.9.50'
582 PACKAGE_VERSION='0.9.52'
583 PACKAGE_STRING='firetools 0.9.52'
584584 PACKAGE_BUGREPORT='netblue30@yahoo.com'
585585 PACKAGE_URL='http://firejail.wordpress.com'
586586
12491249 # Omit some internal or obsolete options to make the list less imposing.
12501250 # This message is too long to be a string in the A/UX 3.1 sh.
12511251 cat <<_ACEOF
1252 \`configure' configures firetools 0.9.50 to adapt to many kinds of systems.
1252 \`configure' configures firetools 0.9.52 to adapt to many kinds of systems.
12531253
12541254 Usage: $0 [OPTION]... [VAR=VALUE]...
12551255
13111311
13121312 if test -n "$ac_init_help"; then
13131313 case $ac_init_help in
1314 short | recursive ) echo "Configuration of firetools 0.9.50:";;
1314 short | recursive ) echo "Configuration of firetools 0.9.52:";;
13151315 esac
13161316 cat <<\_ACEOF
13171317
14051405 test -n "$ac_init_help" && exit $ac_status
14061406 if $ac_init_version; then
14071407 cat <<\_ACEOF
1408 firetools configure 0.9.50
1408 firetools configure 0.9.52
14091409 generated by GNU Autoconf 2.69
14101410
14111411 Copyright (C) 2012 Free Software Foundation, Inc.
17451745 This file contains any messages produced by compilers while
17461746 running configure, to aid debugging if configure makes a mistake.
17471747
1748 It was created by firetools $as_me 0.9.50, which was
1748 It was created by firetools $as_me 0.9.52, which was
17491749 generated by GNU Autoconf 2.69. Invocation command line was
17501750
17511751 $ $0 $@
44184418 # report actual input values of CONFIG_FILES etc. instead of their
44194419 # values after options handling.
44204420 ac_log="
4421 This file was extended by firetools $as_me 0.9.50, which was
4421 This file was extended by firetools $as_me 0.9.52, which was
44224422 generated by GNU Autoconf 2.69. Invocation command line was
44234423
44244424 CONFIG_FILES = $CONFIG_FILES
44724472 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
44734473 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
44744474 ac_cs_version="\\
4475 firetools config.status 0.9.50
4475 firetools config.status 0.9.52
44764476 configured by $0, generated by GNU Autoconf 2.69,
44774477 with options \\"\$ac_cs_config\\"
44784478
00 AC_PREREQ([2.68])
1 AC_INIT(firetools, 0.9.50, netblue30@yahoo.com, , http://firejail.wordpress.com)
1 AC_INIT(firetools, 0.9.52, netblue30@yahoo.com, , http://firejail.wordpress.com)
22 AC_CONFIG_SRCDIR([src/firetools/main.cpp])
33 #AC_CONFIG_HEADERS([config.h])
44
4444 #if test -f /usr/lib64/qt4/bin/qmake; then
4545 # QMAKE=/usr/lib64/qt4/bin/qmake
4646 #fi
47
47
4848 if test -z "$QMAKE"
4949 then
5050 AC_MSG_ERROR([qmake and/or Qt are missing, please install them.])
1919 mkdir -p $INSTALL_DIR
2020 cd $CODE_DIR
2121 ./configure --prefix=/usr
22 make -j2
22 make -j4
2323 DESTDIR=$INSTALL_DIR make install-strip
2424
2525 cd ..
4545 %{_mandir}/*
4646 %{_datadir}/applications/firetools.desktop
4747 %{_datadir}/pixmaps/firetools.png
48 %{_datadir}/pixmaps/firetools-minimal.png
4849
4950
5051 %changelog
00 #!/bin/bash
1 VER="0.9.50"
1 VER="0.9.52"
22
33 cd ~
44 rm -fr rpmbuild
2626 install -m 644 /usr/share/applications/firejail-ui.desktop firetools-$VER/usr/share/applications/.
2727
2828 mkdir -p firetools-$VER/usr/share/pixmaps
29 install -m 644 /usr/share/pixmaps/firetools-minimal.png firetools-$VER/usr/share/pixmaps/.
2930 install -m 644 /usr/share/pixmaps/firetools.png firetools-$VER/usr/share/pixmaps/.
31 install -m 644 /usr/share/pixmaps/firetools-minimal.png firetools-$VER/usr/share/pixmaps/.
3032 install -m 644 /usr/share/pixmaps/firejail-ui.png firetools-$VER/usr/share/pixmaps/.
3133
3234 mkdir -p firetools-$VER/usr/share/doc/firetools
8183 /usr/share/applications/firetools.desktop
8284 /usr/share/applications/firejail-ui.desktop
8385 /usr/share/pixmaps/firetools.png
86 /usr/share/pixmaps/firetools-minimal.png
8487 /usr/share/pixmaps/firejail-ui.png
8588 /usr/lib/firetools/fmgr
8689 /usr/lib/firetools/fstats
8891 /usr/lib/firetools/uimenus
8992
9093 %changelog
94
95 * Fri Mar 2 2018 netblue30 <netblue30@yahoo.com> 0.9.52-1
9196
9297 * Mon Oct 2 2017 netblue30 <netblue30@yahoo.com> 0.9.50-1
9398
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
11 <qresource prefix="/">
22 <file>resources/background.png</file>
33 <file>resources/firetools.png</file>
4 <file>resources/firetools-minimal.png</file>
45 <file>resources/firejail-ui.png</file>
56 <file>resources/gnome-fs-directory.png</file>
67 </qresource>
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
9595
9696 if (arg_debug)
9797 printf("Linux kernel version %d.%d\n", kernel_major, kernel_minor);
98
98
9999 // initialize resources
100100 //Q_INIT_RESOURCE(firejail-ui);
101101
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
2929
3030 Application::Application(const char *name, const char *description, const char *exec, const char *icon):
3131 name_(name), description_(description), exec_(exec), icon_(icon) {
32
32
3333 app_icon_ = loadIcon(icon_);
3434 };
3535
3636 Application::Application(QString name, QString description, QString exec, QString icon):
3737 name_(name), description_(description), exec_(exec), icon_(icon) {
38
38
3939 app_icon_ = loadIcon(icon_);
4040 };
4141
42 // load an application from a desktop file
42 // Load an application from a desktop file
4343 Application::Application(const char *name):
4444 name_(name), description_("unknown"), exec_("unknown"), icon_("unknown") {
4545
4949 char *fname = get_config_file_name(name);
5050 if (!fname)
5151 return;
52
52
5353 if (arg_debug)
5454 printf("loading %s\n", fname);
5555
6060 return;
6161 }
6262 free(fname);
63
63
6464 // read file
65 #define MAXBUF 10000
65 #define MAXBUF 10000
6666 char buf[MAXBUF];
6767 while (fgets(buf, MAXBUF, fp)) {
6868 // remove '\n'
6969 char *ptr = strchr(buf, '\n');
7070 if (ptr)
7171 *ptr = '\0';
72
72
7373 // skip blancs
7474 char *start = buf;
7575 while (*start == ' ' || *start == '\t')
7676 start++;
77
77
7878 // parse
7979 if (strncmp(buf, "Comment=", 8) == 0)
8080 description_ = buf + 8;
8888 app_icon_ = loadIcon(icon_);
8989 }
9090
91 // Save the app's configuration
9192 int Application::saveConfig() {
9293 char *fname = get_config_file_name(name_.toLocal8Bit().constData());
9394 if (!fname)
9495 return 1;
95
96 // open file
96
97 // Open a file
9798 FILE *fp = fopen(fname, "w");
9899 if (!fp) {
99100 free(fname);
107108 fprintf(fp, "Icon=%s\n", icon_.toLocal8Bit().constData());
108109 fprintf(fp, "Exec=%s\n", exec_.toLocal8Bit().constData());
109110 fclose(fp);
110
111
111112 return 0;
112113 }
113114
114115 /*
115116 From: http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html
116117
117 Icons and themes are looked for in a set of directories. By default, apps should look
118 Icons and themes are looked for in a set of directories. By default, apps should look
118119 in $HOME/.icons (for backwards compatibility), in $XDG_DATA_DIRS/icons and in /
119 usr/share/pixmaps (in that order). Applications may further add their own icon
120 directories to this list, and users may extend or change the list (in application/desktop
121 specific ways).In each of these directories themes are stored as subdirectories.
122 A theme can be spread across several base directories by having subdirectories of
120 usr/share/pixmaps (in that order). Applications may further add their own icon
121 directories to this list, and users may extend or change the list (in application/desktop
122 specific ways).In each of these directories themes are stored as subdirectories.
123 A theme can be spread across several base directories by having subdirectories of
123124 the same name. This way users can extend and override system themes.
124125
125 In order to have a place for third party applications to install their icons there
126 should always exist a theme called "hicolor" [1]. The data for the hicolor theme is
126 In order to have a place for third party applications to install their icons there
127 should always exist a theme called "hicolor" [1]. The data for the hicolor theme is
127128 available for download at: http://www.freedesktop.org/software/icon-theme/. I
128 mplementations are required to look in the "hicolor" theme if an icon was not found
129 in the current theme.
129 mplementations are required to look in the "hicolor" theme if an icon was not found
130 in the current theme.
130131 */
131132
132 // compare strings
133 // compare strings
133134 static inline bool compare_ignore_case(QString q1, QString q2) {
134135 q1 = q1.toLower();
135136 q2 = q2.toLower();
158159 QPixmap pix = icon.pixmap(sz.height(), sz.width());
159160 QPixmap pixin;
160161 int delta = 0;
161
162
162163 if (sz.height() == sz.width() && sz.height() <= 40) {
163164 pixin = pix.scaled(40, 40);
164165 delta = 12;
165166 }
166 else {
167 else {
167168 pixin = pix.scaled(48, 48);
168169 delta = 8;
169170 }
170
171
171172
172173 QPixmap pixout(64, 64);
173174 pixout.fill(QColor(0, 0, 0, 0));
176177 if (arg_debug)
177178 printf("\t- output pixmap: w %d, h %d\n", pixout.width(), pixout.height());
178179 paint->end();
179 return QIcon(pixout);
180 return QIcon(pixout);
180181 }
181182
182183 QIcon Application::loadIcon(QString name) {
183184 if (arg_debug)
184185 printf("searching icon %s\n", name.toLocal8Bit().data());
185
186
186187 if (name == ":resources/fstats" || name == ":resources/firejail-ui") {
187188 if (arg_debug)
188189 printf("\t- resource\n");
189190 return QIcon(name); // not resized, using the real 64x64 size
190191 }
191
192
192193 if (name.startsWith(":resources")) {
193194 if (arg_debug)
194195 printf("\t- resource\n");
195196 return resize48x48(QIcon(name));
196197 }
197
198
198199 if (name.startsWith('/')) {
199200 if (arg_debug)
200201 printf("\t- full path\n");
203204
204205
205206
206 // look for the file in firejail config directory under /home/user
207 // Look for the file in Firejail config directory under /home/user
207208 QString conf = QDir::homePath() + "/.config/firetools/" + name + ".png";
208209 QFileInfo checkFile1(conf);
209210 if (checkFile1.exists() && checkFile1.isFile()) {
241242 if (!qstr.isEmpty())
242243 return resize48x48(QIcon(qstr));
243244 }
244
245
245246 {
246247 QString qstr = walk("/usr/share/icons/hicolor/128x128", name);
247248 if (!qstr.isEmpty())
248249 return resize48x48(QIcon(qstr));
249250 }
250
251
251252 {
252253 QString qstr = walk("/usr/share/icons/hicolor/256x256", name);
253254 if (!qstr.isEmpty())
254255 return resize48x48(QIcon(qstr));
255256 }
256257
257 {
258 {
258259 QDirIterator it("/usr/share/pixmaps", QDirIterator::Subdirectories);
259260 while (it.hasNext()) {
260261 it.next();
266267 return resize48x48(icon);
267268 }
268269 }
269 }
270
270 }
271
271272 if (QIcon::hasThemeIcon(name)) {
272273 if (arg_debug)
273274 printf("\t- fromTheme\n");
280281 return resize48x48(QIcon(qstr));
281282 }
282283
283
284
284285 // we failed to get an icon so far, look all over /usr/share/icons directory
285286 {
286287 QString qstr = walk("/usr/share/icons", name);
288289 return resize48x48(QIcon(qstr));
289290 }
290291
291 // create a new icon
292
293 // Create a new icon
292294 if (arg_debug)
293295 printf("\t- created\n");
296
297 // Create a new QPixmap instance for icons
294298 QPixmap pix(64, 64);
295 pix.fill(Qt::red);
299
300 // Set the background color for generated icons
301 QColor iconBackgroundColor(68, 68, 68);
302
303 // Fill the icon with a color
304 pix.fill(iconBackgroundColor);
305
306
307 // Create a QPainter instance
296308 QPainter painter( &pix );
309
310 // Set color and font for the painter
297311 painter.setPen(Qt::white);
298312 painter.setFont(QFont("Sans"));
313
314 // Draw application's name to the icon
299315 painter.drawText(3, 20, name);
300316 painter.end();
317
318 // Use generated pixmap as an icon
301319 QIcon icon(pix);
320
302321 return icon;
303322 }
304323
305324
325 // Default application configurations for the app launcher
306326 struct DefaultApp {
307327 const char *name;
308328 const char *alias;
312332 };
313333
314334 DefaultApp dapps[] = {
315 // firetools
335 // Firetools
316336 { "firetools", "", "Firetools", PACKAGE_LIBDIR "/fstats", ":resources/fstats" },
317337 { "firejail-ui", "", "Firejail Configuration Wizard", "firejail-ui", ":resources/firejail-ui" },
318
319 // browser
338
339 // Web browsers
320340 { "iceweasel", "", "Debian Iceweasel", "firejail iceweasel", ":resources/firefox" },
321341 { "firefox", "iceweasel", "Mozilla Firefox", "firejail firefox", ":resources/firefox"},
322342 { "icecat", "firefox", "GNU IceCat", "firejail icecat", ":resources/firefox"},
323343 { "chromium", "", "Chromium Web Browser", "firejail chromium", "chromium"},
324344 { "chromium-browser", "chromium", "Chromium Web Browser", "firejail chromium-browser", "chromium-browser"},
345 { "google-chrome", "", "Google Chrome", "firejail google-chrome", "google-chrome"},
325346 { "midori", "", "Midori Web Browser", "firejail midori", "midori" },
326347 { "opera", "", "Opera Web Browser", "firejail opera", "opera" },
327348 { "netsurf", "", "Netsurf Web Browser", "firejail netsurf", "netsurf" },
328349
329 // mail
350 // Email clients
330351 { "icedove", "", "Debian Icedove", "firejail icedove", ":resources/icedove" },
331352 { "thunderbird", "icedove","Thunderbird", "firejail thunderbird", "thunderbird" },
332353
333 // bittorrent
354 // Bittorrent
334355 { "transmission-gtk", "", "Transmission BitTorrent Client", "firejail transmission-gtk", "transmission" },
335356 { "transmission-qt", "transmission-gtk", "Transmission BitTorrent Client", "firejail transmission-qt", "transmission" },
336357 { "deluge", "", "Deluge BitTorrent Client", "firejail deluge", "deluge" },
337358 { "qbittorrent", "", "qBittorrent Client", "firejail qbittorrent", "qbittorrent" },
338359
339 // viewers
360 // Viewers
340361 { "evince", "", "Evince PDF viewer", "firejail evince", "evince" },
341362 { "qpdfview", "", "qPDFView", "firejail qpdfview", "qpdfview" },
342363 { "xpdf", "", "Xpdf", "firejail xpdf", "xpdf" },
353374 { "calibre", "", "Calibre eBook reader", "firejail calibre", "/usr/share/calibre/images/lt.png" },
354375 { "xreader", "", "xreader", "firejail xreader", "xreader" },
355376
356 // media players, audio/video tools
377 // Media players, audio/video tools
357378 { "xplayer", "", "xplayer", "firejail xplayer", "xplayer" },
358379 { "vlc", "", "VideoLAN Client", "firejail vlc", "vlc" },
359380 { "amarok", "", "Amarok", "firejail amarok", "amarok" },
360 { "dragon", "", "Dragom Player", "firejail dragon", "dragonplayer" },
381 { "dragon", "", "Dragon Player", "firejail dragon", "dragonplayer" },
361382 { "rhythmbox", "", "Rhythmbox", "firejail rhythmbox", "rhythmbox" },
362383 { "totem", "", "Totem", "firejail totem", "totem" },
363384 { "audacious", "", "Audacious", "firejail audacious", "audacious" },
370391 { "ghb", "", "HandBrake", "firejail ghb", "hb-icon" },
371392 { "audacity", "", "Audacity", "firejail audacity", "audacity" },
372393
373 // editor
394 // Editors
374395 { "gimp", "", "Gimp", "firejail gimp", "gimp" },
375396 { "inkscape", "", "Inkscape", "firejail inkscape", "inkscape" },
376397 { "openshot", "", "OpenShot video editor", "firejail openshot", "openshot" },
378399 { "lowriter", "", "LibreOffice Writer", "firejail lowriter", ":resources/libreoffice-writer.png" },
379400
380401
381 // chat
402 // Chat
403 { "signal-desktop", "", "Signal", "firejail signal-desktop", ":resources/signal-desktop.png" },
382404 { "pidgin", "", "Pidgin", "firejail pidgin", "pidgin" },
383405 { "xchat", "", "XChat", "firejail xchat", "xchat" },
384406 { "hexchat", "", "HexChat", "firejail hexchat", "hexchat" },
385407 { "quassel", "", "Quassel IRC", "firejail quassel", "quassel" },
386408 { "empathy", "", "Empathy", "firejail empathy", "empathy" },
387
388 // etc
409
410 // Etc
389411 { "filezilla", "", "FileZilla", "firejail filezilla", "filezilla" },
390412 { "xterm", "", "xterm", "firejail xterm", ":resources/gnome-terminal.png" },
391413 { "urxvt", "", "rxvt-unicode", "firejail urxvt", "urxvt" },
392
393 // games
414
415 // Pw managers
416 { "keepass", "", "keepass", "firejail keepass", "keepass" },
417 { "keepass2", "", "keepass2", "firejail keepass2", "keepass2" },
418 { "keepassx", "", "keepassx", "firejail keepassx", "keepassx" },
419 { "keepassx2", "", "keepassx2", "firejail keepassx2", "keepassx2" },
420 { "keepassxc", "", "keepassxc", "firejail keepassxc", "keepassxc" },
421
422 // Games
394423 { "0ad", "", "0AD", "firejail 0ad", "0ad" },
395424 { "warzone2100", "", "Warzone 2100", "firejail warzone2100", "warzone2100" },
396425 { "etr", "", "Extreme Tux Racer", "firejail etr", "etr" },
398427 { "frozen-bubble", "", "Frozen-Bubble", "firejail frozen-bubble", "frozen-bubble" },
399428 { "2048-qt", "", "2048", "firejail 2048-qt", "2048-qt" },
400429 { "pingus", "", "Pingus", "firejail pingus", "pingus" },
401
430
402431 { 0, 0, 0, 0, 0 }
403432 };
404433
409438 return true;
410439 app++;
411440 }
412
441
413442 return false;
414443 }
415444
419448 if (it->name_ == name)
420449 return true;
421450 }
422
451
423452 return false;
424453 }
425454
440469
441470 void applications_init() {
442471 // load default apps
472 if (arg_debug)
473 printf("Loading default applications\n");
474
443475 DefaultApp *app = &dapps[0];
444476 while (app->name != 0) {
445 // de we have the program?
477 if (arg_debug)
478 printf("checking %s\n", app->name);
479
480 // do we have the program?
446481 if (which(app->name) == false) {
447482 app++;
448 continue;
449 }
450
483 continue;
484 }
485
451486 // is there an alias?
452487 if (*app->alias != '\0' && which(app->alias)) {
453488 app++;
454489 continue;
455490 }
456
491
457492 // is there a user config file?
458493 if (have_config_file(app->name))
459494 applist.append(Application(app->name));
462497
463498 app++;
464499 }
465
500
466501 // load user apps from home directory
467502 char *home = get_home_directory();
468503 if (!home)
476511 free(homecfg);
477512 return;
478513 }
479
514
480515 // walk home config directory
481516 struct dirent *entry;
482517 while ((entry = readdir(dir))) {
484519 continue;
485520 if (strcmp(entry->d_name, "..") == 0)
486521 continue;
487
522
488523 // look only at .desktop files
489524 int len = strlen(entry->d_name);
490525 if (len <= 8)
497532 free(fname);
498533 continue;
499534 }
500
535
501536 // check if the app is in default list
502537 fflush(0);
503538 *ending = '\0';
507542 if (strcmp(fname, app->name) == 0) {
508543 found = true;
509544 }
510
545
511546 app++;
512547 }
513548 if (found) {
514549 free(fname);
515550 continue;
516551 }
517
552
518553 // load file
519554 applist.append(Application(fname));
520555 free(fname);
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
2323 #include <QIcon>
2424
2525 #define TOP 10
26 #define MARGIN 5
26 #define MARGIN 2
2727 #define AFRAMES 6 // animation frames
2828 #define ADELAY 20 // animation delay
2929 #define ROWS 6
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
3434
3535
3636 EditDialog::EditDialog(QString name, QString desc, QString cmd): QDialog() {
37 // editing
37 // Editing
3838 QLabel *lname = new QLabel;
3939 lname->setText(tr("Name"));
4040 name_ = new QLineEdit;
5252 cmd_ = new QLineEdit;
5353 cmd_->setText(cmd);
5454
55 // buttons
55 // Buttons
5656 QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok
5757 | QDialogButtonBox::Cancel);
5858 connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
6565 QLabel *icon_txt3 = new QLabel("You can supply your own icon by placing it in ~/.config/firetools.");
6666
6767
68 // layout- editing
68 // Layout - editing
6969 QGridLayout *layout = new QGridLayout;
7070 layout->addItem(new QSpacerItem(30, 15), 0, 0);
7171 layout->addItem(new QSpacerItem(300, 15), 0, 2);
7777 layout->addWidget(lcmd, 3, 1);
7878 layout->addWidget(cmd_, 3, 2);
7979
80 // icon note
80 // Icon note
8181 layout->addItem(new QSpacerItem(10,20), 4, 0);
8282 layout->addWidget(icon_txt1, 5, 1, 1, 2);
8383 layout->addWidget(icon_txt2, 6, 1, 1, 2);
8484 layout->addWidget(icon_txt3, 7, 1, 1, 2);
8585 layout->addItem(new QSpacerItem(30, 15), 8, 0);
8686
87 // layout - buttons
87 // Layout - buttons
8888 layout->addItem(new QSpacerItem(30, 30), 9, 0);
8989 layout->addWidget(helpButton, 10, 1);
9090 layout->addWidget(buttonBox, 10, 2);
9494 setWindowTitle(tr("Edit Sandbox"));
9595 }
9696
97 // Help dialog
9798 void EditDialog::help() {
9899 QMessageBox msgBox;
99100
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 <!DOCTYPE RCC><RCC version="1.0">
11 <qresource prefix="/">
22 <file>resources/firetools.png</file>
3 <file>resources/firetools-minimal.png</file>
34 <file>resources/fstats.png</file>
45 <file>resources/firejail-ui.png</file>
56 <file>resources/icedove.png</file>
67 <file>resources/firefox.png</file>
78 <file>resources/libreoffice-writer.png</file>
89 <file>resources/gnome-terminal.png</file>
10 <file>resources/signal-desktop.png</file>
911 </qresource>
1012 </RCC>
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
4141 "Categories=Qt;System;Security;\n";
4242
4343
44 // Usage instructions for the command line output
4445 static void usage() {
4546 printf("firetools - Firejail tools and stats utility\n\n");
4647 printf("Usage: firetools [options]\n\n");
5657 int main(int argc, char *argv[]) {
5758 int arg_minimize = 0;
5859
59 // parse arguments
60 // Parse arguments
6061 for (int i = 1; i < argc; i++) {
6162 if (strcmp(argv[i], "--debug") == 0)
6263 arg_debug = 1;
6970 return 0;
7071 }
7172 else if (strcmp(argv[i], "--autostart") == 0) {
72 // find jome directory
73 // Find home directory
7374 char *home = get_home_directory();
7475 if (!home) {
7576 fprintf(stderr, "Error: cannot find user home directory");
7677 return 1;
7778 }
7879
79 // create a .config/autostart directory if it doesn't exist
80 // Create a .config/autostart directory if it doesn't exist
8081 char *autodir;
8182 if (asprintf(&autodir, "%s/.config/autostart", home) == -1)
8283 errExit("asprintf");
8384 int rv = mkdir(autodir, 0755);
8485 (void) rv;
8586
86 // create desktop file
87 // Create desktop file
8788 char *autofile;
8889 if (asprintf(&autofile, "%s/.config/autostart/firetools.desktop", home) == -1)
8990 errExit("asprintf");
108109
109110 #if QT_VERSION >= 0x050000
110111 struct stat s;
111 // test run time dependencies - print warning and continue program
112 // Test run time dependencies - print warning and continue program
112113 QString ppath = QLibraryInfo::location(QLibraryInfo::PluginsPath);
113114 ppath += "/imageformats/libqsvg.so";
114115 if (stat(ppath.toUtf8().constData(), &s) == -1) {
117118 }
118119 #endif
119120
120 // test run time dependencies - exit
121 // Test run time dependencies - exit
121122 if (!which("firejail")) {
122123 fprintf(stderr, "Error: firejail package not found, please install it!\n");
123124 exit(1);
124125 }
125126
126 // create firetools directory if it doesn't exist
127 // Create firetools directory if it doesn't exist
127128 create_config_directory();
128129
129 // initialize resources
130 // Initialize resources
130131 Q_INIT_RESOURCE(firetools);
131132
132133 QApplication app(argc, argv);
134135 if (!arg_minimize)
135136 fc.show();
136137
137 // configure system tray
138 QSystemTrayIcon icon(QIcon(":resources/firetools.png"));
138 // Configure system tray
139 QSystemTrayIcon icon(QIcon(":resources/firetools-minimal.png"));
139140 icon.show();
140141 icon.setToolTip("Firetools (click to open)");
141142 QMenu *trayIconMenu = new QMenu(&fc);
146147 icon.setContextMenu(trayIconMenu);
147148 icon.connect(&icon, SIGNAL(activated(QSystemTrayIcon: :ActivationReason)), &fc, SLOT(trayActivated(QSystemTrayIcon: :ActivationReason)));
148149
149 // direct all errror to /dev/null to work around this qt bug:
150 // Direct all errror to /dev/null to work around this qt bug:
150151 // https://bugreports.qt.io/browse/QTBUG-43270
151152 FILE *rv = NULL;
152153 if (!arg_debug) {
154155 (void) rv;
155156 }
156157
157 // start application
158 // Start application
158159 int tmp = app.exec();
159160 (void) tmp;
160161
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
7373 "Drag the launcher with the left mouse button.\n"
7474 "Use the right mouse button to open a context menu."));
7575 setWindowTitle(tr("Firelauncher"));
76
76
7777 }
7878
7979 void MainWindow::edit() {
8080 if (edit_index_ != -1) {
8181 EditDialog *edit;
82
82
8383 // new entry
8484 if (active_index_ == -1) {
8585 edit = new EditDialog("", "", "");
9898 else
9999 QMessageBox::critical(this, tr("Firejail Tools"),
100100 tr("<br/>Sandbox already defined.<br/><br/><br/>"));
101
102101 }
103102 }
104
103
105104 // existing entry
106105 else {
107106 //printf("%s\n", applist[active_index_].exec_.toLocal8Bit().constData());
114113 }
115114 }
116115 delete edit;
117
116
118117 // update
119118 hide();
120119 show();
122121 }
123122 }
124123
124 // Remove application from the list
125125 void MainWindow::remove() {
126 //printf("line %d, active index %d, name %s\n", __LINE__, active_index_,
126 //printf("line %d, active index %d, name %s\n", __LINE__, active_index_,
127127 // applist[active_index_].name_.toLocal8Bit().constData());
128128
129129 char *fname = get_config_file_name(applist[active_index_].name_.toLocal8Bit().constData());
134134 printf("Application removed:\n");
135135 applist_print();
136136 }
137
137
138138 // update
139139 hide();
140140 show();
144144 }
145145
146146
147 // Run application
147148 void MainWindow::run() {
148149 int index = active_index_;
149150 if (index != -1) {
151152 int rv = system(exec.toStdString().c_str());
152153 (void) rv;
153154 }
154
155
155156 animation_id_ = AFRAMES;
156157 QTimer::singleShot(0, this, SLOT(update()));
157158 }
158159
160 // Run statistics tools
159161 void MainWindow::runTools() {
160162 // start fstats as a separate process
161163 int rv = system(PACKAGE_LIBDIR "/fstats &");
162164 (void) rv;
163165 }
164166
167 // Start firejail-ui
165168 void MainWindow::newSandbox() {
166169 // start firejail-ui as a separate process
167170 int rv = system("firejail-ui &");
168171 (void) rv;
169172 }
170173
174 // About window
171175 void MainWindow::runAbout() {
172176 QString msg = "<table cellpadding=\"10\"><tr><td><img src=\":/resources/firetools.png\"></td>";
173177 msg += "<td>" + tr(
174
178
175179 "Firetools is a GUI application for Firejail. "
176180 "It offers a system tray launcher for sandboxed apps, "
177181 "sandbox editing, management, and statistics. "
179183
180184 "Firejail is a SUID sandbox program that reduces the risk of security "
181185 "breaches by restricting the running environment of untrusted applications "
182 "using Linux namespaces, Linux capabilities and seccomp-bpf.<br/><br/>") +
186 "using Linux namespaces, Linux capabilities and seccomp-bpf.<br/><br/>") +
183187 tr("Firetools version:") + " " + PACKAGE_VERSION + "<br/>" +
184188 tr("QT version: ") + " " + QT_VERSION_STR + "<br/>" +
185189 tr("License:") + " GPL v2<br/>" +
188192 QMessageBox::about(this, tr("About"), msg);
189193 }
190194
195 // Mouse events: mouse release
191196 void MainWindow::mouseReleaseEvent(QMouseEvent *event) {
192197 int nelem = applist.count();
193198 int cols = nelem / ROWS + 1;
196201 int x = event->pos().x();
197202 int y = event->pos().y();
198203
199 if (x >= MARGIN * 2 + cols * 64 - 8 && x <= MARGIN * 2 + cols * 64 + 4 &&
204 if (x >= MARGIN * 2 + cols * 64 - 16 && x <= MARGIN * 2 + cols * 64 + 4 &&
200205 y >= 4 && y <= 15) {
201206
202207 showMinimized();
206211 }
207212 }
208213
214 // Mouse events: mouse press
209215 void MainWindow::mousePressEvent(QMouseEvent *event) {
210216 if (event->button() == Qt::LeftButton) {
211217 dragPosition_ = event->globalPos() - frameGeometry().topLeft();
237243 }
238244
239245
246 // Mouse events
240247 void MainWindow::mouseMoveEvent(QMouseEvent *event) {
241248 if (event->buttons() & Qt::LeftButton) {
242249 move(event->globalPos() - dragPosition_);
244251 }
245252 }
246253
247
254 // Mouse events: double-click
248255 void MainWindow::mouseDoubleClickEvent(QMouseEvent *event) {
249256 if (event->button() == Qt::LeftButton) {
250257 QPoint pos = event->pos();
261268 }
262269 }
263270
271 // Main window visual design
264272 void MainWindow::paintEvent(QPaintEvent *) {
273 // Count the number applications and put the value to the variable
265274 int nelem = applist.count();
275
276 // Columns is the amount of applications divided by number of rows + 1
266277 int cols = nelem / ROWS + 1;
267278
279 // Start painting
268280 QPainter painter(this);
269281 painter.setRenderHint(QPainter::Antialiasing);
282
283 // Window size hint
270284 QSize sz = sizeHint();
271 painter.fillRect(QRect(0, 0, sz.width(), sz.height()), QBrush(QColor(255, 20, 20)));
272
285
286 // Window rectangle size coordinates
287 QRect windowRectSize(0, 0, sz.width(), sz.height());
288
289 // Background color for the main window
290 // (dark gray)
291 QBrush windowBackgroundColor(QColor(68, 68, 68));
292
293 // Fills the given rectangle with the specified color values.
294 // https://doc.qt.io/qt-5.10/qpainter.html#drawRect
295 painter.fillRect(windowRectSize, windowBackgroundColor);
296
297 // Loop icons to rows
273298 int i = 0;
274299 int j = 0;
275300 for (; i < nelem; i++, j++) {
276301 if (j >= ROWS)
277302 j = 0;
278
303
304 // Select icon from the looped items
279305 QIcon icon = applist[i].app_icon_;
306
280307 int sz = 64 ;
281308 if (active_index_ == i)
282309 sz -= animation_id_ * 3;
283
284 QPixmap pixmap = icon.pixmap(QSize(sz, sz), QIcon::Normal, QIcon::On);
285 painter.drawPixmap(QPoint(MARGIN * 2 + (64 - sz) / 2 + (i / ROWS) * 64, MARGIN *2 + j * 64 + TOP + (64 - sz) / 2), pixmap);
286 }
287
288 // vertical bars
289 QPen pen1(Qt::black);
290 painter.setPen(pen1);
291 for (i = 0; i < cols; i++) {
292 painter.drawLine(MARGIN * 2 + i * 64 + 21, MARGIN * 2 + TOP, MARGIN * 2 + i * 64 + 21, MARGIN * 2 + ROWS * 64 + TOP);
293 painter.drawLine(MARGIN * 2 + i * 64 + 43, MARGIN * 2 + TOP, MARGIN * 2 + i * 64 + 43, MARGIN * 2 + ROWS * 64 + TOP);
294 painter.drawLine(MARGIN * 2 + i * 64 + 64, MARGIN * 2 + TOP, MARGIN * 2 + i * 64 + 64, MARGIN * 2 + ROWS * 64 + TOP);
295 }
296
297 // horizontal bars
298 for (i = 0; i < ROWS - 1; i++) {
299 painter.drawLine(MARGIN * 2, MARGIN * 2 + 64 * (i + 1) - 1 + TOP,
300 MARGIN * 2 + 64 * cols, MARGIN * 2 + 64 * (i + 1) - 1 + TOP);
301
302 }
303
304 // close button
305 painter.fillRect(QRect(MARGIN * 2 + cols * 64 - 8, 8, 12, 3), QBrush(Qt::white));
306
307
310
311
312 // More details and examples:
313 // - https://doc.qt.io/qt-5.10/qpainter.html#drawPixmap
314
315 // Target
316 int pixmapTargetXposition = MARGIN * 2 + (64 - sz) / 2 + (i / ROWS) * 64;
317 int pixmapTargetYposition = MARGIN *2 + j * 64 + TOP + (64 - sz) / 2;
318
319 QPoint pixmapTarget(pixmapTargetXposition, pixmapTargetYposition);
320
321 // Source
322 int pixmapWidth = sz;
323 int pixmapHeight = sz;
324
325 QSize pixmapSize(pixmapWidth, pixmapHeight);
326
327 // "The QPixmap class is an off-screen image representation that can be used as a paint device."
328 // - https://doc.qt.io/qt-5.10/qpixmap.html
329 // "Returns a pixmap with the requested size, mode, and state,"
330 // - https://doc.qt.io/qt-5.10/qicon.html#pixmap
331 QPixmap pixmap = icon.pixmap(pixmapSize, QIcon::Normal, QIcon::On);
332
333
334 // Paint pixmap items
335 painter.drawPixmap(pixmapTarget, pixmap);
336 }
337
338
339 // Close button
340 // Rectangle size & coordinates for the close button
341 // QRect closeButtonRectSize(MARGIN * 2 + cols * 64 - 8, 8, 12, 3);
342 QRect closeButtonRectSize(MARGIN * 2 + cols * 64 - 14,6, 12, 3);
343
344 // Color for the close button
345 QBrush closeButtonRectColor(Qt::white);
346
347 // Fills the given rectangle with the color
348 painter.fillRect(closeButtonRectSize, closeButtonRectColor);
349
350
351 // Default font
308352 painter.setFont(QFont("Sans", TOP, QFont::Normal));
309 // QPen pen2(Qt::white);
310 // painter.setPen(pen2);
311 // painter.drawText(MARGIN * 2, TOP + MARGIN / 2, "Firetools");
312
353
354 // Animation timer detay if animations are enabled
313355 if (animation_id_ > 0) {
314356 animation_id_--;
315357 QTimer::singleShot(ADELAY, this, SLOT(update()));
316358 }
317
318
319 }
320
321
359 }
360
361
362 // Window resize
322363 void MainWindow::resizeEvent(QResizeEvent * /* event */) {
323364 int nelem = applist.count();
324365 int cols = nelem / ROWS + 1;
325
366
326367 // margins
327368 QRegion m1(0, 0, cols * 64 + MARGIN * 4, TOP + ROWS * 64 + MARGIN * 4);
328369 QRegion m2(MARGIN, MARGIN + TOP, cols * 64 + MARGIN * 2, ROWS * 64 + MARGIN * 2);
329370 QRegion m3(MARGIN * 2, MARGIN * 2 + TOP, cols * 64, ROWS * 64);
330
371
331372 QRegion all = m1.subtracted(m2);
332373 all = all.united(m3);
333
374
334375 setMask(all);
335376 }
336377
337378
338 QSize MainWindow::sizeHint() const
339 {
379 // Window size hint
380 QSize MainWindow::sizeHint() const {
340381 int nelem = applist.count();
341382 int cols = nelem / ROWS + 1;
342
383
343384 return QSize(64 * cols + MARGIN * 4, ROWS * 64 + MARGIN * 4 + TOP);
344385 }
345386
347388 bool MainWindow::event(QEvent *event) {
348389 if (event->type() == QEvent::ToolTip) {
349390 QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
350
391
351392 int index = applications_get_index(helpEvent->pos());
352393 if (index == -1) {
353394 int x = helpEvent->pos().x();
354395 int y = helpEvent->pos().y();
355396 int nelem = applist.count();
356397 int cols = nelem / ROWS + 1;
357
398
358399 if (x >= MARGIN * 2 + cols * 64 - 8 && x <= MARGIN * 2 + cols * 64 + 4 &&
359400 y >= 4 && y <= 15) {
360401 QToolTip::showText(helpEvent->globalPos(), QString("Minimize"));
365406 QToolTip::showText(helpEvent->globalPos(), QString("Run tools"));
366407 return true;
367408 }
368
409
369410 else
370411 QToolTip::hideText();
371412 }
455496 addAction(qquit);
456497 }
457498
499 // Help dialog
458500 void MainWindow::help() {
459501 QMessageBox msgBox;
460
502
461503 QString txt;
462504 txt += "<br/>";
463505 txt += "Click on \"Firetools\" in the left top corner to open the tools window.<br/>\n";
481523 QMessageBox::about(this, tr("Firejail Launcher"), txt);
482524 }
483525
526 // Shutdown sequence
484527 void MainWindow::main_quit() {
485528 printf("exiting...\n");
486529
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
0 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
1 <!-- Created with Inkscape (http://www.inkscape.org/) -->
2
3 <svg
4 xmlns:dc="http://purl.org/dc/elements/1.1/"
5 xmlns:cc="http://creativecommons.org/ns#"
6 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
7 xmlns:svg="http://www.w3.org/2000/svg"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
10 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
11 width="210mm"
12 height="297mm"
13 viewBox="0 0 210 297"
14 version="1.1"
15 id="svg8"
16 inkscape:version="0.92.1 r15371"
17 sodipodi:docname="signal.svg"
18 inkscape:export-filename="/home/netblue/work/github/firetools/src/firetools/resources/signal.svg.png"
19 inkscape:export-xdpi="97.366898"
20 inkscape:export-ydpi="97.366898">
21 <defs
22 id="defs2" />
23 <sodipodi:namedview
24 id="base"
25 pagecolor="#ffffff"
26 bordercolor="#666666"
27 borderopacity="1.0"
28 inkscape:pageopacity="0.0"
29 inkscape:pageshadow="2"
30 inkscape:zoom="1.0824912"
31 inkscape:cx="174.23932"
32 inkscape:cy="330.41888"
33 inkscape:document-units="mm"
34 inkscape:current-layer="layer1"
35 showgrid="false"
36 inkscape:window-width="1280"
37 inkscape:window-height="976"
38 inkscape:window-x="0"
39 inkscape:window-y="0"
40 inkscape:window-maximized="1" />
41 <metadata
42 id="metadata5">
43 <rdf:RDF>
44 <cc:Work
45 rdf:about="">
46 <dc:format>image/svg+xml</dc:format>
47 <dc:type
48 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
49 <dc:title />
50 </cc:Work>
51 </rdf:RDF>
52 </metadata>
53 <g
54 inkscape:label="Layer 1"
55 inkscape:groupmode="layer"
56 id="layer1">
57 <rect
58 style="opacity:1;fill:#118eed;fill-opacity:1;stroke:#118eed;stroke-width:0.47898597;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
59 id="rect3766"
60 width="32.837307"
61 height="32.828217"
62 x="48.764767"
63 y="194.49706"
64 ry="3.9030087"
65 inkscape:export-xdpi="97.366936"
66 inkscape:export-ydpi="97.366936" />
67 </g>
68 <g
69 inkscape:groupmode="layer"
70 id="layer2"
71 inkscape:label="Layer 2">
72 <ellipse
73 style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.38701198;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
74 id="path3680"
75 cx="66.001335"
76 cy="210.4606"
77 rx="10.694626"
78 ry="10.66853"
79 inkscape:export-xdpi="97.366936"
80 inkscape:export-ydpi="97.366936" />
81 <path
82 style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.30078718;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
83 d="m 57.910381,217.97564 -0.977709,4.04506 3.733062,-2.06955 z"
84 id="path4579"
85 inkscape:connector-curvature="0"
86 inkscape:export-xdpi="97.366936"
87 inkscape:export-ydpi="97.366936" />
88 </g>
89 </svg>
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 <!DOCTYPE RCC><RCC version="1.0">
11 <qresource prefix="/">
22 <file>resources/firetools.png</file>
3 <file>resources/firetools-minimal.png</file>
34 <file>resources/go-top.png</file>
45 <file>resources/go-up.png</file>
56 <file>resources/user-home.png</file>
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
5353 paths_.append(QString(ptr + 10));
5454 ops_.append(QString("R"));
5555 }
56 else if (strncmp(ptr, "whitelist ", 10) == 0 ) {
57 paths_.append(QString(ptr + 10));
58 ops_.append(QString("W"));
59 }
6056 else if (strncmp(ptr, "clone ", 6) == 0 ) {
6157 paths_.append(QString(ptr + 6));
6258 ops_.append(QString("C"));
59 }
60 else if (strncmp(ptr, "create ", 7) == 0 ) {
61 paths_.append(QString(ptr + 7));
62 ops_.append(QString("G")); // generated
6363 }
6464
6565 ptr = strtok(NULL, "\n");
8686 }
8787 }
8888
89 QString rv = str;
90 if (str.endsWith("B"))
91 rv = "B";
92 if (str.endsWith("T"))
93 rv = "T";
94
9589 if (arg_debug)
96 printf("checkFile database %s, result %s\n", str.toUtf8().constData(), rv.toUtf8().constData());
97 return rv;
90 printf("checkFile database %s, result %s\n", full_path.toUtf8().constData(), str.toUtf8().constData());
91 return str;
9892 }
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
3838 tr("<br/><b>Firejail</b> software not found. Please install it.<br/><br/><br/>"));
3939 exit(1);
4040 }
41
41
4242 // verify sandbox
4343 {
4444 char *cmd;
5353 exit(1);
5454 }
5555 }
56
56
5757 // initialize FS
5858 fs_ = new FS(pid);
59
59
6060 top_ = new TopWidget(this);
6161 connect(top_, SIGNAL(upClicked()), this, SLOT(handleUp()));
6262 connect(top_, SIGNAL(rootClicked()), this, SLOT(handleRoot()));
6363 connect(top_, SIGNAL(refreshClicked()), this, SLOT(handleRefresh()));
6464 connect(top_, SIGNAL(homeClicked()), this, SLOT(handleHome()));
65
65
6666 line_ = new QLineEdit(this);
6767 QString txt = build_line();
6868 line_->setText(txt);
6969 line_->setReadOnly(true);
70
70
7171 table_ = new QTableWidget(0, 6, this);
7272 QStringList header;
7373 header.append(" ");
8484 table_->setColumnWidth(3, 100);
8585 table_->setColumnWidth(4, 100);
8686 table_->setColumnWidth(5, 500);
87 table_->horizontalHeader()->setStretchLastSection(true);
87 table_->horizontalHeader()->setStretchLastSection(true);
8888 table_->setShowGrid(false);
8989 table_->setColumnHidden(0, true);
9090 connect(table_, SIGNAL(cellClicked(int, int)), this, SLOT (cellClicked(int, int)));
9494 empty1->setMinimumWidth(30);
9595 QWidget *empty2 = new QWidget(this);
9696 empty2->setMinimumWidth(10);
97
97
9898 QGridLayout *mainLayout = new QGridLayout;
9999 mainLayout->addWidget(top_, 0, 0);
100100 mainLayout->addWidget(empty1, 0, 1);
134134 qpath.replace(" ", "\\ ");
135135 path = qpath.toUtf8().constData();
136136 }
137
137
138138 if (arg_debug)
139 printf("print_files path %s\n", path);
140
139 printf("print_files path %s\n", path);
140
141141 char *cmd;
142142 if (asprintf(&cmd, "firejail --ls=%d %s 2>&1", pid_, path) == -1)
143143 errExit("asprintf");
161161
162162 // fs flags
163163 fs_->checkPath(QString(path));
164
164
165165 char *ptr = strtok(out, "\n");
166166 rows = 0;
167167 while (ptr) {
170170 strncmp(ptr, "Error:", 6) == 0) {
171171 ptr = strtok(NULL, "\n");
172172 continue;
173 }
173 }
174174 split_command(ptr);
175
175
176176 // adjust the list in order to accept file names with spaces
177177 if (sargc > 5) {
178178 char *ptr = sargv[4];
183183 *ptr = ' ';
184184 }
185185 sargc = 5;
186 }
187
186 }
187
188188 if (sargc == 5) {
189189 if (strcmp(sargv[4], "..") != 0 && strcmp(sargv[4], ".") != 0) {
190190 table_->setRowCount(rows + 1);
191
191
192192 // image
193193 if (*sargv[0] == 'd') {
194194 table_->setItem(rows, 0, new QTableWidgetItem("D"));
211211 timage->setData(Qt::DecorationRole, QPixmap::fromImage(*img));
212212 table_->setItem(rows, 1, new QTableWidgetItem(*timage));
213213 }
214
214
215215 // fs flags
216216 QString s = fs_->checkFile(QString(sargv[4]));
217 if (s == "B")
217
218 if (s.contains("B"))
218219 s = "Blacklist";
219 else if ( s == "T")
220 else if (s.contains("T") && s.contains("R"))
221 s = "Temporary-RO";
222 else if (s.contains("T"))
220223 s = "Temporary";
221 else if ( s== "R")
224 else if (s.contains("G")) {
225 if (s.contains("R"))
226 s = "Generated-RO";
227 else
228 s = "Generated";
229 }
230 else if (s.contains("C")) {
231 if (s.contains("R"))
232 s = "Clone-RO";
233 else
234 s = "Clone";
235 }
236 else if (s.contains("R"))
222237 s = "Read-only";
223 else if ( s== "C")
224 s = "Clone";
225 else if ( s== "W")
226 s = "Whitelist";
227 else if (s == "WR")
228 s = "Read-only";
229238
230239 QTableWidgetItem *item = new QTableWidgetItem(s);
231 item->setTextAlignment(Qt::AlignCenter);
240 item->setTextAlignment(Qt::AlignCenter);
232241 table_->setItem(rows, 2, item);
233
242
234243 item = new QTableWidgetItem(sargv[1]);
235 item->setTextAlignment(Qt::AlignCenter);
244 item->setTextAlignment(Qt::AlignCenter);
236245 table_->setItem(rows, 3, item);
237246
238247 item = new QTableWidgetItem(sargv[3]);
239248 item->setTextAlignment(Qt::AlignCenter);
240249 table_->setItem(rows, 4, item);
241
250
242251 item = new QTableWidgetItem(QString(" ") + QString(sargv[4]));
243252 // item->setTextAlignment(Qt::AlignHorizontal_Mask);
244253 table_->setItem(rows, 5, item);
245 rows++;
254 rows++;
246255 }
247256 }
248
257
249258 ptr = strtok(NULL, "\n");
250 }
259 }
251260 }
252261
253262 void MainWindow::handleUp() {
255264 return handleRefresh();
256265
257266 path_.takeLast();
258 QString full_path = build_path();
267 QString full_path = build_path();
259268 print_files(full_path.toStdString().c_str());
260269 QString txt = build_line();
261270 line_->setText(txt);
262271 }
263272
264273 void MainWindow::handleRefresh() {
265 QString full_path = build_path();
274 QString full_path = build_path();
266275 print_files(full_path.toStdString().c_str());
267276 QString txt = build_line();
268277 line_->setText(txt);
274283 path_.append(QString("home"));
275284 if (username)
276285 path_.append(QString(username));
277 QString full_path = build_path();
286 QString full_path = build_path();
278287 print_files(full_path.toStdString().c_str());
279288 QString txt = build_line();
280289 line_->setText(txt);
289298
290299 QString MainWindow::build_path() {
291300 QString retval = QString("/");
292
301
293302 for (int i = 0; i < path_.size(); ++i) {
294303 retval += path_.at(i);
295304 retval += QString("/");
301310 QString MainWindow::build_line() {
302311 QString retval = "/";
303312 // retval.sprintf("%d:///", pid_);
304
313
305314 for (int i = 0; i < path_.size(); ++i) {
306315 retval += path_.at(i);
307316 retval += QString("/");
308317 }
309
318
310319 return retval;
311320 }
312321
320329 dir = dir.mid(2);
321330 path_.append(dir);
322331
323 QString full_path = build_path();
332 QString full_path = build_path();
324333 print_files(full_path.toStdString().c_str());
325334 QString txt = build_line();
326335 line_->setText(txt);
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
4343 void print_files(const char *path);
4444 QString build_path();
4545 QString build_line();
46
46
4747 private:
4848 pid_t pid_;
4949 TopWidget *top_;
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
4444 static int getX11Display(pid_t pid);
4545
4646
47 StatsDialog::StatsDialog(): QDialog(), mode_(MODE_TOP), pid_(0), uid_(0),
47 StatsDialog::StatsDialog(): QDialog(), mode_(MODE_TOP), pid_(0), uid_(0),
4848 pid_initialized_(false), pid_seccomp_(false), pid_caps_(QString("")), pid_noroot_(false),
4949 pid_cpu_cores_(QString("")), pid_protocol_(QString("")), pid_name_(QString("")),
5050 profile_(QString("")), pid_x11_(0),
5757 procView_->setOpenLinks(false);
5858 procView_->setOpenExternalLinks(false);
5959 procView_->setText("accumulating data...");
60
60
6161 connect(procView_, SIGNAL(anchorClicked(const QUrl &)), this, SLOT(anchorClicked(const QUrl &)));
6262
6363 QGridLayout *layout = new QGridLayout;
6464 layout->addWidget(procView_, 0, 0);
6565 setLayout(layout);
66
66
6767 // set screen size and title
6868 int x;
6969 int y;
7070 config_read_screen_size(&x, &y);
7171 resize(x, y);
7272 setWindowTitle(tr("Firetools"));
73
73
7474 // detect if joining a sandbox is possible on this system
7575 struct utsname u;
7676 int rv = uname(&u);
8484 have_join_ = false;
8585 }
8686 }
87
87
8888 // detect the number of capabilities supported by the current kernel
8989 char *str = run_program("firejail --debug-caps");
9090 if (!str)
9595 printf("%d capabilities supported by the kernel\n", val);
9696 caps_cnt_ = val;
9797 }
98
98
9999 struct stat s;
100 if (getuid() != 0 && stat("/proc/sys/kernel/grsecurity", &s) == 0)
100 if (getuid() != 0 && stat("/proc/sys/kernel/grsecurity", &s) == 0)
101101 no_network_ = true;
102102
103103 thread_ = new PidThread();
104104 connect(thread_, SIGNAL(cycleReady()), this, SLOT(cycleReady()));
105
105
106106 }
107107
108108 StatsDialog::~StatsDialog() {
125125 msg += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"newsandbox\">Configuration Wizard</a>";
126126 msg += "</td></tr></table>";
127127 }
128
128
129129 else if (mode_ == MODE_PID) {
130130 msg += "<table><tr><td width=\"5\"></td><td>";
131131 msg += "<a href=\"top\">Home</a>";
132 if (uid_ == getuid())
132 if (uid_ == getuid())
133133 msg += " &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"shut\">Shutdown</a>";
134134 if (have_join_ && uid_ == getuid())
135135 msg += " &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"join\">Join</a>";
138138 msg += " &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"dns\">DNS</a>";
139139 msg += "</td></tr></table>";
140140 }
141
142 else if (mode_ == MODE_TREE || mode_ == MODE_SECCOMP || mode_ == MODE_DNS || mode_ == MODE_CAPS) {
141
142 else {
143143 msg += "<table><tr><td width=\"5\"></td><td>";
144144 msg += "<a href=\"top\">Home</a>";
145145 msg += " &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"back\">" + QString::number(pid_) + "</a>";
146 if (uid_ == getuid())
146 if (uid_ == getuid())
147147 msg += " &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"shut\">Shutdown</a>";
148148 if (have_join_ && uid_ == getuid())
149149 msg += " &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"join\">Join</a>";
161161 QString msg = header() + "<hr>";
162162 msg += "<table><tr><td width=\"5\"></td><td><b>Sandbox List</b></td></tr></table><br/>\n";
163163 msg += "<table><tr><td width=\"5\"></td><td width=\"60\">PID</td/><td width=\"60\">CPU<br/>(%)</td><td>Memory<br/>(KiB)&nbsp;&nbsp;</td><td>RX<br/>(KB/s)&nbsp;&nbsp;</td><td>TX<br/>(KB/s)&nbsp;&nbsp;</td><td>Command</td>\n";
164
164
165165 int cycle = Db::instance().getCycle();
166166 assert(cycle < DbPid::MAXCYCLE);
167167 DbPid *ptr = Db::instance().firstPid();
168
169
168
169
170170 while (ptr) {
171171 pid_t pid = ptr->getPid();
172172 const char *cmd = ptr->getCmd();
176176 if (asprintf(&str, "<tr><td></td><td><a href=\"%d\">%d</a></td><td>%.02f</td><td>%d</td><td>%.02f</td><td>%.02f</td><td>%s</td></tr>",
177177 pid, pid, st->cpu_, (int) (st->rss_ + st->shared_),
178178 st->rx_, st->tx_, cmd) != -1) {
179
179
180180 msg += str;
181181 free(str);
182182 }
183183 }
184
184
185185 ptr = ptr->getNext();
186186 }
187
188 msg += "</table>";
187
188 msg += "</table>";
189189 procView_->setHtml(msg);
190190 }
191191
192
193 void StatsDialog::updateTree() {
194 int cycle = Db::instance().getCycle();
195 assert(cycle < DbPid::MAXCYCLE);
192 void StatsDialog::updateFirewall() {
196193 DbPid *dbptr = Db::instance().findPid(pid_);
197194 if (!dbptr) {
198 QString msg = "Process not found!<br/>";
199 msg += "<hr>" + header();
200 procView_->setHtml(msg);
201195 mode_ = MODE_TOP;
202 QTimer::singleShot(2000, this, SLOT(cycleReady()));
196 return;
197 }
198
199 if (arg_debug)
200 printf("reading firewall configuration\n");
201 QString msg = header() + "<hr>";
202
203 char *cmd;
204 if (asprintf(&cmd, "firejail --netfilter.print=%d", pid_) != -1) {
205 char *str = run_program(cmd);
206 if (str)
207 msg += "<pre>" + QString(str) + "</pre>";
208 }
209
210 procView_->setHtml(msg);
211
212 }
213
214
215 void StatsDialog::updateTree() {
216 DbPid *dbptr = Db::instance().findPid(pid_);
217 if (!dbptr) {
218 mode_ = MODE_TOP;
203219 return;
204220 }
205221
207223 printf("reading process tree configuration\n");
208224 QString msg = header();
209225 msg += "<hr><table><tr><td width=\"5\"></td><td>";
210
226
211227 char *str = 0;
212228 char *cmd;
213229 if (asprintf(&cmd, "firemon --tree --nowrap %d", pid_) != -1) {
219235 *ptr = '\0';
220236 msg += QString(str) + "<br/>\n";
221237 ptr++;
222
238
223239 while (*ptr == ' ') {
224240 msg += "&nbsp;&nbsp;";
225241 ptr++;
226 }
242 }
227243 str = ptr;
228244 continue;
229245 }
230246 ptr++;
231247 }
232248 free(cmd);
233 }
249 }
234250
235251 msg += "</td></tr></table>";
236252 procView_->setHtml(msg);
237253 }
238254
255
239256 void StatsDialog::updateSeccomp() {
240 int cycle = Db::instance().getCycle();
241 assert(cycle < DbPid::MAXCYCLE);
242257 DbPid *dbptr = Db::instance().findPid(pid_);
243258 if (!dbptr) {
244 QString msg = "Process not found!<br/>";
245 msg += "<hr>" + header();
246 procView_->setHtml(msg);
247259 mode_ = MODE_TOP;
248 QTimer::singleShot(2000, this, SLOT(cycleReady()));
249260 return;
250261 }
251262
255266 printf("reading seccomp configuration\n");
256267 QString msg = header();
257268 msg += "<hr><table><tr><td width=\"5\"></td><td>";
258
269
259270 char *str = 0;
260271 char *cmd;
261272 if (asprintf(&cmd, "firejail --seccomp.print=%d", pid_) != -1) {
267278 *ptr = '\0';
268279 msg += QString(str) + "<br/>\n";
269280 ptr++;
270
281
271282 while (*ptr == ' ') {
272283 msg += "&nbsp;&nbsp;";
273284 ptr++;
274 }
285 }
275286 str = ptr;
276287 continue;
277288 }
278289 ptr++;
279290 }
280291 free(cmd);
281 }
282
292 }
293
283294 msg += "</td></tr></table>";
284295 procView_->setHtml(msg);
285296 storage_seccomp_ = msg;
288299
289300
290301 void StatsDialog::updateCaps() {
291 int cycle = Db::instance().getCycle();
292 assert(cycle < DbPid::MAXCYCLE);
293302 DbPid *dbptr = Db::instance().findPid(pid_);
294303 if (!dbptr) {
295 QString msg = "Process not found!<br/>";
296 msg += "<hr>" + header();
297 procView_->setHtml(msg);
298304 mode_ = MODE_TOP;
299 QTimer::singleShot(2000, this, SLOT(cycleReady()));
300305 return;
301306 }
302307
306311 printf("reading caps configuration\n");
307312 msg = header();
308313 msg += "<hr><table><tr><td width=\"5\"></td><td>";
309
314
310315 char *str = 0;
311316 char *cmd;
312317 if (asprintf(&cmd, "firejail --caps.print=%d", pid_) != -1) {
320325 if (cnt >= caps_cnt_)
321326 break;
322327 cnt++;
323
328
324329 *ptr = '\0';
325330 msg += QString(str) + "<br/>\n";
326331 ptr++;
327
328 // while (*ptr == ' ') {
329 // msg += "&nbsp;&nbsp;";
330 // ptr++;
331 // }
332332 str = ptr;
333333 continue;
334334 }
335335 ptr++;
336336 }
337337 free(cmd);
338 }
339
338 }
339
340340 msg += "</pre></td></tr></table>";
341341 procView_->setHtml(msg);
342342 storage_caps_ = msg;
344344 }
345345
346346 void StatsDialog::updateDns() {
347 int cycle = Db::instance().getCycle();
348 assert(cycle < DbPid::MAXCYCLE);
349347 DbPid *dbptr = Db::instance().findPid(pid_);
350348 if (!dbptr) {
351 QString msg = "Process not found!<br/>";
352 msg += "<hr>" + header();
353 procView_->setHtml(msg);
354349 mode_ = MODE_TOP;
355 QTimer::singleShot(2000, this, SLOT(cycleReady()));
356350 return;
357351 }
358352
360354 if (msg.isEmpty()) {
361355 if (arg_debug)
362356 printf("reading dns configuration\n");
363
357
364358 msg = header();
365359 msg += "<hr><table><tr><td width=\"5\"></td><td>";
366
360
367361 char *str = 0;
368362 char *cmd;
369363 if (asprintf(&cmd, "firejail --dns.print=%d", pid_) != -1) {
370364 str = run_program(cmd);
371365 char *ptr = str;
372
366
373367 // htmlize!
374368 while (*ptr != 0) {
375369 if (*ptr == '\n') {
376370 *ptr = '\0';
377371 msg += QString(str) + "<br/>\n";
378372 ptr++;
379
373
380374 while (*ptr == ' ') {
381375 msg += "&nbsp;&nbsp;";
382376 ptr++;
383 }
377 }
384378 str = ptr;
385379 continue;
386380 }
387381 ptr++;
388382 }
389 }
383 }
390384 free(cmd);
391
385
392386 msg += "</td></tr></table>";
393387 procView_->setHtml(msg);
394388 storage_dns_ = msg;
398392 void StatsDialog::kernelSecuritySettings() {
399393 if (arg_debug)
400394 printf("Checking security settings for pid %d\n", pid_);
401
395
402396 // reset all
403397 pid_seccomp_ = false;
404398 pid_caps_ = QString("");
405399 pid_cpu_cores_ = QString("");
406400 pid_protocol_ = QString("");
407401 pid_mem_deny_exec_ = QString("disabled");
402 pid_apparmor_ = QString("");
408403
409404 // caps
410405 char *cmd;
432427 }
433428 }
434429 free(cmd);
435
430
436431 // cpu cores
437432 if (asprintf(&cmd, "firemon --cpu %d", pid_) == -1)
438433 return;
449444 // protocols
450445 if (asprintf(&cmd, "firejail --protocol.print=%d", pid_) == -1)
451446 return;
447
452448 str = run_program(cmd);
453449 if (str) {
454450 if (strncmp(str, "Cannot", 6) == 0)
458454 }
459455 free(cmd);
460456
457 // mem deny exec
461458 if (asprintf(&cmd, "firejail --ls=%d /run/firejail/mnt", pid_) == -1)
462459 return;
463460 str = run_program(cmd);
464461 if (str) {
465462 if (strstr(str, "seccomp.mdwx"))
466463 pid_mem_deny_exec_ = "enabled";
464 }
465 free(cmd);
466
467 // apparmor
468 if (asprintf(&cmd, "firejail --apparmor.print=%d", pid_) == -1)
469 return;
470 str = run_program(cmd);
471 if (str) {
472 const char *tofind = "AppArmor: ";
473 char *ptr = strstr(str, tofind);
474 if (ptr)
475 pid_apparmor_ = QString(ptr + strlen(tofind));
467476 }
468477 free(cmd);
469478 }
477486 if (pids[i].level == 2 && pids[i].parent == id)
478487 return i;
479488 }
480
489
481490 return -1;
482491 }
483492
484493
485494
486
495
487496 void StatsDialog::updatePid() {
488497 QString msg = "";
489498
491500 assert(cycle < DbPid::MAXCYCLE);
492501 DbPid *ptr = Db::instance().findPid(pid_);
493502 if (!ptr) {
494 msg += "Process not found!<br/>";
495 msg += "<hr>" + header();
496 procView_->setHtml(msg);
497503 mode_ = MODE_TOP;
498 QTimer::singleShot(2000, this, SLOT(cycleReady()));
499504 return;
500505 }
501506
502507 const char *cmd = ptr->getCmd();
503508 if (!cmd) {
504 msg += "Process not found!<br/>";
505 msg += "<hr>" + header();
506 procView_->setHtml(msg);
507509 mode_ = MODE_TOP;
508 QTimer::singleShot(2000, this, SLOT(cycleReady()));
509510 return;
510511 }
511512
533534 msg += "<tr><td width=\"5\"></td><td><b>Command:</b> " + QString(cmd) + "</td></tr>";
534535 if (!profile_.isEmpty())
535536 msg += "<tr><td width=\"5\"></td><td><b>Profile:</b> " + profile_ + "</td></tr>";
536 // add
537 // add
537538 msg += "</table><br/>";
538539
539540 msg += "<table>";
542543 msg += "<td><b>RX:</b> unknown</td></tr>";
543544 else
544545 msg += QString("<td><b>RX:</b> ") + QString::number(st->rx_) + " KB/s</td></tr>";
545
546
546547 msg += QString("<tr><td></td><td><b>User:</b> ") + pw->pw_name + "</td>";
547548 if (ptr->networkDisabled() || no_network_)
548549 msg += "<td><b>TX:</b> unknown</td></tr>";
558559 msg += "</td></tr>";
559560
560561 msg += QString("<tr><td></td><td><b>Memory:</b> ") + QString::number((int) (st->rss_ + st->shared_)) + " KiB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>";
561 msg += QString("<td><b>Capabilities:</b> <a href=\"caps\">") + pid_caps_ + "</a></td></tr>";
562
563 msg += QString("<tr><td></td><td><b>RSS</b> " + QString::number((int) st->rss_) + ", <b>shared</b> " + QString::number((int) st->shared_)) + "</td>";
564
562 msg += QString("<td><b>Capabilities:</b> <a href=\"caps\">") + pid_caps_ + "</a></td></tr>";
563
564 msg += QString("<tr><td></td><td><b>RSS</b> " + QString::number((int) st->rss_) + ", <b>shared</b> " + QString::number((int) st->shared_)) + "</td>";
565
565566 // user namespace
566567 msg += "<td><b>User Namespace:</b> ";
567
568
568569 if (pid_noroot_)
569570 msg += "enabled";
570571 else
590591 // memory deny exec
591592 msg += "<td><b>Memory deny exec:</b> " + pid_mem_deny_exec_ + "</td></tr>";
592593
594
595 // apparmor
596 if (!pid_apparmor_.isEmpty())
597 msg += "<tr><td></td><td></td><td><b>AppArmor: </b>" + pid_apparmor_ + "</td></tr>";
598
599
593600 // graph type
594601 msg += "<tr></tr>";
595602 msg += "<tr><td></td>";
596603 if (graph_type_ == GRAPH_4MIN) {
597 msg += "<td><b>Stats: </b>1min <a href=\"1h\">1h</a> <a href=\"12h\">12h</a></td></tr>\n";
604 msg += "<td><b>Stats: </b>1min <a href=\"1h\">1h</a> <a href=\"12h\">12h</a></td>";
598605 }
599606 else if (graph_type_ == GRAPH_1H) {
600 msg += "<td><b>Stats: </b><a href=\"1min\">1min</a> 1h <a href=\"12h\">12h</a></td></tr>\n";
607 msg += "<td><b>Stats: </b><a href=\"1min\">1min</a> 1h <a href=\"12h\">12h</a></td>";
601608 }
602609 else if (graph_type_ == GRAPH_12H) {
603 msg += "<td><b>Stats: </b><a href=\"1min\">1min</a> <a href=\"1h\">1h</a> 12h</td></tr>\n";
610 msg += "<td><b>Stats: </b><a href=\"1min\">1min</a> <a href=\"1h\">1h</a> 12h</td>";
604611 }
605612 else
606613 assert(0);
614
615 // netfilter
616 if (ptr->networkDisabled() == false && no_network_ == false)
617 msg += "<td><b>Firewall</b>: <a href=\"firewall\">enabled</a></td></tr>\n";
618 else
619 msg += "<td><b>Firewall</b>: system firewall</td></tr>\n";
607620
608621 // graphs
609622 msg += "<tr></tr>";
612625 msg += "<tr><td></td><td>"+ graph(2, ptr, cycle, graph_type_) + "</td><td>" + graph(3, ptr, cycle, graph_type_) + "</td></tr>";
613626
614627 msg += QString("</table><br/>");
615
628
616629 // bandwidth limits
617630 if (ptr->networkDisabled() == false && no_network_ == false) {
618631 char *fname;
649662 updateDns();
650663 else if (mode_ == MODE_CAPS)
651664 updateCaps();
665 else if (mode_ == MODE_FIREWALL)
666 updateFirewall();
652667 }
653668
654669 void StatsDialog::anchorClicked(const QUrl & link) {
655670 cleanStorage(); // full storage cleanup on any click
656671 QString linkstr = link.toString();
657
672
658673 if (linkstr == "top") {
659674 mode_ = MODE_TOP;
660675 }
669684 mode_ = MODE_PID;
670685 else if (mode_ == MODE_CAPS)
671686 mode_ = MODE_PID;
672 else if (mode_ == MODE_TOP);
687 else if (mode_ == MODE_FIREWALL)
688 mode_ = MODE_PID;
689 else if (mode_ == MODE_TOP)
690 ;
673691 else
674692 assert(0);
675693 }
693711 }
694712 else if (linkstr == "dns") {
695713 mode_ = MODE_DNS;
714 }
715 else if (linkstr == "firewall") {
716 mode_ = MODE_FIREWALL;
696717 }
697718 else if (linkstr == "shut") {
698719 QMessageBox msgBox;
709730 (void) rv;
710731 free(cmd);
711732 }
712 QApplication::restoreOverrideCursor();
733 QApplication::restoreOverrideCursor();
713734 mode_ = MODE_TOP;
714735 }
715736 }
733754 else if (linkstr == "about") {
734755 QString msg = "<table cellpadding=\"10\"><tr><td><img src=\":/resources/fstats.png\"></td>";
735756 msg += "<td>" + tr(
736 "Firetools stores shortcuts to preconfigured Firejail "
737 "sandboxes for several popular Linux applications. It also provides "
738 "a number of tools to manage running sandboxes.<br/>"
739 "<br/>"
757 "Firetools is a GUI application for Firejail. "
758 "It offers a system tray launcher for sandboxed apps, "
759 "sandbox editing, management, and statistics. "
760 "The software package also includes a sandbox configuration wizard, firejail-ui.<br/><br/>"
740761 "Firejail is a SUID sandbox program that reduces the risk of security "
741762 "breaches by restricting the running environment of untrusted applications "
742 "using Linux namespaces, Linux capabilities and seccomp-bpf.<br/><br/>") +
763 "using Linux namespaces, Linux capabilities and seccomp-bpf.<br/><br/>") +
743764 tr("Firetools version:") + " " + PACKAGE_VERSION + "<br/>" +
744765 tr("QT version: ") + " " + QT_VERSION_STR + "<br/>" +
745766 tr("License:") + " GPL v2<br/>" +
746767 tr("Homepage:") + " " + QString(PACKAGE_URL) + "</td></tr></table><br/><br/>";
747768
748769 QMessageBox::about(this, tr("About"), msg);
749
770
750771 }
751772 else if (linkstr == "newsandbox") {
752773 // start firejail-ui as a separate process
769790 pid_x11_ = 0;
770791 mode_ = MODE_PID;
771792 }
772
793
773794 if (data_ready)
774795 cycleReady();
775796 }
776
797
777798
778799 static bool userNamespace(pid_t pid) {
779800 if (arg_debug)
780801 printf("Checking user namespace for pid %d\n", pid);
781
802
782803 // test user namespaces available in the kernel
783804 struct stat s1;
784805 struct stat s2;
792813 pid = find_child(pid);
793814 if (pid == -1)
794815 return false;
795
816
796817 // read uid map
797818 char *uidmap;
798819 if (asprintf(&uidmap, "/proc/%u/uid_map", pid) == -1)
813834 }
814835 fclose(fp);
815836 free(uidmap);
816 return found;
837 return found;
817838 }
818839
819840 static QString getName(pid_t pid) {
830851 fclose(fp);
831852 }
832853 free(fname);
833
854
834855 return retval;
835856 }
836857
848869 fclose(fp);
849870 }
850871 free(fname);
851
872
852873 return retval;
853874 }
854875
866887 fclose(fp);
867888 }
868889 free(fname);
869
890
870891 return retval;
871892 }
00 /*
1 * Copyright (C) 2015-2017 Firetools Authors
1 * Copyright (C) 2015-2018 Firetools Authors
22 *
33 * This file is part of firetools project
44 *
4949 void updateSeccomp();
5050 void updateDns();
5151 void updateCaps();
52 void updateFirewall();
5253 void cleanStorage();
5354
5455 private:
6061 #define MODE_SECCOMP 3
6162 #define MODE_DNS 4
6263 #define MODE_CAPS 5
64 #define MODE_FIREWALL 6
6365 int mode_;
6466 int pid_; // pid value for mode 1
6567 uid_t uid_;
7375 QString pid_protocol_;
7476 QString pid_name_;
7577 QString pid_mem_deny_exec_;
78 QString pid_apparmor_;
7679 QString profile_;
7780 int pid_x11_;
7881