summaryrefslogtreecommitdiff
path: root/AnonymousAccessCommand
diff options
context:
space:
mode:
Diffstat (limited to 'AnonymousAccessCommand')
-rwxr-xr-xAnonymousAccessCommand126
1 files changed, 126 insertions, 0 deletions
diff --git a/AnonymousAccessCommand b/AnonymousAccessCommand
new file mode 100755
index 0000000..443d25e
--- /dev/null
+++ b/AnonymousAccessCommand
@@ -0,0 +1,126 @@
1#!/bin/sh
2default_msg()
3{
4 sshfpline="$(get_sshfp_authline ${SSH_CLIENT%% *})"
5 cat <<EOF >&2
6
7 You are:
8
9 $authline
10 $sshfpline
11
12EOF
13}
14
15get_sshfp_authline()
16{
17 (
18 r=${1:-.}
19 key=$(mktemp) || exit
20 trap 'rm -rf "$key"' EXIT
21 echo "$authline" > "$key"
22 get_sshfp "$key" "$r"
23 )
24}
25
26get_sshfp()
27{
28 (
29 key="$1"
30 r="${2:-.}"
31 dns=$(mktemp) || exit
32 trap 'rm -rf "$dns"' EXIT
33
34 ssh-keygen -r "$r" -f "$key" > "$dns"
35 exec < "$dns"
36 while read line
37 do
38 set -- $line
39 if [ "$3 $5" = "SSHFP 2" ]
40 then
41 echo "$line"
42 break
43 fi
44 done
45 )
46}
47
48ssh_client_fingerprint_base16()
49{
50 set -- $(get_sshfp_authline)
51 [ "$6" ]
52 echo $6
53}
54
55check_if_self_forge()
56{
57 # TODO: don't use description, but something else.
58 local dir="$1"
59 [ -d "$dir" ] || exit
60 [ -r "$dir"/description ] || exit
61 read description < "$dir"/description
62 if [ "$description" != self-forge ] && [ "$(GIT_DIR=$dir git config core.self-forge)" != true ]
63 then
64 echo 'Error: access denied. The specified directory is not a self-forge.' >&2
65 exit
66 fi
67}
68
69read authtype authline < "$SSH_USER_AUTH" || exit
70[ "$authtype" = publickey ] || exit
71
72cmd=${SSH_ORIGINAL_COMMAND%% *}
73
74case "$cmd" in
75 git-send-pack | git-upload-pack)
76 GIT_NAMESPACE=
77 ;;
78 git-receive-pack)
79 export GIT_NAMESPACE="$(ssh_client_fingerprint_base16)"
80 [ "$GIT_NAMESPACE" ] || exit
81 ;;
82 *)
83 default_msg
84 exit
85 ;;
86esac
87
88arg=${SSH_ORIGINAL_COMMAND#* }
89arg=${arg%\'}
90arg=${arg#\'}
91case "$arg" in
92 *\'*) exit ;;
93 *.git) ;;
94 *) arg=$arg/.git ;;
95esac
96
97dir=$(readlink -e "$arg") || exit
98
99check_if_self_forge "$dir"
100
101with_allowCurrentBranch()
102{
103 local cmd="$1" dir="$2"
104 (
105 set -eC
106 lockfile=$GIT_DIR/index.lock
107 echo $$ > "$lockfile"
108 trap 'rm -f "$lockfile"' EXIT
109
110 # This doesn't seem very secure. Need to patch git probably.
111 for deny in CurrentBranch # DeleteCurrent
112 do git config receive.deny$deny false
113 done
114 "$@"
115 for deny in CurrentBranch # DeleteCurrent
116 do git config receive.deny$deny true
117 done
118 )
119}
120
121if [ "$GIT_NAMESPACE" ]
122then
123 GIT_DIR=$dir with_allowCurrentBranch "$cmd" "$dir"
124else
125 "$cmd" "$dir"
126fi