#!/bin/sh default_msg() { sshfpline="$(get_sshfp_authline ${SSH_CLIENT%% *})" cat <&2 You are: $authline $sshfpline EOF } get_sshfp_authline() { ( r=${1:-.} key=$(mktemp) || exit trap 'rm -rf "$key"' EXIT echo "$authline" > "$key" get_sshfp "$key" "$r" ) } get_sshfp() { ( key="$1" r="${2:-.}" dns=$(mktemp) || exit trap 'rm -rf "$dns"' EXIT ssh-keygen -r "$r" -f "$key" > "$dns" exec < "$dns" while read line do set -- $line if [ "$3 $5" = "SSHFP 2" ] then echo "$line" break fi done ) } ssh_client_fingerprint_base16() { set -- $(get_sshfp_authline) [ "$6" ] echo $6 } check_if_self_forge() { # TODO: don't use description, but something else. local dir="$1" [ -d "$dir" ] || exit [ -r "$dir"/description ] || exit read description < "$dir"/description if [ "$description" != self-forge ] && [ "$(GIT_DIR=$dir git config core.self-forge)" != true ] then echo 'Error: access denied. The specified directory is not a self-forge.' >&2 exit fi } read authtype authline < "$SSH_USER_AUTH" || exit [ "$authtype" = publickey ] || exit cmd=${SSH_ORIGINAL_COMMAND%% *} case "$cmd" in git-send-pack | git-upload-pack) GIT_NAMESPACE= ;; git-receive-pack) export GIT_NAMESPACE="$(ssh_client_fingerprint_base16)" [ "$GIT_NAMESPACE" ] || exit ;; *) default_msg exit ;; esac arg=${SSH_ORIGINAL_COMMAND#* } arg=${arg%\'} arg=${arg#\'} case "$arg" in *\'*) exit ;; *.git) ;; *) arg=$arg/.git ;; esac dir=$(readlink -e "$arg") || exit check_if_self_forge "$dir" with_allowCurrentBranch() { local cmd="$1" dir="$2" ( set -eC lockfile=$GIT_DIR/index.lock echo $$ > "$lockfile" trap 'rm -f "$lockfile"' EXIT git config core.bare true "$@" git config core.bare false ) } if [ "$GIT_NAMESPACE" ] then GIT_DIR=$dir with_allowCurrentBranch "$cmd" "$dir" else "$cmd" "$dir" fi