New upstream version 0.9.52
Reiner Herrmann
6 years ago
10 | 10 | |
11 | 11 | firetools_config_extras.h: |
12 | 12 | echo "#define PACKAGE_LIBDIR \"$(DESTDIR)/$(PREFIX)/lib/firetools\"" > firetools_config_extras.h |
13 | ||
13 | ||
14 | 14 | .PHONY: src |
15 | 15 | src: firetools_config_extras.h |
16 | 16 | $(MAKE) -C $@ $(MFLAGS) |
34 | 34 | rm -fr autom4te.cache |
35 | 35 | rm -f sanitizer.sh |
36 | 36 | |
37 | ||
37 | ||
38 | 38 | realinstall: |
39 | 39 | mkdir -p $(DESTDIR)/$(PREFIX)/bin |
40 | 40 | mkdir -p $(DESTDIR)/$(PREFIX)/share/applications |
51 | 51 | install -c -m 0644 src/firetools/firetools.desktop $(DESTDIR)/$(PREFIX)/share/applications/. |
52 | 52 | install -c -m 0644 src/firejail-ui/firejail-ui.desktop $(DESTDIR)/$(PREFIX)/share/applications/. |
53 | 53 | 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/. | |
54 | 55 | install -c -m 0644 src/firejail-ui/resources/firejail-ui.png $(DESTDIR)/$(PREFIX)/share/pixmaps/. |
55 | 56 | install -c -m 0644 COPYING $(DESTDIR)/$(DOCDIR)/. |
56 | 57 | install -c -m 0644 README $(DESTDIR)/$(DOCDIR)/. |
73 | 74 | rm -f $(DESTDIR)/$(PREFIX)/bin/firetools |
74 | 75 | rm -f $(DESTDIR)/$(PREFIX)/bin/firejail-ui |
75 | 76 | rm -f $(DESTDIR)/$(PREFIX)/share/pixmaps/firetools.png |
77 | rm -f $(DESTDIR)/$(PREFIX)/share/pixmaps/firetools-minimal.png | |
76 | 78 | rm -f $(DESTDIR)/$(PREFIX)/share/pixmaps/firejail-ui.png |
77 | 79 | rm -f $(DESTDIR)/$(PREFIX)/share/applications/firetools.desktop |
78 | 80 | rm -f $(DESTDIR)/$(PREFIX)/share/applications/firejail-ui.desktop |
87 | 89 | mv config.status.old config.status |
88 | 90 | rm -fr $(NAME)-$(VERSION) $(NAME)-$(VERSION).tar.xz |
89 | 91 | 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 .; | |
91 | 93 | 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 .. |
92 | 94 | cd $(NAME)-$(VERSION); cp -a ../COPYING .; cp -a ../README .; cp -a ../RELNOTES .; cd .. |
93 | 95 | cd $(NAME)-$(VERSION); rm -fr `find . -name .svn`; rm -fr $(NAME)-$(VERSION); cd .. |
17 | 17 | Firetools Authors: |
18 | 18 | |
19 | 19 | 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 | |
20 | 28 | Reiner Herrmann |
21 | 29 | - Debian and Ubuntu integration |
22 | 30 | - various fixes |
23 | 31 | Warren Togami (https://github.com/wtogami) |
24 | 32 | - rewrite of mkrpm.sh, Fedora packaging cleanup |
25 | 33 | Piraty (https://github.com/Piraty) |
26 | - use system's icons when available | |
34 | - use system's icons when available | |
27 | 35 | Topi Miettinen (https://github.com/topimiettinen) |
28 | 36 | - change labels to black to be visible with dark themes and various other fixes |
29 | 37 | dmio (https://github.com/dmio) |
31 | 39 | |
32 | 40 | Terminal icon (gnome-terminal.png) taken from Gnome project, license LGPL v3 or CC BY-SA 3.0. |
33 | 41 | |
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. | |
35 | 43 | |
36 | 44 | Icedove icon (icedove.png) taken from Debian project, license MPL 1.1 or GPL v2 or LGPL v2.1. |
37 | 45 | |
38 | 46 | Firefox icon (firefox.png) taken from Firefox project, license MPL 2.0. |
39 | 47 | |
40 | 48 | 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), | |
42 | 50 | license LGPL |
43 | 51 | |
44 | 52 | fmgr and firejail-ui icons (emblem-symbolic-link.png, view-refresh.png) taken from Adwaita project |
45 | 53 | (http://gnome-look.org/content/show.php/?content=144237), license GPL |
46 | 54 | |
55 | ||
47 | 56 | 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 | ||
0 | 8 | firetools (0.9.50) baseline; urgency=low |
1 | 9 | * modif: removed the periodic window update for seccomp, caps, |
2 | 10 | and dns |
3 | * feature: memory deny exec stats support | |
11 | * feature: memory deny exec stats support | |
4 | 12 | * feature: print security profile name in stats window |
5 | 13 | * feature: protocol support in firejail-ui |
6 | 14 | * feature: nodvd support in firejail-ui |
0 | 0 | #! /bin/sh |
1 | 1 | # 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. | |
3 | 3 | # |
4 | 4 | # Report bugs to <netblue30@yahoo.com>. |
5 | 5 | # |
579 | 579 | # Identity of this package. |
580 | 580 | PACKAGE_NAME='firetools' |
581 | 581 | 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' | |
584 | 584 | PACKAGE_BUGREPORT='netblue30@yahoo.com' |
585 | 585 | PACKAGE_URL='http://firejail.wordpress.com' |
586 | 586 | |
1249 | 1249 | # Omit some internal or obsolete options to make the list less imposing. |
1250 | 1250 | # This message is too long to be a string in the A/UX 3.1 sh. |
1251 | 1251 | 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. | |
1253 | 1253 | |
1254 | 1254 | Usage: $0 [OPTION]... [VAR=VALUE]... |
1255 | 1255 | |
1311 | 1311 | |
1312 | 1312 | if test -n "$ac_init_help"; then |
1313 | 1313 | 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:";; | |
1315 | 1315 | esac |
1316 | 1316 | cat <<\_ACEOF |
1317 | 1317 | |
1405 | 1405 | test -n "$ac_init_help" && exit $ac_status |
1406 | 1406 | if $ac_init_version; then |
1407 | 1407 | cat <<\_ACEOF |
1408 | firetools configure 0.9.50 | |
1408 | firetools configure 0.9.52 | |
1409 | 1409 | generated by GNU Autoconf 2.69 |
1410 | 1410 | |
1411 | 1411 | Copyright (C) 2012 Free Software Foundation, Inc. |
1745 | 1745 | This file contains any messages produced by compilers while |
1746 | 1746 | running configure, to aid debugging if configure makes a mistake. |
1747 | 1747 | |
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 | |
1749 | 1749 | generated by GNU Autoconf 2.69. Invocation command line was |
1750 | 1750 | |
1751 | 1751 | $ $0 $@ |
4418 | 4418 | # report actual input values of CONFIG_FILES etc. instead of their |
4419 | 4419 | # values after options handling. |
4420 | 4420 | 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 | |
4422 | 4422 | generated by GNU Autoconf 2.69. Invocation command line was |
4423 | 4423 | |
4424 | 4424 | CONFIG_FILES = $CONFIG_FILES |
4472 | 4472 | cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 |
4473 | 4473 | ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" |
4474 | 4474 | ac_cs_version="\\ |
4475 | firetools config.status 0.9.50 | |
4475 | firetools config.status 0.9.52 | |
4476 | 4476 | configured by $0, generated by GNU Autoconf 2.69, |
4477 | 4477 | with options \\"\$ac_cs_config\\" |
4478 | 4478 |
0 | 0 | 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) | |
2 | 2 | AC_CONFIG_SRCDIR([src/firetools/main.cpp]) |
3 | 3 | #AC_CONFIG_HEADERS([config.h]) |
4 | 4 | |
44 | 44 | #if test -f /usr/lib64/qt4/bin/qmake; then |
45 | 45 | # QMAKE=/usr/lib64/qt4/bin/qmake |
46 | 46 | #fi |
47 | ||
47 | ||
48 | 48 | if test -z "$QMAKE" |
49 | 49 | then |
50 | 50 | AC_MSG_ERROR([qmake and/or Qt are missing, please install them.]) |
19 | 19 | mkdir -p $INSTALL_DIR |
20 | 20 | cd $CODE_DIR |
21 | 21 | ./configure --prefix=/usr |
22 | make -j2 | |
22 | make -j4 | |
23 | 23 | DESTDIR=$INSTALL_DIR make install-strip |
24 | 24 | |
25 | 25 | cd .. |
45 | 45 | %{_mandir}/* |
46 | 46 | %{_datadir}/applications/firetools.desktop |
47 | 47 | %{_datadir}/pixmaps/firetools.png |
48 | %{_datadir}/pixmaps/firetools-minimal.png | |
48 | 49 | |
49 | 50 | |
50 | 51 | %changelog |
0 | 0 | #!/bin/bash |
1 | VER="0.9.50" | |
1 | VER="0.9.52" | |
2 | 2 | |
3 | 3 | cd ~ |
4 | 4 | rm -fr rpmbuild |
26 | 26 | install -m 644 /usr/share/applications/firejail-ui.desktop firetools-$VER/usr/share/applications/. |
27 | 27 | |
28 | 28 | mkdir -p firetools-$VER/usr/share/pixmaps |
29 | install -m 644 /usr/share/pixmaps/firetools-minimal.png firetools-$VER/usr/share/pixmaps/. | |
29 | 30 | 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/. | |
30 | 32 | install -m 644 /usr/share/pixmaps/firejail-ui.png firetools-$VER/usr/share/pixmaps/. |
31 | 33 | |
32 | 34 | mkdir -p firetools-$VER/usr/share/doc/firetools |
81 | 83 | /usr/share/applications/firetools.desktop |
82 | 84 | /usr/share/applications/firejail-ui.desktop |
83 | 85 | /usr/share/pixmaps/firetools.png |
86 | /usr/share/pixmaps/firetools-minimal.png | |
84 | 87 | /usr/share/pixmaps/firejail-ui.png |
85 | 88 | /usr/lib/firetools/fmgr |
86 | 89 | /usr/lib/firetools/fstats |
88 | 91 | /usr/lib/firetools/uimenus |
89 | 92 | |
90 | 93 | %changelog |
94 | ||
95 | * Fri Mar 2 2018 netblue30 <netblue30@yahoo.com> 0.9.52-1 | |
91 | 96 | |
92 | 97 | * Mon Oct 2 2017 netblue30 <netblue30@yahoo.com> 0.9.50-1 |
93 | 98 |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
1 | 1 | <qresource prefix="/"> |
2 | 2 | <file>resources/background.png</file> |
3 | 3 | <file>resources/firetools.png</file> |
4 | <file>resources/firetools-minimal.png</file> | |
4 | 5 | <file>resources/firejail-ui.png</file> |
5 | 6 | <file>resources/gnome-fs-directory.png</file> |
6 | 7 | </qresource> |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
95 | 95 | |
96 | 96 | if (arg_debug) |
97 | 97 | printf("Linux kernel version %d.%d\n", kernel_major, kernel_minor); |
98 | ||
98 | ||
99 | 99 | // initialize resources |
100 | 100 | //Q_INIT_RESOURCE(firejail-ui); |
101 | 101 |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
Binary diff not shown
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
29 | 29 | |
30 | 30 | Application::Application(const char *name, const char *description, const char *exec, const char *icon): |
31 | 31 | name_(name), description_(description), exec_(exec), icon_(icon) { |
32 | ||
32 | ||
33 | 33 | app_icon_ = loadIcon(icon_); |
34 | 34 | }; |
35 | 35 | |
36 | 36 | Application::Application(QString name, QString description, QString exec, QString icon): |
37 | 37 | name_(name), description_(description), exec_(exec), icon_(icon) { |
38 | ||
38 | ||
39 | 39 | app_icon_ = loadIcon(icon_); |
40 | 40 | }; |
41 | 41 | |
42 | // load an application from a desktop file | |
42 | // Load an application from a desktop file | |
43 | 43 | Application::Application(const char *name): |
44 | 44 | name_(name), description_("unknown"), exec_("unknown"), icon_("unknown") { |
45 | 45 | |
49 | 49 | char *fname = get_config_file_name(name); |
50 | 50 | if (!fname) |
51 | 51 | return; |
52 | ||
52 | ||
53 | 53 | if (arg_debug) |
54 | 54 | printf("loading %s\n", fname); |
55 | 55 | |
60 | 60 | return; |
61 | 61 | } |
62 | 62 | free(fname); |
63 | ||
63 | ||
64 | 64 | // read file |
65 | #define MAXBUF 10000 | |
65 | #define MAXBUF 10000 | |
66 | 66 | char buf[MAXBUF]; |
67 | 67 | while (fgets(buf, MAXBUF, fp)) { |
68 | 68 | // remove '\n' |
69 | 69 | char *ptr = strchr(buf, '\n'); |
70 | 70 | if (ptr) |
71 | 71 | *ptr = '\0'; |
72 | ||
72 | ||
73 | 73 | // skip blancs |
74 | 74 | char *start = buf; |
75 | 75 | while (*start == ' ' || *start == '\t') |
76 | 76 | start++; |
77 | ||
77 | ||
78 | 78 | // parse |
79 | 79 | if (strncmp(buf, "Comment=", 8) == 0) |
80 | 80 | description_ = buf + 8; |
88 | 88 | app_icon_ = loadIcon(icon_); |
89 | 89 | } |
90 | 90 | |
91 | // Save the app's configuration | |
91 | 92 | int Application::saveConfig() { |
92 | 93 | char *fname = get_config_file_name(name_.toLocal8Bit().constData()); |
93 | 94 | if (!fname) |
94 | 95 | return 1; |
95 | ||
96 | // open file | |
96 | ||
97 | // Open a file | |
97 | 98 | FILE *fp = fopen(fname, "w"); |
98 | 99 | if (!fp) { |
99 | 100 | free(fname); |
107 | 108 | fprintf(fp, "Icon=%s\n", icon_.toLocal8Bit().constData()); |
108 | 109 | fprintf(fp, "Exec=%s\n", exec_.toLocal8Bit().constData()); |
109 | 110 | fclose(fp); |
110 | ||
111 | ||
111 | 112 | return 0; |
112 | 113 | } |
113 | 114 | |
114 | 115 | /* |
115 | 116 | From: http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html |
116 | 117 | |
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 | |
118 | 119 | 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 | |
123 | 124 | the same name. This way users can extend and override system themes. |
124 | 125 | |
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 | |
127 | 128 | 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. | |
130 | 131 | */ |
131 | 132 | |
132 | // compare strings | |
133 | // compare strings | |
133 | 134 | static inline bool compare_ignore_case(QString q1, QString q2) { |
134 | 135 | q1 = q1.toLower(); |
135 | 136 | q2 = q2.toLower(); |
158 | 159 | QPixmap pix = icon.pixmap(sz.height(), sz.width()); |
159 | 160 | QPixmap pixin; |
160 | 161 | int delta = 0; |
161 | ||
162 | ||
162 | 163 | if (sz.height() == sz.width() && sz.height() <= 40) { |
163 | 164 | pixin = pix.scaled(40, 40); |
164 | 165 | delta = 12; |
165 | 166 | } |
166 | else { | |
167 | else { | |
167 | 168 | pixin = pix.scaled(48, 48); |
168 | 169 | delta = 8; |
169 | 170 | } |
170 | ||
171 | ||
171 | 172 | |
172 | 173 | QPixmap pixout(64, 64); |
173 | 174 | pixout.fill(QColor(0, 0, 0, 0)); |
176 | 177 | if (arg_debug) |
177 | 178 | printf("\t- output pixmap: w %d, h %d\n", pixout.width(), pixout.height()); |
178 | 179 | paint->end(); |
179 | return QIcon(pixout); | |
180 | return QIcon(pixout); | |
180 | 181 | } |
181 | 182 | |
182 | 183 | QIcon Application::loadIcon(QString name) { |
183 | 184 | if (arg_debug) |
184 | 185 | printf("searching icon %s\n", name.toLocal8Bit().data()); |
185 | ||
186 | ||
186 | 187 | if (name == ":resources/fstats" || name == ":resources/firejail-ui") { |
187 | 188 | if (arg_debug) |
188 | 189 | printf("\t- resource\n"); |
189 | 190 | return QIcon(name); // not resized, using the real 64x64 size |
190 | 191 | } |
191 | ||
192 | ||
192 | 193 | if (name.startsWith(":resources")) { |
193 | 194 | if (arg_debug) |
194 | 195 | printf("\t- resource\n"); |
195 | 196 | return resize48x48(QIcon(name)); |
196 | 197 | } |
197 | ||
198 | ||
198 | 199 | if (name.startsWith('/')) { |
199 | 200 | if (arg_debug) |
200 | 201 | printf("\t- full path\n"); |
203 | 204 | |
204 | 205 | |
205 | 206 | |
206 | // look for the file in firejail config directory under /home/user | |
207 | // Look for the file in Firejail config directory under /home/user | |
207 | 208 | QString conf = QDir::homePath() + "/.config/firetools/" + name + ".png"; |
208 | 209 | QFileInfo checkFile1(conf); |
209 | 210 | if (checkFile1.exists() && checkFile1.isFile()) { |
241 | 242 | if (!qstr.isEmpty()) |
242 | 243 | return resize48x48(QIcon(qstr)); |
243 | 244 | } |
244 | ||
245 | ||
245 | 246 | { |
246 | 247 | QString qstr = walk("/usr/share/icons/hicolor/128x128", name); |
247 | 248 | if (!qstr.isEmpty()) |
248 | 249 | return resize48x48(QIcon(qstr)); |
249 | 250 | } |
250 | ||
251 | ||
251 | 252 | { |
252 | 253 | QString qstr = walk("/usr/share/icons/hicolor/256x256", name); |
253 | 254 | if (!qstr.isEmpty()) |
254 | 255 | return resize48x48(QIcon(qstr)); |
255 | 256 | } |
256 | 257 | |
257 | { | |
258 | { | |
258 | 259 | QDirIterator it("/usr/share/pixmaps", QDirIterator::Subdirectories); |
259 | 260 | while (it.hasNext()) { |
260 | 261 | it.next(); |
266 | 267 | return resize48x48(icon); |
267 | 268 | } |
268 | 269 | } |
269 | } | |
270 | ||
270 | } | |
271 | ||
271 | 272 | if (QIcon::hasThemeIcon(name)) { |
272 | 273 | if (arg_debug) |
273 | 274 | printf("\t- fromTheme\n"); |
280 | 281 | return resize48x48(QIcon(qstr)); |
281 | 282 | } |
282 | 283 | |
283 | ||
284 | ||
284 | 285 | // we failed to get an icon so far, look all over /usr/share/icons directory |
285 | 286 | { |
286 | 287 | QString qstr = walk("/usr/share/icons", name); |
288 | 289 | return resize48x48(QIcon(qstr)); |
289 | 290 | } |
290 | 291 | |
291 | // create a new icon | |
292 | ||
293 | // Create a new icon | |
292 | 294 | if (arg_debug) |
293 | 295 | printf("\t- created\n"); |
296 | ||
297 | // Create a new QPixmap instance for icons | |
294 | 298 | 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 | |
296 | 308 | QPainter painter( &pix ); |
309 | ||
310 | // Set color and font for the painter | |
297 | 311 | painter.setPen(Qt::white); |
298 | 312 | painter.setFont(QFont("Sans")); |
313 | ||
314 | // Draw application's name to the icon | |
299 | 315 | painter.drawText(3, 20, name); |
300 | 316 | painter.end(); |
317 | ||
318 | // Use generated pixmap as an icon | |
301 | 319 | QIcon icon(pix); |
320 | ||
302 | 321 | return icon; |
303 | 322 | } |
304 | 323 | |
305 | 324 | |
325 | // Default application configurations for the app launcher | |
306 | 326 | struct DefaultApp { |
307 | 327 | const char *name; |
308 | 328 | const char *alias; |
312 | 332 | }; |
313 | 333 | |
314 | 334 | DefaultApp dapps[] = { |
315 | // firetools | |
335 | // Firetools | |
316 | 336 | { "firetools", "", "Firetools", PACKAGE_LIBDIR "/fstats", ":resources/fstats" }, |
317 | 337 | { "firejail-ui", "", "Firejail Configuration Wizard", "firejail-ui", ":resources/firejail-ui" }, |
318 | ||
319 | // browser | |
338 | ||
339 | // Web browsers | |
320 | 340 | { "iceweasel", "", "Debian Iceweasel", "firejail iceweasel", ":resources/firefox" }, |
321 | 341 | { "firefox", "iceweasel", "Mozilla Firefox", "firejail firefox", ":resources/firefox"}, |
322 | 342 | { "icecat", "firefox", "GNU IceCat", "firejail icecat", ":resources/firefox"}, |
323 | 343 | { "chromium", "", "Chromium Web Browser", "firejail chromium", "chromium"}, |
324 | 344 | { "chromium-browser", "chromium", "Chromium Web Browser", "firejail chromium-browser", "chromium-browser"}, |
345 | { "google-chrome", "", "Google Chrome", "firejail google-chrome", "google-chrome"}, | |
325 | 346 | { "midori", "", "Midori Web Browser", "firejail midori", "midori" }, |
326 | 347 | { "opera", "", "Opera Web Browser", "firejail opera", "opera" }, |
327 | 348 | { "netsurf", "", "Netsurf Web Browser", "firejail netsurf", "netsurf" }, |
328 | 349 | |
329 | ||
350 | // Email clients | |
330 | 351 | { "icedove", "", "Debian Icedove", "firejail icedove", ":resources/icedove" }, |
331 | 352 | { "thunderbird", "icedove","Thunderbird", "firejail thunderbird", "thunderbird" }, |
332 | 353 | |
333 | // bittorrent | |
354 | // Bittorrent | |
334 | 355 | { "transmission-gtk", "", "Transmission BitTorrent Client", "firejail transmission-gtk", "transmission" }, |
335 | 356 | { "transmission-qt", "transmission-gtk", "Transmission BitTorrent Client", "firejail transmission-qt", "transmission" }, |
336 | 357 | { "deluge", "", "Deluge BitTorrent Client", "firejail deluge", "deluge" }, |
337 | 358 | { "qbittorrent", "", "qBittorrent Client", "firejail qbittorrent", "qbittorrent" }, |
338 | 359 | |
339 | // viewers | |
360 | // Viewers | |
340 | 361 | { "evince", "", "Evince PDF viewer", "firejail evince", "evince" }, |
341 | 362 | { "qpdfview", "", "qPDFView", "firejail qpdfview", "qpdfview" }, |
342 | 363 | { "xpdf", "", "Xpdf", "firejail xpdf", "xpdf" }, |
353 | 374 | { "calibre", "", "Calibre eBook reader", "firejail calibre", "/usr/share/calibre/images/lt.png" }, |
354 | 375 | { "xreader", "", "xreader", "firejail xreader", "xreader" }, |
355 | 376 | |
356 | // media players, audio/video tools | |
377 | // Media players, audio/video tools | |
357 | 378 | { "xplayer", "", "xplayer", "firejail xplayer", "xplayer" }, |
358 | 379 | { "vlc", "", "VideoLAN Client", "firejail vlc", "vlc" }, |
359 | 380 | { "amarok", "", "Amarok", "firejail amarok", "amarok" }, |
360 | { "dragon", "", "Dragom Player", "firejail dragon", "dragonplayer" }, | |
381 | { "dragon", "", "Dragon Player", "firejail dragon", "dragonplayer" }, | |
361 | 382 | { "rhythmbox", "", "Rhythmbox", "firejail rhythmbox", "rhythmbox" }, |
362 | 383 | { "totem", "", "Totem", "firejail totem", "totem" }, |
363 | 384 | { "audacious", "", "Audacious", "firejail audacious", "audacious" }, |
370 | 391 | { "ghb", "", "HandBrake", "firejail ghb", "hb-icon" }, |
371 | 392 | { "audacity", "", "Audacity", "firejail audacity", "audacity" }, |
372 | 393 | |
373 | // editor | |
394 | // Editors | |
374 | 395 | { "gimp", "", "Gimp", "firejail gimp", "gimp" }, |
375 | 396 | { "inkscape", "", "Inkscape", "firejail inkscape", "inkscape" }, |
376 | 397 | { "openshot", "", "OpenShot video editor", "firejail openshot", "openshot" }, |
378 | 399 | { "lowriter", "", "LibreOffice Writer", "firejail lowriter", ":resources/libreoffice-writer.png" }, |
379 | 400 | |
380 | 401 | |
381 | // chat | |
402 | // Chat | |
403 | { "signal-desktop", "", "Signal", "firejail signal-desktop", ":resources/signal-desktop.png" }, | |
382 | 404 | { "pidgin", "", "Pidgin", "firejail pidgin", "pidgin" }, |
383 | 405 | { "xchat", "", "XChat", "firejail xchat", "xchat" }, |
384 | 406 | { "hexchat", "", "HexChat", "firejail hexchat", "hexchat" }, |
385 | 407 | { "quassel", "", "Quassel IRC", "firejail quassel", "quassel" }, |
386 | 408 | { "empathy", "", "Empathy", "firejail empathy", "empathy" }, |
387 | ||
388 | // etc | |
409 | ||
410 | // Etc | |
389 | 411 | { "filezilla", "", "FileZilla", "firejail filezilla", "filezilla" }, |
390 | 412 | { "xterm", "", "xterm", "firejail xterm", ":resources/gnome-terminal.png" }, |
391 | 413 | { "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 | |
394 | 423 | { "0ad", "", "0AD", "firejail 0ad", "0ad" }, |
395 | 424 | { "warzone2100", "", "Warzone 2100", "firejail warzone2100", "warzone2100" }, |
396 | 425 | { "etr", "", "Extreme Tux Racer", "firejail etr", "etr" }, |
398 | 427 | { "frozen-bubble", "", "Frozen-Bubble", "firejail frozen-bubble", "frozen-bubble" }, |
399 | 428 | { "2048-qt", "", "2048", "firejail 2048-qt", "2048-qt" }, |
400 | 429 | { "pingus", "", "Pingus", "firejail pingus", "pingus" }, |
401 | ||
430 | ||
402 | 431 | { 0, 0, 0, 0, 0 } |
403 | 432 | }; |
404 | 433 | |
409 | 438 | return true; |
410 | 439 | app++; |
411 | 440 | } |
412 | ||
441 | ||
413 | 442 | return false; |
414 | 443 | } |
415 | 444 | |
419 | 448 | if (it->name_ == name) |
420 | 449 | return true; |
421 | 450 | } |
422 | ||
451 | ||
423 | 452 | return false; |
424 | 453 | } |
425 | 454 | |
440 | 469 | |
441 | 470 | void applications_init() { |
442 | 471 | // load default apps |
472 | if (arg_debug) | |
473 | printf("Loading default applications\n"); | |
474 | ||
443 | 475 | DefaultApp *app = &dapps[0]; |
444 | 476 | 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? | |
446 | 481 | if (which(app->name) == false) { |
447 | 482 | app++; |
448 | continue; | |
449 | } | |
450 | ||
483 | continue; | |
484 | } | |
485 | ||
451 | 486 | // is there an alias? |
452 | 487 | if (*app->alias != '\0' && which(app->alias)) { |
453 | 488 | app++; |
454 | 489 | continue; |
455 | 490 | } |
456 | ||
491 | ||
457 | 492 | // is there a user config file? |
458 | 493 | if (have_config_file(app->name)) |
459 | 494 | applist.append(Application(app->name)); |
462 | 497 | |
463 | 498 | app++; |
464 | 499 | } |
465 | ||
500 | ||
466 | 501 | // load user apps from home directory |
467 | 502 | char *home = get_home_directory(); |
468 | 503 | if (!home) |
476 | 511 | free(homecfg); |
477 | 512 | return; |
478 | 513 | } |
479 | ||
514 | ||
480 | 515 | // walk home config directory |
481 | 516 | struct dirent *entry; |
482 | 517 | while ((entry = readdir(dir))) { |
484 | 519 | continue; |
485 | 520 | if (strcmp(entry->d_name, "..") == 0) |
486 | 521 | continue; |
487 | ||
522 | ||
488 | 523 | // look only at .desktop files |
489 | 524 | int len = strlen(entry->d_name); |
490 | 525 | if (len <= 8) |
497 | 532 | free(fname); |
498 | 533 | continue; |
499 | 534 | } |
500 | ||
535 | ||
501 | 536 | // check if the app is in default list |
502 | 537 | fflush(0); |
503 | 538 | *ending = '\0'; |
507 | 542 | if (strcmp(fname, app->name) == 0) { |
508 | 543 | found = true; |
509 | 544 | } |
510 | ||
545 | ||
511 | 546 | app++; |
512 | 547 | } |
513 | 548 | if (found) { |
514 | 549 | free(fname); |
515 | 550 | continue; |
516 | 551 | } |
517 | ||
552 | ||
518 | 553 | // load file |
519 | 554 | applist.append(Application(fname)); |
520 | 555 | free(fname); |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
23 | 23 | #include <QIcon> |
24 | 24 | |
25 | 25 | #define TOP 10 |
26 | #define MARGIN 5 | |
26 | #define MARGIN 2 | |
27 | 27 | #define AFRAMES 6 // animation frames |
28 | 28 | #define ADELAY 20 // animation delay |
29 | 29 | #define ROWS 6 |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
34 | 34 | |
35 | 35 | |
36 | 36 | EditDialog::EditDialog(QString name, QString desc, QString cmd): QDialog() { |
37 | // editing | |
37 | // Editing | |
38 | 38 | QLabel *lname = new QLabel; |
39 | 39 | lname->setText(tr("Name")); |
40 | 40 | name_ = new QLineEdit; |
52 | 52 | cmd_ = new QLineEdit; |
53 | 53 | cmd_->setText(cmd); |
54 | 54 | |
55 | // buttons | |
55 | // Buttons | |
56 | 56 | QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok |
57 | 57 | | QDialogButtonBox::Cancel); |
58 | 58 | connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); |
65 | 65 | QLabel *icon_txt3 = new QLabel("You can supply your own icon by placing it in ~/.config/firetools."); |
66 | 66 | |
67 | 67 | |
68 | // layout- editing | |
68 | // Layout - editing | |
69 | 69 | QGridLayout *layout = new QGridLayout; |
70 | 70 | layout->addItem(new QSpacerItem(30, 15), 0, 0); |
71 | 71 | layout->addItem(new QSpacerItem(300, 15), 0, 2); |
77 | 77 | layout->addWidget(lcmd, 3, 1); |
78 | 78 | layout->addWidget(cmd_, 3, 2); |
79 | 79 | |
80 | // icon note | |
80 | // Icon note | |
81 | 81 | layout->addItem(new QSpacerItem(10,20), 4, 0); |
82 | 82 | layout->addWidget(icon_txt1, 5, 1, 1, 2); |
83 | 83 | layout->addWidget(icon_txt2, 6, 1, 1, 2); |
84 | 84 | layout->addWidget(icon_txt3, 7, 1, 1, 2); |
85 | 85 | layout->addItem(new QSpacerItem(30, 15), 8, 0); |
86 | 86 | |
87 | // layout - buttons | |
87 | // Layout - buttons | |
88 | 88 | layout->addItem(new QSpacerItem(30, 30), 9, 0); |
89 | 89 | layout->addWidget(helpButton, 10, 1); |
90 | 90 | layout->addWidget(buttonBox, 10, 2); |
94 | 94 | setWindowTitle(tr("Edit Sandbox")); |
95 | 95 | } |
96 | 96 | |
97 | // Help dialog | |
97 | 98 | void EditDialog::help() { |
98 | 99 | QMessageBox msgBox; |
99 | 100 |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | <!DOCTYPE RCC><RCC version="1.0"> |
1 | 1 | <qresource prefix="/"> |
2 | 2 | <file>resources/firetools.png</file> |
3 | <file>resources/firetools-minimal.png</file> | |
3 | 4 | <file>resources/fstats.png</file> |
4 | 5 | <file>resources/firejail-ui.png</file> |
5 | 6 | <file>resources/icedove.png</file> |
6 | 7 | <file>resources/firefox.png</file> |
7 | 8 | <file>resources/libreoffice-writer.png</file> |
8 | 9 | <file>resources/gnome-terminal.png</file> |
10 | <file>resources/signal-desktop.png</file> | |
9 | 11 | </qresource> |
10 | 12 | </RCC> |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
41 | 41 | "Categories=Qt;System;Security;\n"; |
42 | 42 | |
43 | 43 | |
44 | // Usage instructions for the command line output | |
44 | 45 | static void usage() { |
45 | 46 | printf("firetools - Firejail tools and stats utility\n\n"); |
46 | 47 | printf("Usage: firetools [options]\n\n"); |
56 | 57 | int main(int argc, char *argv[]) { |
57 | 58 | int arg_minimize = 0; |
58 | 59 | |
59 | // parse arguments | |
60 | // Parse arguments | |
60 | 61 | for (int i = 1; i < argc; i++) { |
61 | 62 | if (strcmp(argv[i], "--debug") == 0) |
62 | 63 | arg_debug = 1; |
69 | 70 | return 0; |
70 | 71 | } |
71 | 72 | else if (strcmp(argv[i], "--autostart") == 0) { |
72 | // find jome directory | |
73 | // Find home directory | |
73 | 74 | char *home = get_home_directory(); |
74 | 75 | if (!home) { |
75 | 76 | fprintf(stderr, "Error: cannot find user home directory"); |
76 | 77 | return 1; |
77 | 78 | } |
78 | 79 | |
79 | // create a .config/autostart directory if it doesn't exist | |
80 | // Create a .config/autostart directory if it doesn't exist | |
80 | 81 | char *autodir; |
81 | 82 | if (asprintf(&autodir, "%s/.config/autostart", home) == -1) |
82 | 83 | errExit("asprintf"); |
83 | 84 | int rv = mkdir(autodir, 0755); |
84 | 85 | (void) rv; |
85 | 86 | |
86 | // create desktop file | |
87 | // Create desktop file | |
87 | 88 | char *autofile; |
88 | 89 | if (asprintf(&autofile, "%s/.config/autostart/firetools.desktop", home) == -1) |
89 | 90 | errExit("asprintf"); |
108 | 109 | |
109 | 110 | #if QT_VERSION >= 0x050000 |
110 | 111 | struct stat s; |
111 | // test run time dependencies - print warning and continue program | |
112 | // Test run time dependencies - print warning and continue program | |
112 | 113 | QString ppath = QLibraryInfo::location(QLibraryInfo::PluginsPath); |
113 | 114 | ppath += "/imageformats/libqsvg.so"; |
114 | 115 | if (stat(ppath.toUtf8().constData(), &s) == -1) { |
117 | 118 | } |
118 | 119 | #endif |
119 | 120 | |
120 | // test run time dependencies - exit | |
121 | // Test run time dependencies - exit | |
121 | 122 | if (!which("firejail")) { |
122 | 123 | fprintf(stderr, "Error: firejail package not found, please install it!\n"); |
123 | 124 | exit(1); |
124 | 125 | } |
125 | 126 | |
126 | // create firetools directory if it doesn't exist | |
127 | // Create firetools directory if it doesn't exist | |
127 | 128 | create_config_directory(); |
128 | 129 | |
129 | // initialize resources | |
130 | // Initialize resources | |
130 | 131 | Q_INIT_RESOURCE(firetools); |
131 | 132 | |
132 | 133 | QApplication app(argc, argv); |
134 | 135 | if (!arg_minimize) |
135 | 136 | fc.show(); |
136 | 137 | |
137 | // configure system tray | |
138 | QSystemTrayIcon icon(QIcon(":resources/firetools.png")); | |
138 | // Configure system tray | |
139 | QSystemTrayIcon icon(QIcon(":resources/firetools-minimal.png")); | |
139 | 140 | icon.show(); |
140 | 141 | icon.setToolTip("Firetools (click to open)"); |
141 | 142 | QMenu *trayIconMenu = new QMenu(&fc); |
146 | 147 | icon.setContextMenu(trayIconMenu); |
147 | 148 | icon.connect(&icon, SIGNAL(activated(QSystemTrayIcon: :ActivationReason)), &fc, SLOT(trayActivated(QSystemTrayIcon: :ActivationReason))); |
148 | 149 | |
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: | |
150 | 151 | // https://bugreports.qt.io/browse/QTBUG-43270 |
151 | 152 | FILE *rv = NULL; |
152 | 153 | if (!arg_debug) { |
154 | 155 | (void) rv; |
155 | 156 | } |
156 | 157 | |
157 | // start application | |
158 | // Start application | |
158 | 159 | int tmp = app.exec(); |
159 | 160 | (void) tmp; |
160 | 161 |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
73 | 73 | "Drag the launcher with the left mouse button.\n" |
74 | 74 | "Use the right mouse button to open a context menu.")); |
75 | 75 | setWindowTitle(tr("Firelauncher")); |
76 | ||
76 | ||
77 | 77 | } |
78 | 78 | |
79 | 79 | void MainWindow::edit() { |
80 | 80 | if (edit_index_ != -1) { |
81 | 81 | EditDialog *edit; |
82 | ||
82 | ||
83 | 83 | // new entry |
84 | 84 | if (active_index_ == -1) { |
85 | 85 | edit = new EditDialog("", "", ""); |
98 | 98 | else |
99 | 99 | QMessageBox::critical(this, tr("Firejail Tools"), |
100 | 100 | tr("<br/>Sandbox already defined.<br/><br/><br/>")); |
101 | ||
102 | 101 | } |
103 | 102 | } |
104 | ||
103 | ||
105 | 104 | // existing entry |
106 | 105 | else { |
107 | 106 | //printf("%s\n", applist[active_index_].exec_.toLocal8Bit().constData()); |
114 | 113 | } |
115 | 114 | } |
116 | 115 | delete edit; |
117 | ||
116 | ||
118 | 117 | // update |
119 | 118 | hide(); |
120 | 119 | show(); |
122 | 121 | } |
123 | 122 | } |
124 | 123 | |
124 | // Remove application from the list | |
125 | 125 | 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_, | |
127 | 127 | // applist[active_index_].name_.toLocal8Bit().constData()); |
128 | 128 | |
129 | 129 | char *fname = get_config_file_name(applist[active_index_].name_.toLocal8Bit().constData()); |
134 | 134 | printf("Application removed:\n"); |
135 | 135 | applist_print(); |
136 | 136 | } |
137 | ||
137 | ||
138 | 138 | // update |
139 | 139 | hide(); |
140 | 140 | show(); |
144 | 144 | } |
145 | 145 | |
146 | 146 | |
147 | // Run application | |
147 | 148 | void MainWindow::run() { |
148 | 149 | int index = active_index_; |
149 | 150 | if (index != -1) { |
151 | 152 | int rv = system(exec.toStdString().c_str()); |
152 | 153 | (void) rv; |
153 | 154 | } |
154 | ||
155 | ||
155 | 156 | animation_id_ = AFRAMES; |
156 | 157 | QTimer::singleShot(0, this, SLOT(update())); |
157 | 158 | } |
158 | 159 | |
160 | // Run statistics tools | |
159 | 161 | void MainWindow::runTools() { |
160 | 162 | // start fstats as a separate process |
161 | 163 | int rv = system(PACKAGE_LIBDIR "/fstats &"); |
162 | 164 | (void) rv; |
163 | 165 | } |
164 | 166 | |
167 | // Start firejail-ui | |
165 | 168 | void MainWindow::newSandbox() { |
166 | 169 | // start firejail-ui as a separate process |
167 | 170 | int rv = system("firejail-ui &"); |
168 | 171 | (void) rv; |
169 | 172 | } |
170 | 173 | |
174 | // About window | |
171 | 175 | void MainWindow::runAbout() { |
172 | 176 | QString msg = "<table cellpadding=\"10\"><tr><td><img src=\":/resources/firetools.png\"></td>"; |
173 | 177 | msg += "<td>" + tr( |
174 | ||
178 | ||
175 | 179 | "Firetools is a GUI application for Firejail. " |
176 | 180 | "It offers a system tray launcher for sandboxed apps, " |
177 | 181 | "sandbox editing, management, and statistics. " |
179 | 183 | |
180 | 184 | "Firejail is a SUID sandbox program that reduces the risk of security " |
181 | 185 | "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/>") + | |
183 | 187 | tr("Firetools version:") + " " + PACKAGE_VERSION + "<br/>" + |
184 | 188 | tr("QT version: ") + " " + QT_VERSION_STR + "<br/>" + |
185 | 189 | tr("License:") + " GPL v2<br/>" + |
188 | 192 | QMessageBox::about(this, tr("About"), msg); |
189 | 193 | } |
190 | 194 | |
195 | // Mouse events: mouse release | |
191 | 196 | void MainWindow::mouseReleaseEvent(QMouseEvent *event) { |
192 | 197 | int nelem = applist.count(); |
193 | 198 | int cols = nelem / ROWS + 1; |
196 | 201 | int x = event->pos().x(); |
197 | 202 | int y = event->pos().y(); |
198 | 203 | |
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 && | |
200 | 205 | y >= 4 && y <= 15) { |
201 | 206 | |
202 | 207 | showMinimized(); |
206 | 211 | } |
207 | 212 | } |
208 | 213 | |
214 | // Mouse events: mouse press | |
209 | 215 | void MainWindow::mousePressEvent(QMouseEvent *event) { |
210 | 216 | if (event->button() == Qt::LeftButton) { |
211 | 217 | dragPosition_ = event->globalPos() - frameGeometry().topLeft(); |
237 | 243 | } |
238 | 244 | |
239 | 245 | |
246 | // Mouse events | |
240 | 247 | void MainWindow::mouseMoveEvent(QMouseEvent *event) { |
241 | 248 | if (event->buttons() & Qt::LeftButton) { |
242 | 249 | move(event->globalPos() - dragPosition_); |
244 | 251 | } |
245 | 252 | } |
246 | 253 | |
247 | ||
254 | // Mouse events: double-click | |
248 | 255 | void MainWindow::mouseDoubleClickEvent(QMouseEvent *event) { |
249 | 256 | if (event->button() == Qt::LeftButton) { |
250 | 257 | QPoint pos = event->pos(); |
261 | 268 | } |
262 | 269 | } |
263 | 270 | |
271 | // Main window visual design | |
264 | 272 | void MainWindow::paintEvent(QPaintEvent *) { |
273 | // Count the number applications and put the value to the variable | |
265 | 274 | int nelem = applist.count(); |
275 | ||
276 | // Columns is the amount of applications divided by number of rows + 1 | |
266 | 277 | int cols = nelem / ROWS + 1; |
267 | 278 | |
279 | // Start painting | |
268 | 280 | QPainter painter(this); |
269 | 281 | painter.setRenderHint(QPainter::Antialiasing); |
282 | ||
283 | // Window size hint | |
270 | 284 | 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 | |
273 | 298 | int i = 0; |
274 | 299 | int j = 0; |
275 | 300 | for (; i < nelem; i++, j++) { |
276 | 301 | if (j >= ROWS) |
277 | 302 | j = 0; |
278 | ||
303 | ||
304 | // Select icon from the looped items | |
279 | 305 | QIcon icon = applist[i].app_icon_; |
306 | ||
280 | 307 | int sz = 64 ; |
281 | 308 | if (active_index_ == i) |
282 | 309 | 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 | |
308 | 352 | 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 | |
313 | 355 | if (animation_id_ > 0) { |
314 | 356 | animation_id_--; |
315 | 357 | QTimer::singleShot(ADELAY, this, SLOT(update())); |
316 | 358 | } |
317 | ||
318 | ||
319 | } | |
320 | ||
321 | ||
359 | } | |
360 | ||
361 | ||
362 | // Window resize | |
322 | 363 | void MainWindow::resizeEvent(QResizeEvent * /* event */) { |
323 | 364 | int nelem = applist.count(); |
324 | 365 | int cols = nelem / ROWS + 1; |
325 | ||
366 | ||
326 | 367 | // margins |
327 | 368 | QRegion m1(0, 0, cols * 64 + MARGIN * 4, TOP + ROWS * 64 + MARGIN * 4); |
328 | 369 | QRegion m2(MARGIN, MARGIN + TOP, cols * 64 + MARGIN * 2, ROWS * 64 + MARGIN * 2); |
329 | 370 | QRegion m3(MARGIN * 2, MARGIN * 2 + TOP, cols * 64, ROWS * 64); |
330 | ||
371 | ||
331 | 372 | QRegion all = m1.subtracted(m2); |
332 | 373 | all = all.united(m3); |
333 | ||
374 | ||
334 | 375 | setMask(all); |
335 | 376 | } |
336 | 377 | |
337 | 378 | |
338 | QSize MainWindow::sizeHint() const | |
339 | { | |
379 | // Window size hint | |
380 | QSize MainWindow::sizeHint() const { | |
340 | 381 | int nelem = applist.count(); |
341 | 382 | int cols = nelem / ROWS + 1; |
342 | ||
383 | ||
343 | 384 | return QSize(64 * cols + MARGIN * 4, ROWS * 64 + MARGIN * 4 + TOP); |
344 | 385 | } |
345 | 386 | |
347 | 388 | bool MainWindow::event(QEvent *event) { |
348 | 389 | if (event->type() == QEvent::ToolTip) { |
349 | 390 | QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event); |
350 | ||
391 | ||
351 | 392 | int index = applications_get_index(helpEvent->pos()); |
352 | 393 | if (index == -1) { |
353 | 394 | int x = helpEvent->pos().x(); |
354 | 395 | int y = helpEvent->pos().y(); |
355 | 396 | int nelem = applist.count(); |
356 | 397 | int cols = nelem / ROWS + 1; |
357 | ||
398 | ||
358 | 399 | if (x >= MARGIN * 2 + cols * 64 - 8 && x <= MARGIN * 2 + cols * 64 + 4 && |
359 | 400 | y >= 4 && y <= 15) { |
360 | 401 | QToolTip::showText(helpEvent->globalPos(), QString("Minimize")); |
365 | 406 | QToolTip::showText(helpEvent->globalPos(), QString("Run tools")); |
366 | 407 | return true; |
367 | 408 | } |
368 | ||
409 | ||
369 | 410 | else |
370 | 411 | QToolTip::hideText(); |
371 | 412 | } |
455 | 496 | addAction(qquit); |
456 | 497 | } |
457 | 498 | |
499 | // Help dialog | |
458 | 500 | void MainWindow::help() { |
459 | 501 | QMessageBox msgBox; |
460 | ||
502 | ||
461 | 503 | QString txt; |
462 | 504 | txt += "<br/>"; |
463 | 505 | txt += "Click on \"Firetools\" in the left top corner to open the tools window.<br/>\n"; |
481 | 523 | QMessageBox::about(this, tr("Firejail Launcher"), txt); |
482 | 524 | } |
483 | 525 | |
526 | // Shutdown sequence | |
484 | 527 | void MainWindow::main_quit() { |
485 | 528 | printf("exiting...\n"); |
486 | 529 |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
Binary diff not shown
Binary diff not shown
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> |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | <!DOCTYPE RCC><RCC version="1.0"> |
1 | 1 | <qresource prefix="/"> |
2 | 2 | <file>resources/firetools.png</file> |
3 | <file>resources/firetools-minimal.png</file> | |
3 | 4 | <file>resources/go-top.png</file> |
4 | 5 | <file>resources/go-up.png</file> |
5 | 6 | <file>resources/user-home.png</file> |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
53 | 53 | paths_.append(QString(ptr + 10)); |
54 | 54 | ops_.append(QString("R")); |
55 | 55 | } |
56 | else if (strncmp(ptr, "whitelist ", 10) == 0 ) { | |
57 | paths_.append(QString(ptr + 10)); | |
58 | ops_.append(QString("W")); | |
59 | } | |
60 | 56 | else if (strncmp(ptr, "clone ", 6) == 0 ) { |
61 | 57 | paths_.append(QString(ptr + 6)); |
62 | 58 | 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 | |
63 | 63 | } |
64 | 64 | |
65 | 65 | ptr = strtok(NULL, "\n"); |
86 | 86 | } |
87 | 87 | } |
88 | 88 | |
89 | QString rv = str; | |
90 | if (str.endsWith("B")) | |
91 | rv = "B"; | |
92 | if (str.endsWith("T")) | |
93 | rv = "T"; | |
94 | ||
95 | 89 | 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; | |
98 | 92 | } |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
38 | 38 | tr("<br/><b>Firejail</b> software not found. Please install it.<br/><br/><br/>")); |
39 | 39 | exit(1); |
40 | 40 | } |
41 | ||
41 | ||
42 | 42 | // verify sandbox |
43 | 43 | { |
44 | 44 | char *cmd; |
53 | 53 | exit(1); |
54 | 54 | } |
55 | 55 | } |
56 | ||
56 | ||
57 | 57 | // initialize FS |
58 | 58 | fs_ = new FS(pid); |
59 | ||
59 | ||
60 | 60 | top_ = new TopWidget(this); |
61 | 61 | connect(top_, SIGNAL(upClicked()), this, SLOT(handleUp())); |
62 | 62 | connect(top_, SIGNAL(rootClicked()), this, SLOT(handleRoot())); |
63 | 63 | connect(top_, SIGNAL(refreshClicked()), this, SLOT(handleRefresh())); |
64 | 64 | connect(top_, SIGNAL(homeClicked()), this, SLOT(handleHome())); |
65 | ||
65 | ||
66 | 66 | line_ = new QLineEdit(this); |
67 | 67 | QString txt = build_line(); |
68 | 68 | line_->setText(txt); |
69 | 69 | line_->setReadOnly(true); |
70 | ||
70 | ||
71 | 71 | table_ = new QTableWidget(0, 6, this); |
72 | 72 | QStringList header; |
73 | 73 | header.append(" "); |
84 | 84 | table_->setColumnWidth(3, 100); |
85 | 85 | table_->setColumnWidth(4, 100); |
86 | 86 | table_->setColumnWidth(5, 500); |
87 | table_->horizontalHeader()->setStretchLastSection(true); | |
87 | table_->horizontalHeader()->setStretchLastSection(true); | |
88 | 88 | table_->setShowGrid(false); |
89 | 89 | table_->setColumnHidden(0, true); |
90 | 90 | connect(table_, SIGNAL(cellClicked(int, int)), this, SLOT (cellClicked(int, int))); |
94 | 94 | empty1->setMinimumWidth(30); |
95 | 95 | QWidget *empty2 = new QWidget(this); |
96 | 96 | empty2->setMinimumWidth(10); |
97 | ||
97 | ||
98 | 98 | QGridLayout *mainLayout = new QGridLayout; |
99 | 99 | mainLayout->addWidget(top_, 0, 0); |
100 | 100 | mainLayout->addWidget(empty1, 0, 1); |
134 | 134 | qpath.replace(" ", "\\ "); |
135 | 135 | path = qpath.toUtf8().constData(); |
136 | 136 | } |
137 | ||
137 | ||
138 | 138 | if (arg_debug) |
139 | printf("print_files path %s\n", path); | |
140 | ||
139 | printf("print_files path %s\n", path); | |
140 | ||
141 | 141 | char *cmd; |
142 | 142 | if (asprintf(&cmd, "firejail --ls=%d %s 2>&1", pid_, path) == -1) |
143 | 143 | errExit("asprintf"); |
161 | 161 | |
162 | 162 | // fs flags |
163 | 163 | fs_->checkPath(QString(path)); |
164 | ||
164 | ||
165 | 165 | char *ptr = strtok(out, "\n"); |
166 | 166 | rows = 0; |
167 | 167 | while (ptr) { |
170 | 170 | strncmp(ptr, "Error:", 6) == 0) { |
171 | 171 | ptr = strtok(NULL, "\n"); |
172 | 172 | continue; |
173 | } | |
173 | } | |
174 | 174 | split_command(ptr); |
175 | ||
175 | ||
176 | 176 | // adjust the list in order to accept file names with spaces |
177 | 177 | if (sargc > 5) { |
178 | 178 | char *ptr = sargv[4]; |
183 | 183 | *ptr = ' '; |
184 | 184 | } |
185 | 185 | sargc = 5; |
186 | } | |
187 | ||
186 | } | |
187 | ||
188 | 188 | if (sargc == 5) { |
189 | 189 | if (strcmp(sargv[4], "..") != 0 && strcmp(sargv[4], ".") != 0) { |
190 | 190 | table_->setRowCount(rows + 1); |
191 | ||
191 | ||
192 | 192 | // image |
193 | 193 | if (*sargv[0] == 'd') { |
194 | 194 | table_->setItem(rows, 0, new QTableWidgetItem("D")); |
211 | 211 | timage->setData(Qt::DecorationRole, QPixmap::fromImage(*img)); |
212 | 212 | table_->setItem(rows, 1, new QTableWidgetItem(*timage)); |
213 | 213 | } |
214 | ||
214 | ||
215 | 215 | // fs flags |
216 | 216 | QString s = fs_->checkFile(QString(sargv[4])); |
217 | if (s == "B") | |
217 | ||
218 | if (s.contains("B")) | |
218 | 219 | 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")) | |
220 | 223 | 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")) | |
222 | 237 | 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"; | |
229 | 238 | |
230 | 239 | QTableWidgetItem *item = new QTableWidgetItem(s); |
231 | item->setTextAlignment(Qt::AlignCenter); | |
240 | item->setTextAlignment(Qt::AlignCenter); | |
232 | 241 | table_->setItem(rows, 2, item); |
233 | ||
242 | ||
234 | 243 | item = new QTableWidgetItem(sargv[1]); |
235 | item->setTextAlignment(Qt::AlignCenter); | |
244 | item->setTextAlignment(Qt::AlignCenter); | |
236 | 245 | table_->setItem(rows, 3, item); |
237 | 246 | |
238 | 247 | item = new QTableWidgetItem(sargv[3]); |
239 | 248 | item->setTextAlignment(Qt::AlignCenter); |
240 | 249 | table_->setItem(rows, 4, item); |
241 | ||
250 | ||
242 | 251 | item = new QTableWidgetItem(QString(" ") + QString(sargv[4])); |
243 | 252 | // item->setTextAlignment(Qt::AlignHorizontal_Mask); |
244 | 253 | table_->setItem(rows, 5, item); |
245 | rows++; | |
254 | rows++; | |
246 | 255 | } |
247 | 256 | } |
248 | ||
257 | ||
249 | 258 | ptr = strtok(NULL, "\n"); |
250 | } | |
259 | } | |
251 | 260 | } |
252 | 261 | |
253 | 262 | void MainWindow::handleUp() { |
255 | 264 | return handleRefresh(); |
256 | 265 | |
257 | 266 | path_.takeLast(); |
258 | QString full_path = build_path(); | |
267 | QString full_path = build_path(); | |
259 | 268 | print_files(full_path.toStdString().c_str()); |
260 | 269 | QString txt = build_line(); |
261 | 270 | line_->setText(txt); |
262 | 271 | } |
263 | 272 | |
264 | 273 | void MainWindow::handleRefresh() { |
265 | QString full_path = build_path(); | |
274 | QString full_path = build_path(); | |
266 | 275 | print_files(full_path.toStdString().c_str()); |
267 | 276 | QString txt = build_line(); |
268 | 277 | line_->setText(txt); |
274 | 283 | path_.append(QString("home")); |
275 | 284 | if (username) |
276 | 285 | path_.append(QString(username)); |
277 | QString full_path = build_path(); | |
286 | QString full_path = build_path(); | |
278 | 287 | print_files(full_path.toStdString().c_str()); |
279 | 288 | QString txt = build_line(); |
280 | 289 | line_->setText(txt); |
289 | 298 | |
290 | 299 | QString MainWindow::build_path() { |
291 | 300 | QString retval = QString("/"); |
292 | ||
301 | ||
293 | 302 | for (int i = 0; i < path_.size(); ++i) { |
294 | 303 | retval += path_.at(i); |
295 | 304 | retval += QString("/"); |
301 | 310 | QString MainWindow::build_line() { |
302 | 311 | QString retval = "/"; |
303 | 312 | // retval.sprintf("%d:///", pid_); |
304 | ||
313 | ||
305 | 314 | for (int i = 0; i < path_.size(); ++i) { |
306 | 315 | retval += path_.at(i); |
307 | 316 | retval += QString("/"); |
308 | 317 | } |
309 | ||
318 | ||
310 | 319 | return retval; |
311 | 320 | } |
312 | 321 | |
320 | 329 | dir = dir.mid(2); |
321 | 330 | path_.append(dir); |
322 | 331 | |
323 | QString full_path = build_path(); | |
332 | QString full_path = build_path(); | |
324 | 333 | print_files(full_path.toStdString().c_str()); |
325 | 334 | QString txt = build_line(); |
326 | 335 | line_->setText(txt); |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
43 | 43 | void print_files(const char *path); |
44 | 44 | QString build_path(); |
45 | 45 | QString build_line(); |
46 | ||
46 | ||
47 | 47 | private: |
48 | 48 | pid_t pid_; |
49 | 49 | TopWidget *top_; |
Binary diff not shown
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
44 | 44 | static int getX11Display(pid_t pid); |
45 | 45 | |
46 | 46 | |
47 | StatsDialog::StatsDialog(): QDialog(), mode_(MODE_TOP), pid_(0), uid_(0), | |
47 | StatsDialog::StatsDialog(): QDialog(), mode_(MODE_TOP), pid_(0), uid_(0), | |
48 | 48 | pid_initialized_(false), pid_seccomp_(false), pid_caps_(QString("")), pid_noroot_(false), |
49 | 49 | pid_cpu_cores_(QString("")), pid_protocol_(QString("")), pid_name_(QString("")), |
50 | 50 | profile_(QString("")), pid_x11_(0), |
57 | 57 | procView_->setOpenLinks(false); |
58 | 58 | procView_->setOpenExternalLinks(false); |
59 | 59 | procView_->setText("accumulating data..."); |
60 | ||
60 | ||
61 | 61 | connect(procView_, SIGNAL(anchorClicked(const QUrl &)), this, SLOT(anchorClicked(const QUrl &))); |
62 | 62 | |
63 | 63 | QGridLayout *layout = new QGridLayout; |
64 | 64 | layout->addWidget(procView_, 0, 0); |
65 | 65 | setLayout(layout); |
66 | ||
66 | ||
67 | 67 | // set screen size and title |
68 | 68 | int x; |
69 | 69 | int y; |
70 | 70 | config_read_screen_size(&x, &y); |
71 | 71 | resize(x, y); |
72 | 72 | setWindowTitle(tr("Firetools")); |
73 | ||
73 | ||
74 | 74 | // detect if joining a sandbox is possible on this system |
75 | 75 | struct utsname u; |
76 | 76 | int rv = uname(&u); |
84 | 84 | have_join_ = false; |
85 | 85 | } |
86 | 86 | } |
87 | ||
87 | ||
88 | 88 | // detect the number of capabilities supported by the current kernel |
89 | 89 | char *str = run_program("firejail --debug-caps"); |
90 | 90 | if (!str) |
95 | 95 | printf("%d capabilities supported by the kernel\n", val); |
96 | 96 | caps_cnt_ = val; |
97 | 97 | } |
98 | ||
98 | ||
99 | 99 | 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) | |
101 | 101 | no_network_ = true; |
102 | 102 | |
103 | 103 | thread_ = new PidThread(); |
104 | 104 | connect(thread_, SIGNAL(cycleReady()), this, SLOT(cycleReady())); |
105 | ||
105 | ||
106 | 106 | } |
107 | 107 | |
108 | 108 | StatsDialog::~StatsDialog() { |
125 | 125 | msg += " <a href=\"newsandbox\">Configuration Wizard</a>"; |
126 | 126 | msg += "</td></tr></table>"; |
127 | 127 | } |
128 | ||
128 | ||
129 | 129 | else if (mode_ == MODE_PID) { |
130 | 130 | msg += "<table><tr><td width=\"5\"></td><td>"; |
131 | 131 | msg += "<a href=\"top\">Home</a>"; |
132 | if (uid_ == getuid()) | |
132 | if (uid_ == getuid()) | |
133 | 133 | msg += " <a href=\"shut\">Shutdown</a>"; |
134 | 134 | if (have_join_ && uid_ == getuid()) |
135 | 135 | msg += " <a href=\"join\">Join</a>"; |
138 | 138 | msg += " <a href=\"dns\">DNS</a>"; |
139 | 139 | msg += "</td></tr></table>"; |
140 | 140 | } |
141 | ||
142 | else if (mode_ == MODE_TREE || mode_ == MODE_SECCOMP || mode_ == MODE_DNS || mode_ == MODE_CAPS) { | |
141 | ||
142 | else { | |
143 | 143 | msg += "<table><tr><td width=\"5\"></td><td>"; |
144 | 144 | msg += "<a href=\"top\">Home</a>"; |
145 | 145 | msg += " <a href=\"back\">" + QString::number(pid_) + "</a>"; |
146 | if (uid_ == getuid()) | |
146 | if (uid_ == getuid()) | |
147 | 147 | msg += " <a href=\"shut\">Shutdown</a>"; |
148 | 148 | if (have_join_ && uid_ == getuid()) |
149 | 149 | msg += " <a href=\"join\">Join</a>"; |
161 | 161 | QString msg = header() + "<hr>"; |
162 | 162 | msg += "<table><tr><td width=\"5\"></td><td><b>Sandbox List</b></td></tr></table><br/>\n"; |
163 | 163 | msg += "<table><tr><td width=\"5\"></td><td width=\"60\">PID</td/><td width=\"60\">CPU<br/>(%)</td><td>Memory<br/>(KiB) </td><td>RX<br/>(KB/s) </td><td>TX<br/>(KB/s) </td><td>Command</td>\n"; |
164 | ||
164 | ||
165 | 165 | int cycle = Db::instance().getCycle(); |
166 | 166 | assert(cycle < DbPid::MAXCYCLE); |
167 | 167 | DbPid *ptr = Db::instance().firstPid(); |
168 | ||
169 | ||
168 | ||
169 | ||
170 | 170 | while (ptr) { |
171 | 171 | pid_t pid = ptr->getPid(); |
172 | 172 | const char *cmd = ptr->getCmd(); |
176 | 176 | 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>", |
177 | 177 | pid, pid, st->cpu_, (int) (st->rss_ + st->shared_), |
178 | 178 | st->rx_, st->tx_, cmd) != -1) { |
179 | ||
179 | ||
180 | 180 | msg += str; |
181 | 181 | free(str); |
182 | 182 | } |
183 | 183 | } |
184 | ||
184 | ||
185 | 185 | ptr = ptr->getNext(); |
186 | 186 | } |
187 | ||
188 | msg += "</table>"; | |
187 | ||
188 | msg += "</table>"; | |
189 | 189 | procView_->setHtml(msg); |
190 | 190 | } |
191 | 191 | |
192 | ||
193 | void StatsDialog::updateTree() { | |
194 | int cycle = Db::instance().getCycle(); | |
195 | assert(cycle < DbPid::MAXCYCLE); | |
192 | void StatsDialog::updateFirewall() { | |
196 | 193 | DbPid *dbptr = Db::instance().findPid(pid_); |
197 | 194 | if (!dbptr) { |
198 | QString msg = "Process not found!<br/>"; | |
199 | msg += "<hr>" + header(); | |
200 | procView_->setHtml(msg); | |
201 | 195 | 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; | |
203 | 219 | return; |
204 | 220 | } |
205 | 221 | |
207 | 223 | printf("reading process tree configuration\n"); |
208 | 224 | QString msg = header(); |
209 | 225 | msg += "<hr><table><tr><td width=\"5\"></td><td>"; |
210 | ||
226 | ||
211 | 227 | char *str = 0; |
212 | 228 | char *cmd; |
213 | 229 | if (asprintf(&cmd, "firemon --tree --nowrap %d", pid_) != -1) { |
219 | 235 | *ptr = '\0'; |
220 | 236 | msg += QString(str) + "<br/>\n"; |
221 | 237 | ptr++; |
222 | ||
238 | ||
223 | 239 | while (*ptr == ' ') { |
224 | 240 | msg += " "; |
225 | 241 | ptr++; |
226 | } | |
242 | } | |
227 | 243 | str = ptr; |
228 | 244 | continue; |
229 | 245 | } |
230 | 246 | ptr++; |
231 | 247 | } |
232 | 248 | free(cmd); |
233 | } | |
249 | } | |
234 | 250 | |
235 | 251 | msg += "</td></tr></table>"; |
236 | 252 | procView_->setHtml(msg); |
237 | 253 | } |
238 | 254 | |
255 | ||
239 | 256 | void StatsDialog::updateSeccomp() { |
240 | int cycle = Db::instance().getCycle(); | |
241 | assert(cycle < DbPid::MAXCYCLE); | |
242 | 257 | DbPid *dbptr = Db::instance().findPid(pid_); |
243 | 258 | if (!dbptr) { |
244 | QString msg = "Process not found!<br/>"; | |
245 | msg += "<hr>" + header(); | |
246 | procView_->setHtml(msg); | |
247 | 259 | mode_ = MODE_TOP; |
248 | QTimer::singleShot(2000, this, SLOT(cycleReady())); | |
249 | 260 | return; |
250 | 261 | } |
251 | 262 | |
255 | 266 | printf("reading seccomp configuration\n"); |
256 | 267 | QString msg = header(); |
257 | 268 | msg += "<hr><table><tr><td width=\"5\"></td><td>"; |
258 | ||
269 | ||
259 | 270 | char *str = 0; |
260 | 271 | char *cmd; |
261 | 272 | if (asprintf(&cmd, "firejail --seccomp.print=%d", pid_) != -1) { |
267 | 278 | *ptr = '\0'; |
268 | 279 | msg += QString(str) + "<br/>\n"; |
269 | 280 | ptr++; |
270 | ||
281 | ||
271 | 282 | while (*ptr == ' ') { |
272 | 283 | msg += " "; |
273 | 284 | ptr++; |
274 | } | |
285 | } | |
275 | 286 | str = ptr; |
276 | 287 | continue; |
277 | 288 | } |
278 | 289 | ptr++; |
279 | 290 | } |
280 | 291 | free(cmd); |
281 | } | |
282 | ||
292 | } | |
293 | ||
283 | 294 | msg += "</td></tr></table>"; |
284 | 295 | procView_->setHtml(msg); |
285 | 296 | storage_seccomp_ = msg; |
288 | 299 | |
289 | 300 | |
290 | 301 | void StatsDialog::updateCaps() { |
291 | int cycle = Db::instance().getCycle(); | |
292 | assert(cycle < DbPid::MAXCYCLE); | |
293 | 302 | DbPid *dbptr = Db::instance().findPid(pid_); |
294 | 303 | if (!dbptr) { |
295 | QString msg = "Process not found!<br/>"; | |
296 | msg += "<hr>" + header(); | |
297 | procView_->setHtml(msg); | |
298 | 304 | mode_ = MODE_TOP; |
299 | QTimer::singleShot(2000, this, SLOT(cycleReady())); | |
300 | 305 | return; |
301 | 306 | } |
302 | 307 | |
306 | 311 | printf("reading caps configuration\n"); |
307 | 312 | msg = header(); |
308 | 313 | msg += "<hr><table><tr><td width=\"5\"></td><td>"; |
309 | ||
314 | ||
310 | 315 | char *str = 0; |
311 | 316 | char *cmd; |
312 | 317 | if (asprintf(&cmd, "firejail --caps.print=%d", pid_) != -1) { |
320 | 325 | if (cnt >= caps_cnt_) |
321 | 326 | break; |
322 | 327 | cnt++; |
323 | ||
328 | ||
324 | 329 | *ptr = '\0'; |
325 | 330 | msg += QString(str) + "<br/>\n"; |
326 | 331 | ptr++; |
327 | ||
328 | // while (*ptr == ' ') { | |
329 | // msg += " "; | |
330 | // ptr++; | |
331 | // } | |
332 | 332 | str = ptr; |
333 | 333 | continue; |
334 | 334 | } |
335 | 335 | ptr++; |
336 | 336 | } |
337 | 337 | free(cmd); |
338 | } | |
339 | ||
338 | } | |
339 | ||
340 | 340 | msg += "</pre></td></tr></table>"; |
341 | 341 | procView_->setHtml(msg); |
342 | 342 | storage_caps_ = msg; |
344 | 344 | } |
345 | 345 | |
346 | 346 | void StatsDialog::updateDns() { |
347 | int cycle = Db::instance().getCycle(); | |
348 | assert(cycle < DbPid::MAXCYCLE); | |
349 | 347 | DbPid *dbptr = Db::instance().findPid(pid_); |
350 | 348 | if (!dbptr) { |
351 | QString msg = "Process not found!<br/>"; | |
352 | msg += "<hr>" + header(); | |
353 | procView_->setHtml(msg); | |
354 | 349 | mode_ = MODE_TOP; |
355 | QTimer::singleShot(2000, this, SLOT(cycleReady())); | |
356 | 350 | return; |
357 | 351 | } |
358 | 352 | |
360 | 354 | if (msg.isEmpty()) { |
361 | 355 | if (arg_debug) |
362 | 356 | printf("reading dns configuration\n"); |
363 | ||
357 | ||
364 | 358 | msg = header(); |
365 | 359 | msg += "<hr><table><tr><td width=\"5\"></td><td>"; |
366 | ||
360 | ||
367 | 361 | char *str = 0; |
368 | 362 | char *cmd; |
369 | 363 | if (asprintf(&cmd, "firejail --dns.print=%d", pid_) != -1) { |
370 | 364 | str = run_program(cmd); |
371 | 365 | char *ptr = str; |
372 | ||
366 | ||
373 | 367 | // htmlize! |
374 | 368 | while (*ptr != 0) { |
375 | 369 | if (*ptr == '\n') { |
376 | 370 | *ptr = '\0'; |
377 | 371 | msg += QString(str) + "<br/>\n"; |
378 | 372 | ptr++; |
379 | ||
373 | ||
380 | 374 | while (*ptr == ' ') { |
381 | 375 | msg += " "; |
382 | 376 | ptr++; |
383 | } | |
377 | } | |
384 | 378 | str = ptr; |
385 | 379 | continue; |
386 | 380 | } |
387 | 381 | ptr++; |
388 | 382 | } |
389 | } | |
383 | } | |
390 | 384 | free(cmd); |
391 | ||
385 | ||
392 | 386 | msg += "</td></tr></table>"; |
393 | 387 | procView_->setHtml(msg); |
394 | 388 | storage_dns_ = msg; |
398 | 392 | void StatsDialog::kernelSecuritySettings() { |
399 | 393 | if (arg_debug) |
400 | 394 | printf("Checking security settings for pid %d\n", pid_); |
401 | ||
395 | ||
402 | 396 | // reset all |
403 | 397 | pid_seccomp_ = false; |
404 | 398 | pid_caps_ = QString(""); |
405 | 399 | pid_cpu_cores_ = QString(""); |
406 | 400 | pid_protocol_ = QString(""); |
407 | 401 | pid_mem_deny_exec_ = QString("disabled"); |
402 | pid_apparmor_ = QString(""); | |
408 | 403 | |
409 | 404 | // caps |
410 | 405 | char *cmd; |
432 | 427 | } |
433 | 428 | } |
434 | 429 | free(cmd); |
435 | ||
430 | ||
436 | 431 | // cpu cores |
437 | 432 | if (asprintf(&cmd, "firemon --cpu %d", pid_) == -1) |
438 | 433 | return; |
449 | 444 | // protocols |
450 | 445 | if (asprintf(&cmd, "firejail --protocol.print=%d", pid_) == -1) |
451 | 446 | return; |
447 | ||
452 | 448 | str = run_program(cmd); |
453 | 449 | if (str) { |
454 | 450 | if (strncmp(str, "Cannot", 6) == 0) |
458 | 454 | } |
459 | 455 | free(cmd); |
460 | 456 | |
457 | // mem deny exec | |
461 | 458 | if (asprintf(&cmd, "firejail --ls=%d /run/firejail/mnt", pid_) == -1) |
462 | 459 | return; |
463 | 460 | str = run_program(cmd); |
464 | 461 | if (str) { |
465 | 462 | if (strstr(str, "seccomp.mdwx")) |
466 | 463 | 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)); | |
467 | 476 | } |
468 | 477 | free(cmd); |
469 | 478 | } |
477 | 486 | if (pids[i].level == 2 && pids[i].parent == id) |
478 | 487 | return i; |
479 | 488 | } |
480 | ||
489 | ||
481 | 490 | return -1; |
482 | 491 | } |
483 | 492 | |
484 | 493 | |
485 | 494 | |
486 | ||
495 | ||
487 | 496 | void StatsDialog::updatePid() { |
488 | 497 | QString msg = ""; |
489 | 498 | |
491 | 500 | assert(cycle < DbPid::MAXCYCLE); |
492 | 501 | DbPid *ptr = Db::instance().findPid(pid_); |
493 | 502 | if (!ptr) { |
494 | msg += "Process not found!<br/>"; | |
495 | msg += "<hr>" + header(); | |
496 | procView_->setHtml(msg); | |
497 | 503 | mode_ = MODE_TOP; |
498 | QTimer::singleShot(2000, this, SLOT(cycleReady())); | |
499 | 504 | return; |
500 | 505 | } |
501 | 506 | |
502 | 507 | const char *cmd = ptr->getCmd(); |
503 | 508 | if (!cmd) { |
504 | msg += "Process not found!<br/>"; | |
505 | msg += "<hr>" + header(); | |
506 | procView_->setHtml(msg); | |
507 | 509 | mode_ = MODE_TOP; |
508 | QTimer::singleShot(2000, this, SLOT(cycleReady())); | |
509 | 510 | return; |
510 | 511 | } |
511 | 512 | |
533 | 534 | msg += "<tr><td width=\"5\"></td><td><b>Command:</b> " + QString(cmd) + "</td></tr>"; |
534 | 535 | if (!profile_.isEmpty()) |
535 | 536 | msg += "<tr><td width=\"5\"></td><td><b>Profile:</b> " + profile_ + "</td></tr>"; |
536 | // add | |
537 | // add | |
537 | 538 | msg += "</table><br/>"; |
538 | 539 | |
539 | 540 | msg += "<table>"; |
542 | 543 | msg += "<td><b>RX:</b> unknown</td></tr>"; |
543 | 544 | else |
544 | 545 | msg += QString("<td><b>RX:</b> ") + QString::number(st->rx_) + " KB/s</td></tr>"; |
545 | ||
546 | ||
546 | 547 | msg += QString("<tr><td></td><td><b>User:</b> ") + pw->pw_name + "</td>"; |
547 | 548 | if (ptr->networkDisabled() || no_network_) |
548 | 549 | msg += "<td><b>TX:</b> unknown</td></tr>"; |
558 | 559 | msg += "</td></tr>"; |
559 | 560 | |
560 | 561 | msg += QString("<tr><td></td><td><b>Memory:</b> ") + QString::number((int) (st->rss_ + st->shared_)) + " KiB </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 | ||
565 | 566 | // user namespace |
566 | 567 | msg += "<td><b>User Namespace:</b> "; |
567 | ||
568 | ||
568 | 569 | if (pid_noroot_) |
569 | 570 | msg += "enabled"; |
570 | 571 | else |
590 | 591 | // memory deny exec |
591 | 592 | msg += "<td><b>Memory deny exec:</b> " + pid_mem_deny_exec_ + "</td></tr>"; |
592 | 593 | |
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 | ||
593 | 600 | // graph type |
594 | 601 | msg += "<tr></tr>"; |
595 | 602 | msg += "<tr><td></td>"; |
596 | 603 | 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>"; | |
598 | 605 | } |
599 | 606 | 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>"; | |
601 | 608 | } |
602 | 609 | 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>"; | |
604 | 611 | } |
605 | 612 | else |
606 | 613 | 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"; | |
607 | 620 | |
608 | 621 | // graphs |
609 | 622 | msg += "<tr></tr>"; |
612 | 625 | msg += "<tr><td></td><td>"+ graph(2, ptr, cycle, graph_type_) + "</td><td>" + graph(3, ptr, cycle, graph_type_) + "</td></tr>"; |
613 | 626 | |
614 | 627 | msg += QString("</table><br/>"); |
615 | ||
628 | ||
616 | 629 | // bandwidth limits |
617 | 630 | if (ptr->networkDisabled() == false && no_network_ == false) { |
618 | 631 | char *fname; |
649 | 662 | updateDns(); |
650 | 663 | else if (mode_ == MODE_CAPS) |
651 | 664 | updateCaps(); |
665 | else if (mode_ == MODE_FIREWALL) | |
666 | updateFirewall(); | |
652 | 667 | } |
653 | 668 | |
654 | 669 | void StatsDialog::anchorClicked(const QUrl & link) { |
655 | 670 | cleanStorage(); // full storage cleanup on any click |
656 | 671 | QString linkstr = link.toString(); |
657 | ||
672 | ||
658 | 673 | if (linkstr == "top") { |
659 | 674 | mode_ = MODE_TOP; |
660 | 675 | } |
669 | 684 | mode_ = MODE_PID; |
670 | 685 | else if (mode_ == MODE_CAPS) |
671 | 686 | 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 | ; | |
673 | 691 | else |
674 | 692 | assert(0); |
675 | 693 | } |
693 | 711 | } |
694 | 712 | else if (linkstr == "dns") { |
695 | 713 | mode_ = MODE_DNS; |
714 | } | |
715 | else if (linkstr == "firewall") { | |
716 | mode_ = MODE_FIREWALL; | |
696 | 717 | } |
697 | 718 | else if (linkstr == "shut") { |
698 | 719 | QMessageBox msgBox; |
709 | 730 | (void) rv; |
710 | 731 | free(cmd); |
711 | 732 | } |
712 | QApplication::restoreOverrideCursor(); | |
733 | QApplication::restoreOverrideCursor(); | |
713 | 734 | mode_ = MODE_TOP; |
714 | 735 | } |
715 | 736 | } |
733 | 754 | else if (linkstr == "about") { |
734 | 755 | QString msg = "<table cellpadding=\"10\"><tr><td><img src=\":/resources/fstats.png\"></td>"; |
735 | 756 | 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/>" | |
740 | 761 | "Firejail is a SUID sandbox program that reduces the risk of security " |
741 | 762 | "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/>") + | |
743 | 764 | tr("Firetools version:") + " " + PACKAGE_VERSION + "<br/>" + |
744 | 765 | tr("QT version: ") + " " + QT_VERSION_STR + "<br/>" + |
745 | 766 | tr("License:") + " GPL v2<br/>" + |
746 | 767 | tr("Homepage:") + " " + QString(PACKAGE_URL) + "</td></tr></table><br/><br/>"; |
747 | 768 | |
748 | 769 | QMessageBox::about(this, tr("About"), msg); |
749 | ||
770 | ||
750 | 771 | } |
751 | 772 | else if (linkstr == "newsandbox") { |
752 | 773 | // start firejail-ui as a separate process |
769 | 790 | pid_x11_ = 0; |
770 | 791 | mode_ = MODE_PID; |
771 | 792 | } |
772 | ||
793 | ||
773 | 794 | if (data_ready) |
774 | 795 | cycleReady(); |
775 | 796 | } |
776 | ||
797 | ||
777 | 798 | |
778 | 799 | static bool userNamespace(pid_t pid) { |
779 | 800 | if (arg_debug) |
780 | 801 | printf("Checking user namespace for pid %d\n", pid); |
781 | ||
802 | ||
782 | 803 | // test user namespaces available in the kernel |
783 | 804 | struct stat s1; |
784 | 805 | struct stat s2; |
792 | 813 | pid = find_child(pid); |
793 | 814 | if (pid == -1) |
794 | 815 | return false; |
795 | ||
816 | ||
796 | 817 | // read uid map |
797 | 818 | char *uidmap; |
798 | 819 | if (asprintf(&uidmap, "/proc/%u/uid_map", pid) == -1) |
813 | 834 | } |
814 | 835 | fclose(fp); |
815 | 836 | free(uidmap); |
816 | return found; | |
837 | return found; | |
817 | 838 | } |
818 | 839 | |
819 | 840 | static QString getName(pid_t pid) { |
830 | 851 | fclose(fp); |
831 | 852 | } |
832 | 853 | free(fname); |
833 | ||
854 | ||
834 | 855 | return retval; |
835 | 856 | } |
836 | 857 | |
848 | 869 | fclose(fp); |
849 | 870 | } |
850 | 871 | free(fname); |
851 | ||
872 | ||
852 | 873 | return retval; |
853 | 874 | } |
854 | 875 | |
866 | 887 | fclose(fp); |
867 | 888 | } |
868 | 889 | free(fname); |
869 | ||
890 | ||
870 | 891 | return retval; |
871 | 892 | } |
0 | 0 | /* |
1 | * Copyright (C) 2015-2017 Firetools Authors | |
1 | * Copyright (C) 2015-2018 Firetools Authors | |
2 | 2 | * |
3 | 3 | * This file is part of firetools project |
4 | 4 | * |
49 | 49 | void updateSeccomp(); |
50 | 50 | void updateDns(); |
51 | 51 | void updateCaps(); |
52 | void updateFirewall(); | |
52 | 53 | void cleanStorage(); |
53 | 54 | |
54 | 55 | private: |
60 | 61 | #define MODE_SECCOMP 3 |
61 | 62 | #define MODE_DNS 4 |
62 | 63 | #define MODE_CAPS 5 |
64 | #define MODE_FIREWALL 6 | |
63 | 65 | int mode_; |
64 | 66 | int pid_; // pid value for mode 1 |
65 | 67 | uid_t uid_; |
73 | 75 | QString pid_protocol_; |
74 | 76 | QString pid_name_; |
75 | 77 | QString pid_mem_deny_exec_; |
78 | QString pid_apparmor_; | |
76 | 79 | QString profile_; |
77 | 80 | int pid_x11_; |
78 | 81 |