Files
git/http.c
Johannes Schindelin 613b3cac30 http: fix emptyAuth=auto for Negotiate/SPNEGO (#6170)
When a server advertises Negotiate (SPNEGO) authentication alongside
Basic, the "auto" mode of http.emptyAuth should allow libcurl to
attempt Kerberos authentication using the system ticket cache before
falling back to credential_fill(). Currently this never happens due
to an interaction between two older features.

The Negotiate-stripping logic from 4dbe66464b (remote-curl: fall back
to Basic auth if Negotiate fails, 2015-01-08) removes
CURLAUTH_GSSNEGOTIATE on the first 401, before the auto-detection
from 40a18fc77c (http: add an "auto" mode for http.emptyauth,
2017-02-25) gets a chance to see it as an "exotic" method. The result
is that auto mode silently degrades to the same behavior as
emptyAuth=false for any server whose only non-Basic/Digest method is
Negotiate, forcing Kerberos users to manually set http.emptyAuth=true
to get seamless ticket-based authentication.

This series fixes the interaction by delaying the Negotiate stripping
in auto mode by one round-trip, giving empty auth a chance to use the
system Kerberos ticket. If there is no valid ticket, Negotiate is
stripped on the second 401 and we fall through to credential_fill()
as before. The true and false modes are unchanged.

  Patch 1: Extract a http_reauth_prepare() helper from the three
           retry paths that call credential_fill() on HTTP_REAUTH.
           Pure refactor, no behavior change.

  Patch 2: Delay the GSSNEGOTIATE stripping in auto mode and teach
           http_reauth_prepare() to skip credential_fill() when
           empty auth should be attempted first.

  Patch 3: Add tests verifying that auto mode produces an extra
           round-trip (empty auth attempt) compared to false mode,
           using the existing nph-custom-auth.sh CGI infrastructure.

There is a trade-off in auto mode: when a server advertises Negotiate
but the client has no valid Kerberos ticket, there is one extra
round-trip compared to the current behavior. This matches the
trade-off already documented in 40a18fc77c. Users who want to avoid
it can set http.emptyAuth=false.
2026-04-16 08:24:00 +00:00

79 KiB