diff mbox series

[1/1] http: allow using netrc for WebDAV-based HTTP protocol

Message ID 20250223015331.588161-2-sandals@crustytoothpaste.net (mailing list archive)
State New
Headers show
Series Fix netrc usage with WebDAV-based HTTP protocol | expand

Commit Message

brian m. carlson Feb. 23, 2025, 1:53 a.m. UTC
For an extended period of time, we've enabled libcurl's netrc
functionality, which will read credentials from the netrc file if none
are provided.  Unfortunately, we have also not documented this fact or
written any tests for it, but people have come to rely on it.

In 610cbc1dfb ("http: allow authenticating proactively", 2024-07-10), we
accidentally broke the ability of users to use the netrc file for the
WebDAV-based HTTP protocol.  Notably, it works on the initial request
but does not work on subsequent requests, which causes failures because
that version of the protocol will necessarily make multiple requests.

This happens because curl_empty_auth_enabled never returns -1, only 0 or
1, and so if http.proactiveAuth is not enabled, the username and
password are always set to empty credentials, which prevents libcurl's
fallback to netrc from working.  However, in other cases, the server
continues to get a 401 response and the credential helper is invoked,
which is the normal behavior, so this was not noticed earlier.

To fix this, change the condition to check for enabling empty auth and
also not having proactive auth enabled, which should result in the
username and password not being set to a single colon in the typical
case, and thus the netrc file being used.

Reported-by: Peter Georg <peter.georg@physik.uni-regensburg.de>
Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 http.c                      |  3 +--
 t/t5540-http-push-webdav.sh | 10 ++++++++++
 2 files changed, 11 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/http.c b/http.c
index f4504133e8..0c9a872809 100644
--- a/http.c
+++ b/http.c
@@ -598,8 +598,7 @@  static void init_curl_http_auth(CURL *result)
 {
 	if ((!http_auth.username || !*http_auth.username) &&
 	    (!http_auth.credential || !*http_auth.credential)) {
-		int empty_auth = curl_empty_auth_enabled();
-		if ((empty_auth != -1 && !always_auth_proactively()) || empty_auth == 1) {
+		if (!always_auth_proactively() && curl_empty_auth_enabled()) {
 			curl_easy_setopt(result, CURLOPT_USERPWD, ":");
 			return;
 		} else if (!always_auth_proactively()) {
diff --git a/t/t5540-http-push-webdav.sh b/t/t5540-http-push-webdav.sh
index 37db3dec0c..3fa05ff185 100755
--- a/t/t5540-http-push-webdav.sh
+++ b/t/t5540-http-push-webdav.sh
@@ -201,4 +201,14 @@  test_expect_failure 'push to password-protected repository (no user in URL)' '
 	test_cmp expect actual
 '
 
+test_expect_success 'push to password-protected repository (netrc)' '
+	test_commit pw-netrc &&
+	echo "default login user@host password pass@host" >"$HOME/.netrc" &&
+	GIT_TRACE=1 GIT_CURL_VERBOSE=1 git push "$HTTPD_URL/auth/dumb/test_repo.git" HEAD &&
+	git rev-parse --verify HEAD >expect &&
+	git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/auth/dumb/test_repo.git" \
+		rev-parse --verify HEAD >actual &&
+	test_cmp expect actual
+'
+
 test_done