diff options
-rw-r--r-- | .github/workflows/build-extra.yml | 6 | ||||
-rw-r--r-- | .github/workflows/build.yml | 4 | ||||
-rw-r--r-- | .github/workflows/codeql-analysis.yml | 2 | ||||
-rw-r--r-- | .github/workflows/profile-checks.yml | 2 | ||||
-rw-r--r-- | Makefile.in | 3 | ||||
-rwxr-xr-x | configure | 3 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rwxr-xr-x | contrib/firejail-welcome.sh | 128 | ||||
-rwxr-xr-x | src/firecfg/firejail-welcome.sh | 204 | ||||
-rw-r--r-- | src/firecfg/main.c | 30 | ||||
-rw-r--r-- | src/fzenity/Makefile.in | 17 | ||||
-rw-r--r-- | src/fzenity/main.c | 176 |
12 files changed, 438 insertions, 139 deletions
diff --git a/.github/workflows/build-extra.yml b/.github/workflows/build-extra.yml index 4f5fc5049..27f11459c 100644 --- a/.github/workflows/build-extra.yml +++ b/.github/workflows/build-extra.yml | |||
@@ -30,7 +30,7 @@ jobs: | |||
30 | build-clang: | 30 | build-clang: |
31 | runs-on: ubuntu-20.04 | 31 | runs-on: ubuntu-20.04 |
32 | steps: | 32 | steps: |
33 | - uses: actions/checkout@dcd71f646680f2efd8db4afa5ad64fdcba30e748 | 33 | - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b |
34 | - name: configure | 34 | - name: configure |
35 | run: CC=clang-11 ./configure --enable-fatal-warnings | 35 | run: CC=clang-11 ./configure --enable-fatal-warnings |
36 | - name: make | 36 | - name: make |
@@ -38,7 +38,7 @@ jobs: | |||
38 | scan-build: | 38 | scan-build: |
39 | runs-on: ubuntu-20.04 | 39 | runs-on: ubuntu-20.04 |
40 | steps: | 40 | steps: |
41 | - uses: actions/checkout@dcd71f646680f2efd8db4afa5ad64fdcba30e748 | 41 | - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b |
42 | - name: install clang-tools-11 | 42 | - name: install clang-tools-11 |
43 | run: sudo apt-get install clang-tools-11 | 43 | run: sudo apt-get install clang-tools-11 |
44 | - name: configure | 44 | - name: configure |
@@ -48,7 +48,7 @@ jobs: | |||
48 | cppcheck: | 48 | cppcheck: |
49 | runs-on: ubuntu-20.04 | 49 | runs-on: ubuntu-20.04 |
50 | steps: | 50 | steps: |
51 | - uses: actions/checkout@dcd71f646680f2efd8db4afa5ad64fdcba30e748 | 51 | - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b |
52 | - name: install cppcheck | 52 | - name: install cppcheck |
53 | run: sudo apt-get install cppcheck | 53 | run: sudo apt-get install cppcheck |
54 | - name: cppcheck | 54 | - name: cppcheck |
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4d54b5178..faea6970f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml | |||
@@ -22,7 +22,9 @@ jobs: | |||
22 | build_and_test: | 22 | build_and_test: |
23 | runs-on: ubuntu-20.04 | 23 | runs-on: ubuntu-20.04 |
24 | steps: | 24 | steps: |
25 | - uses: actions/checkout@dcd71f646680f2efd8db4afa5ad64fdcba30e748 | 25 | - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b |
26 | - name: update package information | ||
27 | run: sudo apt-get update | ||
26 | - name: install dependencies | 28 | - name: install dependencies |
27 | run: sudo apt-get install gcc-11 libapparmor-dev libselinux1-dev expect xzdec | 29 | run: sudo apt-get install gcc-11 libapparmor-dev libselinux1-dev expect xzdec |
28 | - name: configure | 30 | - name: configure |
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 69fc8834b..95f00a34e 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml | |||
@@ -43,7 +43,7 @@ jobs: | |||
43 | 43 | ||
44 | steps: | 44 | steps: |
45 | - name: Checkout repository | 45 | - name: Checkout repository |
46 | uses: actions/checkout@dcd71f646680f2efd8db4afa5ad64fdcba30e748 | 46 | uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b |
47 | 47 | ||
48 | # Initializes the CodeQL tools for scanning. | 48 | # Initializes the CodeQL tools for scanning. |
49 | - name: Initialize CodeQL | 49 | - name: Initialize CodeQL |
diff --git a/.github/workflows/profile-checks.yml b/.github/workflows/profile-checks.yml index 59997db2f..9138e8a57 100644 --- a/.github/workflows/profile-checks.yml +++ b/.github/workflows/profile-checks.yml | |||
@@ -20,7 +20,7 @@ jobs: | |||
20 | profile-checks: | 20 | profile-checks: |
21 | runs-on: ubuntu-20.04 | 21 | runs-on: ubuntu-20.04 |
22 | steps: | 22 | steps: |
23 | - uses: actions/checkout@dcd71f646680f2efd8db4afa5ad64fdcba30e748 | 23 | - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b |
24 | - name: sort.py | 24 | - name: sort.py |
25 | run: ./ci/check/profiles/sort.py etc/inc/*.inc etc/{profile-a-l,profile-m-z}/*.profile | 25 | run: ./ci/check/profiles/sort.py etc/inc/*.inc etc/{profile-a-l,profile-m-z}/*.profile |
26 | - name: private-etc-always-required.sh | 26 | - name: private-etc-always-required.sh |
diff --git a/Makefile.in b/Makefile.in index 9b1ecc4ad..945e30e84 100644 --- a/Makefile.in +++ b/Makefile.in | |||
@@ -27,7 +27,7 @@ COMPLETIONDIRS = src/zsh_completion src/bash_completion | |||
27 | all: all_items mydirs $(MAN_TARGET) filters | 27 | all: all_items mydirs $(MAN_TARGET) filters |
28 | APPS = src/firecfg/firecfg src/firejail/firejail src/firemon/firemon src/profstats/profstats src/jailcheck/jailcheck | 28 | APPS = src/firecfg/firecfg src/firejail/firejail src/firemon/firemon src/profstats/profstats src/jailcheck/jailcheck |
29 | SBOX_APPS = src/fbuilder/fbuilder src/ftee/ftee src/fids/fids | 29 | SBOX_APPS = src/fbuilder/fbuilder src/ftee/ftee src/fids/fids |
30 | SBOX_APPS_NON_DUMPABLE = src/fcopy/fcopy src/fldd/fldd src/fnet/fnet src/fnetfilter/fnetfilter | 30 | SBOX_APPS_NON_DUMPABLE = src/fcopy/fcopy src/fldd/fldd src/fnet/fnet src/fnetfilter/fnetfilter src/fzenity/fzenity |
31 | SBOX_APPS_NON_DUMPABLE += src/fsec-optimize/fsec-optimize src/fsec-print/fsec-print src/fseccomp/fseccomp | 31 | SBOX_APPS_NON_DUMPABLE += src/fsec-optimize/fsec-optimize src/fsec-print/fsec-print src/fseccomp/fseccomp |
32 | SBOX_APPS_NON_DUMPABLE += src/fnettrace/fnettrace src/fnettrace-dns/fnettrace-dns src/fnettrace-sni/fnettrace-sni | 32 | SBOX_APPS_NON_DUMPABLE += src/fnettrace/fnettrace src/fnettrace-dns/fnettrace-dns src/fnettrace-sni/fnettrace-sni |
33 | MYDIRS = src/lib $(MAN_SRC) $(COMPLETIONDIRS) | 33 | MYDIRS = src/lib $(MAN_SRC) $(COMPLETIONDIRS) |
@@ -118,6 +118,7 @@ endif | |||
118 | install -m 0755 src/jailcheck/jailcheck $(DESTDIR)$(bindir) | 118 | install -m 0755 src/jailcheck/jailcheck $(DESTDIR)$(bindir) |
119 | # libraries and plugins | 119 | # libraries and plugins |
120 | install -m 0755 -d $(DESTDIR)$(libdir)/firejail | 120 | install -m 0755 -d $(DESTDIR)$(libdir)/firejail |
121 | install -m 0755 -t $(DESTDIR)$(libdir)/firejail src/firecfg/firejail-welcome.sh | ||
121 | install -m 0644 -t $(DESTDIR)$(libdir)/firejail $(MYLIBS) $(SECCOMP_FILTERS) | 122 | install -m 0644 -t $(DESTDIR)$(libdir)/firejail $(MYLIBS) $(SECCOMP_FILTERS) |
122 | install -m 0755 -t $(DESTDIR)$(libdir)/firejail $(SBOX_APPS) | 123 | install -m 0755 -t $(DESTDIR)$(libdir)/firejail $(SBOX_APPS) |
123 | install -m 0755 -t $(DESTDIR)$(libdir)/firejail src/profstats/profstats | 124 | install -m 0755 -t $(DESTDIR)$(libdir)/firejail src/profstats/profstats |
@@ -4288,7 +4288,7 @@ fi | |||
4288 | 4288 | ||
4289 | ac_config_files="$ac_config_files mkdeb.sh" | 4289 | ac_config_files="$ac_config_files mkdeb.sh" |
4290 | 4290 | ||
4291 | ac_config_files="$ac_config_files Makefile src/common.mk src/lib/Makefile src/fcopy/Makefile src/fnet/Makefile src/firejail/Makefile src/fnetfilter/Makefile src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/fbuilder/Makefile src/fsec-print/Makefile src/ftee/Makefile src/fseccomp/Makefile src/fldd/Makefile src/libpostexecseccomp/Makefile src/fsec-optimize/Makefile src/profstats/Makefile src/man/Makefile src/zsh_completion/Makefile src/bash_completion/Makefile test/Makefile src/jailcheck/Makefile src/fids/Makefile src/fnettrace/Makefile src/fnettrace-dns/Makefile src/fnettrace-sni/Makefile" | 4291 | ac_config_files="$ac_config_files Makefile src/common.mk src/lib/Makefile src/fcopy/Makefile src/fnet/Makefile src/firejail/Makefile src/fnetfilter/Makefile src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/fbuilder/Makefile src/fsec-print/Makefile src/ftee/Makefile src/fseccomp/Makefile src/fldd/Makefile src/libpostexecseccomp/Makefile src/fsec-optimize/Makefile src/fzenity/Makefile src/profstats/Makefile src/man/Makefile src/zsh_completion/Makefile src/bash_completion/Makefile test/Makefile src/jailcheck/Makefile src/fids/Makefile src/fnettrace/Makefile src/fnettrace-dns/Makefile src/fnettrace-sni/Makefile" |
4292 | 4292 | ||
4293 | cat >confcache <<\_ACEOF | 4293 | cat >confcache <<\_ACEOF |
4294 | # This file is a shell script that caches the results of configure | 4294 | # This file is a shell script that caches the results of configure |
@@ -5016,6 +5016,7 @@ do | |||
5016 | "src/fldd/Makefile") CONFIG_FILES="$CONFIG_FILES src/fldd/Makefile" ;; | 5016 | "src/fldd/Makefile") CONFIG_FILES="$CONFIG_FILES src/fldd/Makefile" ;; |
5017 | "src/libpostexecseccomp/Makefile") CONFIG_FILES="$CONFIG_FILES src/libpostexecseccomp/Makefile" ;; | 5017 | "src/libpostexecseccomp/Makefile") CONFIG_FILES="$CONFIG_FILES src/libpostexecseccomp/Makefile" ;; |
5018 | "src/fsec-optimize/Makefile") CONFIG_FILES="$CONFIG_FILES src/fsec-optimize/Makefile" ;; | 5018 | "src/fsec-optimize/Makefile") CONFIG_FILES="$CONFIG_FILES src/fsec-optimize/Makefile" ;; |
5019 | "src/fzenity/Makefile") CONFIG_FILES="$CONFIG_FILES src/fzenity/Makefile" ;; | ||
5019 | "src/profstats/Makefile") CONFIG_FILES="$CONFIG_FILES src/profstats/Makefile" ;; | 5020 | "src/profstats/Makefile") CONFIG_FILES="$CONFIG_FILES src/profstats/Makefile" ;; |
5020 | "src/man/Makefile") CONFIG_FILES="$CONFIG_FILES src/man/Makefile" ;; | 5021 | "src/man/Makefile") CONFIG_FILES="$CONFIG_FILES src/man/Makefile" ;; |
5021 | "src/zsh_completion/Makefile") CONFIG_FILES="$CONFIG_FILES src/zsh_completion/Makefile" ;; | 5022 | "src/zsh_completion/Makefile") CONFIG_FILES="$CONFIG_FILES src/zsh_completion/Makefile" ;; |
diff --git a/configure.ac b/configure.ac index 071dea228..4066618e0 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -279,7 +279,7 @@ AC_CONFIG_FILES([mkdeb.sh], [chmod +x mkdeb.sh]) | |||
279 | AC_CONFIG_FILES([Makefile src/common.mk src/lib/Makefile src/fcopy/Makefile src/fnet/Makefile src/firejail/Makefile src/fnetfilter/Makefile \ | 279 | AC_CONFIG_FILES([Makefile src/common.mk src/lib/Makefile src/fcopy/Makefile src/fnet/Makefile src/firejail/Makefile src/fnetfilter/Makefile \ |
280 | src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/fbuilder/Makefile src/fsec-print/Makefile \ | 280 | src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/fbuilder/Makefile src/fsec-print/Makefile \ |
281 | src/ftee/Makefile src/fseccomp/Makefile src/fldd/Makefile src/libpostexecseccomp/Makefile src/fsec-optimize/Makefile \ | 281 | src/ftee/Makefile src/fseccomp/Makefile src/fldd/Makefile src/libpostexecseccomp/Makefile src/fsec-optimize/Makefile \ |
282 | src/profstats/Makefile src/man/Makefile src/zsh_completion/Makefile src/bash_completion/Makefile test/Makefile \ | 282 | src/fzenity/Makefile src/profstats/Makefile src/man/Makefile src/zsh_completion/Makefile src/bash_completion/Makefile test/Makefile \ |
283 | src/jailcheck/Makefile src/fids/Makefile src/fnettrace/Makefile src/fnettrace-dns/Makefile src/fnettrace-sni/Makefile]) | 283 | src/jailcheck/Makefile src/fids/Makefile src/fnettrace/Makefile src/fnettrace-dns/Makefile src/fnettrace-sni/Makefile]) |
284 | AC_OUTPUT | 284 | AC_OUTPUT |
285 | 285 | ||
diff --git a/contrib/firejail-welcome.sh b/contrib/firejail-welcome.sh deleted file mode 100755 index c9b6c450b..000000000 --- a/contrib/firejail-welcome.sh +++ /dev/null | |||
@@ -1,128 +0,0 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | # This file is part of Firejail project | ||
4 | # Copyright (C) 2020-2022 Firejail Authors | ||
5 | # License GPL v2 | ||
6 | |||
7 | if ! command -v zenity >/dev/null; then | ||
8 | echo "Please install zenity." | ||
9 | exit 1 | ||
10 | fi | ||
11 | if ! command -v sudo >/dev/null; then | ||
12 | echo "Please install sudo." | ||
13 | exit 1 | ||
14 | fi | ||
15 | |||
16 | export LANG=en_US.UTF8 | ||
17 | |||
18 | zenity --title=firejail-welcome.sh --text-info --width=750 --height=500 <<EOM | ||
19 | Welcome to firejail! | ||
20 | |||
21 | This is a quick setup guide for newbies. | ||
22 | |||
23 | Profiles for programs can be found in /etc/firejail. Own customizations should go in a file named | ||
24 | <profile-name>.local in ~/.config/firejal. | ||
25 | |||
26 | Firejail's own configuration can be found at /etc/firejail/firejail.config. | ||
27 | |||
28 | Please note that running this script a second time can set new options, but does not unset options | ||
29 | set in a previous run. | ||
30 | |||
31 | Website: https://firejail.wordpress.com | ||
32 | Bug-Tracker: https://github.com/netblue30/firejail/issues | ||
33 | Documentation: | ||
34 | - https://github.com/netblue30/firejail/wiki | ||
35 | - https://github.com/netblue30/firejail/wiki/Frequently-Asked-Questions | ||
36 | - https://firejail.wordpress.com/documentation-2 | ||
37 | - man:firejail(1) and man:firejail-profile(5) | ||
38 | |||
39 | PS: If you have any improvements for this script, open an issue or pull request. | ||
40 | EOM | ||
41 | [[ $? -eq 1 ]] && exit 0 | ||
42 | |||
43 | sed_scripts=() | ||
44 | |||
45 | read -r -d $'\0' MSG_Q_BROWSER_DISABLE_U2F <<EOM | ||
46 | <big><b>Should browsers be allowed to access u2f hardware?</b></big> | ||
47 | EOM | ||
48 | |||
49 | read -r -d $'\0' MSG_Q_BROWSER_ALLOW_DRM <<EOM | ||
50 | <big><b>Should browsers be able to play DRM content?</b></big> | ||
51 | |||
52 | \$HOME is noexec,nodev,nosuid by default for the most sandboxes. This means that executing programs which are located in \$HOME, | ||
53 | is forbidden, the setuid attribute on files is ignored and device files inside \$HOME don't work. Browsers install proprietary | ||
54 | DRM plug-ins such as Widevine under \$HOME by default. In order to use them, \$HOME must be mounted exec inside the sandbox to | ||
55 | allow their execution. Clearly, this may help an attacker to start malicious code. | ||
56 | |||
57 | NOTE: Other software written in an interpreter language such as bash, python or java can always be started from \$HOME. | ||
58 | |||
59 | HINT: If <tt>/home</tt> has its own partition, you can mount it <tt>nodev,nosuid</tt> for all programs. | ||
60 | EOM | ||
61 | |||
62 | read -r -d $'\0' MSG_L_ADVANCED_OPTIONS <<EOM | ||
63 | You maybe want to set some of these advanced options. | ||
64 | EOM | ||
65 | |||
66 | read -r -d $'\0' MSG_Q_RUN_FIRECFG <<EOM | ||
67 | <big><b>Should most programs be started in firejail by default?</b></big> | ||
68 | EOM | ||
69 | |||
70 | read -r -d $'\0' MSG_I_ROOT_REQUIRED <<EOM | ||
71 | In order to apply these changes, root privileges are required. | ||
72 | You will now be asked to enter your password. | ||
73 | EOM | ||
74 | |||
75 | read -r -d $'\0' MSG_I_FINISH <<EOM | ||
76 | 🥳 | ||
77 | EOM | ||
78 | |||
79 | if zenity --title=firejail-welcome.sh --question --ellipsize --text="$MSG_Q_BROWSER_DISABLE_U2F"; then | ||
80 | sed_scripts+=("-e s/# browser-disable-u2f yes/browser-disable-u2f no/") | ||
81 | fi | ||
82 | |||
83 | if zenity --title=firejail-welcome.sh --question --ellipsize --text="$MSG_Q_BROWSER_ALLOW_DRM"; then | ||
84 | sed_scripts+=("-e s/# browser-allow-drm no/browser-allow-drm yes/") | ||
85 | fi | ||
86 | |||
87 | advanced_options=$(zenity --title=firejail-welcome.sh --list --width=800 --height=200 \ | ||
88 | --text="$MSG_L_ADVANCED_OPTIONS" --multiple --checklist --separator=" " \ | ||
89 | --column="" --column=Option --column=Description <<EOM | ||
90 | |||
91 | force-nonewprivs | ||
92 | Always set nonewprivs, this is a strong mitigation against exploits in firejail. However some programs like chromium or wireshark maybe don't work anymore. | ||
93 | |||
94 | restricted-network | ||
95 | Restrict all network related commands except 'net none' to root only. | ||
96 | |||
97 | seccomp-error-action=kill | ||
98 | Kill programs which violate seccomp rules (default: return a error). | ||
99 | EOM | ||
100 | ) | ||
101 | |||
102 | if [[ $advanced_options == *force-nonewprivs* ]]; then | ||
103 | sed_scripts+=("-e s/# force-nonewprivs no/force-nonewprivs yes/") | ||
104 | fi | ||
105 | if [[ $advanced_options == *restricted-network* ]]; then | ||
106 | sed_scripts+=("-e s/# restricted-network no/restricted-network yes/") | ||
107 | fi | ||
108 | if [[ $advanced_options == *seccomp-error-action=kill* ]]; then | ||
109 | sed_scripts+=("-e s/# seccomp-error-action EPERM/seccomp-error-action kill/") | ||
110 | fi | ||
111 | |||
112 | if zenity --title=firejail-welcome.sh --question --ellipsize --text="$MSG_Q_RUN_FIRECFG"; then | ||
113 | run_firecfg=true | ||
114 | fi | ||
115 | |||
116 | zenity --title=firejail-welcome.sh --info --ellipsize --text="$MSG_I_ROOT_REQUIRED" | ||
117 | |||
118 | passwd=$(zenity --title=firejail-welcome.sh --password --cancel-label=OK) | ||
119 | if [[ -n "${sed_scripts[*]}" ]]; then | ||
120 | sudo -S -p "" -- sed -i "${sed_scripts[@]}" /etc/firejail/firejail.config <<<"$passwd" || { zenity --title=firejail-welcome.sh --error; exit 1; }; | ||
121 | fi | ||
122 | if [[ "$run_firecfg" == "true" ]]; then | ||
123 | sudo -S -p "" -- firecfg <<<"$passwd" || { zenity --title=firejail-welcome.sh --error; exit 1; }; | ||
124 | fi | ||
125 | sudo -k | ||
126 | unset passwd | ||
127 | |||
128 | zenity --title=firejail-welcome.sh --info --icon-name=security-medium-symbolic --text="$MSG_I_FINISH" | ||
diff --git a/src/firecfg/firejail-welcome.sh b/src/firecfg/firejail-welcome.sh new file mode 100755 index 000000000..a7e74ebc3 --- /dev/null +++ b/src/firecfg/firejail-welcome.sh | |||
@@ -0,0 +1,204 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | # This file is part of Firejail project | ||
4 | # Copyright (C) 2020-2022 Firejail Authors | ||
5 | # License GPL v2 | ||
6 | # | ||
7 | # Usage: firejail-welcome PROGRAM SYSCONFDIR USER_NAME | ||
8 | # where PROGRAM is detected and driven by firecfg. | ||
9 | # SYSCONFDIR is most of the time /etc/firejail. | ||
10 | # | ||
11 | # The plan is to go with zenity by default. If zenity is not installed | ||
12 | # we will provide a console-only replacement in /usr/lib/firejail/fzenity | ||
13 | # | ||
14 | |||
15 | if ! command -v "$1" >/dev/null; then | ||
16 | echo "Please install $1." | ||
17 | exit 1 | ||
18 | fi | ||
19 | |||
20 | PROGRAM="sudo -u $3 $1" | ||
21 | SYSCONFDIR=$2 | ||
22 | export LANG=en_US.UTF8 | ||
23 | |||
24 | TITLE="Firejail Configuration Guide" | ||
25 | sed_scripts=() | ||
26 | run_firecfg=false | ||
27 | enable_u2f=false | ||
28 | enable_drm=false | ||
29 | enable_seccomp_kill=false | ||
30 | enable_restricted_net=false | ||
31 | enable_nonewprivs=false | ||
32 | |||
33 | #****************************************************** | ||
34 | # Intro | ||
35 | #****************************************************** | ||
36 | read -r -d $'\0' MSG_INTRO <<EOM | ||
37 | <big><b>Welcome to Firejail!</b></big> | ||
38 | |||
39 | This guide will walk you through some of the most common sandbox customizations. | ||
40 | At the end of the guide you'll have the option to save your changes in Firejail's | ||
41 | global config file at <b>/etc/firejail/firejail.config</b>. A copy of the original file is saved | ||
42 | as <b>/etc/firejal/firejail.config-</b>. | ||
43 | |||
44 | Please note that running this script a second time can set new options, but does | ||
45 | not clear options set in a previous run. | ||
46 | |||
47 | Press OK to continue, or close this window to stop the program. | ||
48 | |||
49 | EOM | ||
50 | $PROGRAM --title="$TITLE" --info --width=600 --height=40 --text="$MSG_INTRO" | ||
51 | [[ $? -eq 1 ]] && exit 0 | ||
52 | |||
53 | #****************************************************** | ||
54 | # symlinks | ||
55 | #****************************************************** | ||
56 | read -r -d $'\0' MSG_Q_RUN_FIRECFG <<EOM | ||
57 | <big><b>Should most programs be sandboxed by default?</b></big> | ||
58 | |||
59 | Currently, Firejail recognizes more than 1000 regular desktop programs. These programs | ||
60 | can be sandboxed automatically when you start them. | ||
61 | |||
62 | EOM | ||
63 | |||
64 | if $PROGRAM --title="$TITLE" --question --ellipsize --text="$MSG_Q_RUN_FIRECFG"; then | ||
65 | run_firecfg=true | ||
66 | fi | ||
67 | |||
68 | #****************************************************** | ||
69 | # U2F | ||
70 | #****************************************************** | ||
71 | read -r -d $'\0' MSG_Q_BROWSER_DISABLE_U2F <<EOM | ||
72 | <big><b>Should browsers be allowed to access u2f hardware?</b></big> | ||
73 | |||
74 | Universal Two-Factor (U2F) devices are used as a password store for online | ||
75 | accounts. These devices usually come in a form of a USB key. | ||
76 | |||
77 | EOM | ||
78 | |||
79 | if $PROGRAM --title="$TITLE" --question --ellipsize --text="$MSG_Q_BROWSER_DISABLE_U2F"; then | ||
80 | enable_u2f=true | ||
81 | sed_scripts+=("-e s/# browser-disable-u2f yes/browser-disable-u2f no/") | ||
82 | fi | ||
83 | |||
84 | #****************************************************** | ||
85 | # DRM | ||
86 | #****************************************************** | ||
87 | read -r -d $'\0' MSG_Q_BROWSER_ALLOW_DRM <<EOM | ||
88 | <big><b>Should browsers be able to play DRM content?</b></big> | ||
89 | |||
90 | The home directory is <tt>noexec,nodev,nosuid</tt> by default for most applications. | ||
91 | This means that executing programs located in your home directory is forbidden. | ||
92 | |||
93 | Browsers install proprietary DRM plug-ins such as Widevine in your home directory. | ||
94 | In order to use them, your home must be mounted <tt>exec</tt> inside the sandbox. This | ||
95 | may give the people developing and distributing the plug-in access to your private | ||
96 | data. | ||
97 | |||
98 | NOTE: Software written in an interpreted language such as bash, python or java can | ||
99 | always be started from home directory. | ||
100 | |||
101 | HINT: If <tt>/home</tt> has its own partition, you can mount it <tt>nodev,nosuid</tt> for all programs. | ||
102 | |||
103 | EOM | ||
104 | |||
105 | if $PROGRAM --title="$TITLE" --question --ellipsize --text="$MSG_Q_BROWSER_ALLOW_DRM"; then | ||
106 | enable_drm=true | ||
107 | sed_scripts+=("-e s/# browser-allow-drm no/browser-allow-drm yes/") | ||
108 | fi | ||
109 | |||
110 | #****************************************************** | ||
111 | # nonewprivs | ||
112 | #****************************************************** | ||
113 | read -r -d $'\0' MSG_Q_NONEWPRIVS <<EOM | ||
114 | <big><b>Should we force nonweprivs by default?</b></big> | ||
115 | |||
116 | nonewprivs is a Linux kernel feature that prevents programs from rising privileges. | ||
117 | It is also a strong mitigation against exploits in Firejail. However, some programs | ||
118 | like chromium, wireshark, or even ping might not work. | ||
119 | |||
120 | NOTE: seccomp enables nonewprivs automatically. Most applications supported by | ||
121 | default by Firejail are using seccomp. | ||
122 | |||
123 | EOM | ||
124 | |||
125 | if $PROGRAM --title="$TITLE" --question --ellipsize --text="$MSG_Q_NONEWPRIVS"; then | ||
126 | enable_nonewprivs=true | ||
127 | sed_scripts+=("-e s/# force-nonewprivs no/force-nonewprivs yes/") | ||
128 | fi | ||
129 | |||
130 | #****************************************************** | ||
131 | # restricted network | ||
132 | #****************************************************** | ||
133 | read -r -d $'\0' MSG_Q_NETWORK <<EOM | ||
134 | <big><b>Should we restrict network functionality?</b></big> | ||
135 | |||
136 | Restrict all network related commands except '<tt>net none</tt>' to root only. | ||
137 | |||
138 | EOM | ||
139 | |||
140 | if $PROGRAM --title="$TITLE" --question --ellipsize --text="$MSG_Q_NETWORK"; then | ||
141 | enable_restricted_net=true | ||
142 | sed_scripts+=("-e s/# restricted-network no/restricted-network yes/") | ||
143 | fi | ||
144 | |||
145 | #****************************************************** | ||
146 | # seccomp kill | ||
147 | #****************************************************** | ||
148 | read -r -d $'\0' MSG_Q_SECCOMP <<EOM | ||
149 | <big><b>Should we kill programs that violate seccomp rules?</b></big> | ||
150 | |||
151 | By default seccomp prevents the program from running the syscall and returns an error. | ||
152 | |||
153 | EOM | ||
154 | |||
155 | if $PROGRAM --title="$TITLE" --question --ellipsize --text="$MSG_Q_SECCOMP"; then | ||
156 | enable_seccomp_kill=true | ||
157 | sed_scripts+=("-e s/# seccomp-error-action EPERM/seccomp-error-action kill/") | ||
158 | fi | ||
159 | |||
160 | #****************************************************** | ||
161 | # root | ||
162 | #****************************************************** | ||
163 | read -r -d $'\0' MSG_RUN <<EOM | ||
164 | Now, I will apply the changes. This is what I will do: | ||
165 | |||
166 | |||
167 | EOM | ||
168 | MSG_RUN+="\n\n" | ||
169 | if [[ "$run_firecfg" == "true" ]]; then | ||
170 | MSG_RUN+=" * enable Firejail for all recognized programs\n" | ||
171 | fi | ||
172 | if [[ "$enable_u2f" == "true" ]]; then | ||
173 | MSG_RUN+=" * allow browsers to access U2F devices\n" | ||
174 | fi | ||
175 | if [[ "$enable_drm" == "true" ]]; then | ||
176 | MSG_RUN+=" * allow browsers to play DRM content\n" | ||
177 | fi | ||
178 | if [[ "$enable_nonewprivs" == "true" ]]; then | ||
179 | MSG_RUN+=" * enable nonewprivs globally\n" | ||
180 | fi | ||
181 | if [[ "$enable_restricted_net" == "true" ]]; then | ||
182 | MSG_RUN+=" * restrict networking features\n" | ||
183 | fi | ||
184 | if [[ "$enable_seccomp_kill" == "true" ]]; then | ||
185 | MSG_RUN+=" * enable seccomp kill\n" | ||
186 | fi | ||
187 | MSG_RUN+="\n\nPress OK to continue, or close this window to stop the program." | ||
188 | |||
189 | $PROGRAM --title="$TITLE" --info --width=600 --height=40 --text="$MSG_RUN" | ||
190 | [[ $? -eq 1 ]] && exit 0 | ||
191 | |||
192 | if [[ -n "${sed_scripts[*]}" ]]; then | ||
193 | cp "$SYSCONFDIR"/firejail.config "$SYSCONFDIR"/firejail.config- | ||
194 | sed -i "${sed_scripts[@]}" "$SYSCONFDIR"/firejail.config | ||
195 | fi | ||
196 | if [[ "$run_firecfg" == "true" ]]; then | ||
197 | # return 55 to inform firecfg symlinks are desired | ||
198 | exit 55 | ||
199 | fi | ||
200 | |||
201 | #****************************************************** | ||
202 | # all done | ||
203 | #****************************************************** | ||
204 | exit 0 | ||
diff --git a/src/firecfg/main.c b/src/firecfg/main.c index 2f346fecd..07e30415b 100644 --- a/src/firecfg/main.c +++ b/src/firecfg/main.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "../include/firejail_user.h" | 22 | #include "../include/firejail_user.h" |
23 | int arg_debug = 0; | 23 | int arg_debug = 0; |
24 | char *arg_bindir = "/usr/local/bin"; | 24 | char *arg_bindir = "/usr/local/bin"; |
25 | int arg_guide = 0; | ||
25 | 26 | ||
26 | static char *usage_str = | 27 | static char *usage_str = |
27 | "Firecfg is the desktop configuration utility for Firejail software. The utility\n" | 28 | "Firecfg is the desktop configuration utility for Firejail software. The utility\n" |
@@ -37,6 +38,7 @@ static char *usage_str = | |||
37 | " --debug - print debug messages.\n\n" | 38 | " --debug - print debug messages.\n\n" |
38 | " --fix - fix .desktop files.\n\n" | 39 | " --fix - fix .desktop files.\n\n" |
39 | " --fix-sound - create ~/.config/pulse/client.conf file.\n\n" | 40 | " --fix-sound - create ~/.config/pulse/client.conf file.\n\n" |
41 | " --guide - guided configuration for new users.\n\n" | ||
40 | " --help, -? - this help screen.\n\n" | 42 | " --help, -? - this help screen.\n\n" |
41 | " --list - list all firejail symbolic links.\n\n" | 43 | " --list - list all firejail symbolic links.\n\n" |
42 | " --version - print program version and exit.\n\n" | 44 | " --version - print program version and exit.\n\n" |
@@ -373,6 +375,9 @@ int main(int argc, char **argv) { | |||
373 | fix_desktop_files(home); | 375 | fix_desktop_files(home); |
374 | return 0; | 376 | return 0; |
375 | } | 377 | } |
378 | else if (strcmp(argv[i], "--guide") == 0) { | ||
379 | arg_guide = 1; | ||
380 | } | ||
376 | else if (strcmp(argv[i], "--list") == 0) { | 381 | else if (strcmp(argv[i], "--list") == 0) { |
377 | list(); | 382 | list(); |
378 | return 0; | 383 | return 0; |
@@ -437,6 +442,29 @@ int main(int argc, char **argv) { | |||
437 | umask(orig_umask); | 442 | umask(orig_umask); |
438 | } | 443 | } |
439 | 444 | ||
445 | if (arg_guide) { | ||
446 | char *cmd; | ||
447 | if (arg_debug) { | ||
448 | if (asprintf(&cmd, "sudo %s/firejail/firejail-welcome.sh /usr/lib/firejail/fzenity %s %s", LIBDIR, SYSCONFDIR, user) == -1) | ||
449 | errExit("asprintf"); | ||
450 | } | ||
451 | else { | ||
452 | if (asprintf(&cmd, "sudo %s/firejail/firejail-welcome.sh /usr/bin/zenity %s %s", LIBDIR, SYSCONFDIR, user) == -1) | ||
453 | errExit("asprintf"); | ||
454 | } | ||
455 | int status = system(cmd); | ||
456 | if (status == -1) { | ||
457 | fprintf(stderr, "Error: cannot run firejail-welcome.sh\n"); | ||
458 | exit(1); | ||
459 | } | ||
460 | free(cmd); | ||
461 | |||
462 | // the last 8 bits of the status is the return value of the command executed by system() | ||
463 | // firejail-welcome.sh returns 55 if setting sysmlinks is required | ||
464 | if (WEXITSTATUS(status) != 55) | ||
465 | return 0; | ||
466 | } | ||
467 | |||
440 | // clear all symlinks | 468 | // clear all symlinks |
441 | clean(); | 469 | clean(); |
442 | 470 | ||
@@ -468,8 +496,6 @@ int main(int argc, char **argv) { | |||
468 | #endif | 496 | #endif |
469 | } | 497 | } |
470 | 498 | ||
471 | |||
472 | |||
473 | // set new symlinks based on ~/.config/firejail directory | 499 | // set new symlinks based on ~/.config/firejail directory |
474 | set_links_homedir(home); | 500 | set_links_homedir(home); |
475 | 501 | ||
diff --git a/src/fzenity/Makefile.in b/src/fzenity/Makefile.in new file mode 100644 index 000000000..d9f976165 --- /dev/null +++ b/src/fzenity/Makefile.in | |||
@@ -0,0 +1,17 @@ | |||
1 | .PHONY: all | ||
2 | all: fzenity | ||
3 | |||
4 | include ../common.mk | ||
5 | |||
6 | %.o : %.c $(H_FILE_LIST) ../include/common.h | ||
7 | $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@ | ||
8 | |||
9 | fzenity: $(OBJS) | ||
10 | $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(EXTRA_LDFLAGS) | ||
11 | |||
12 | .PHONY: clean | ||
13 | clean:; rm -fr *.o fzenity *.gcov *.gcda *.gcno *.plist | ||
14 | |||
15 | .PHONY: distclean | ||
16 | distclean: clean | ||
17 | rm -fr Makefile | ||
diff --git a/src/fzenity/main.c b/src/fzenity/main.c new file mode 100644 index 000000000..4a0d3abac --- /dev/null +++ b/src/fzenity/main.c | |||
@@ -0,0 +1,176 @@ | |||
1 | #include "../include/common.h" | ||
2 | #include <sys/ioctl.h> | ||
3 | |||
4 | static char *arg_title = NULL; | ||
5 | static char *arg_text = NULL; | ||
6 | static int arg_info = 0; | ||
7 | static int arg_question = 0; | ||
8 | |||
9 | static inline void ansi_topleft(void) { | ||
10 | char str[] = {0x1b, '[', '1', ';', '1', 'H', '\0'}; | ||
11 | printf("%s", str); | ||
12 | fflush(0); | ||
13 | } | ||
14 | |||
15 | static inline void ansi_clrscr(void) { | ||
16 | ansi_topleft(); | ||
17 | char str[] = {0x1b, '[', '0', 'J', '\0'}; | ||
18 | printf("%s", str); | ||
19 | fflush(0); | ||
20 | } | ||
21 | |||
22 | char *remove_markup(char *in) { | ||
23 | char *out = malloc(strlen(in) + 1); | ||
24 | if (!out) | ||
25 | errExit("malloc"); | ||
26 | memset(out, 0, strlen(in) + 1); | ||
27 | |||
28 | char *ptr = in; | ||
29 | char *outptr = out; | ||
30 | while (*ptr != '\0') { | ||
31 | // skip <> markup | ||
32 | if (*ptr == '<') { | ||
33 | while (*ptr != '\0' && *ptr != '>') | ||
34 | ptr++; | ||
35 | if (*ptr == '\0') { | ||
36 | fprintf(stderr, "Error: invalid markup\n"); | ||
37 | exit(0); | ||
38 | } | ||
39 | ptr++; | ||
40 | } | ||
41 | // replace literal \n with char '\n' | ||
42 | else if (*ptr == '\\' && *(ptr + 1) == 'n') { | ||
43 | ptr += 2; | ||
44 | *outptr++ = '\n'; | ||
45 | continue; | ||
46 | } | ||
47 | // replace '/n' with ' ' | ||
48 | else if (*ptr == '\n') { | ||
49 | if (*(ptr + 1) == '\n') { | ||
50 | *outptr++ = '\n'; | ||
51 | *outptr++ = '\n'; | ||
52 | ptr += 2; | ||
53 | } | ||
54 | else { | ||
55 | *outptr++ = ' '; | ||
56 | ptr++; | ||
57 | } | ||
58 | } | ||
59 | else | ||
60 | *outptr++ = *ptr++; | ||
61 | } | ||
62 | |||
63 | return out; | ||
64 | } | ||
65 | |||
66 | char *print_line(char *in, int col) { | ||
67 | char *ptr = in; | ||
68 | int i = 0; | ||
69 | while (*ptr != '\n' && *ptr != '\0' && i < col) { | ||
70 | ptr++; | ||
71 | i++; | ||
72 | } | ||
73 | |||
74 | if (*ptr == '\n') { | ||
75 | *ptr++ = '\0'; | ||
76 | printf("%s\n", in); | ||
77 | return ptr++; | ||
78 | } | ||
79 | else if (i == col) { | ||
80 | while (*ptr != ' ' && ptr != in) | ||
81 | ptr--; | ||
82 | *ptr++ = '\0'; | ||
83 | printf("%s\n", in); | ||
84 | return ptr; | ||
85 | } | ||
86 | assert(0); | ||
87 | return NULL; | ||
88 | } | ||
89 | |||
90 | void paginate(char *in) { | ||
91 | struct winsize w; | ||
92 | int col = 80; | ||
93 | if (ioctl(0, TIOCGWINSZ, &w) == 0) | ||
94 | col = w.ws_col; | ||
95 | |||
96 | char *ptr = in; | ||
97 | while (*ptr != '\0') { | ||
98 | if (strlen(ptr) < col) { | ||
99 | printf("%s", ptr); | ||
100 | return; | ||
101 | } | ||
102 | ptr =print_line(ptr, col); | ||
103 | } | ||
104 | |||
105 | return; | ||
106 | } | ||
107 | |||
108 | static void info(void) { | ||
109 | ansi_clrscr(); | ||
110 | if (arg_text == NULL) { | ||
111 | fprintf(stderr, "Error: --text argument required\n"); | ||
112 | exit(1); | ||
113 | } | ||
114 | |||
115 | if (arg_title) | ||
116 | printf("%s\n\n", arg_title); | ||
117 | |||
118 | char *ptr = strstr(arg_text, "Press OK to continue"); | ||
119 | if (ptr) | ||
120 | *ptr = '\0'; | ||
121 | char *out = remove_markup(arg_text); | ||
122 | paginate(out); | ||
123 | free(out); | ||
124 | |||
125 | printf("\nContinue? (Y/N): "); | ||
126 | |||
127 | int c = getchar(); | ||
128 | if (c == 'y' || c == 'Y') | ||
129 | exit(0); | ||
130 | exit(1); | ||
131 | } | ||
132 | |||
133 | static void question(void) { | ||
134 | ansi_clrscr(); | ||
135 | if (arg_text == NULL) { | ||
136 | fprintf(stderr, "Error: --text argument required\n"); | ||
137 | exit(1); | ||
138 | } | ||
139 | |||
140 | if (arg_title) | ||
141 | printf("%s\n\n", arg_title); | ||
142 | |||
143 | char *ptr = strstr(arg_text, "Press OK to continue"); | ||
144 | if (ptr) | ||
145 | *ptr = '\0'; | ||
146 | char *out = remove_markup(arg_text); | ||
147 | paginate(out); | ||
148 | free(out); | ||
149 | |||
150 | printf("\n\n(Y/N): "); | ||
151 | |||
152 | int c = getchar(); | ||
153 | if (c == 'y' || c == 'Y') | ||
154 | exit(0); | ||
155 | exit(1); | ||
156 | } | ||
157 | |||
158 | int main(int argc, char **argv) { | ||
159 | int i; | ||
160 | for (i = 1; i < argc; i++) { | ||
161 | //printf("argv %d: #%s#\n", i, argv[i]); | ||
162 | if (strcmp(argv[i], "--info") == 0) | ||
163 | arg_info = 1; | ||
164 | else if (strcmp(argv[i], "--question") == 0) | ||
165 | arg_question = 1; | ||
166 | else if (strncmp(argv[i], "--text=", 7) == 0) | ||
167 | arg_text = argv[i] + 7; | ||
168 | } | ||
169 | |||
170 | if (arg_question) | ||
171 | question(); | ||
172 | else if (arg_info) | ||
173 | info(); | ||
174 | |||
175 | return 0; | ||
176 | } | ||