blob: ffdc07a987864d1bc7eed4c7b31192c5c021bc7a (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
#!/bin/sh
default_msg()
{
sshfpline="$(get_sshfp_authline ${SSH_CLIENT%% *})"
cat <<EOF >&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
}
is_self_forge()
{
local dir="$1" confval
[ -d "$dir" ] || return
confval=$(GIT_DIR=$dir git config core.self-forge) || return
[ "$confval" = true ]
}
with_soul_bare()
{
(
set -eC
lockfile=$GIT_DIR/index.lock
echo $$ > "$lockfile"
trap 'rm -f "$lockfile"' EXIT
git config core.bare true
"$@"
git config core.bare false
)
}
unsupported()
{
echo "$0: Error: unsupported" >&2
}
read authtype authline < "$SSH_USER_AUTH" || exit
[ "$authtype" = publickey ] || exit
cmd=${SSH_ORIGINAL_COMMAND%% *}
case "$cmd" in
git-send-pack | git-upload-pack | git-receive-pack ) ;;
* )
default_msg
exit
;;
esac
arg=${SSH_ORIGINAL_COMMAND#* }
arg=${arg%\'}
arg=${arg#\'}
case "$arg" in
*\'* )
unsupported
exit
;;
esac
if ! dir=$(readlink -e "$arg")
then exit
elif [ -d "$dir"/.git ]
then dir=$dir/.git
fi
if ! is_self_forge "$dir"
then
echo 'Error: access denied. The specified directory is not a self-forge.' >&2
exit
fi
case "$cmd" in
git-send-pack | git-upload-pack )
GIT_NAMESPACE=
"$cmd" "$dir"
;;
git-receive-pack )
export GIT_NAMESPACE="$(ssh_client_fingerprint_base16)"
[ "$GIT_NAMESPACE" ]
GIT_DIR=$dir with_soul_bare "$cmd" "$dir"
;;
esac
|