aboutsummaryrefslogtreecommitdiffstats
path: root/src/zsh_completion/_firejail.in
blob: 7e8df138e19f340701b472858872fdea8291bb80 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
#compdef firejail

_all_firejails() {
    local -a _all_firejails_list
    for jail in ${(f)"$(_call_program modules_tag "firejail --list 2> /dev/null | cut -d: -f1")"}; do
        _all_firejails_list+=${jail%% *}
    done
    _describe 'firejails list' _all_firejails_list
}

_all_cpus() {
    _cpu_count=$(getconf _NPROCESSORS_ONLN)
    for i in {0..$((_cpu_count-1))} ; do
        print $i
    done
}

_profiles() {
    print $1/*.profile | sed -E "s;^$1/;;g;s;\.profile$;;g;"
}
_profiles_with_ext() {
    print $1/*.profile
}

_all_profiles() {
    _values 'profiles' $(_profiles _SYSCONFDIR_/firejail) $(_profiles $HOME/.config/firejail) $(_profiles_with_ext .)
}

_firejail_args=(
    '*::arguments:_normal'
    '(--profile)'{--profile=,--profile=}'[use a custom profile]: :_all_profiles'
    '--caps[enable default Linux capabilities filter]'
    '(--caps.drop)'{--caps.drop=,--caps.drop=}'[drop capabilities: all|cap1,cap2,...]: :->caps_drop'
    '(--caps.keep)'{--caps.keep=,--caps.keep=}'[keep capabilities: cap1,cap2,...]: :->caps_keep'
    '(--caps.print)'{--caps.print=,--caps.print=}'[print the caps filter name|pid]:firejail:_all_firejails'
    '--allow-debuggers[allow tools such as strace and gdb inside the sandbox]'
    '(--debug)'{--debug,--debug}'[print sandbox debug messages]'
    '--debug-blacklists[debug blacklisting]'
    '--debug-caps[print all recognized capabilities]'
    '--debug-errnos[print all recognized error numbers]'
    '--debug-private-lib[debug for --private-lib option]'
    '--debug-protocols[print all recognized protocols]'
    '--debug-syscalls[print all recognized system calls]'
    '--debug-syscalls32[print all recognized 32 bit system calls]'
    '--debug-whitelists[debug whitelisting]'
    # Ignore that you can do -? too as it's the only short option
    '(--help)'{--help,--help}'[this help screen]'
    '--allusers[all user home directories are visible inside the sandbox]'
    '--appimage[sandbox an AppImage application]'
    '--private[temporary home directory]'
    '(--private)'{--private=,--private=}'[use directory as user home]: : _files -/'
    '--seccomp[enable seccomp filter and apply the default blacklist]'
    '(--seccomp=)'{--seccomp=,--seccomp=}'[enable seccomp filter, blacklist the default syscall list and the syscalls specified by the command]:'
    '(--seccomp.print)'{--seccomp.print=,--seccomp.print=}'[print the seccomp filter for the sandbox identified by name|pid]: : _all_firejails'
    '--seccomp.block-secondary[build only the native architecture filters]'
    '(--seccomp.drop)'{--seccomp.drop=,--seccomp.drop=}'[enable seccomp filter, and blacklist the syscalls specified by the command]: :'
    '(--seccomp.keep)'{--seccomp.keep=,--seccomp.keep=}'[enable seccomp filter, and whitelist the syscalls specified by the command]: :'
    '(--seccomp.32.drop)'{--seccomp.32.drop=,--seccomp.32.drop=}'[enable seccomp filter, and blacklist the 32 bit syscalls specified by the command]: :'
    '(--seccomp.32.keep)'{--seccomp.32.keep=,--seccomp.32.keep=}'[enable seccomp filter, and whitelist the 32 bit syscalls specified by the command]: :'
    '(--seccomp-error-action)'{--seccomp-error-action=,--seccomp-error-action=}'[change error code, kill process or log the attempt]: :(ERRNO kill log)'
    '--memory-deny-write-execute[seccomp filter to block attempts to create memory mappings that are both writable and executable]'
    '*'{--blacklist=,--blacklist=}'[blacklist directory or file]: : _files'
    '--writable-etc[/etc directory is mounted read-write]'
    '--writable-run-user[allow access to /run/user/$UID/systemd and /run/user/$UID/gnupg]'
    '--writable-var[/var directory is mounted read-write]'
    '--writable-var-log[use the real /var/log directory, not a clone]'
    '--build[build a whitelisted profile for the application and print it on stdout]'
    '(--build)'{--build=,--build=}'[build a whitelisted profile for the application and save it]: : _files'
    '(--fs.print)'{--fs.print=,--fs.print=}'[print the filesystem log name|pid]: : _all_firejails'
    '(--join)'{--join=,--join=}'[join the sandbox name|pid]: : _all_firejails'
    '(--join-filesystem)'{--join-filesystem=,--join-filesystem=}'[join the mount namespace name|pid]: : _all_firejails'
    '(--profile.print)'{--profile.print=,--profile.print=}'[print the name of profile file name|pid]: : _all_firejails'
    '(--protocol.print)'{--protocol.print=,--protocol.print=}'[print the protocol filter name|pid]: : _all_firejails'
    '(--shutdown)'{--shutdown=,--shutdown=}'[shutdown the sandbox identified by name|pid]: : _all_firejails'
    '(--cat)'{--cat=,--cat=}'[print content of file from sandbox container name|pid]: : _all_firejails'
    '(--cpu.print)'{--cpu.print=,--cpu.print=}'[print the cpus in use name|pid]: : _all_firejails'
    '--list[list all sandboxes]'
    '(--dns)'{--dns=,--dns=}'[set DNS server]: :'
    '(--protocol)'{--protocol=,--protocol=}'[enable protocol filter]: :'
    '(--join-or-start)'{--join-or-start=,--join-or-start=}'[join the sandbox or start a new one name|pid]: : _all_firejails'
    '(--hosts-file)'{--hosts-file=,--hosts-file=}'[use file as /etc/hosts]: : _files'
    '--shell=none[run the program directly without a user shell]'
    '(--shell)'{--shell=,--shell=}'[set default user shell]: : _files -g "*(*)"'
    '(--output)'{--output=,--output=}'[stdout logging and log rotation]: : _files'
    '(--output-stderr)'{--output-stderr=,--output-stderr=}'[stdout and stderr logging and log rotation]: : _files'
    '--no3d[disable 3D hardware acceleration]'
    '--nodvd[disable DVD and audio CD devices]'
    '--nogroups[disable supplementary groups]'
    '--nonewprivs[sets the NO_NEW_PRIVS prctl]'
    '--noprofile[do not use a security profile]'
    '(--noexec)'{--noexec=,--noexec=}'[remount the file or directory noexec nosuid and nodev]: : _files'
    '--ipc-namespace[enable a new IPC namespace]'
    '--keep-dev-shm[/dev/shm directory is untouched (even with --private-dev)]'
    '--keep-var-tmp[/var/tmp directory is untouched]'
    '--top[monitor the most CPU-intensive sandboxes]'
    '--trace[trace open, access and connect system calls]'
    '--tracelog[add a syslog message for every access to files or directories blacklisted by the security profile]'
    '--tree[print a tree of all sandboxed processes]'
    '(--cpu)'{--cpu=,--cpu=}'[set cpu affinity]: :->cpus'
    '--private-dev[create a new /dev directory with a small number of common device files]'
    '--private-tmp[mount a tmpfs on top of /tmp directory]'
    '--private-cwd[do not inherit working directory inside jail]'
    '(--private-cwd)'{--private-cwd=,--private-cwd=}'[set working directory inside jail]: : _files -/'
    '*'{--read-only=,--read-only=}'[set directory or file read-only]: : _files'
    '*'{--read-write=,--read-write=}'[set directory or file read-write]: : _files'
    '(--tmpfs)'{--tmpfs=,--tmpfs=}'[mount a tmpfs filesystem on directory dirname]: : _files -/'
    '(--private-etc)'{--private-etc=,--private-etc=}'[build a new /etc in a temporary filesystem, and copy the files and directories in the list]: : _files'
    "--deterministic-exit-code[always exit with first child's status code]"
    '--machine-id[preserve /etc/machine-id]'
    # Sample values as I don't think
    # many would enjoy getting a list from -20..20
    '(--nice)'{--nice=,--nice=}'[set nice value]: :(1 10 15 20)'
    # Should be _files, a comma and files or files -/
    '*'{--bind=,--bind=}'[mount-bind dirname1/filename1 on top of dirname2/filename2]: :(file1,file2 dir1,dir2)'
    '--audit[audit the sandbox]'
    '(--audit)'{--audit=,--audit=}'[audit the sandbox with a test-program]: :'
    '(--cgroup)'{--cgroup=,--cgroup=}'[place the sandbox in the specified control group]: :'
    '*'{--env=,--env=}'[set environment variable]: :'
    '(--hostname)'{--hostname=,--hostname=}'[set sandbox hostname]: :'
    '(--ignore)'{--ignore=,--ignore=}'[ignore command in profile files]: :'
    '(--name)'{--name=,--name=}'[set sandbox name]: :'
    '(--rlimit-as)'{--rlimit-as=,--rlimit-as=}"[set the maximum size of the process's virtual memory (address space) in bytes]: :"
    '(--rlimit-cpu)'{--rlimit-cpu=,--rlimit-cpu=}'[set the maximum CPU time in seconds]: :'
    '(--rlimit-fsize)'{--rlimit-fsize=,--rlimit-fsize=}'[set the maximum file size that can be created by a process]: :'
    '(--rlimit-nofile)'{--rlimit-nofile=,--rlimit-nofile=}'[set the maximum number of files that can be opened by a process]: :'
    '(--rlimit-nproc)'{--rlimit-nproc=,--rlimit-nproc=}'[set the maximum number of processes that can be created for the real user ID of the calling process]: :'
    '(--rlimit-sigpending)'{--rlimit-sigpending=,--rlimit-sigpending=}'[set the maximum number of pending signals for a process]: :'
    '*'{--rmenv=,--rmenv=}'[remove environment variable in the new sandbox]: :'
    '(--timeout)'{--timeout=,--timeout=}'[kill the sandbox automatically after the time has elapsed]: :(hh\:mm\:ss)'
    "--quiet[turn off Firejail's output.]"
    '--version[print program version and exit]'
#ifdef HAVE_APPARMOR
    '--apparmor[enable AppArmor confinement]'
    '(--apparmor.print=)'{--apparmor.print=,--apparmor.print=}'[print apparmor status name|pid]:firejail:_all_firejails'
#endif
#ifdef HAVE_CHROOT
    '(--chroot)'{--chroot=,--chroot=}'[chroot into directory]: : _files -/'
#endif
#ifdef HAVE_FILE_TRANSFER
    '(--get)'{--get=,--get=}'[get a file from sandbox container name|pid]: : _all_firejails'
    # --put=name|pid src-filename dest-filename - put a file in sandbox container.
    '(--put)'{--put=,--put=}'[put a file in sandbox container]: :'
    '(--ls)'{--ls=,--ls=}'[list files in sandbox container name|pid]: : _all_firejails'
#endif
#ifdef HAVE_NETWORK
    # '--net=none[enable a new, unconnected network namespace]'
    '(--net)'{--net=,--net=}'[enable network namespaces and connect to this bridge or Ethernet interface (or none to disable)]: :->net_or_none'
    '(--net.print)'{--net.print=,--net.print=}'[print network interface configuration name|pid]: : _all_firejails'
    '(--netfilter.print)'{--netfilter.print=,--netfilter.print=}'[print the firewall name|pid]: : _all_firejails'
    '(--netfilter6.print)'{--netfilter6.print=,--netfilter6.print=}'[print the IPv6 firewall name|pid]: : _all_firejails'
    '--netstats[monitor network statistics]'
    '(--netmask)'{--netmask=,--netmask=}'[define a network mask when dealing with unconfigured parrent interfaces]: :'
    '(--netns)'{--netns=,--netns=}'[Run the program in a named, persistent network namespace]: :'
    '(--netfilter)'{--netfilter=,--netfilter=}'[enable firewall]: :'
    '(--netfilter6)'{--netfilter6=,--netfilter6=}'[enable IPv6 firewall]: :'
    '(--veth-name)'{--veth-name=,--veth-name=}'[use this name for the interface connected to the bridge]: :'
    '(--join-network)'{--join-network=,--join-network=}'[join the network namespace name|pid]: : _all_firejails'
    '(--defaultgw)'{--defaultgw=,--defaultgw=}'[configure default gateway]: :'
    '(--ip)'{--ip=,--ip=}'[set interface IP address none|dhcp|ADDRESS]: :(none dhcp)'
    '(--dns.print)'{--dns.print=,--dns.print=}'[print DNS configuration name|pid]: : _all_firejails'
    '(--interface)'{--interface=,--interface=}'[move interface in sandbox]: :'
    '(--ip6)'{--ip6=,--ip6=}'[set interface IPv6 address or use dhcp via dhclient]: :(dhcp)'
    '(--iprange)'{--iprange=,--iprange=}'[configure an IP address in this range]: :'
    '(--mac)'{--mac=,--mac=}'[set interface MAC address]: :(xx\:xx\:xx\:xx\:xx\:xx)'
    '(--mtu)'{--mtu=,--mtu=}'[set interface MTU]: :'
    '--scan[ARP-scan all the networks from inside a network namespace]'
    '(--bandwidth)'{--bandwidth=,--bandwidth=}'[set bandwidth limits name|pid]: : _all_firejails'
#endif
#ifdef HAVE_X11
    '--x11[enable X11 sandboxing. The software checks first if Xpra is installed, then it checks if Xephyr is installed. If all fails, it will attempt to use X11 security extension]'
    '(--x11)'{--x11=,--x11=}'[disable or enable specific X11 server]: :(none xephyr xorg xpra xvfb)'
    '(--xephyr-screen)'{--xephyr-screen=,--xephyr-screen=}'[set screen size for --x11=xephyr]: :(WIDTHxHEIGHT)'
#endif
#ifdef HAVE_USERNS
    '--noroot[install a user namespace with only the current user]'
#endif
    '--nosound[disable sound system]'
    '--noautopulse[disable automatic ~/.config/pulse init]'
    '--novideo[disable video devices]'
    '--nou2f[disable U2F devices]'
#ifdef HAVE_OVERLAYFS
    '--overlay[mount a filesystem overlay on top of the current filesystem]'
    '(--overlay-named)'{--overlay-named=,--overlay-named=}'[mount a filesystem overlay on top of the current filesystem, and store it in name directory]: : _files -/'
    '--overlay-tmpfs[mount a temporary filesystem overlay on top of the current filesystem]'
    '--overlay-clean[clean all overlays stored in $HOME/.firejail directory]'
#endif
#ifdef HAVE_WHITELIST
    '(--nowhitelist)'{--nowhitelist=,--nowhitelist=}'[disable whitelist for file or directory]: : _files'
    '*'{--whitelist=,--whitelist=}'[whitelist directory or file]: : _files'
#endif
    '(--noblacklist)'{--noblacklist=,--noblacklist=}'[disable blacklist for file or directory]: : _files'
#ifdef HAVE_DBUSPROXY
    '(--dbus-system)'{--dbus-system=,--dbus-system=}'[set system DBus access policy or none]: :'
    '(--dbus-system.broadcast)'{--dbus-system.broadcast=,--dbus-system.broadcast=}'[allow signals on the system DBus according to rule]: :'
    '(--dbus-system.call)'{--dbus-system.call=,--dbus-system.call=}'[allow calls on the system DBus according to rule]: :'
    '(--dbus-system.own)'{--dbus-system.own=,--dbus-system.own=}'[allow ownership of name on the system DBus]: :'
    '(--dbus-system.see)'{--dbus-system.see=,--dbus-system.see=}'[allow seeing name on the system DBus]: :'
    '(--dbus-system.talk)'{--dbus-system.talk=,--dbus-system.talk=}'[allow talking to name on the system DBus]: :'
    '(--dbus-user)'{--dbus-user=,--dbus-user=}'[set session DBus access policy or none]: :'
    '(--dbus-user.broadcast)'{--dbus-user.broadcast=,--dbus-user.broadcast=}'[allow signals on the session DBus according to rule]: :'
    '(--dbus-user.call)'{--dbus-user.call=,--dbus-user.call=}'[allow calls on the session DBus according to rule]: :'
    '(--dbus-user.see)'{--dbus-user.see=,--dbus-user.see=}'[allow seeing name on the session DBus]: :'
    '(--dbus-user.talk)'{--dbus-user.talk=,--dbus-user.talk=}'[allow talking to name on the session DBus]: :'
    '(--dbus-log)'{--dbus-log=,--dbus-log=}'[set DBus log file location]: : _files'
    '(--dbus-system)'{--dbus-system=,--dbus-system=}'[set system DBus access policy]: :(filter none)'
    '--dbus-user.log[turn on logging for the user DBus]'
    '(--dbus-user.own)'{--dbus-user.own=,--dbus-user.own=}'[allow ownership of name on the session DBus]: :'
    '--dbus-system.log[turn on logging for the system DBus]'
    '--nodbus[disable D-Bus access]'
#endif
#ifdef HAVE_PRIVATE_HOME
    '(--private-home)'{--private-home=,--private-home=}'[build a new user home in a temporary filesystem, and copy the files and directories in the list in the new home]: :'
#endif
    '(--private-bin)'{--private-bin=,--private-bin=}'[build a new /bin in a temporary filesystem, and copy the programs in the list]: :'
    '(--private-opt)'{--private-opt=,--private-opt=}'[build a new /opt in a temporary filesystem]: :'
    '(--private-srv)'{--private-srv=,--private-srv=}'[build a new /srv in a temporary filesystem]: :'
#ifdef HAVE_USERTMPFS
    '--private-cache[temporary ~/.cache directory]'
#endif
#ifdef HAVE_FIRETUNNEL
    '(--tunnel)'{--tunnel=,--tunnel=}'[connect the sandbox to a tunnel created by firetunnel utility]: :'
#endif
    )


_firejail() {
    _arguments -S $_firejail_args
    case "$state" in
        caps_drop)
            local caps_and_all=(all $(firejail --debug-caps | awk '/[0-9]+\s*- /{print $3}'))
            _values -s "," 'caps_drop' $caps_and_all
            ;;
        caps_keep)
            local caps=($(firejail --debug-caps | awk '/[0-9]+\s*- /{print $3}'))
            _values -s "," 'caps_keep' $caps
            ;;
        cpus)
            _values -s "," 'cpus' $(_all_cpus)
            ;;
        net_or_none)
            local netdevs=($(ip link | awk '{print $2}' | grep '^.*:$' | tr -d ':'))
            local net_and_none=(none $netdevs)
            _values 'net' $net_and_none
            ;;
    esac
}