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