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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
|
test_description='Check the shipped auth extensions'
CGIT_TEST_NO_CREATE_REPOS=YesPlease
. ./setup.sh
. "$TEST_OUTPUT_DIRECTORY/extensions/lib.sh"
auth_hash=$(openssl passwd -6 -salt testsalt "open sesame" 2>/dev/null) ||
auth_hash=
for lua in $interpreters
do
for variant in inline file
do
test_expect_success "auth-$variant checks under $lua" '
mkdir "unit-$lua-$variant" &&
"$lua" "$EXT_TEST_DIRECTORY/test-auth.lua" \
"$EXTENSIONS_DIRECTORY/auth-$variant.lua" $variant "$PWD/unit-$lua-$variant"
'
done
auth_libs=AUTH_LIBS_$(echo "$lua" | tr a-z. A-Z_)
if test -n "$auth_hash" &&
"$lua" -e "
require('openssl.hmac') require('openssl.rand') require('posix.sys.stat')
assert(require('posix.unistd').crypt('open sesame', '$auth_hash') == '$auth_hash')
" >/dev/null 2>&1
then
test_set_prereq $auth_libs
fi
for variant in inline file
do
test_expect_success $auth_libs "auth-$variant checks against the real libraries under $lua" '
mkdir "real-$lua-$variant" &&
"$lua" "$EXT_TEST_DIRECTORY/test-auth.lua" \
"$EXTENSIONS_DIRECTORY/auth-$variant.lua" $variant "$PWD/real-$lua-$variant" "$auth_hash"
'
done
done
test_expect_success 'create a repository with one commit' '
test_create_repo repos/authy &&
(
cd repos/authy &&
echo content >file &&
git add file &&
git commit -m "guarded commit"
)
'
if test "$CGIT_HAS_LUA" -eq 1 &&
! cgit_lua_probe "$PWD/repos/authy/.git" openssl.rand openssl.hmac posix.sys.stat posix.unistd
then
test_set_prereq CGIT_LUA_NOAUTH
say 'cgit lua lacks luaossl or luaposix, expecting protected pages refused'
elif test "$CGIT_HAS_LUA" -eq 1 && test -n "$auth_hash"
then
cat >crypt-probe.lua <<-EOF
function filter_open(...) end
function filter_write(str) end
function filter_close()
if require("posix.unistd").crypt("open sesame", "$auth_hash") == "$auth_hash" then
html("CRYPT_PROBE_YES")
end
return 0
end
EOF
cgitrc_repo crypt-probe-rc authy "repo.commit-filter=lua:$PWD/crypt-probe.lua"
if cgit_rc crypt-probe-rc "url=authy/commit/" | grep CRYPT_PROBE_YES >/dev/null
then
test_set_prereq CGIT_LUA_AUTH
fi
fi
test_expect_success CGIT_LUA 'point cgit at the unedited auth filter' '
cat >cgitrc <<-EOF
virtual-root=/
cache-size=0
auth-filter=lua:$EXTENSIONS_DIRECTORY/auth-inline.lua
repo.url=authy
repo.path=$PWD/repos/authy/.git
EOF
'
test_expect_success CGIT_LUA 'an unedited copy protects nothing' '
cgit_url "authy/log/" >tmp &&
grep ">guarded commit</a>" tmp
'
test_expect_success CGIT_LUA_NOAUTH 'without the modules a protected repository stays closed' '
cat >protect.awk <<-\EOF &&
/^local secret_filename = / { print "local secret_filename = \"" secret "\""; next }
{ print }
/^local protected_repos = [{]$/ { print "\t[\"authy\"] = { alice = true }," }
EOF
awk -v secret="$PWD/guarded-secret" -f protect.awk "$EXTENSIONS_DIRECTORY/auth-inline.lua" >guarded.lua &&
grep "\"authy\"" guarded.lua &&
grep "guarded-secret" guarded.lua &&
cat >guardedrc <<-EOF &&
virtual-root=/
cache-size=0
auth-filter=lua:$PWD/guarded.lua
repo.url=authy
repo.path=$PWD/repos/authy/.git
EOF
cgit_rc guardedrc "url=authy/log/" >tmp 2>err &&
! grep "guarded commit" tmp &&
grep "<p class=.login-error. role=.alert.>Logins are unavailable" tmp &&
grep -E "^\[cgit\] .*module .(openssl\.rand|openssl\.hmac|posix\.sys\.stat|posix\.unistd). not found" err
'
test_expect_success CGIT_LUA_AUTH 'a login through cgit opens a protected repository' '
cat >grant.awk <<-EOF &&
/^local secret_filename = / { print "local secret_filename = \"$PWD/login-secret\""; next }
{ print }
/^local protected_repos = [{]\$/ { print "\t[\"authy\"] = { alice = true }," }
/^local users = [{]\$/ { print "\talice = \"$auth_hash\"," }
EOF
awk -f grant.awk "$EXTENSIONS_DIRECTORY/auth-inline.lua" >granted.lua &&
grep "login-secret" granted.lua &&
grep "testsalt" granted.lua &&
grep "\"authy\"" granted.lua &&
cgitrc_repo grantrc authy "auth-filter=lua:$PWD/granted.lua" &&
(export HTTPS=on && cgit_ok grantrc "url=authy/log/") >form &&
grep "<form class=.login." form &&
! grep "guarded commit" form &&
token=$(sed -n "s/.*value=.\(redirect|[^|]*|0|[0-9a-f]*|[0-9a-f]*\).*/\1/p" form) &&
test -n "$token" &&
body="username=alice&password=open+sesame&redirect=$(printf "%s\n" "$token" |
sed "s/%/%25/g; s/+/%2B/g; s/|/%7C/g")" &&
printf "%s" "$body" >post &&
(
export CGIT_CONFIG="$PWD/grantrc" QUERY_STRING=p=login REQUEST_METHOD=POST \
HTTPS=on CONTENT_LENGTH=${#body} CONTENT_TYPE=application/x-www-form-urlencoded &&
cgit <post >answer 2>err
) &&
test_must_be_empty err &&
grep "^Status: 302" answer &&
grep "^Location: /authy/log/\$" answer &&
cookie=$(sed -n "s/^Set-Cookie: \(__Host-cgitauth=[^;]*\);.*/\1/p" answer) &&
test -n "$cookie" &&
(export HTTPS=on HTTP_COOKIE="$cookie" && cgit_ok grantrc "url=authy/log/") >tmp &&
grep ">guarded commit</a>" tmp &&
(export HTTPS=on && cgit_ok grantrc "url=authy/log/") >tmp &&
grep "<form class=.login." tmp &&
! grep "guarded commit" tmp
'
test_expect_success 'an auth filter is handed the repository url' '
write_script seen.sh <<-\EOF &&
test "$1" = authenticate-cookie && printf "%s\n" "$9" >seen
exit 1
EOF
cgitrc_repo seenrc team/tools.git "auth-filter=exec:$PWD/seen.sh" \
"repo.path=$PWD/repos/authy/.git" "repo.name=tools.git" &&
echo team/tools.git >expect &&
cgit_ok seenrc "url=team/tools.git/log/" >tmp &&
grep ">guarded commit</a>" tmp &&
test_cmp expect seen &&
rm seen &&
cgit_ok seenrc "r=team/tools.git&p=log" >tmp &&
grep ">guarded commit</a>" tmp &&
test_cmp expect seen &&
mkdir -p scan/team &&
git clone -q --bare repos/authy scan/team/tools.git &&
cat >scanrc <<-EOF &&
virtual-root=/
cache-size=0
auth-filter=exec:$PWD/seen.sh
section-from-path=1
scan-path=$PWD/scan
EOF
cgit_ok scanrc "" >tmp &&
grep ">tools.git</a>" tmp &&
rm seen &&
cgit_ok scanrc "url=team/tools.git/log/" >tmp &&
grep ">guarded commit</a>" tmp &&
test_cmp expect seen
'
test_expect_success 'the login page keeps the repository to itself' '
write_script deny.sh <<-\EOF &&
test "$1" = body && echo "<p>sign in</p>"
exit 0
EOF
cat >denyrc <<-EOF &&
virtual-root=/
cache-size=0
root-desc=the whole site
auth-filter=exec:$PWD/deny.sh
repo.url=authy
repo.path=$PWD/repos/authy/.git
repo.desc=the secret plan
repo.owner=Mallory Owner
repo.hide=1
EOF
cgit_rc denyrc "url=authy/log/" >tmp &&
grep "<p>sign in</p>" tmp &&
grep "<p class=.sub desc.>the whole site</p>" tmp &&
grep "<meta name=.description. content=.the whole site.>" tmp &&
! grep "secret plan" tmp &&
! grep "Mallory" tmp
'
test_expect_success 'the login page asks not to be indexed' '
cgit_rc denyrc "url=authy/log/" >tmp &&
grep "^Status: 200" tmp &&
grep "<meta name=.robots. content=.noindex, nofollow.>" tmp &&
{
echo "robots=" &&
cat denyrc
} >norobotsrc &&
cgit_rc norobotsrc "url=authy/log/" >tmp &&
grep "<meta name=.robots. content=.noindex, nofollow.>" tmp
'
test_done
|