On Thu, Jan 26, 2023 at 05:02:27AM -0500, Jeff King wrote: > I suspect this could all be done as a CGI wrapping git-http-backend. You > can influence the HTTP response code by sending: > > Status: 401 Authorization Required > WWW-Authenticate: whatever you want > > And likewise you can see what the client sends by putting something like > this in apache.conf: > > SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 > > and then reading $HTTP_AUTHORIZATION as you like. At that point, it > feels like a simple shell or perl script could then decide whether to > return a 401 or not (and if not, then just exec git-http-backend to do > the rest). And the scripts would be simple enough that you could have > individual scripts to implement various schemes, rather than > implementing this configuration scheme. You can control which script is > run based on the URL; see the way we match /broken_smart/, etc, in > t/lib-httpd/apache.conf. And here's a minimally worked-out example of that approach. It's on top of your patches so I could use your credential-helper infrastructure in the test, but the intent is that it would replace all of the test-tool server patches and be rolled into t5556 as appropriate. --- t/lib-httpd.sh | 1 + t/lib-httpd/apache.conf | 6 ++++++ t/lib-httpd/custom-auth.sh | 18 ++++++++++++++++ t/t5563-simple-http-auth.sh | 42 +++++++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+) create mode 100644 t/lib-httpd/custom-auth.sh create mode 100755 t/t5563-simple-http-auth.sh diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh index 608949ea80..ab255bdbc5 100644 --- a/t/lib-httpd.sh +++ b/t/lib-httpd.sh @@ -137,6 +137,7 @@ prepare_httpd() { install_script error-smart-http.sh install_script error.sh install_script apply-one-time-perl.sh + install_script custom-auth.sh ln -s "$LIB_HTTPD_MODULE_PATH" "$HTTPD_ROOT_PATH/modules" diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf index 0294739a77..4b2256363f 100644 --- a/t/lib-httpd/apache.conf +++ b/t/lib-httpd/apache.conf @@ -135,6 +135,11 @@ Alias /auth/dumb/ www/auth/dumb/ SetEnv GIT_HTTP_EXPORT_ALL SetEnv GIT_PROTOCOL </LocationMatch> +<LocationMatch /custom_auth/> + SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH} + SetEnv GIT_HTTP_EXPORT_ALL + CGIPassAuth on +</LocationMatch> ScriptAlias /smart/incomplete_length/git-upload-pack incomplete-length-upload-pack-v2-http.sh/ ScriptAlias /smart/incomplete_body/git-upload-pack incomplete-body-upload-pack-v2-http.sh/ ScriptAlias /smart/no_report/git-receive-pack error-no-report.sh/ @@ -144,6 +149,7 @@ ScriptAlias /broken_smart/ broken-smart-http.sh/ ScriptAlias /error_smart/ error-smart-http.sh/ ScriptAlias /error/ error.sh/ ScriptAliasMatch /one_time_perl/(.*) apply-one-time-perl.sh/$1 +ScriptAliasMatch /custom_auth/(.*) custom-auth.sh/$1 <Directory ${GIT_EXEC_PATH}> Options FollowSymlinks </Directory> diff --git a/t/lib-httpd/custom-auth.sh b/t/lib-httpd/custom-auth.sh new file mode 100644 index 0000000000..686895ee8c --- /dev/null +++ b/t/lib-httpd/custom-auth.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +# Our acceptable auth here is hard-coded, but we could +# read it from a file provided by individual tests, etc. +# +# base64("alice:secret-passwd") +USERPASS64=YWxpY2U6c2VjcmV0LXBhc3N3ZA== + +case "$HTTP_AUTHORIZATION" in +"Basic $USERPASS64") + exec "$GIT_EXEC_PATH"/git-http-backend + ;; +*) + echo 'Status: 401 Auth Required' + echo 'WWW-Authenticate: Basic realm="whatever"' + echo + ;; +esac diff --git a/t/t5563-simple-http-auth.sh b/t/t5563-simple-http-auth.sh new file mode 100755 index 0000000000..314f9217e6 --- /dev/null +++ b/t/t5563-simple-http-auth.sh @@ -0,0 +1,42 @@ +#!/bin/sh + +test_description='test http auth header and credential helper interop' + +. ./test-lib.sh +. "$TEST_DIRECTORY"/lib-httpd.sh +. "$TEST_DIRECTORY"/lib-credential-helper.sh + +start_httpd + +setup_credential_helper + +test_expect_success 'setup repository' ' + test_commit foo && + git init --bare "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && + git push --mirror "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" +' + +test_expect_success 'access using custom auth' ' + set_credential_reply get <<-EOF && + username=alice + password=secret-passwd + EOF + + git -c "credential.helper=!\"$CREDENTIAL_HELPER\"" ls-remote \ + "$HTTPD_URL/custom_auth/repo.git" && + + expect_credential_query get <<-EOF && + protocol=http + host=$HTTPD_DEST + wwwauth[]=Basic realm="whatever" + EOF + + expect_credential_query store <<-EOF + protocol=http + host=$HTTPD_DEST + username=alice + password=secret-passwd + EOF +' + +test_done -- 2.39.1.738.g5e5f8a2714