3 test_description
='test http auth header and credential helper interop'
5 TEST_PASSES_SANITIZE_LEAK
=true
7 .
"$TEST_DIRECTORY"/lib-httpd.sh
10 if ! test_have_prereq CGIPASSAUTH
12 skip_all
="no CGIPassAuth support"
17 test_expect_success
'setup_credential_helper' '
18 mkdir "$TRASH_DIRECTORY/bin" &&
19 PATH=$PATH:"$TRASH_DIRECTORY/bin" &&
22 CREDENTIAL_HELPER="$TRASH_DIRECTORY/bin/git-credential-test-helper" &&
23 write_script "$CREDENTIAL_HELPER" <<-\EOF
25 teefile=$cmd-query-temp.cred
26 catfile=$cmd-reply.cred
27 sed -n -e "/^$/q" -e "p" >>$teefile
28 state=$(sed -ne "s/^state\[\]=helper://p" "$teefile")
31 mv "$teefile" "$cmd-query.cred"
33 mv "$teefile" "$cmd-query-$state.cred"
34 catfile="$cmd-reply-$state.cred"
36 if test "$cmd" = "get"
43 set_credential_reply
() {
44 local suffix
="$(test -n "$2" && echo "-$2")"
45 cat >"$TRASH_DIRECTORY/$1-reply$suffix.cred"
48 expect_credential_query
() {
49 local suffix
="$(test -n "$2" && echo "-$2")"
50 cat >"$TRASH_DIRECTORY/$1-expect$suffix.cred" &&
51 test_cmp
"$TRASH_DIRECTORY/$1-expect$suffix.cred" \
52 "$TRASH_DIRECTORY/$1-query$suffix.cred"
57 rm -f "$HTTPD_ROOT_PATH"/custom-auth.valid \
58 "$HTTPD_ROOT_PATH"/custom-auth.challenge
61 test_expect_success
'setup repository' '
63 git init --bare "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
64 git push --mirror "$HTTPD_DOCUMENT_ROOT_PATH/repo.git"
67 test_expect_success
'access using basic auth' '
68 test_when_finished "per_test_cleanup" &&
70 set_credential_reply get <<-EOF &&
72 password=secret-passwd
75 # Basic base64(alice:secret-passwd)
76 cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
77 id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
80 cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
82 id=default response=WWW-Authenticate: Basic realm="example.com"
85 test_config_global credential.helper test-helper &&
86 git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
88 expect_credential_query get <<-EOF &&
93 wwwauth[]=Basic realm="example.com"
96 expect_credential_query store <<-EOF
100 password=secret-passwd
104 test_expect_success
'access using basic auth via authtype' '
105 test_when_finished "per_test_cleanup" &&
107 set_credential_reply get <<-EOF &&
108 capability[]=authtype
110 credential=YWxpY2U6c2VjcmV0LXBhc3N3ZA==
113 # Basic base64(alice:secret-passwd)
114 cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
115 id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
118 cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
120 id=default response=WWW-Authenticate: Basic realm="example.com"
123 test_config_global credential.helper test-helper &&
124 GIT_CURL_VERBOSE=1 git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
126 expect_credential_query get <<-EOF &&
127 capability[]=authtype
131 wwwauth[]=Basic realm="example.com"
134 expect_credential_query store <<-EOF
135 capability[]=authtype
137 credential=YWxpY2U6c2VjcmV0LXBhc3N3ZA==
143 test_expect_success
'access using basic auth invalid credentials' '
144 test_when_finished "per_test_cleanup" &&
146 set_credential_reply get <<-EOF &&
148 password=wrong-passwd
151 # Basic base64(alice:secret-passwd)
152 cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
153 id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
156 cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
158 id=default response=WWW-Authenticate: Basic realm="example.com"
161 test_config_global credential.helper test-helper &&
162 test_must_fail git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
164 expect_credential_query get <<-EOF &&
165 capability[]=authtype
169 wwwauth[]=Basic realm="example.com"
172 expect_credential_query erase <<-EOF
176 password=wrong-passwd
177 wwwauth[]=Basic realm="example.com"
181 test_expect_success
'access using basic proactive auth' '
182 test_when_finished "per_test_cleanup" &&
184 set_credential_reply get <<-EOF &&
186 password=secret-passwd
189 # Basic base64(alice:secret-passwd)
190 cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
191 id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
194 cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
196 id=default status=403
199 test_config_global credential.helper test-helper &&
200 test_config_global http.proactiveAuth basic &&
201 git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
203 expect_credential_query get <<-EOF &&
204 capability[]=authtype
211 expect_credential_query store <<-EOF
215 password=secret-passwd
219 test_expect_success
'access using auto proactive auth with basic default' '
220 test_when_finished "per_test_cleanup" &&
222 set_credential_reply get <<-EOF &&
224 password=secret-passwd
227 # Basic base64(alice:secret-passwd)
228 cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
229 id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
232 cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
234 id=default status=403
237 test_config_global credential.helper test-helper &&
238 test_config_global http.proactiveAuth auto &&
239 git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
241 expect_credential_query get <<-EOF &&
242 capability[]=authtype
248 expect_credential_query store <<-EOF
252 password=secret-passwd
256 test_expect_success
'access using auto proactive auth with authtype from credential helper' '
257 test_when_finished "per_test_cleanup" &&
259 set_credential_reply get <<-EOF &&
260 capability[]=authtype
262 credential=YS1naXQtdG9rZW4=
265 # Basic base64(a-git-token)
266 cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
267 id=1 creds=Bearer YS1naXQtdG9rZW4=
270 CHALLENGE="$HTTPD_ROOT_PATH/custom-auth.challenge" &&
272 cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
274 id=default status=403
277 test_config_global credential.helper test-helper &&
278 test_config_global http.proactiveAuth auto &&
279 git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
281 expect_credential_query get <<-EOF &&
282 capability[]=authtype
288 expect_credential_query store <<-EOF
289 capability[]=authtype
291 credential=YS1naXQtdG9rZW4=
297 test_expect_success
'access using basic auth with extra challenges' '
298 test_when_finished "per_test_cleanup" &&
300 set_credential_reply get <<-EOF &&
302 password=secret-passwd
305 # Basic base64(alice:secret-passwd)
306 cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
307 id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
310 cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
312 id=default response=WWW-Authenticate: FooBar param1="value1" param2="value2"
313 id=default response=WWW-Authenticate: Bearer authorize_uri="id.example.com" p=1 q=0
314 id=default response=WWW-Authenticate: Basic realm="example.com"
317 test_config_global credential.helper test-helper &&
318 git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
320 expect_credential_query get <<-EOF &&
321 capability[]=authtype
325 wwwauth[]=FooBar param1="value1" param2="value2"
326 wwwauth[]=Bearer authorize_uri="id.example.com" p=1 q=0
327 wwwauth[]=Basic realm="example.com"
330 expect_credential_query store <<-EOF
334 password=secret-passwd
338 test_expect_success
'access using basic auth mixed-case wwwauth header name' '
339 test_when_finished "per_test_cleanup" &&
341 set_credential_reply get <<-EOF &&
343 password=secret-passwd
346 # Basic base64(alice:secret-passwd)
347 cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
348 id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
351 cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
353 id=default response=www-authenticate: foobar param1="value1" param2="value2"
354 id=default response=WWW-AUTHENTICATE: BEARER authorize_uri="id.example.com" p=1 q=0
355 id=default response=WwW-aUtHeNtIcAtE: baSiC realm="example.com"
358 test_config_global credential.helper test-helper &&
359 git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
361 expect_credential_query get <<-EOF &&
362 capability[]=authtype
366 wwwauth[]=foobar param1="value1" param2="value2"
367 wwwauth[]=BEARER authorize_uri="id.example.com" p=1 q=0
368 wwwauth[]=baSiC realm="example.com"
371 expect_credential_query store <<-EOF
375 password=secret-passwd
379 test_expect_success
'access using basic auth with wwwauth header continuations' '
380 test_when_finished "per_test_cleanup" &&
382 set_credential_reply get <<-EOF &&
384 password=secret-passwd
387 # Basic base64(alice:secret-passwd)
388 cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
389 id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
392 # Note that leading and trailing whitespace is important to correctly
393 # simulate a continuation/folded header.
394 cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
396 id=default response=WWW-Authenticate: FooBar param1="value1"
397 id=default response= param2="value2"
398 id=default response=WWW-Authenticate: Bearer authorize_uri="id.example.com"
399 id=default response= p=1
400 id=default response= q=0
401 id=default response=WWW-Authenticate: Basic realm="example.com"
404 test_config_global credential.helper test-helper &&
405 git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
407 expect_credential_query get <<-EOF &&
408 capability[]=authtype
412 wwwauth[]=FooBar param1="value1" param2="value2"
413 wwwauth[]=Bearer authorize_uri="id.example.com" p=1 q=0
414 wwwauth[]=Basic realm="example.com"
417 expect_credential_query store <<-EOF
421 password=secret-passwd
425 test_expect_success
'access using basic auth with wwwauth header empty continuations' '
426 test_when_finished "per_test_cleanup" &&
428 set_credential_reply get <<-EOF &&
430 password=secret-passwd
433 # Basic base64(alice:secret-passwd)
434 cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
435 id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
438 CHALLENGE="$HTTPD_ROOT_PATH/custom-auth.challenge" &&
440 # Note that leading and trailing whitespace is important to correctly
441 # simulate a continuation/folded header.
442 printf "id=1 status=200\n" >"$CHALLENGE" &&
443 printf "id=default response=WWW-Authenticate: FooBar param1=\"value1\"\r\n" >>"$CHALLENGE" &&
444 printf "id=default response= \r\n" >>"$CHALLENGE" &&
445 printf "id=default response= param2=\"value2\"\r\n" >>"$CHALLENGE" &&
446 printf "id=default response=WWW-Authenticate: Bearer authorize_uri=\"id.example.com\"\r\n" >>"$CHALLENGE" &&
447 printf "id=default response= p=1\r\n" >>"$CHALLENGE" &&
448 printf "id=default response= \r\n" >>"$CHALLENGE" &&
449 printf "id=default response= q=0\r\n" >>"$CHALLENGE" &&
450 printf "id=default response=WWW-Authenticate: Basic realm=\"example.com\"\r\n" >>"$CHALLENGE" &&
452 test_config_global credential.helper test-helper &&
453 git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
455 expect_credential_query get <<-EOF &&
456 capability[]=authtype
460 wwwauth[]=FooBar param1="value1" param2="value2"
461 wwwauth[]=Bearer authorize_uri="id.example.com" p=1 q=0
462 wwwauth[]=Basic realm="example.com"
465 expect_credential_query store <<-EOF
469 password=secret-passwd
473 test_expect_success
'access using basic auth with wwwauth header mixed line-endings' '
474 test_when_finished "per_test_cleanup" &&
476 set_credential_reply get <<-EOF &&
478 password=secret-passwd
481 # Basic base64(alice:secret-passwd)
482 cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
483 id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
486 CHALLENGE="$HTTPD_ROOT_PATH/custom-auth.challenge" &&
488 # Note that leading and trailing whitespace is important to correctly
489 # simulate a continuation/folded header.
490 printf "id=1 status=200\n" >"$CHALLENGE" &&
491 printf "id=default response=WWW-Authenticate: FooBar param1=\"value1\"\r\n" >>"$CHALLENGE" &&
492 printf "id=default response= \r\n" >>"$CHALLENGE" &&
493 printf "id=default response=\tparam2=\"value2\"\r\n" >>"$CHALLENGE" &&
494 printf "id=default response=WWW-Authenticate: Basic realm=\"example.com\"" >>"$CHALLENGE" &&
496 test_config_global credential.helper test-helper &&
497 git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
499 expect_credential_query get <<-EOF &&
500 capability[]=authtype
504 wwwauth[]=FooBar param1="value1" param2="value2"
505 wwwauth[]=Basic realm="example.com"
508 expect_credential_query store <<-EOF
512 password=secret-passwd
516 test_expect_success
'access using bearer auth' '
517 test_when_finished "per_test_cleanup" &&
519 set_credential_reply get <<-EOF &&
520 capability[]=authtype
522 credential=YS1naXQtdG9rZW4=
525 # Basic base64(a-git-token)
526 cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
527 id=1 creds=Bearer YS1naXQtdG9rZW4=
530 CHALLENGE="$HTTPD_ROOT_PATH/custom-auth.challenge" &&
532 cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
534 id=default response=WWW-Authenticate: FooBar param1="value1" param2="value2"
535 id=default response=WWW-Authenticate: Bearer authorize_uri="id.example.com" p=1 q=0
536 id=default response=WWW-Authenticate: Basic realm="example.com"
539 test_config_global credential.helper test-helper &&
540 git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
542 expect_credential_query get <<-EOF &&
543 capability[]=authtype
547 wwwauth[]=FooBar param1="value1" param2="value2"
548 wwwauth[]=Bearer authorize_uri="id.example.com" p=1 q=0
549 wwwauth[]=Basic realm="example.com"
552 expect_credential_query store <<-EOF
553 capability[]=authtype
555 credential=YS1naXQtdG9rZW4=
561 test_expect_success
'access using bearer auth with invalid credentials' '
562 test_when_finished "per_test_cleanup" &&
564 set_credential_reply get <<-EOF &&
565 capability[]=authtype
567 credential=incorrect-token
570 # Basic base64(a-git-token)
571 cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
572 id=1 creds=Bearer YS1naXQtdG9rZW4=
575 CHALLENGE="$HTTPD_ROOT_PATH/custom-auth.challenge" &&
577 cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
579 id=default response=WWW-Authenticate: FooBar param1="value1" param2="value2"
580 id=default response=WWW-Authenticate: Bearer authorize_uri="id.example.com" p=1 q=0
581 id=default response=WWW-Authenticate: Basic realm="example.com"
584 test_config_global credential.helper test-helper &&
585 test_must_fail git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
587 expect_credential_query get <<-EOF &&
588 capability[]=authtype
592 wwwauth[]=FooBar param1="value1" param2="value2"
593 wwwauth[]=Bearer authorize_uri="id.example.com" p=1 q=0
594 wwwauth[]=Basic realm="example.com"
597 expect_credential_query erase <<-EOF
598 capability[]=authtype
600 credential=incorrect-token
603 wwwauth[]=FooBar param1="value1" param2="value2"
604 wwwauth[]=Bearer authorize_uri="id.example.com" p=1 q=0
605 wwwauth[]=Basic realm="example.com"
609 test_expect_success
'access using three-legged auth' '
610 test_when_finished "per_test_cleanup" &&
612 set_credential_reply get <<-EOF &&
613 capability[]=authtype
616 credential=YS1naXQtdG9rZW4=
617 state[]=helper:foobar
621 set_credential_reply get foobar <<-EOF &&
622 capability[]=authtype
625 credential=YW5vdGhlci10b2tlbg==
626 state[]=helper:bazquux
629 cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
630 id=1 creds=Multistage YS1naXQtdG9rZW4=
631 id=2 creds=Multistage YW5vdGhlci10b2tlbg==
634 CHALLENGE="$HTTPD_ROOT_PATH/custom-auth.challenge" &&
636 cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
637 id=1 status=401 response=WWW-Authenticate: Multistage challenge="456"
638 id=1 status=401 response=WWW-Authenticate: Bearer authorize_uri="id.example.com" p=1 q=0
640 id=default response=WWW-Authenticate: Multistage challenge="123"
641 id=default response=WWW-Authenticate: Bearer authorize_uri="id.example.com" p=1 q=0
644 test_config_global credential.helper test-helper &&
645 git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
647 expect_credential_query get <<-EOF &&
648 capability[]=authtype
652 wwwauth[]=Multistage challenge="123"
653 wwwauth[]=Bearer authorize_uri="id.example.com" p=1 q=0
656 expect_credential_query get foobar <<-EOF &&
657 capability[]=authtype
662 wwwauth[]=Multistage challenge="456"
663 wwwauth[]=Bearer authorize_uri="id.example.com" p=1 q=0
664 state[]=helper:foobar
667 expect_credential_query store bazquux <<-EOF
668 capability[]=authtype
671 credential=YW5vdGhlci10b2tlbg==
674 state[]=helper:bazquux