#!/usr/bin/env fish # load environment source (dirname (status --current-filename))/env set -l gitCommand set -l repoDir # redirect stdout/stderr to file, no information to potential attacker begin # check given git command # basic form is '' set -l currentUser (whoami) set -l matcher (string match -r -g $_GIT_VALIDATION_REGEX -- "$argv") if test (count $matcher) -ne 2 echo "$(date -Is): DENY bad_format user=$currentUser ip=$SSH_CONNECTION argv=$argv" exit 1 end # extract variables from git command set gitCommand $matcher[1] set -l repo $matcher[2] # check for permissions needed set -l permission switch "$gitCommand" case "git-upload-pack" # allow clone/fetch/pull set permission [rw] case "git-upload-archive" # allow remote archive set permission [rw] case "git-receive-pack" # only allow for write users set permission [w] case '*' # this should not happend because we sanitize above the git command echo "$(date -Is): DENY unkown_git_command user=$currentUser ip=$SSH_CONNECTION realPath=$realPath argv=$argv" exit 2 end # adjust repo path to /srv/repos set repoDir /(string join -n '/' srv repos (string split '/' $repo)) # check if realPath is in jail under /srv/repos set -l realPath (realpath $repoDir) if not string match -r -q -- "/srv/repos/.*" "$realPath" echo "$(date -Is): DENY jail_escape user=$currentUser ip=$SSH_CONNECTION realPath=$realPath argv=$argv" exit 3 end # check for permissions if not cat $_REPO_PERMISSIONS_FILE | grep -q -E "^$repoDir:$currentUser:$permission\$" echo "$(date -Is): DENY no_permissions user=$currentUser ip=$SSH_CONNECTION argv=$argv" exit 4 end # info logging echo "$(date -Is): ALLOW ok user=$currentUser ip=$SSH_CONNECTION argv=$argv" end &>>$_LOG # execute parsed git command /usr/bin/sudo -u git /usr/bin/git-shell -c "$gitCommand '$repoDir'"