]> git.ipfire.org Git - thirdparty/git.git/blame - t/lib-credential.sh
Start the 2.46 cycle
[thirdparty/git.git] / t / lib-credential.sh
CommitLineData
f27491d5
JK
1# Shell library for testing credential handling including helpers. See t0302
2# for an example of testing a specific helper.
abca927d
JK
3
4# Try a set of credential helpers; the expected stdin,
5# stdout and stderr should be provided on stdin,
6# separated by "--".
7check() {
e30b2feb
JRI
8 credential_opts=
9 credential_cmd=$1
10 shift
11 for arg in "$@"; do
12 credential_opts="$credential_opts -c credential.helper='$arg'"
13 done
abca927d
JK
14 read_chunk >stdin &&
15 read_chunk >expect-stdout &&
16 read_chunk >expect-stderr &&
e30b2feb
JRI
17 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 &&
abca927d 22 test_cmp expect-stdout stdout &&
1108cea7 23 test_cmp expect-stderr stderr
abca927d
JK
24}
25
26read_chunk() {
27 while read line; do
28 case "$line" in
29 --) break ;;
30 *) echo "$line" ;;
31 esac
32 done
33}
34
e2770979
JK
35# 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
0ce02e2f
H
46 reject $1 https example.com user-expiry
47 reject $1 https example.com user-expiry-overwrite
a5c76569 48 reject $1 https example.com user4
aeb21ce2
H
49 reject $1 https example.com user-distinct-pass
50 reject $1 https example.com user-overwrite
6c26da84
H
51 reject $1 https example.com user-erase1
52 reject $1 https example.com user-erase2
83e6eb7d 53 reject $1 https victim.example.com user
e2770979
JK
54 reject $1 http path.tld user
55 reject $1 https timeout.tld user
3c90bda6 56 reject $1 https sso.tld
e2770979
JK
57}
58
59reject() {
60 (
61 echo protocol=$2
62 echo host=$3
63 echo username=$4
e30b2feb 64 ) | git -c credential.helper=$1 credential reject
e2770979
JK
65}
66
67helper_test() {
68 HELPER=$1
69
70 test_expect_success "helper ($HELPER) has no existing data" '
71 check fill $HELPER <<-\EOF
72 protocol=https
73 host=example.com
74 --
2d6dc182
MM
75 protocol=https
76 host=example.com
e2770979
JK
77 username=askpass-username
78 password=askpass-password
79 --
80 askpass: Username for '\''https://example.com'\'':
81 askpass: Password for '\''https://askpass-username@example.com'\'':
82 EOF
83 '
84
85 test_expect_success "helper ($HELPER) stores password" '
86 check approve $HELPER <<-\EOF
87 protocol=https
88 host=example.com
89 username=store-user
90 password=store-pass
91 EOF
92 '
93
94 test_expect_success "helper ($HELPER) can retrieve password" '
95 check fill $HELPER <<-\EOF
96 protocol=https
97 host=example.com
98 --
2d6dc182
MM
99 protocol=https
100 host=example.com
e2770979
JK
101 username=store-user
102 password=store-pass
103 --
104 EOF
105 '
106
107 test_expect_success "helper ($HELPER) requires matching protocol" '
108 check fill $HELPER <<-\EOF
109 protocol=http
110 host=example.com
111 --
2d6dc182
MM
112 protocol=http
113 host=example.com
e2770979
JK
114 username=askpass-username
115 password=askpass-password
116 --
117 askpass: Username for '\''http://example.com'\'':
118 askpass: Password for '\''http://askpass-username@example.com'\'':
119 EOF
120 '
121
122 test_expect_success "helper ($HELPER) requires matching host" '
123 check fill $HELPER <<-\EOF
124 protocol=https
125 host=other.tld
126 --
2d6dc182
MM
127 protocol=https
128 host=other.tld
e2770979
JK
129 username=askpass-username
130 password=askpass-password
131 --
132 askpass: Username for '\''https://other.tld'\'':
133 askpass: Password for '\''https://askpass-username@other.tld'\'':
134 EOF
135 '
136
137 test_expect_success "helper ($HELPER) requires matching username" '
138 check fill $HELPER <<-\EOF
139 protocol=https
140 host=example.com
141 username=other
142 --
2d6dc182
MM
143 protocol=https
144 host=example.com
e2770979
JK
145 username=other
146 password=askpass-password
147 --
148 askpass: Password for '\''https://other@example.com'\'':
149 EOF
150 '
151
152 test_expect_success "helper ($HELPER) requires matching path" '
153 test_config credential.usehttppath true &&
154 check approve $HELPER <<-\EOF &&
155 protocol=http
156 host=path.tld
157 path=foo.git
158 username=user
159 password=pass
160 EOF
161 check fill $HELPER <<-\EOF
162 protocol=http
163 host=path.tld
164 path=bar.git
165 --
2d6dc182
MM
166 protocol=http
167 host=path.tld
168 path=bar.git
e2770979
JK
169 username=askpass-username
170 password=askpass-password
171 --
172 askpass: Username for '\''http://path.tld/bar.git'\'':
173 askpass: Password for '\''http://askpass-username@path.tld/bar.git'\'':
174 EOF
175 '
176
aeb21ce2
H
177 test_expect_success "helper ($HELPER) overwrites on store" '
178 check approve $HELPER <<-\EOF &&
179 protocol=https
180 host=example.com
181 username=user-overwrite
182 password=pass1
183 EOF
184 check approve $HELPER <<-\EOF &&
185 protocol=https
186 host=example.com
187 username=user-overwrite
188 password=pass2
189 EOF
190 check fill $HELPER <<-\EOF &&
191 protocol=https
192 host=example.com
193 username=user-overwrite
194 --
195 protocol=https
196 host=example.com
197 username=user-overwrite
198 password=pass2
199 EOF
200 check reject $HELPER <<-\EOF &&
201 protocol=https
202 host=example.com
203 username=user-overwrite
204 password=pass2
205 EOF
206 check fill $HELPER <<-\EOF
207 protocol=https
208 host=example.com
209 username=user-overwrite
210 --
211 protocol=https
212 host=example.com
213 username=user-overwrite
214 password=askpass-password
215 --
216 askpass: Password for '\''https://user-overwrite@example.com'\'':
217 EOF
218 '
219
e2770979
JK
220 test_expect_success "helper ($HELPER) can forget host" '
221 check reject $HELPER <<-\EOF &&
222 protocol=https
223 host=example.com
224 EOF
225 check fill $HELPER <<-\EOF
226 protocol=https
227 host=example.com
228 --
2d6dc182
MM
229 protocol=https
230 host=example.com
e2770979
JK
231 username=askpass-username
232 password=askpass-password
233 --
234 askpass: Username for '\''https://example.com'\'':
235 askpass: Password for '\''https://askpass-username@example.com'\'':
236 EOF
237 '
238
239 test_expect_success "helper ($HELPER) can store multiple users" '
240 check approve $HELPER <<-\EOF &&
241 protocol=https
242 host=example.com
243 username=user1
244 password=pass1
245 EOF
246 check approve $HELPER <<-\EOF &&
247 protocol=https
248 host=example.com
249 username=user2
250 password=pass2
251 EOF
252 check fill $HELPER <<-\EOF &&
253 protocol=https
254 host=example.com
255 username=user1
256 --
2d6dc182
MM
257 protocol=https
258 host=example.com
e2770979
JK
259 username=user1
260 password=pass1
261 EOF
262 check fill $HELPER <<-\EOF
263 protocol=https
264 host=example.com
265 username=user2
266 --
2d6dc182
MM
267 protocol=https
268 host=example.com
e2770979
JK
269 username=user2
270 password=pass2
271 EOF
272 '
273
aeb21ce2
H
274 test_expect_success "helper ($HELPER) does not erase a password distinct from input" '
275 check approve $HELPER <<-\EOF &&
276 protocol=https
277 host=example.com
278 username=user-distinct-pass
279 password=pass1
280 EOF
281 check reject $HELPER <<-\EOF &&
282 protocol=https
283 host=example.com
284 username=user-distinct-pass
285 password=pass2
286 EOF
287 check fill $HELPER <<-\EOF
288 protocol=https
289 host=example.com
290 username=user-distinct-pass
291 --
292 protocol=https
293 host=example.com
294 username=user-distinct-pass
295 password=pass1
296 EOF
297 '
298
e2770979
JK
299 test_expect_success "helper ($HELPER) can forget user" '
300 check reject $HELPER <<-\EOF &&
301 protocol=https
302 host=example.com
303 username=user1
304 EOF
305 check fill $HELPER <<-\EOF
306 protocol=https
307 host=example.com
308 username=user1
309 --
2d6dc182
MM
310 protocol=https
311 host=example.com
e2770979
JK
312 username=user1
313 password=askpass-password
314 --
315 askpass: Password for '\''https://user1@example.com'\'':
316 EOF
317 '
318
319 test_expect_success "helper ($HELPER) remembers other user" '
320 check fill $HELPER <<-\EOF
321 protocol=https
322 host=example.com
323 username=user2
324 --
2d6dc182
MM
325 protocol=https
326 host=example.com
e2770979
JK
327 username=user2
328 password=pass2
329 EOF
330 '
3c90bda6
JB
331
332 test_expect_success "helper ($HELPER) can store empty username" '
333 check approve $HELPER <<-\EOF &&
334 protocol=https
335 host=sso.tld
336 username=
337 password=
338 EOF
339 check fill $HELPER <<-\EOF
340 protocol=https
341 host=sso.tld
342 --
343 protocol=https
344 host=sso.tld
345 username=
346 password=
347 EOF
348 '
71201ab0 349
6c26da84
H
350 test_expect_success "helper ($HELPER) erases all matching credentials" '
351 check approve $HELPER <<-\EOF &&
352 protocol=https
353 host=example.com
354 username=user-erase1
355 password=pass1
356 EOF
357 check approve $HELPER <<-\EOF &&
358 protocol=https
359 host=example.com
360 username=user-erase2
361 password=pass1
362 EOF
363 check reject $HELPER <<-\EOF &&
364 protocol=https
365 host=example.com
366 EOF
367 check fill $HELPER <<-\EOF
368 protocol=https
369 host=example.com
370 --
371 protocol=https
372 host=example.com
373 username=askpass-username
374 password=askpass-password
375 --
376 askpass: Username for '\''https://example.com'\'':
377 askpass: Password for '\''https://askpass-username@example.com'\'':
378 EOF
379 '
380
71201ab0
TB
381 : ${GIT_TEST_LONG_CRED_BUFFER:=1024}
382 # 23 bytes accounts for "wwwauth[]=basic realm=" plus NUL
383 LONG_VALUE_LEN=$((GIT_TEST_LONG_CRED_BUFFER - 23))
384 LONG_VALUE=$(perl -e 'print "a" x shift' $LONG_VALUE_LEN)
385
386 test_expect_success "helper ($HELPER) not confused by long header" '
387 check approve $HELPER <<-\EOF &&
388 protocol=https
389 host=victim.example.com
390 username=user
391 password=to-be-stolen
392 EOF
393
394 check fill $HELPER <<-EOF
395 protocol=https
396 host=badguy.example.com
397 wwwauth[]=basic realm=${LONG_VALUE}host=victim.example.com
398 --
399 protocol=https
400 host=badguy.example.com
401 username=askpass-username
402 password=askpass-password
403 wwwauth[]=basic realm=${LONG_VALUE}host=victim.example.com
404 --
405 askpass: Username for '\''https://badguy.example.com'\'':
406 askpass: Password for '\''https://askpass-username@badguy.example.com'\'':
407 EOF
408 '
e2770979
JK
409}
410
411helper_test_timeout() {
412 HELPER="$*"
413
414 test_expect_success "helper ($HELPER) times out" '
415 check approve "$HELPER" <<-\EOF &&
416 protocol=https
417 host=timeout.tld
418 username=user
419 password=pass
420 EOF
421 sleep 2 &&
422 check fill "$HELPER" <<-\EOF
423 protocol=https
424 host=timeout.tld
425 --
2d6dc182
MM
426 protocol=https
427 host=timeout.tld
e2770979
JK
428 username=askpass-username
429 password=askpass-password
430 --
431 askpass: Username for '\''https://timeout.tld'\'':
432 askpass: Password for '\''https://askpass-username@timeout.tld'\'':
433 EOF
434 '
435}
abca927d 436
0ce02e2f
H
437helper_test_password_expiry_utc() {
438 HELPER=$1
439
440 test_expect_success "helper ($HELPER) stores password_expiry_utc" '
441 check approve $HELPER <<-\EOF
442 protocol=https
443 host=example.com
444 username=user-expiry
445 password=pass
446 password_expiry_utc=9999999999
447 EOF
448 '
449
450 test_expect_success "helper ($HELPER) gets password_expiry_utc" '
451 check fill $HELPER <<-\EOF
452 protocol=https
453 host=example.com
454 username=user-expiry
455 --
456 protocol=https
457 host=example.com
458 username=user-expiry
459 password=pass
460 password_expiry_utc=9999999999
461 --
462 EOF
463 '
464
465 test_expect_success "helper ($HELPER) overwrites when password_expiry_utc changes" '
466 check approve $HELPER <<-\EOF &&
467 protocol=https
468 host=example.com
469 username=user-expiry-overwrite
470 password=pass1
471 password_expiry_utc=9999999998
472 EOF
473 check approve $HELPER <<-\EOF &&
474 protocol=https
475 host=example.com
476 username=user-expiry-overwrite
477 password=pass2
478 password_expiry_utc=9999999999
479 EOF
480 check fill $HELPER <<-\EOF &&
481 protocol=https
482 host=example.com
483 username=user-expiry-overwrite
484 --
485 protocol=https
486 host=example.com
487 username=user-expiry-overwrite
488 password=pass2
489 password_expiry_utc=9999999999
490 EOF
491 check reject $HELPER <<-\EOF &&
492 protocol=https
493 host=example.com
494 username=user-expiry-overwrite
495 password=pass2
496 EOF
497 check fill $HELPER <<-\EOF
498 protocol=https
499 host=example.com
500 username=user-expiry-overwrite
501 --
502 protocol=https
503 host=example.com
504 username=user-expiry-overwrite
505 password=askpass-password
506 --
507 askpass: Password for '\''https://user-expiry-overwrite@example.com'\'':
508 EOF
509 '
510}
511
a5c76569
H
512helper_test_oauth_refresh_token() {
513 HELPER=$1
514
515 test_expect_success "helper ($HELPER) stores oauth_refresh_token" '
516 check approve $HELPER <<-\EOF
517 protocol=https
518 host=example.com
519 username=user4
520 password=pass
521 oauth_refresh_token=xyzzy
522 EOF
523 '
524
525 test_expect_success "helper ($HELPER) gets oauth_refresh_token" '
526 check fill $HELPER <<-\EOF
527 protocol=https
528 host=example.com
529 username=user4
530 --
531 protocol=https
532 host=example.com
533 username=user4
534 password=pass
535 oauth_refresh_token=xyzzy
536 --
537 EOF
538 '
539}
540
c049216f 541write_script askpass <<\EOF
abca927d 542echo >&2 askpass: $*
5a435202 543what=$(echo $1 | cut -d" " -f1 | tr A-Z a-z | tr -cd a-z)
abca927d
JK
544echo "askpass-$what"
545EOF
abca927d
JK
546GIT_ASKPASS="$PWD/askpass"
547export GIT_ASKPASS