Git fork
at reftables-rust 685 lines 15 kB view raw
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 "--". 7check() { 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 26read_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. 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 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 https victim.example.com user 54 reject $1 http path.tld user 55 reject $1 https timeout.tld user 56 reject $1 https sso.tld 57} 58 59reject() { 60 ( 61 echo protocol=$2 62 echo host=$3 63 echo username=$4 64 ) | git -c credential.helper=$1 credential reject 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 -- 75 protocol=https 76 host=example.com 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 -- 99 protocol=https 100 host=example.com 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 -- 112 protocol=http 113 host=example.com 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 -- 127 protocol=https 128 host=other.tld 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 -- 143 protocol=https 144 host=example.com 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 -- 166 protocol=http 167 host=path.tld 168 path=bar.git 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 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 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 -- 229 protocol=https 230 host=example.com 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 -- 257 protocol=https 258 host=example.com 259 username=user1 260 password=pass1 261 EOF 262 check fill $HELPER <<-\EOF 263 protocol=https 264 host=example.com 265 username=user2 266 -- 267 protocol=https 268 host=example.com 269 username=user2 270 password=pass2 271 EOF 272 ' 273 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 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 -- 310 protocol=https 311 host=example.com 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 -- 325 protocol=https 326 host=example.com 327 username=user2 328 password=pass2 329 EOF 330 ' 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 ' 349 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 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 ' 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 -- 426 protocol=https 427 host=timeout.tld 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} 436 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 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 541helper_test_authtype() { 542 HELPER=$1 543 544 test_expect_success "helper ($HELPER) stores authtype and credential" ' 545 check approve $HELPER <<-\EOF 546 capability[]=authtype 547 authtype=Bearer 548 credential=random-token 549 protocol=https 550 host=git.example.com 551 EOF 552 ' 553 554 test_expect_success "helper ($HELPER) gets authtype and credential" ' 555 check fill $HELPER <<-\EOF 556 capability[]=authtype 557 protocol=https 558 host=git.example.com 559 -- 560 capability[]=authtype 561 authtype=Bearer 562 credential=random-token 563 protocol=https 564 host=git.example.com 565 -- 566 EOF 567 ' 568 569 test_expect_success "helper ($HELPER) gets authtype and credential only if request has authtype capability" ' 570 check fill $HELPER <<-\EOF 571 protocol=https 572 host=git.example.com 573 -- 574 protocol=https 575 host=git.example.com 576 username=askpass-username 577 password=askpass-password 578 -- 579 askpass: Username for '\''https://git.example.com'\'': 580 askpass: Password for '\''https://askpass-username@git.example.com'\'': 581 EOF 582 ' 583 584 test_expect_success "helper ($HELPER) stores authtype and credential with username" ' 585 check approve $HELPER <<-\EOF 586 capability[]=authtype 587 authtype=Bearer 588 credential=other-token 589 protocol=https 590 host=git.example.com 591 username=foobar 592 EOF 593 ' 594 595 test_expect_success "helper ($HELPER) gets authtype and credential with username" ' 596 check fill $HELPER <<-\EOF 597 capability[]=authtype 598 protocol=https 599 host=git.example.com 600 username=foobar 601 -- 602 capability[]=authtype 603 authtype=Bearer 604 credential=other-token 605 protocol=https 606 host=git.example.com 607 username=foobar 608 -- 609 EOF 610 ' 611 612 test_expect_success "helper ($HELPER) does not get authtype and credential with different username" ' 613 check fill $HELPER <<-\EOF 614 capability[]=authtype 615 protocol=https 616 host=git.example.com 617 username=barbaz 618 -- 619 protocol=https 620 host=git.example.com 621 username=barbaz 622 password=askpass-password 623 -- 624 askpass: Password for '\''https://barbaz@git.example.com'\'': 625 EOF 626 ' 627 628 test_expect_success "helper ($HELPER) does not store ephemeral authtype and credential" ' 629 check approve $HELPER <<-\EOF && 630 capability[]=authtype 631 authtype=Bearer 632 credential=git2-token 633 protocol=https 634 host=git2.example.com 635 ephemeral=1 636 EOF 637 638 check fill $HELPER <<-\EOF 639 capability[]=authtype 640 protocol=https 641 host=git2.example.com 642 -- 643 protocol=https 644 host=git2.example.com 645 username=askpass-username 646 password=askpass-password 647 -- 648 askpass: Username for '\''https://git2.example.com'\'': 649 askpass: Password for '\''https://askpass-username@git2.example.com'\'': 650 EOF 651 ' 652 653 test_expect_success "helper ($HELPER) does not store ephemeral username and password" ' 654 check approve $HELPER <<-\EOF && 655 capability[]=authtype 656 protocol=https 657 host=git2.example.com 658 user=barbaz 659 password=secret 660 ephemeral=1 661 EOF 662 663 check fill $HELPER <<-\EOF 664 capability[]=authtype 665 protocol=https 666 host=git2.example.com 667 -- 668 protocol=https 669 host=git2.example.com 670 username=askpass-username 671 password=askpass-password 672 -- 673 askpass: Username for '\''https://git2.example.com'\'': 674 askpass: Password for '\''https://askpass-username@git2.example.com'\'': 675 EOF 676 ' 677} 678 679write_script askpass <<\EOF 680echo >&2 askpass: $* 681what=$(echo $1 | cut -d" " -f1 | tr A-Z a-z | tr -cd a-z) 682echo "askpass-$what" 683EOF 684GIT_ASKPASS="$PWD/askpass" 685export GIT_ASKPASS