mirror of
https://github.com/9001/copyparty.git
synced 2025-10-02 22:52:29 -06:00
This commit includes a variety of different non-destructive fixes and formatting as recommended by shellcheck and by ruff's check/format. Fixes include things like double quoting vars to prevent space issues, variety of line formatting in python files, and removing of unused imports
165 lines
4.2 KiB
Bash
Executable file
165 lines
4.2 KiB
Bash
Executable file
#!/bin/bash
|
|
set -e
|
|
|
|
# runs copyparty (or any other program really) in a chroot
|
|
#
|
|
# assumption: these directories, and everything within, are owned by root
|
|
sysdirs=(); for v in /bin /lib /lib32 /lib64 /sbin /usr /etc/alternatives ; do
|
|
[ -e "$v" ] && sysdirs+=("$v")
|
|
done
|
|
|
|
# error-handler
|
|
help() { cat <<'EOF'
|
|
|
|
usage:
|
|
./prisonparty.sh <ROOTDIR> <USER|UID> <GROUP|GID> [VOLDIR [VOLDIR...]] -- python3 copyparty-sfx.py [...]
|
|
|
|
example:
|
|
./prisonparty.sh /var/lib/copyparty-jail cpp cpp /mnt/nas/music -- python3 copyparty-sfx.py -v /mnt/nas/music::rwmd
|
|
|
|
example for running straight from source (instead of using an sfx):
|
|
PYTHONPATH=$PWD ./prisonparty.sh /var/lib/copyparty-jail cpp cpp /mnt/nas/music -- python3 -um copyparty -v /mnt/nas/music::rwmd
|
|
|
|
note that if you have python modules installed as --user (such as bpm/key detectors),
|
|
you should add /home/foo/.local as a VOLDIR
|
|
|
|
EOF
|
|
exit 1
|
|
}
|
|
|
|
|
|
errs=
|
|
for c in awk chroot dirname getent lsof mknod mount realpath sed sort stat uniq; do
|
|
command -v $c >/dev/null || {
|
|
echo ERROR: command not found: $c
|
|
errs=1
|
|
}
|
|
done
|
|
[ $errs ] && exit 1
|
|
|
|
|
|
# read arguments
|
|
trap help EXIT
|
|
jail="$(realpath "$1")"; shift
|
|
uid="$1"; shift
|
|
gid="$1"; shift
|
|
|
|
vols=()
|
|
while true; do
|
|
v="$1"; shift
|
|
[ "$v" = -- ] && break # end of volumes
|
|
[ "$#" -eq 0 ] && break # invalid usage
|
|
vols+=( "$(realpath "$v" || echo "$v")" )
|
|
done
|
|
pybin="$1"; shift
|
|
pybin="$(command -v "$pybin")"
|
|
pyarg=
|
|
while true; do
|
|
v="$1"
|
|
[ "${v:0:1}" = - ] || break
|
|
pyarg="$pyarg $v"
|
|
shift
|
|
done
|
|
cpp="$1"; shift
|
|
[ -d "$cpp" ] && cppdir="$PWD" || {
|
|
# sfx, not module
|
|
cpp="$(realpath "$cpp")"
|
|
cppdir="$(dirname "$cpp")"
|
|
}
|
|
trap - EXIT
|
|
|
|
usr="$(getent passwd "$uid" | cut -d: -f1)"
|
|
[ "$usr" ] || { echo "ERROR invalid username/uid $uid"; exit 1; }
|
|
uid="$(getent passwd "$uid" | cut -d: -f3)"
|
|
|
|
grp="$(getent group "$gid" | cut -d: -f1)"
|
|
[ "$grp" ] || { echo "ERROR invalid groupname/gid $gid"; exit 1; }
|
|
gid="$(getent group "$gid" | cut -d: -f3)"
|
|
|
|
# debug/vis
|
|
echo
|
|
echo "chroot-dir = $jail"
|
|
echo "user:group = $uid:$gid ($usr:$grp)"
|
|
echo " copyparty = $cpp"
|
|
echo
|
|
printf '\033[33m%s\033[0m\n' "copyparty can access these folders and all their subdirectories:"
|
|
for v in "${vols[@]}"; do
|
|
printf '\033[36m ├─\033[0m %s \033[36m ── added by (You)\033[0m\n' "$v"
|
|
done
|
|
printf '\033[36m ├─\033[0m %s \033[36m ── where the copyparty binary is\033[0m\n' "$cppdir"
|
|
printf '\033[36m ╰─\033[0m %s \033[36m ── the folder you are currently in\033[0m\n' "$PWD"
|
|
vols+=("$cppdir" "$PWD")
|
|
echo
|
|
|
|
|
|
# remove any trailing slashes
|
|
jail="${jail%/}"
|
|
|
|
|
|
# bind-mount system directories and volumes
|
|
for a in {1..30}; do mkdir "$jail/.prisonlock" && break; sleep 0.1; done
|
|
printf '%s\n' "${sysdirs[@]}" "${vols[@]}" | sed -r 's`/$``' | LC_ALL=C sort | uniq |
|
|
while IFS= read -r v; do
|
|
[ -e "$v" ] || {
|
|
printf '\033[1;31mfolder does not exist:\033[0m %s\n' "$v"
|
|
continue
|
|
}
|
|
i1=$(stat -c%D.%i "$v/" 2>/dev/null || echo a)
|
|
i2=$(stat -c%D.%i "$jail$v/" 2>/dev/null || echo b)
|
|
[ "$i1" = "$i2" ] && continue
|
|
mount | grep -qF " $jail$v " && echo wtf "$i1" "$i2" "$v" && continue
|
|
mkdir -p "$jail$v"
|
|
mount --bind "$v" "$jail$v"
|
|
done
|
|
rmdir "$jail/.prisonlock" || true
|
|
|
|
|
|
cln() {
|
|
trap - EXIT
|
|
wait -f -n $p && rv=0 || rv=$?
|
|
cd /
|
|
echo "stopping chroot..."
|
|
for a in {1..30}; do mkdir "$jail/.prisonlock" && break; sleep 0.1; done
|
|
lsof "$jail" 2>/dev/null | grep -F "$jail" &&
|
|
echo "chroot is in use; will not unmount" ||
|
|
{
|
|
mount | grep -F " on $jail" |
|
|
awk '{sub(/ type .*/,"");sub(/.* on /,"");print}' |
|
|
LC_ALL=C sort -r | while IFS= read -r v; do
|
|
umount "$v" && echo "umount OK: $v"
|
|
done
|
|
}
|
|
rmdir "$jail/.prisonlock" || true
|
|
exit "$rv"
|
|
}
|
|
trap cln EXIT
|
|
|
|
|
|
# create a tmp
|
|
mkdir -p "$jail/tmp"
|
|
chmod 777 "$jail/tmp"
|
|
|
|
|
|
# create a dev
|
|
(cd "$jail"; mkdir -p dev; cd dev
|
|
[ -e null ] || mknod -m 666 null c 1 3
|
|
[ -e zero ] || mknod -m 666 zero c 1 5
|
|
[ -e random ] || mknod -m 444 random c 1 8
|
|
[ -e urandom ] || mknod -m 444 urandom c 1 9
|
|
)
|
|
|
|
|
|
# run copyparty
|
|
HOME="$(getent passwd $uid | cut -d: -f6)"
|
|
export HOME
|
|
export USER="$usr"
|
|
export LOGNAME="$USER"
|
|
#echo "pybin [$pybin]"
|
|
#echo "pyarg [$pyarg]"
|
|
#echo "cpp [$cpp]"
|
|
chroot --userspec="$uid:$gid" "$jail" "$pybin" "$pyarg" "$cpp" "$@" &
|
|
p=$!
|
|
trap 'kill -USR1 $p' USR1
|
|
trap 'trap - INT TERM; kill $p' INT TERM
|
|
wait
|