Git authentication over apache_mod_krb
I'm using git repo with git-http-backend. In apache2 I have location what needs authentication for clone and push actions. When I protected it location with AuthType Basic all works is fine, git passes authentication and can clone and push, but if I change type to KerberosV5 git can't access to repo with correctly credentials. If I'm using my browser I have access to location what to protect kerberos.
git clone http://user@mydomain.com/git/myapp.git
Initialized empty Git repository in /tmp/myapp/.git/
Password:
error: The requested URL returned error: 401 while accessing http://user@mydomain.com/git/myapp.git/info/refs
fatal: HTTP request failed
and in apache error logs
[Fri Aug 06 17:15:50 2010] [debug] src/mod_auth开发者_运维百科_kerb.c(1579): [client 192.168.12.153] kerb_authenticate_user entered with user (NULL) and auth_type KerberosV5
[Fri Aug 06 17:15:50 2010] [debug] src/mod_auth_kerb.c(1579): [client 192.168.12.153]kerb_authenticate_user entered with user (NULL) and auth_type KerberosV5
git-core 1:1.7.1-1~bpo50+1 apache2 2.2.9-10+lenny8 libapache2-mod-auth-kerb 5.3-5
Problem in curl, because git in debian was compiled with curl option
ANY_AUTH
, and when git client try connect to webserver and first ask it negotiate auth and it can't do it, git don't try basic auth.
That will be more robust, with Git 2.3.1 (Q1/Q2 2015): see commit 4dbe664 by brian m. carlson (bk2204
):
remote-curl
: fall back toBasic
auth ifNegotiate
fails
Apache servers using
mod_auth_kerb
can be configured to allow the user to authenticate either using Negotiate (using the Kerberos ticket) or Basic authentication (using the Kerberos password). Often, one will want to use Negotiate authentication if it is available, but fall back to Basic authentication if the ticket is missing or expired.
However,
libcurl
will try very hard to use something other thanBasic
auth, even over HTTPS.
IfBasic
and something else are offered,libcurl
will never attempt to useBasic
, even if the other option fails.
Teach the HTTP client code to stop trying authentication mechanisms that don't use a password (currentlyNegotiate
) after the first failure, since if they failed the first time, they will never succeed.
when git client try connect to webserver and first ask it negotiate auth and it can't do it, git don't try basic auth.
It will, with Git 2.32 (Q2 2021) (see second part below): before, when accessing a server with a URL like https://user:pass@site/
, Git did not to fall back to the basic authentication with the credential material embedded in the URL after the "Negotiate" authentication failed.
Now (Git 2.32), Git does (not yet, but soon).
See commit 1b0d954 (22 Mar 2021) by Christopher Schenk (chschenk
).
(Merged by Junio C Hamano -- gitster
-- in commit 5013802, 30 Mar 2021)
remote-curl
: fall back to basic auth if Negotiate failsSigned-off-by: Christopher Schenk
When the username and password are supplied in a url like this
https://myuser:secret@git.exampe/myrepo.git
and the server supports the negotiate authenticaten method, git does not fall back to basic auth andlibcurl
hardly tries to authenticate with the negotiate method.Stop using the Negotiate authentication method after the first failure because if it fails on the first try it will never succeed.
However, this is still in progress:
See commit ecf7b12, commit b694f1e (18 May 2021) by Jeff King (peff
).
(Merged by Junio C Hamano -- gitster
-- in commit c69f2f8, 21 May 2021)
Revert "remote-curl
: fall back to basic auth if Negotiate fails"Reported-by: Ben Humphreys
Signed-off-by: Jeff King
This reverts commit 1b0d954 (
remote-curl
: fall back to basic auth if Negotiate fails, 2021-03-22, Git v2.32.0-rc0 -- merge listed in batch #5).That commit does fix the situation it intended to (avoiding Negotiate even when the credentials were provided in the URL), but it creates a more serious regression: we now never hit the conditional for "we had a username and password, tried them, but the server still gave us a 401".
That has two bad effects:
- we never call
credential_reject()
, and thus a bogus credential stored by a helper will live on forever- we never return
HTTP_NOAUTH,
so the error message the user gets is "The requested URL returned error: 401
", instead of "Authentication failed
".Doing this correctly seems non-trivial, as we don't know whether the Negotiate auth was a problem.
Since this is a regression in the upcoming v2.23.0 release (for which we're in-rc0
), let's revert for now and work on a fix separately.(Note that this isn't a pure revert; the previous commit added a test showing the regression, so we can now flip it to
expect_success
).
Problem in curl, because git in debian was compiled with curl option ANY_AUTH, and when git client try connect to webserver and first ask it negotiate auth and it can't do it, git don't try basic auth, because basic is lower security than negotiate. When I try curl --anyauth I can' get data from webserver too, but if I change --basic all works fine, problem in that I can't tell git what auth should use.
It's something weird in libcurl, not a problem in Git. There is a workaround. Libcurl doesn't enable any authentication code if you don't pass username and password to the library. This happens if you use negotiate (kerberos) too which doesn't require username and password. The simple solution:
echo http://x:x@git.example.com > ~/.git-credentials
git config --global credential.helper store
x:x is the username and password. You can use any random string there. It's only needed to enable the code path to authentication in libcurl. Then kerberos will work (works for me :) ).
精彩评论