t5563: add tests for http.emptyAuth with Negotiate
Add tests exercising the interaction between http.emptyAuth and servers that advertise Negotiate (SPNEGO) authentication. Verify that auto mode gives Negotiate a chance via empty auth (resulting in two 401 responses before falling through to credential_fill with Basic credentials), and that false mode strips Negotiate immediately (only one 401 response). Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Matthew John Cheetham committed
Apr 16, 2026 at 09:20 UTC
9b1630b97273beceb64ea8f740c5820317aaa8b3
1 file changed
+74
t/t5563-simple-http-auth.sh
+74
@@ -719,4 +719,78 @@ test_expect_success 'access using three-legged auth' '
719
EOF
720
'
721
722
+test_lazy_prereq SPNEGO 'curl --version | grep -qi "SPNEGO\|GSS-API\|Kerberos\|negotiate"'
723
+
724
+test_expect_success SPNEGO 'http.emptyAuth=auto attempts Negotiate before credential_fill' '
725
+ test_when_finished "per_test_cleanup" &&
726
+
727
+ set_credential_reply get <<-EOF &&
728
+ username=alice
729
+ password=secret-passwd
730
+ EOF
731
+
732
+ # Basic base64(alice:secret-passwd)
733
+ cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
734
+ id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
735
+ EOF
736
+
737
+ cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
738
+ id=1 status=200
739
+ id=default response=WWW-Authenticate: Negotiate
740
+ id=default response=WWW-Authenticate: Basic realm="example.com"
741
+ EOF
742
+
743
+ test_config_global credential.helper test-helper &&
744
+ GIT_TRACE_CURL="$TRASH_DIRECTORY/trace-auto" \
745
+ git -c http.emptyAuth=auto \
746
+ ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
747
+
748
+ # In auto mode with a Negotiate+Basic server, there should be
749
+ # three 401 responses: (1) initial no-auth request, (2) empty-auth
750
+ # retry where Negotiate fails (no Kerberos ticket), (3) libcurl
751
+ # internal Negotiate retry. The fourth attempt uses Basic
752
+ # credentials from credential_fill and succeeds.
753
+ grep "HTTP/[0-9.]* 401" "$TRASH_DIRECTORY/trace-auto" >actual_401s &&
754
+ test_line_count = 3 actual_401s &&
755
+
756
+ expect_credential_query get <<-EOF
757
+ capability[]=authtype
758
+ capability[]=state
759
+ protocol=http
760
+ host=$HTTPD_DEST
761
+ wwwauth[]=Negotiate
762
+ wwwauth[]=Basic realm="example.com"
763
+ EOF
764
+'
765
+
766
+test_expect_success SPNEGO 'http.emptyAuth=false skips Negotiate' '
767
+ test_when_finished "per_test_cleanup" &&
768
+
769
+ set_credential_reply get <<-EOF &&
770
+ username=alice
771
+ password=secret-passwd
772
+ EOF
773
+
774
+ # Basic base64(alice:secret-passwd)
775
+ cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
776
+ id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
777
+ EOF
778
+
779
+ cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
780
+ id=1 status=200
781
+ id=default response=WWW-Authenticate: Negotiate
782
+ id=default response=WWW-Authenticate: Basic realm="example.com"
783
+ EOF
784
+
785
+ test_config_global credential.helper test-helper &&
786
+ GIT_TRACE_CURL="$TRASH_DIRECTORY/trace-false" \
787
+ git -c http.emptyAuth=false \
788
+ ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
789
+
790
+ # With emptyAuth=false, Negotiate is stripped immediately and
791
+ # credential_fill is called right away. Only one 401 response.
792
+ grep "HTTP/[0-9.]* 401" "$TRASH_DIRECTORY/trace-false" >actual_401s &&
793
+ test_line_count = 1 actual_401s
794
+'
795
+
796
test_done