gitreef

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 22e307880062bf0171071d854955d5981c4a7c44
parent e4671ac2614317002fc9342777a5530e73a79c50
Author: Matthias Jaros <jaros@mailbox.org>
Date:   Sat, 15 Nov 2025 13:20:40 +0100

Refactored git-run to use functions

Diffstat:
Msrc/git-run | 88+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
1 file changed, 52 insertions(+), 36 deletions(-)

diff --git a/src/git-run b/src/git-run @@ -3,62 +3,79 @@ # load environment source (status dirname)/env -set -l gitCommand -set -l repoDir +# global variables +set gitCommand +set repoDir +set currentUser (whoami) -# redirect stdout/stderr to file, no information to potential attacker -begin - set -l currentUser (whoami) +function log --on-event log_event + echo "$(date -Is): $argv[1..2] user=$currentUser $argv[3..] ip=$SSH_CONNECTION" >> $_LOG +end +function verifyGitCommand # check given git command # basic form is <git-command> '<path-to-repo>' - set -l matcher (string match -r -g $_GIT_VALIDATION_REGEX -- "$argv") + set -l matcher $argv if test (count $matcher) -ne 2 - echo "$(date -Is): DENY bad_format user=$currentUser ip=$SSH_CONNECTION argv=$argv" - exit 1 + emit log_event DENY bad_format "argv=$argv" + return 1 end +end - # extract variables from git command - set gitCommand $matcher[1] - set -l repo $matcher[2] - - # check for permissions needed +function verifyRepoJail + set -l realPath (realpath $repoDir) + if not string match -r -q -- "/srv/repos/.*" "$realPath" + emit log_event DENY jail_escape "realPath=$realPath" + return 2 + end +end + +function verifyPermissions set -l permission switch "$gitCommand" - case "git-upload-pack" - # allow clone/fetch/pull + case "git-upload-pack" + # allow clone/fetch/pull set permission [rw] - case "git-upload-archive" - # allow remote archive + case "git-upload-archive" + # allow remote archive set permission [rw] - case "git-receive-pack" - # only allow for write users + case "git-receive-pack" + # only allow for write users set permission [w] - case '*' + case '*' # this should not happend because we sanitize above the git command - echo "$(date -Is): DENY unkown_git_command user=$currentUser ip=$SSH_CONNECTION gitCommand=$gitCommand argv=$argv" - exit 2 + emit log_event DENY unkown_git_command "gitCommand=$gitCommand" + return 3 + end + + # check for permissions + if not cat $_REPO_PERMISSIONS_FILE | grep -q -E "^$repoDir:$currentUser:$permission\$" + emit log_event DENY no_permissions + return 4 end +end + +# redirect stdout/stderr to file, no information to potential attacker +begin + set -l matcher (string match -r -g $_GIT_VALIDATION_REGEX -- "$argv") + verifyGitCommand $matcher; or exit $status + + # extract variables + set gitCommand $matcher[1] + set -l repo $matcher[2] # 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 + verifyRepoJail; or exit $status + + # check for permissions needed + verifyPermissions; or exit $status # info logging - echo "$(date -Is): ALLOW ok user=$currentUser ip=$SSH_CONNECTION argv=$argv" + emit log_event ALLOW ok "argv=$argv" end &>>$_LOG # execute parsed git command -/usr/bin/sudo -u git /usr/bin/git-shell -c "$gitCommand '$repoDir'" -\ No newline at end of file +/usr/bin/sudo -u git /usr/bin/git-shell -c "$gitCommand '$repoDir'"