diff options
author | Jonas Gunz <himself@jonasgunz.de> | 2020-07-20 01:04:04 +0200 |
---|---|---|
committer | Jonas Gunz <himself@jonasgunz.de> | 2020-07-20 01:04:04 +0200 |
commit | 3b69a787e6b76cc4cbc762b8c02aae2ded5e3ab1 (patch) | |
tree | 3d79916d7813c981e1431957844c956ff4899cb7 /gitwrapper.sh | |
parent | 03ff52d5dd428c08802cf8ae28a36fd806dd63a9 (diff) | |
download | reposync-3b69a787e6b76cc4cbc762b8c02aae2ded5e3ab1.tar.gz |
advanced access control
Diffstat (limited to 'gitwrapper.sh')
-rwxr-xr-x | gitwrapper.sh | 89 |
1 files changed, 77 insertions, 12 deletions
diff --git a/gitwrapper.sh b/gitwrapper.sh index f619143..a7ef645 100755 --- a/gitwrapper.sh +++ b/gitwrapper.sh @@ -11,25 +11,90 @@ # command="/path/to/wrapper.sh myrepos" ssh-rsa ... user@example # -[ -z "$1" ] && >&2 echo Invalid configuration in authorized_keys && exit 1 -ALLOWED_REPODIR="$1" +function perror() { + >&2 echo "$@" +} + +# 1: exit code +function usage() { + >&2 cat << EOF +$(basename $0) [options] + +Options: + -r <DIR> Allowed directory for pull + -w <DIR> Allowed directory for push + -i Allow inetractive Login +EOF + exit $1 +} + +# checks, if this instance has access rights to git repo and +# for a valid path and repo name: 'folder/name.git'. paths containing '..' +# will allways fail. +# 1: path 2: w/r +function has_access() { + local array=() + [ "$2" = "w" ] && array=("${WRITING[@]}") + [ "$2" = "r" ] && array=("${READING[@]}") + + readonly path_regex='^\s*/.*$|\.\.' + if [[ "$1" =~ $path_regex ]]; then + perror "Invalid file name." + return 1 + fi + + basename $1 + + readonly reponame_regex='^\w+\.git$' + if [[ ! "$(basename "$1")" =~ $reponame_regex ]]; then + perror "Invalid repository" + return 1 + fi + + for dir in "${array[@]}"; do + [ "$(dirname "$1")" = "$dir" ] && return 0 + done + + perror Invalid repository + return 1 +} + +#READING=( repos jonas public ) +#WRITING=( jonas ) +# +#has_access "public/asdf.git" "r" +#exit $? + +unset INTERACTIVE READING WRITING +READING=() +WRITING=() + +while getopts "r:w:i" options; do + case "$options" in + i) + INTERACTIVE="yes";; + r) + READING+=( "$OPTARG" );; + w) + WRITING+=( "$OPTARG" );; + :) + perror "-$OPTARG requires argument" + usage 1;; + *) + perror "Unknown option $options" + usage 1;; + esac +done if [ -z "$SSH_ORIGINAL_COMMAND" ]; then - bash + [ "$INTERACTIVE" = "yes" ] && bash exit $? fi repo_path=$(sed -n 's/^git upload-pack \(.*\)$/\1/p' <<< "$SSH_ORIGINAL_COMMAND") if [ ! -z "$repo_path" ]; then - if grep -q '\.\.' <<< "$repo_path"; then - >&2 echo Invalid file name. - exit 1 - fi - - reponame_regex='^\w+\.git$' - if [ "$(dirname "$repo_path")" != "$ALLOWED_REPODIR" ] || \ - [[ ! "$(basename "$repo_path")" =~ $reponame_regex ]]; then - >&2 echo Invalid repository + if ! has_access "$repo_path" "w"; then + perror "An error occured: No such file or directory." exit 1 fi |