|
|
|
@@ -32,7 +32,6 @@ fi
|
|
|
|
|
|
|
|
|
|
## MUTABLE GLOBAL VARIABLES AND HELPER FUNCTIONS
|
|
|
|
|
|
|
|
|
|
profileDirs=()
|
|
|
|
|
# isDisable: set non-empty to invoke the binary without any sandboxing
|
|
|
|
|
isDisable=
|
|
|
|
|
# isDryRun: don't actually execute the program or sandbox: just print the command which would be run (and which the user may run from their own shell)
|
|
|
|
@@ -76,8 +75,6 @@ net=
|
|
|
|
|
dns=()
|
|
|
|
|
# list of `VAR=VALUE` environment variables to add to the sandboxed program's environment
|
|
|
|
|
portalEnv=()
|
|
|
|
|
# profilesNamed: list of profile names we've successfully loaded
|
|
|
|
|
profilesNamed=()
|
|
|
|
|
|
|
|
|
|
# arguments to forward onto a specific backend (if that backend is active)
|
|
|
|
|
firejailFlags=()
|
|
|
|
@@ -126,8 +123,7 @@ usage() {
|
|
|
|
|
echo ' allow access to the host <path>, relative to XDG_RUNTIME_DIR'
|
|
|
|
|
echo ' --sanebox-add-pwd'
|
|
|
|
|
echo ' shorthand for `--sanebox-path $PWD`'
|
|
|
|
|
echo ' --sanebox-profile <profile>'
|
|
|
|
|
echo ' --sanebox-profile-dir <dir>'
|
|
|
|
|
echo ' --sanebox-profile <path/to/profile>'
|
|
|
|
|
echo ' --sanebox-cache-symlink <from> <to>'
|
|
|
|
|
echo ' assume that <from> is a symlink to <to>'
|
|
|
|
|
echo ' performance optimization to avoid spawning a readlink subshell'
|
|
|
|
@@ -353,34 +349,6 @@ loadProfileByPath() {
|
|
|
|
|
parseArgs "${_profArgs[@]}"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tryLoadProfileByName() {
|
|
|
|
|
local profile="$1"
|
|
|
|
|
if [ "${profile:0:1}" = "/" ]; then
|
|
|
|
|
# absolute path to profile.
|
|
|
|
|
# consider it an error if it doesn't exist.
|
|
|
|
|
# in general, prefer to use `--sanebox-profile-dir` and specify the profile by name.
|
|
|
|
|
# doing so maximizes compatibility with anything else that uses the name, like firejail.
|
|
|
|
|
loadProfileByPath "$profile"
|
|
|
|
|
else
|
|
|
|
|
profilesNamed+=("$profile")
|
|
|
|
|
|
|
|
|
|
for profileDir in "${profileDirs[@]}"; do
|
|
|
|
|
local profilePath="$profileDir/$profile.profile"
|
|
|
|
|
debug "try profile at path: '$profilePath'"
|
|
|
|
|
if [ -f "$profilePath" ]; then
|
|
|
|
|
loadProfileByPath "$profilePath"
|
|
|
|
|
break
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
initDefaultProfileDirs() {
|
|
|
|
|
for d in ${XDG_DATA_DIRS//:/ }; do
|
|
|
|
|
profileDirs+=("$d/sanebox/profiles")
|
|
|
|
|
done
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# subroutine of `tryArgAsPath` for after the arg has been converted into a valid (but possibly not existing) path.
|
|
|
|
|
# adds an entry to `paths` and evals `true` on success;
|
|
|
|
|
# evals `false` if the path couldn't be added, for any reason.
|
|
|
|
@@ -569,16 +537,9 @@ parseArgs() {
|
|
|
|
|
(--sanebox-profile)
|
|
|
|
|
# load the profile *immediately*, inline.
|
|
|
|
|
# this way, user arguments which come later on the CLI can override any profile config, v.s. if profile loading were defered.
|
|
|
|
|
tryLoadProfileByName "$1"
|
|
|
|
|
loadProfileByPath "$1"
|
|
|
|
|
shift
|
|
|
|
|
;;
|
|
|
|
|
(--sanebox-profile-dir)
|
|
|
|
|
# add another directory in which to search for profiles,
|
|
|
|
|
# and give it *greater* precedence than the existing search directories (i.e. override the default profile)
|
|
|
|
|
local dir="$1"
|
|
|
|
|
shift
|
|
|
|
|
profileDirs=("$dir" "${profileDirs[@]}")
|
|
|
|
|
;;
|
|
|
|
|
(--sanebox-cache-symlink)
|
|
|
|
|
local from="$1"
|
|
|
|
|
shift
|
|
|
|
@@ -597,9 +558,6 @@ parseArgs() {
|
|
|
|
|
|
|
|
|
|
## FIREJAIL BACKEND
|
|
|
|
|
|
|
|
|
|
firejailName=
|
|
|
|
|
firejailProfile=
|
|
|
|
|
|
|
|
|
|
firejailSetup() {
|
|
|
|
|
debug "firejailSetup: noop"
|
|
|
|
|
}
|
|
|
|
@@ -617,29 +575,8 @@ firejailIngestDns() {
|
|
|
|
|
firejailIngestKeepNamespace() {
|
|
|
|
|
debug "firejailIngestKeepNamespace: noop"
|
|
|
|
|
}
|
|
|
|
|
firejailIngestProfile() {
|
|
|
|
|
if [ -z "$firejailName" ]; then
|
|
|
|
|
firejailName="$1"
|
|
|
|
|
fi
|
|
|
|
|
if [ -z "$firejailProfile" ]; then
|
|
|
|
|
local fjProfileDirs=(@firejailProfileDirs@)
|
|
|
|
|
for fjProfileDir in "${fjProfileDirs[@]}"; do
|
|
|
|
|
local fjProfile="$fjProfileDir/$1.profile"
|
|
|
|
|
debug "try firejail profile at path: '$fjProfile'"
|
|
|
|
|
if [ -f "$fjProfile" ]; then
|
|
|
|
|
firejailProfile="$fjProfile"
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
firejailGetCli() {
|
|
|
|
|
if [ -n "$firejailName" ]; then
|
|
|
|
|
firejailFlags+=("--join-or-start=$firejailName")
|
|
|
|
|
fi
|
|
|
|
|
if [ -n "$firejailProfile" ]; then
|
|
|
|
|
firejailFlags+=("--profile=$firejailProfile")
|
|
|
|
|
fi
|
|
|
|
|
locate _firejail "firejail" "@firejail@/bin/firejail"
|
|
|
|
|
cliArgs=(
|
|
|
|
|
"$_firejail" "${firejailFlags[@]}" --
|
|
|
|
@@ -720,9 +657,6 @@ bwrapIngestKeepNamespace() {
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
}
|
|
|
|
|
bwrapIngestProfile() {
|
|
|
|
|
debug "bwrapIngestProfile: stubbed"
|
|
|
|
|
}
|
|
|
|
|
bwrapIngestCapability() {
|
|
|
|
|
bwrapFlags+=("--cap-add" "cap_$1")
|
|
|
|
|
}
|
|
|
|
@@ -796,9 +730,6 @@ landlockIngestNet() {
|
|
|
|
|
landlockIngestKeepNamespace() {
|
|
|
|
|
debug "landlockIngestKeepNamespace: noop"
|
|
|
|
|
}
|
|
|
|
|
landlockIngestProfile() {
|
|
|
|
|
debug "landlockIngestProfile: stubbed"
|
|
|
|
|
}
|
|
|
|
|
landlockIngestCapability() {
|
|
|
|
|
capshonlyIngestCapability "$1"
|
|
|
|
|
}
|
|
|
|
@@ -834,9 +765,6 @@ capshonlyIngestNet() {
|
|
|
|
|
capshonlyIngestKeepNamespace() {
|
|
|
|
|
debug "capshonlyIngestKeepNamespace: noop"
|
|
|
|
|
}
|
|
|
|
|
capshonlyIngestProfile() {
|
|
|
|
|
debug "capshonlyIngestProfile: stubbed"
|
|
|
|
|
}
|
|
|
|
|
capshonlyIngestCapability() {
|
|
|
|
|
# N.B. `capsh` parsing of `--caps=X` arg is idiosyncratic:
|
|
|
|
|
# - valid: `capsh --caps=CAP_FOO,CAP_BAR=eip -- <cmd>`
|
|
|
|
@@ -880,9 +808,6 @@ noneIngestNet() {
|
|
|
|
|
noneIngestKeepNamespace() {
|
|
|
|
|
:
|
|
|
|
|
}
|
|
|
|
|
noneIngestProfile() {
|
|
|
|
|
:
|
|
|
|
|
}
|
|
|
|
|
noneIngestCapability() {
|
|
|
|
|
:
|
|
|
|
|
}
|
|
|
|
@@ -999,17 +924,12 @@ ingestForBackend() {
|
|
|
|
|
for ns in "${keepNamespace[@]}"; do
|
|
|
|
|
"$method"IngestKeepNamespace "$ns"
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
for prof in "${profilesNamed[@]}"; do
|
|
|
|
|
"$method"IngestProfile "$prof"
|
|
|
|
|
done
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## TOPLEVEL EXECUTION
|
|
|
|
|
# no code evaluated before this point should be dependent on user args / environment.
|
|
|
|
|
|
|
|
|
|
initDefaultProfileDirs
|
|
|
|
|
parseArgsAndEnvironment "$@"
|
|
|
|
|
|
|
|
|
|
# variables meant to be inherited
|
|
|
|
|