diff options
author | brian m. carlson <sandals@crustytoothpaste.net> | 2024-04-17 00:02:37 +0000 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2024-04-16 22:39:08 -0700 |
commit | ac4c7cbfaa1871e8865d5fa5b8142a70da37cce4 (patch) | |
tree | 8e5b267bc7d0199482a49a60dcf644dc804dea27 /t | |
parent | 37417b771707786756e94a589441e6510e9f57e4 (diff) | |
download | git-ac4c7cbfaa1871e8865d5fa5b8142a70da37cce4.tar.gz |
credential: add support for multistage credential rounds
Over HTTP, NTLM and Kerberos require two rounds of authentication on the
client side. It's possible that there are custom authentication schemes
that also implement this same approach. Since these are tricky schemes
to implement and the HTTP library in use may not always handle them
gracefully on all systems, it would be helpful to allow the credential
helper to implement them instead for increased portability and
robustness.
To allow this to happen, add a boolean flag, continue, that indicates
that instead of failing when we get a 401, we should retry another round
of authentication. However, this necessitates some changes in our
current credential code so that we can make this work.
Keep the state[] headers between iterations, but only use them to send
to the helper and only consider the new ones we read from the credential
helper to be valid on subsequent iterations. That avoids us passing
stale data when we finally approve or reject the credential. Similarly,
clear the multistage and wwwauth[] values appropriately so that we
don't pass stale data or think we're trying a multiround response when
we're not. Remove the credential values so that we can actually fill a
second time with new responses.
Limit the number of iterations of reauthentication we do to 3. This
means that if there's a problem, we'll terminate with an error message
instead of retrying indefinitely and not informing the user (and
possibly conducting a DoS on the server).
In our tests, handle creating multiple response output files from our
helper so we can verify that each of the messages sent is correct.
Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 't')
-rwxr-xr-x | t/t5563-simple-http-auth.sh | 89 |
1 files changed, 84 insertions, 5 deletions
diff --git a/t/t5563-simple-http-auth.sh b/t/t5563-simple-http-auth.sh index 515185ae00..5d5caa3f58 100755 --- a/t/t5563-simple-http-auth.sh +++ b/t/t5563-simple-http-auth.sh @@ -21,9 +21,17 @@ test_expect_success 'setup_credential_helper' ' CREDENTIAL_HELPER="$TRASH_DIRECTORY/bin/git-credential-test-helper" && write_script "$CREDENTIAL_HELPER" <<-\EOF cmd=$1 - teefile=$cmd-query.cred + teefile=$cmd-query-temp.cred catfile=$cmd-reply.cred sed -n -e "/^$/q" -e "p" >>$teefile + state=$(sed -ne "s/^state\[\]=helper://p" "$teefile") + if test -z "$state" + then + mv "$teefile" "$cmd-query.cred" + else + mv "$teefile" "$cmd-query-$state.cred" + catfile="$cmd-reply-$state.cred" + fi if test "$cmd" = "get" then cat $catfile @@ -32,13 +40,15 @@ test_expect_success 'setup_credential_helper' ' ' set_credential_reply () { - cat >"$TRASH_DIRECTORY/$1-reply.cred" + local suffix="$(test -n "$2" && echo "-$2")" + cat >"$TRASH_DIRECTORY/$1-reply$suffix.cred" } expect_credential_query () { - cat >"$TRASH_DIRECTORY/$1-expect.cred" && - test_cmp "$TRASH_DIRECTORY/$1-expect.cred" \ - "$TRASH_DIRECTORY/$1-query.cred" + local suffix="$(test -n "$2" && echo "-$2")" + cat >"$TRASH_DIRECTORY/$1-expect$suffix.cred" && + test_cmp "$TRASH_DIRECTORY/$1-expect$suffix.cred" \ + "$TRASH_DIRECTORY/$1-query$suffix.cred" } per_test_cleanup () { @@ -479,4 +489,73 @@ test_expect_success 'access using bearer auth with invalid credentials' ' EOF ' +test_expect_success 'access using three-legged auth' ' + test_when_finished "per_test_cleanup" && + + set_credential_reply get <<-EOF && + capability[]=authtype + capability[]=state + authtype=Multistage + credential=YS1naXQtdG9rZW4= + state[]=helper:foobar + continue=1 + EOF + + set_credential_reply get foobar <<-EOF && + capability[]=authtype + capability[]=state + authtype=Multistage + credential=YW5vdGhlci10b2tlbg== + state[]=helper:bazquux + EOF + + cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF && + id=1 creds=Multistage YS1naXQtdG9rZW4= + id=2 creds=Multistage YW5vdGhlci10b2tlbg== + EOF + + CHALLENGE="$HTTPD_ROOT_PATH/custom-auth.challenge" && + + cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF && + id=1 status=401 response=WWW-Authenticate: Multistage challenge="456" + id=1 status=401 response=WWW-Authenticate: Bearer authorize_uri="id.example.com" p=1 q=0 + id=2 status=200 + id=default response=WWW-Authenticate: Multistage challenge="123" + id=default response=WWW-Authenticate: Bearer authorize_uri="id.example.com" p=1 q=0 + EOF + + test_config_global credential.helper test-helper && + git ls-remote "$HTTPD_URL/custom_auth/repo.git" && + + expect_credential_query get <<-EOF && + capability[]=authtype + capability[]=state + protocol=http + host=$HTTPD_DEST + wwwauth[]=Multistage challenge="123" + wwwauth[]=Bearer authorize_uri="id.example.com" p=1 q=0 + EOF + + expect_credential_query get foobar <<-EOF && + capability[]=authtype + capability[]=state + authtype=Multistage + protocol=http + host=$HTTPD_DEST + wwwauth[]=Multistage challenge="456" + wwwauth[]=Bearer authorize_uri="id.example.com" p=1 q=0 + state[]=helper:foobar + EOF + + expect_credential_query store bazquux <<-EOF + capability[]=authtype + capability[]=state + authtype=Multistage + credential=YW5vdGhlci10b2tlbg== + protocol=http + host=$HTTPD_DEST + state[]=helper:bazquux + EOF +' + test_done |