commit c9ab443370bc9b6721cb27f44fd6fdbdafc7811d
parent e77d8f3167396075738b1f9c7a925e17e8436f88
Author: Matthias Jaros <jaros@mailbox.org>
Date: Mon, 27 Oct 2025 11:08:53 +0100
Added basic acl handling of read/write git repos
Diffstat:
4 files changed, 37 insertions(+), 8 deletions(-)
diff --git a/docker-compose.yml b/docker-compose.yml
@@ -11,8 +11,10 @@ services:
- GIT_UID=1000
- USER_handy=handy:ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPsl91WPAT8aWwZ6y5WAfXU9PoHzxJ3YG9uFgSmlGQr2HwV+gL/XaTBJ4Brj+pa+R7tfYEBMi+7Navx/ZsEmr9E= mj@xps15
- USER_yolo=yolo:ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPsl91WPAT8aWwZ6y5WAfXU9PoHzxJ3YG9uFgSmlGQr2HwV+gL/XaTBJ4Brj+pa+R7tfYEBMi+7Navx/ZsEmr9E= mj@xps15
- - REPO_pass=/pass.git:handy
- - REPO_test=/test-test.git:handy
+ - REPO_test1=/test1.git;handy
+ - REPO_test2=/test2.git;handy:w
+ - REPO_test3=/test3.git;handy:a
+ - REPO_test4_test=/test-test.git;handy:w
volumes:
- ./donotsync/ssh:/var/ssh
- ./donotsync/repos:/srv/repos
diff --git a/src/env b/src/env
@@ -5,3 +5,4 @@ set _REPO_VALIDATION_REGEX "((?:\/[a-zA-Z0-9_\-\.]+)+.git)"
set _GIT_VALIDATION_REGEX "^(git-(?:upload-pack|receive-pack|upload-archive)) '$_REPO_VALIDATION_REGEX'\$"
set _GIT_SUDO_GROUP gitsudo
set _LOG /var/log/git-run
+set _PERMISSIONS r w
diff --git a/src/git-run b/src/git-run
@@ -20,6 +20,24 @@ begin
# 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))
@@ -28,13 +46,13 @@ begin
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 2
+ exit 3
end
# check for permissions
- if not cat $_REPO_PERMISSIONS_FILE | grep -q -E "^$repoDir:$currentUser\$"
+ 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 3
+ exit 4
end
# info logging
diff --git a/src/init b/src/init
@@ -54,7 +54,7 @@ end
function setupRepo
set -l repoConfig $argv[1]
- set -l parsedConfig (string split ':' -- $repoConfig)
+ set -l parsedConfig (string split ';' -- $repoConfig)
set -l repo $parsedConfig[1]
# check repo name
@@ -70,8 +70,16 @@ function setupRepo
echo "Setting up repo: $repo"
# write user as allowed into permission file
- for user in $parsedConfig[2..]
- echo "$repoDir:$user" >> $_REPO_PERMISSIONS_FILE
+ for userConfig in $parsedConfig[2..]
+ set -l parsedConfig (string split ':' -- $userConfig)
+ set -l user $parsedConfig[1]
+ set -l permission $parsedConfig[2]
+
+ # check for valid permission
+ if not contains $permission $_PERMISSIONS
+ set permission "r"
+ end
+ echo "$repoDir:$user:$permission" >> $_REPO_PERMISSIONS_FILE
end
# setup repo dir