* Default authentication over https? @ 2016-04-11 16:04 Isaac Levy 2016-04-13 22:36 ` Jeff King 0 siblings, 1 reply; 7+ messages in thread From: Isaac Levy @ 2016-04-11 16:04 UTC (permalink / raw) To: git Hi all, I use a git server which requires authentication over https. Git seems determined to always try an unauthenticated request first, slowing down operations by a couple seconds. Is there a way to configure git to default to authenticated requests? Thanks! Regards, Isaac Levy ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Default authentication over https? 2016-04-11 16:04 Default authentication over https? Isaac Levy @ 2016-04-13 22:36 ` Jeff King 2016-04-14 9:46 ` Daniel Stenberg 0 siblings, 1 reply; 7+ messages in thread From: Jeff King @ 2016-04-13 22:36 UTC (permalink / raw) To: Isaac Levy; +Cc: git On Mon, Apr 11, 2016 at 12:04:02PM -0400, Isaac Levy wrote: > I use a git server which requires authentication over https. Git seems > determined to always try an unauthenticated request first, slowing > down operations by a couple seconds. > > Is there a way to configure git to default to authenticated requests? Thanks! No, there isn't. Very old versions of git would ask for the password if you provided a username, but since v1.7.8 we only do so in response to an HTTP 401. The code is still there to do the "proactive" asking, but it's not wired up to any particular config option. However, I don't think even that would give you what you want. Because I think that even if we provide a credential, curl will make an initial request (presumably to find out which auth type it should use, but that is just a guess). I don't know if there is a way to convince curl to stick the credential in the first request (if my guess is right, then perhaps by setting the auth type explicitly, or even by sticking in our own Authorization header). So I think the answer for now is "no", but it might be possible (and not even that hard) to do with a patch. -Peff ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Default authentication over https? 2016-04-13 22:36 ` Jeff King @ 2016-04-14 9:46 ` Daniel Stenberg 2016-04-14 21:32 ` Isaac Levy 0 siblings, 1 reply; 7+ messages in thread From: Daniel Stenberg @ 2016-04-14 9:46 UTC (permalink / raw) To: Jeff King; +Cc: Isaac Levy, git On Wed, 13 Apr 2016, Jeff King wrote: > However, I don't think even that would give you what you want. Because I > think that even if we provide a credential, curl will make an initial > request (presumably to find out which auth type it should use, but that > is just a guess). I don't know if there is a way to convince curl to > stick the credential in the first request curl supports this. but then you must do exactly that: tell libcurl to use that single auth method only. It will of course make it fail if you select the wrong method etc. The unauthenticated first request is both to probe for which methods the server wants, but also works for the case when users provide credentials without the server actually ending up asking for them... -- / daniel.haxx.se ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Default authentication over https? 2016-04-14 9:46 ` Daniel Stenberg @ 2016-04-14 21:32 ` Isaac Levy 2016-04-15 22:21 ` Jeff King 0 siblings, 1 reply; 7+ messages in thread From: Isaac Levy @ 2016-04-14 21:32 UTC (permalink / raw) To: Daniel Stenberg; +Cc: Jeff King, git After the authenticated request, curl says it's keeping the connection open, but the next fetch seems to do two handshakes again. The unauthenticated request closes the connection, so the 2nd handshake is forced, but I'm not sure why subsequent git fetches still do handshakes. I did a bit of sleuthing w/ source, GIT_CURL_VERBOSE and wireshark. We're using GitHub enterprise -- it'd just be nice if there was a better way to configure for super fast fetches. ssh with cached connections does avoid the SSL this overhead -- though as I recall git protocols over ssh are less performant. Finally I also checked out the persistent-https contrib section as a workaround but couldn't get it to work. Is that project dead? Thank you for your replies and support. Regards, Isaac On Thu, Apr 14, 2016 at 5:46 AM, Daniel Stenberg <daniel@haxx.se> wrote: > On Wed, 13 Apr 2016, Jeff King wrote: > >> However, I don't think even that would give you what you want. Because I >> think that even if we provide a credential, curl will make an initial >> request (presumably to find out which auth type it should use, but that >> is just a guess). I don't know if there is a way to convince curl to >> stick the credential in the first request > > > curl supports this. but then you must do exactly that: tell libcurl to use > that single auth method only. It will of course make it fail if you select > the wrong method etc. > > The unauthenticated first request is both to probe for which methods the > server wants, but also works for the case when users provide credentials > without the server actually ending up asking for them... > > -- > > / daniel.haxx.se ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Default authentication over https? 2016-04-14 21:32 ` Isaac Levy @ 2016-04-15 22:21 ` Jeff King 2016-04-15 22:43 ` Jeff King 0 siblings, 1 reply; 7+ messages in thread From: Jeff King @ 2016-04-15 22:21 UTC (permalink / raw) To: Isaac Levy; +Cc: Daniel Stenberg, git On Thu, Apr 14, 2016 at 05:32:16PM -0400, Isaac Levy wrote: > After the authenticated request, curl says it's keeping the connection > open, but the next fetch seems to do two handshakes again. The > unauthenticated request closes the connection, so the 2nd handshake is > forced, but I'm not sure why subsequent git fetches still do > handshakes. I did a bit of sleuthing w/ source, GIT_CURL_VERBOSE and > wireshark. > > We're using GitHub enterprise -- it'd just be nice if there was a > better way to configure for super fast fetches. ssh with cached > connections does avoid the SSL this overhead -- though as I recall git > protocols over ssh are less performant. It's the opposite; generally git is more efficient over ssh, because we have a true full-duplex connection, and we can do everything over a single session (though setup for the ssh session may or may not be faster than SSL). Here's what I observed just for the initial contact. If I instrument git like this: diff --git a/http.c b/http.c index 4304b80..9bedad7 100644 --- a/http.c +++ b/http.c @@ -1422,6 +1422,7 @@ static int http_request(const char *url, curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "gzip"); + warning("running one curl slot..."); ret = run_one_slot(slot, &results); if (options && options->content_type) { and run: GIT_CURL_VERBOSE=1 git ls-remote 2>&1 | egrep '< HTTP|> |^Auth|^warn' I get three requests: warning: running one curl slot... > GET /my/repo/info/refs?service=git-upload-pack HTTP/1.1 < HTTP/1.1 401 Authorization Required warning: running one curl slot... > GET /my/repo/info/refs?service=git-upload-pack HTTP/1.1 < HTTP/1.1 401 Authorization Required > GET /my/repo/info/refs?service=git-upload-pack HTTP/1.1 Authorization: Basic ... < HTTP/1.1 200 OK The first request is us (git) asking curl to hit the URL, and curl returns the 401 from the server to us. At that point we'll prompt the user (or the credential helper) for the password, and then we'll give that to curl and ask it to make the request again. Curl will do the probe with the 401, because we haven't set an auth type, and then follow up (without returning the 401 to git) with the right credentials. I think we can take that down to _two_ requests pretty easily. We know in the very first request that the server told us something like: < WWW-Authenticate: Basic realm="GitHub" but curl doesn't remember that. However, we should be able to pull it out of the old request and feed it into the new one. That would save the second request, which is just a probe. But ideally we'd have this down to one request. I think we could do something like this: diff --git a/http.c b/http.c index 9bedad7..7e5009d 100644 --- a/http.c +++ b/http.c @@ -870,6 +870,11 @@ struct active_request_slot *get_active_slot(void) #ifdef LIBCURL_CAN_HANDLE_AUTH_ANY curl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH, http_auth_methods); #endif + + /* XXX should be configurable via http.* or whatever */ + curl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); + credential_fill(&http_auth); + if (http_auth.password || curl_empty_auth) init_curl_http_auth(slot->curl); My request then looks like: warning: running one curl slot... > GET /my/repo/info/refs?service=git-upload-pack HTTP/1.1 Authorization: Basic ... < HTTP/1.1 200 OK with just a single round-trip. Obviously the hard-coding there is wrong, but the mental model here is that the user would do something like: git config http.https://github.com.auth basic to say "I know I want to do Basic auth for this host", and that would trigger git to tell that to curl, and to prompt for the password preemptively. The obvious downside is that it requires manual configuration, and some clue about "Basic" versus other auth types. I didn't trace the protocol further, but I suspect that curl ends up doing that probe for _each_ request, because each time we hand it only the credential without telling it that we know the server wants "Basic" auth. So that tries to keep the number of requests down in the first place. As far as reusing connections for the connections we _do_ make, I'm not sure. I do see curl claiming to leave the connection up: * Connection #0 to host github.com left intact but then we seem to make a separate one for the next request: * Hostname github.com was found in DNS cache * Trying 192.30.252.120... * Connected to github.com (192.30.252.120) port 443 (#1) I'm not sure why that is. We do get SSL reuse: * SSL re-using session ID * SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256 which is good. And then of the two requests curl makes later, the second one has: * Re-using existing connection! (#1) with host github.com which is good. So I'm not sure why we don't reuse connection #0 from the very first request. Perhaps it's something in the way we are setting up the curl handle. > Finally I also checked out the persistent-https contrib section as a > workaround but couldn't get it to work. Is that project dead? I don't know. It certainly hasn't seen a lot of activity lately, but Google folks might still be using it (I think the original impetus was for fetching of many repos from the same server for the Android project). I don't know that we've seen any mention of wide use on the list. -Peff ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: Default authentication over https? 2016-04-15 22:21 ` Jeff King @ 2016-04-15 22:43 ` Jeff King 2016-04-15 23:02 ` brian m. carlson 0 siblings, 1 reply; 7+ messages in thread From: Jeff King @ 2016-04-15 22:43 UTC (permalink / raw) To: Isaac Levy; +Cc: brian m. carlson, Daniel Stenberg, git On Fri, Apr 15, 2016 at 06:21:20PM -0400, Jeff King wrote: > I think we can take that down to _two_ requests pretty easily. We know > in the very first request that the server told us something like: > > < WWW-Authenticate: Basic realm="GitHub" > > but curl doesn't remember that. However, we should be able to pull it > out of the old request and feed it into the new one. That would save the > second request, which is just a probe. Hmm. Looks like we already pull this out of the curl result for other reasons, but we never feed it back in to the next request. So if I do this: diff --git a/http.c b/http.c index 9bedad7..add9bf2 100644 --- a/http.c +++ b/http.c @@ -1132,6 +1132,8 @@ static int handle_curl_result(struct slot_results *results) return HTTP_NOAUTH; } else { #ifdef LIBCURL_CAN_HANDLE_AUTH_ANY + if (results->auth_avail) + http_auth_methods = results->auth_avail; http_auth_methods &= ~CURLAUTH_GSSNEGOTIATE; #endif return HTTP_REAUTH; that drops my test case down to two requests: once to find out that we need auth via the 401, and then we feed curl sufficient information to do the followup in a single request (the GSSNEGOTIATE thing there is a hack from 4dbe664, which we can ignore for now). Interestingly, curl _does_ reuse the connection this time. I'm still not sure why it didn't in the original case. But this means the whole thing is happening over a single TCP session, which is good (and I didn't have to change my config at all). -Peff ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: Default authentication over https? 2016-04-15 22:43 ` Jeff King @ 2016-04-15 23:02 ` brian m. carlson 0 siblings, 0 replies; 7+ messages in thread From: brian m. carlson @ 2016-04-15 23:02 UTC (permalink / raw) To: Jeff King; +Cc: Isaac Levy, Daniel Stenberg, git [-- Attachment #1: Type: text/plain, Size: 1564 bytes --] On Fri, Apr 15, 2016 at 06:43:35PM -0400, Jeff King wrote: > Hmm. Looks like we already pull this out of the curl result for other > reasons, but we never feed it back in to the next request. So if I do > this: > > diff --git a/http.c b/http.c > index 9bedad7..add9bf2 100644 > --- a/http.c > +++ b/http.c > @@ -1132,6 +1132,8 @@ static int handle_curl_result(struct slot_results *results) > return HTTP_NOAUTH; > } else { > #ifdef LIBCURL_CAN_HANDLE_AUTH_ANY > + if (results->auth_avail) > + http_auth_methods = results->auth_avail; > http_auth_methods &= ~CURLAUTH_GSSNEGOTIATE; > #endif > return HTTP_REAUTH; > > that drops my test case down to two requests: once to find out that we > need auth via the 401, and then we feed curl sufficient information to > do the followup in a single request (the GSSNEGOTIATE thing there is a > hack from 4dbe664, which we can ignore for now). > > Interestingly, curl _does_ reuse the connection this time. I'm still not > sure why it didn't in the original case. But this means the whole thing > is happening over a single TCP session, which is good (and I didn't have > to change my config at all). This looks fine from my point of view. GSS-Negotiate and Digest are going to require at least one round-trip because they need the token or nonce to authenticate. Basic shouldn't, though. -- brian m. carlson / brian with sandals: Houston, Texas, US +1 832 623 2791 | https://www.crustytoothpaste.net/~bmc | My opinion only OpenPGP: https://keybase.io/bk2204 [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 836 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2016-04-18 2:20 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-04-11 16:04 Default authentication over https? Isaac Levy 2016-04-13 22:36 ` Jeff King 2016-04-14 9:46 ` Daniel Stenberg 2016-04-14 21:32 ` Isaac Levy 2016-04-15 22:21 ` Jeff King 2016-04-15 22:43 ` Jeff King 2016-04-15 23:02 ` brian m. carlson
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).