blob: 032b2d8fcc48aa2cd72c60fa05f9b1299680f92c [file] [log] [blame]
Jeff Kingf27491d2020-03-26 04:25:27 -04001# Shell library for testing credential handling including helpers. See t0302
2# for an example of testing a specific helper.
Jeff Kingabca9272011-12-10 05:31:11 -05003
4# Try a set of credential helpers; the expected stdin,
5# stdout and stderr should be provided on stdin,
6# separated by "--".
7check() {
Javier Roucher Iglesiase30b2fe2012-06-24 13:39:59 +02008 credential_opts=
9 credential_cmd=$1
10 shift
11 for arg in "$@"; do
12 credential_opts="$credential_opts -c credential.helper='$arg'"
13 done
Jeff Kingabca9272011-12-10 05:31:11 -050014 read_chunk >stdin &&
15 read_chunk >expect-stdout &&
16 read_chunk >expect-stderr &&
Javier Roucher Iglesiase30b2fe2012-06-24 13:39:59 +020017 if ! eval "git $credential_opts credential $credential_cmd <stdin >stdout 2>stderr"; then
18 echo "git credential failed with code $?" &&
19 cat stderr &&
20 false
21 fi &&
Jeff Kingabca9272011-12-10 05:31:11 -050022 test_cmp expect-stdout stdout &&
Ævar Arnfjörð Bjarmason1108cea2021-02-11 02:53:53 +010023 test_cmp expect-stderr stderr
Jeff Kingabca9272011-12-10 05:31:11 -050024}
25
26read_chunk() {
27 while read line; do
28 case "$line" in
29 --) break ;;
30 *) echo "$line" ;;
31 esac
32 done
33}
34
Jeff Kinge2770972011-12-10 05:34:14 -050035# Clear any residual data from previous tests. We only
36# need this when testing third-party helpers which read and
37# write outside of our trash-directory sandbox.
38#
39# Don't bother checking for success here, as it is
40# outside the scope of tests and represents a best effort to
41# clean up after ourselves.
42helper_test_clean() {
43 reject $1 https example.com store-user
44 reject $1 https example.com user1
45 reject $1 https example.com user2
M Hickforda5c76562023-04-21 09:47:59 +000046 reject $1 https example.com user4
M Hickfordaeb21ce2023-06-15 19:19:32 +000047 reject $1 https example.com user-distinct-pass
48 reject $1 https example.com user-overwrite
M Hickford6c26da82023-06-15 19:19:33 +000049 reject $1 https example.com user-erase1
50 reject $1 https example.com user-erase2
Jeff Kinge2770972011-12-10 05:34:14 -050051 reject $1 http path.tld user
52 reject $1 https timeout.tld user
Jakub Bereżański3c90bda2017-10-30 18:20:12 +010053 reject $1 https sso.tld
Jeff Kinge2770972011-12-10 05:34:14 -050054}
55
56reject() {
57 (
58 echo protocol=$2
59 echo host=$3
60 echo username=$4
Javier Roucher Iglesiase30b2fe2012-06-24 13:39:59 +020061 ) | git -c credential.helper=$1 credential reject
Jeff Kinge2770972011-12-10 05:34:14 -050062}
63
64helper_test() {
65 HELPER=$1
66
67 test_expect_success "helper ($HELPER) has no existing data" '
68 check fill $HELPER <<-\EOF
69 protocol=https
70 host=example.com
71 --
Matthieu Moy2d6dc182012-06-24 13:40:00 +020072 protocol=https
73 host=example.com
Jeff Kinge2770972011-12-10 05:34:14 -050074 username=askpass-username
75 password=askpass-password
76 --
77 askpass: Username for '\''https://example.com'\'':
78 askpass: Password for '\''https://askpass-username@example.com'\'':
79 EOF
80 '
81
82 test_expect_success "helper ($HELPER) stores password" '
83 check approve $HELPER <<-\EOF
84 protocol=https
85 host=example.com
86 username=store-user
87 password=store-pass
88 EOF
89 '
90
91 test_expect_success "helper ($HELPER) can retrieve password" '
92 check fill $HELPER <<-\EOF
93 protocol=https
94 host=example.com
95 --
Matthieu Moy2d6dc182012-06-24 13:40:00 +020096 protocol=https
97 host=example.com
Jeff Kinge2770972011-12-10 05:34:14 -050098 username=store-user
99 password=store-pass
100 --
101 EOF
102 '
103
104 test_expect_success "helper ($HELPER) requires matching protocol" '
105 check fill $HELPER <<-\EOF
106 protocol=http
107 host=example.com
108 --
Matthieu Moy2d6dc182012-06-24 13:40:00 +0200109 protocol=http
110 host=example.com
Jeff Kinge2770972011-12-10 05:34:14 -0500111 username=askpass-username
112 password=askpass-password
113 --
114 askpass: Username for '\''http://example.com'\'':
115 askpass: Password for '\''http://askpass-username@example.com'\'':
116 EOF
117 '
118
119 test_expect_success "helper ($HELPER) requires matching host" '
120 check fill $HELPER <<-\EOF
121 protocol=https
122 host=other.tld
123 --
Matthieu Moy2d6dc182012-06-24 13:40:00 +0200124 protocol=https
125 host=other.tld
Jeff Kinge2770972011-12-10 05:34:14 -0500126 username=askpass-username
127 password=askpass-password
128 --
129 askpass: Username for '\''https://other.tld'\'':
130 askpass: Password for '\''https://askpass-username@other.tld'\'':
131 EOF
132 '
133
134 test_expect_success "helper ($HELPER) requires matching username" '
135 check fill $HELPER <<-\EOF
136 protocol=https
137 host=example.com
138 username=other
139 --
Matthieu Moy2d6dc182012-06-24 13:40:00 +0200140 protocol=https
141 host=example.com
Jeff Kinge2770972011-12-10 05:34:14 -0500142 username=other
143 password=askpass-password
144 --
145 askpass: Password for '\''https://other@example.com'\'':
146 EOF
147 '
148
149 test_expect_success "helper ($HELPER) requires matching path" '
150 test_config credential.usehttppath true &&
151 check approve $HELPER <<-\EOF &&
152 protocol=http
153 host=path.tld
154 path=foo.git
155 username=user
156 password=pass
157 EOF
158 check fill $HELPER <<-\EOF
159 protocol=http
160 host=path.tld
161 path=bar.git
162 --
Matthieu Moy2d6dc182012-06-24 13:40:00 +0200163 protocol=http
164 host=path.tld
165 path=bar.git
Jeff Kinge2770972011-12-10 05:34:14 -0500166 username=askpass-username
167 password=askpass-password
168 --
169 askpass: Username for '\''http://path.tld/bar.git'\'':
170 askpass: Password for '\''http://askpass-username@path.tld/bar.git'\'':
171 EOF
172 '
173
M Hickfordaeb21ce2023-06-15 19:19:32 +0000174 test_expect_success "helper ($HELPER) overwrites on store" '
175 check approve $HELPER <<-\EOF &&
176 protocol=https
177 host=example.com
178 username=user-overwrite
179 password=pass1
180 EOF
181 check approve $HELPER <<-\EOF &&
182 protocol=https
183 host=example.com
184 username=user-overwrite
185 password=pass2
186 EOF
187 check fill $HELPER <<-\EOF &&
188 protocol=https
189 host=example.com
190 username=user-overwrite
191 --
192 protocol=https
193 host=example.com
194 username=user-overwrite
195 password=pass2
196 EOF
197 check reject $HELPER <<-\EOF &&
198 protocol=https
199 host=example.com
200 username=user-overwrite
201 password=pass2
202 EOF
203 check fill $HELPER <<-\EOF
204 protocol=https
205 host=example.com
206 username=user-overwrite
207 --
208 protocol=https
209 host=example.com
210 username=user-overwrite
211 password=askpass-password
212 --
213 askpass: Password for '\''https://user-overwrite@example.com'\'':
214 EOF
215 '
216
Jeff Kinge2770972011-12-10 05:34:14 -0500217 test_expect_success "helper ($HELPER) can forget host" '
218 check reject $HELPER <<-\EOF &&
219 protocol=https
220 host=example.com
221 EOF
222 check fill $HELPER <<-\EOF
223 protocol=https
224 host=example.com
225 --
Matthieu Moy2d6dc182012-06-24 13:40:00 +0200226 protocol=https
227 host=example.com
Jeff Kinge2770972011-12-10 05:34:14 -0500228 username=askpass-username
229 password=askpass-password
230 --
231 askpass: Username for '\''https://example.com'\'':
232 askpass: Password for '\''https://askpass-username@example.com'\'':
233 EOF
234 '
235
236 test_expect_success "helper ($HELPER) can store multiple users" '
237 check approve $HELPER <<-\EOF &&
238 protocol=https
239 host=example.com
240 username=user1
241 password=pass1
242 EOF
243 check approve $HELPER <<-\EOF &&
244 protocol=https
245 host=example.com
246 username=user2
247 password=pass2
248 EOF
249 check fill $HELPER <<-\EOF &&
250 protocol=https
251 host=example.com
252 username=user1
253 --
Matthieu Moy2d6dc182012-06-24 13:40:00 +0200254 protocol=https
255 host=example.com
Jeff Kinge2770972011-12-10 05:34:14 -0500256 username=user1
257 password=pass1
258 EOF
259 check fill $HELPER <<-\EOF
260 protocol=https
261 host=example.com
262 username=user2
263 --
Matthieu Moy2d6dc182012-06-24 13:40:00 +0200264 protocol=https
265 host=example.com
Jeff Kinge2770972011-12-10 05:34:14 -0500266 username=user2
267 password=pass2
268 EOF
269 '
270
M Hickfordaeb21ce2023-06-15 19:19:32 +0000271 test_expect_success "helper ($HELPER) does not erase a password distinct from input" '
272 check approve $HELPER <<-\EOF &&
273 protocol=https
274 host=example.com
275 username=user-distinct-pass
276 password=pass1
277 EOF
278 check reject $HELPER <<-\EOF &&
279 protocol=https
280 host=example.com
281 username=user-distinct-pass
282 password=pass2
283 EOF
284 check fill $HELPER <<-\EOF
285 protocol=https
286 host=example.com
287 username=user-distinct-pass
288 --
289 protocol=https
290 host=example.com
291 username=user-distinct-pass
292 password=pass1
293 EOF
294 '
295
Jeff Kinge2770972011-12-10 05:34:14 -0500296 test_expect_success "helper ($HELPER) can forget user" '
297 check reject $HELPER <<-\EOF &&
298 protocol=https
299 host=example.com
300 username=user1
301 EOF
302 check fill $HELPER <<-\EOF
303 protocol=https
304 host=example.com
305 username=user1
306 --
Matthieu Moy2d6dc182012-06-24 13:40:00 +0200307 protocol=https
308 host=example.com
Jeff Kinge2770972011-12-10 05:34:14 -0500309 username=user1
310 password=askpass-password
311 --
312 askpass: Password for '\''https://user1@example.com'\'':
313 EOF
314 '
315
316 test_expect_success "helper ($HELPER) remembers other user" '
317 check fill $HELPER <<-\EOF
318 protocol=https
319 host=example.com
320 username=user2
321 --
Matthieu Moy2d6dc182012-06-24 13:40:00 +0200322 protocol=https
323 host=example.com
Jeff Kinge2770972011-12-10 05:34:14 -0500324 username=user2
325 password=pass2
326 EOF
327 '
Jakub Bereżański3c90bda2017-10-30 18:20:12 +0100328
329 test_expect_success "helper ($HELPER) can store empty username" '
330 check approve $HELPER <<-\EOF &&
331 protocol=https
332 host=sso.tld
333 username=
334 password=
335 EOF
336 check fill $HELPER <<-\EOF
337 protocol=https
338 host=sso.tld
339 --
340 protocol=https
341 host=sso.tld
342 username=
343 password=
344 EOF
345 '
Taylor Blau71201ab2023-05-01 11:53:51 -0400346
M Hickford6c26da82023-06-15 19:19:33 +0000347 test_expect_success "helper ($HELPER) erases all matching credentials" '
348 check approve $HELPER <<-\EOF &&
349 protocol=https
350 host=example.com
351 username=user-erase1
352 password=pass1
353 EOF
354 check approve $HELPER <<-\EOF &&
355 protocol=https
356 host=example.com
357 username=user-erase2
358 password=pass1
359 EOF
360 check reject $HELPER <<-\EOF &&
361 protocol=https
362 host=example.com
363 EOF
364 check fill $HELPER <<-\EOF
365 protocol=https
366 host=example.com
367 --
368 protocol=https
369 host=example.com
370 username=askpass-username
371 password=askpass-password
372 --
373 askpass: Username for '\''https://example.com'\'':
374 askpass: Password for '\''https://askpass-username@example.com'\'':
375 EOF
376 '
377
Taylor Blau71201ab2023-05-01 11:53:51 -0400378 : ${GIT_TEST_LONG_CRED_BUFFER:=1024}
379 # 23 bytes accounts for "wwwauth[]=basic realm=" plus NUL
380 LONG_VALUE_LEN=$((GIT_TEST_LONG_CRED_BUFFER - 23))
381 LONG_VALUE=$(perl -e 'print "a" x shift' $LONG_VALUE_LEN)
382
383 test_expect_success "helper ($HELPER) not confused by long header" '
384 check approve $HELPER <<-\EOF &&
385 protocol=https
386 host=victim.example.com
387 username=user
388 password=to-be-stolen
389 EOF
390
391 check fill $HELPER <<-EOF
392 protocol=https
393 host=badguy.example.com
394 wwwauth[]=basic realm=${LONG_VALUE}host=victim.example.com
395 --
396 protocol=https
397 host=badguy.example.com
398 username=askpass-username
399 password=askpass-password
400 wwwauth[]=basic realm=${LONG_VALUE}host=victim.example.com
401 --
402 askpass: Username for '\''https://badguy.example.com'\'':
403 askpass: Password for '\''https://askpass-username@badguy.example.com'\'':
404 EOF
405 '
Jeff Kinge2770972011-12-10 05:34:14 -0500406}
407
408helper_test_timeout() {
409 HELPER="$*"
410
411 test_expect_success "helper ($HELPER) times out" '
412 check approve "$HELPER" <<-\EOF &&
413 protocol=https
414 host=timeout.tld
415 username=user
416 password=pass
417 EOF
418 sleep 2 &&
419 check fill "$HELPER" <<-\EOF
420 protocol=https
421 host=timeout.tld
422 --
Matthieu Moy2d6dc182012-06-24 13:40:00 +0200423 protocol=https
424 host=timeout.tld
Jeff Kinge2770972011-12-10 05:34:14 -0500425 username=askpass-username
426 password=askpass-password
427 --
428 askpass: Username for '\''https://timeout.tld'\'':
429 askpass: Password for '\''https://askpass-username@timeout.tld'\'':
430 EOF
431 '
432}
Jeff Kingabca9272011-12-10 05:31:11 -0500433
M Hickforda5c76562023-04-21 09:47:59 +0000434helper_test_oauth_refresh_token() {
435 HELPER=$1
436
437 test_expect_success "helper ($HELPER) stores oauth_refresh_token" '
438 check approve $HELPER <<-\EOF
439 protocol=https
440 host=example.com
441 username=user4
442 password=pass
443 oauth_refresh_token=xyzzy
444 EOF
445 '
446
447 test_expect_success "helper ($HELPER) gets oauth_refresh_token" '
448 check fill $HELPER <<-\EOF
449 protocol=https
450 host=example.com
451 username=user4
452 --
453 protocol=https
454 host=example.com
455 username=user4
456 password=pass
457 oauth_refresh_token=xyzzy
458 --
459 EOF
460 '
461}
462
Ben Waltonc0492162014-09-29 08:02:07 +0100463write_script askpass <<\EOF
Jeff Kingabca9272011-12-10 05:31:11 -0500464echo >&2 askpass: $*
Elia Pinto5a435202014-04-23 06:44:03 -0700465what=$(echo $1 | cut -d" " -f1 | tr A-Z a-z | tr -cd a-z)
Jeff Kingabca9272011-12-10 05:31:11 -0500466echo "askpass-$what"
467EOF
Jeff Kingabca9272011-12-10 05:31:11 -0500468GIT_ASKPASS="$PWD/askpass"
469export GIT_ASKPASS