#!/bin/bash set -e -o pipefail declare -a shared_paths shared_paths=("$homedir"/./src /srv/./src /usr/./src /usr/local/./src) 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_" ] 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 ] 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" ] case "$SSH_ORIGINAL_COMMAND" in *\"* ) exit 1 ;; fossil\ test-http\ * ) set -- $SSH_ORIGINAL_COMMAND [ $# = 3 ] f=/${f%$require_extension}$require_extension for d in "${shared_paths[@]}" do relativePart=${d#*/./} absolutePart=${d%$relativePart} tryPath=$absolutePart$relativePart${f#/$relativePart} if upstreamDatabase=$(realpath -e -s "$tryPath") then break fi done [ "$upstreamDatabase" ] ;; * ) exit 1 ;; esac 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"