-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathfugit
More file actions
executable file
·158 lines (140 loc) · 4.08 KB
/
fugit
File metadata and controls
executable file
·158 lines (140 loc) · 4.08 KB
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#!/usr/bin/env bash
#set -x
LOGFILE="fugit.log"
CONFFILE="fugit.conf"
CONFDIR="$HOME/fugit.d"
CONF=$CONFFILE
# Checks whether a username is in the permission file. (For use with a config directory.)
# $1 filename
# $2 username
contains_confdir(){
if [ ! -r "$1" ]; then
printf "%s %s: Cannot read config file, abort (Path %s)\n" "$(date)" "$2" "$1" >> $LOGFILE
printf "FAIL\n" >&2
exit 24
fi
grep --fixed-strings --silent --line-regexp "$2" "$1"
return $?
}
# Checks whether a username is in the permission string. (For use with one config file.)
# $1 string of permitted users
# $2 username
contains_conffile(){
# temporarily disable pathname expansion to prevent expansion of $1
set -f
for entry in $1; do
if [ "$entry" == "$2" ]; then
set +f
return 0
fi
done
set +f
return 1
}
# Checks whether a user is allowed to perform a pull/push operation on a repo.
# $1 operation [pull|push]
# $2 repo
# $3 username
check_acl(){
REPONAME=${2#/}
# If using confdir, use confdir ACL
if [ -d "$CONF" ]; then
# Fix up the repository name
REPONAME=$(echo "$REPONAME" | tr '/' '_')
# Read the config file
if [ -r "$CONF/$REPONAME.conf" ]; then
eval $(cat "$CONF/$REPONAME.conf")
else
printf "%s %s: Cannot read repo config, abort (Path %s)\n" "$(date)" "$3" "$CONF/$REPONAME.conf" >> $LOGFILE
printf "FAIL\n" >&2
exit 23
fi
if [ "$1" == "pull" ]; then
contains_confdir "$PULL" "$3"
return $?
fi
if [ "$1" == "push" ]; then
contains_confdir "$PUSH" "$3"
return $?
fi
return 1
else
# Use conffile syntax
eval $(grep --fixed-strings --line-regexp --after-context=3 "REPO $REPONAME" $CONFFILE | tail -n +2)
if [ "$1" == "pull" ]; then
contains_conffile "$PULL" "$3"
return $?
fi
if [ "$1" == "push" ]; then
contains_conffile "$PUSH" "$3"
return $?
fi
return 1
fi
return 1
}
# Performs a push operation.
# Requires the config to be read.
# $1 repo
push(){
printf "%s %s: Trying to push to %s (Path %s)\n" "$(date)" "$FUGIT_USER" "$1" "$REAL" >> $LOGFILE
if [ -z "$REAL" ]; then
printf "%s %s: Unknown repo, abort\n" "$(date)" "$FUGIT_USER" >> $LOGFILE
printf "ERR No such repository\n" >&2
return 1
fi
# do access control
if [ "$ACCEPT" == "1" ]; then
git-receive-pack "$REAL"
printf "%s %s: Push accepted\n" "$(date)" "$FUGIT_USER" >> $LOGFILE
else
printf "%s %s: Push rejected\n" "$(date)" "$FUGIT_USER" >> $LOGFILE
printf "ERR Access not permitted\n" >&2
fi
}
# Performs a pull operation.
# Requires the config to be read.
# $1 repo
pull(){
printf "%s %s: Trying to read from %s (Path %s)\n" "$(date)" "$FUGIT_USER" "$1" "$REAL" >> $LOGFILE
if [ -z "$REAL" ]; then
printf "%s %s: Unknown repo, abort\n" "$(date)" "$FUGIT_USER" >> $LOGFILE
printf "ERR No such repository\n" >&2
return 1
fi
# do access control
if [ "$ACCEPT" == "1" ]; then
git-upload-pack "$REAL"
printf "%s %s: Pull accepted\n" "$(date)" "$FUGIT_USER" >> $LOGFILE
else
printf "%s %s: Pull rejected\n" "$(date)" "$FUGIT_USER" >> $LOGFILE
printf "ERR Access not permitted\n" >&2
fi
}
ACCEPT=0
FUGIT_USER=$1
if [ -z "$FUGIT_USER" ]; then
printf "%s UNKNOWN: No user name supplied\n" "$(date)" >> $LOGFILE
exit 1
fi
printf "%s %s: Command is %s\n" "$(date)" "$FUGIT_USER" "$SSH_ORIGINAL_COMMAND" >> $LOGFILE
if [[ "$SSH_ORIGINAL_COMMAND" == "git-receive-pack "* ]]; then
# extract argument
REPO=${SSH_ORIGINAL_COMMAND#git-receive-pack }
# remove quotes (without opening injection possibilities)
REPO=$(echo $REPO | xargs echo)
printf "%s %s: push to repo %s\n" "$(date)" "$FUGIT_USER" "$REPO" >> $LOGFILE
check_acl "push" "$REPO" "$FUGIT_USER" && ACCEPT=1
push "$REPO"
elif [[ "$SSH_ORIGINAL_COMMAND" == "git-upload-pack "* ]]; then
# extract argument
REPO=${SSH_ORIGINAL_COMMAND#git-upload-pack }
# remove quotes (without opening injection possibilities)
REPO=$(echo $REPO | xargs echo)
printf "%s %s: pull from repo %s\n" "$(date)" "$FUGIT_USER" "$REPO" >> $LOGFILE
check_acl "pull" "$REPO" "$FUGIT_USER" && ACCEPT=1
pull "$REPO"
else
printf "%s %s: Unknown command %s\n" "$(date)" "$FUGIT_USER" "$SSH_ORIGINAL_COMMAND" >> $LOGFILE
exit 1
fi