#!/bin/bash set -e -o pipefail declare -a shared_paths require_extension=.fossil IFS=/ read n pid uid <<< "$1" [ "$pid" ] [ "$uid" -gt 0 ] IFS=: read username realname uid_ gid gecos homedir shell < <(getent passwd "$uid") [ "$uid" = "$uid_" ] shared_paths=("$homedir"/./src /srv/./src /usr/./src /usr/local/./src) authtype= while read -d '' do case "${REPLY%%=*}" in 'SSH_USER_AUTH' ) read authtype keytype keyvalue < "${REPLY#*=}" ;; 'SSH_ORIGINAL_COMMAND' ) SSH_ORIGINAL_COMMAND=${REPLY#*=} ;; esac done < /proc/$pid/environ [ "$authtype" = publickey ] case "$SSH_ORIGINAL_COMMAND" in *\"* ) exit 1 ;; : | true | /bin/true ) exit 0 ;; fossil\ test-http\ */../* ) exit 1 ;; fossil\ test-http\ ../* ) exit 1 ;; fossil\ test-http\ */.. ) exit 1 ;; fossil\ test-http\ * ) set -- $SSH_ORIGINAL_COMMAND [ $# = 3 ] for d in "${shared_paths[@]}" do f=${3#${d##*/./}/} # remove prefix "src/" from input if present f=${f%$require_extension}$require_extension # add suffix ".fossil" if not present [ "$f" != "$require_extension" ] # basename is not "" if upstreamDatabase=$(realpath -e -s "$d"/"$f") then break fi done [ "$upstreamDatabase" ] ;; * ) exit 1 ;; esac keyhash= while read do set -- $REPLY if [ "$3 $5" = 'SSHFP 2' ] then keyhash=$6 break fi done < <(ssh-keygen -f <(printf '%s\n' "$keytype $keyvalue") -r .) [ "$keyhash" ] upstreamDatabaseDir=${upstreamDatabase%/*} readWriteDbName=${upstreamDatabase#${upstreamDatabaseDir}/} readWriteDir=$upstreamDatabaseDir/.fossil-remotes/$keyhash as_user() { setpriv --reuid="$uid" --regid="$gid" --clear-groups --inh-caps=-all "$@" } if ! [ -d "$readWriteDir" ] then make_parents= if [[ $readWriteDir == $home/* ]] then [ -d "$upstreamDatabaseDir" ] make_parents=-p fi as_user mkdir $make_parents "$readWriteDir" fi as_user cp -n --reflink -- "$upstreamDatabase" "$readWriteDir"/"$readWriteDbName" exec systemd-run -P \ --property=User="$username" \ --property=ReadOnlyPaths=/ \ --property=ReadWritePaths="$readWriteDir" \ --property=WorkingDirectory="$readWriteDir" \ -- fossil test-http "$readWriteDbName"