aboutsummaryrefslogtreecommitdiff
path: root/gitwrapper.sh
diff options
context:
space:
mode:
authorGravatar Jonas Gunz <himself@jonasgunz.de> 2020-07-20 01:04:04 +0200
committerGravatar Jonas Gunz <himself@jonasgunz.de> 2020-07-20 01:04:04 +0200
commit3b69a787e6b76cc4cbc762b8c02aae2ded5e3ab1 (patch)
tree3d79916d7813c981e1431957844c956ff4899cb7 /gitwrapper.sh
parent03ff52d5dd428c08802cf8ae28a36fd806dd63a9 (diff)
downloadreposync-3b69a787e6b76cc4cbc762b8c02aae2ded5e3ab1.tar.gz
advanced access control
Diffstat (limited to 'gitwrapper.sh')
-rwxr-xr-xgitwrapper.sh89
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