From: Jeff King <peff@peff.net>
To: Clemens Buchacher <drizzd@aon.at>
Cc: git@vger.kernel.org, Junio C Hamano <gitster@pobox.com>
Subject: Re: [PATCH 2/2] fix http auth with multiple curl handles
Date: Thu, 12 Apr 2012 03:09:10 -0400 [thread overview]
Message-ID: <20120412070910.GA31122@sigill.intra.peff.net> (raw)
In-Reply-To: <1334051620-18044-3-git-send-email-drizzd@aon.at>
On Tue, Apr 10, 2012 at 11:53:40AM +0200, Clemens Buchacher wrote:
> HTTP authentication is currently handled by get_refs and fetch_ref, but
> not by fetch_object, fetch_pack or fetch_alternates. In the
> single-threaded case, this is not an issue, since get_refs is always
> called first. It recognigzes the 401 and prompts the user for
> credentials, which will then be used subsequently.
>
> If the curl multi interface is used, however, only the multi handle used
> by get_refs will have credentials configured. Requests made by other
> handles fail with an authentication error.
>
> Fix this by setting CURLOPT_USERPWD whenever a slot is requested.
The reason I didn't like my initial patch was that by calling
curl_easy_setopt() for every request, we end up leaking the password
buffer once per request.
Unfortunately, I don't think there's a way to ask curl whether it has
anything in CURLOPT_USERPWD. So we have to overwrite. Recent versions of
curl will actually copy the string we give it anyway, so the existing
code is already leaking a little bit (but once per process, not once per
request). I wish we could get away with just handing curl the data and
assuming it would copy, but that code came about in curl 7.17.0, in
2007. According to our #if statements, we handle much older versions of
curl, so that is a non-option.
I think the best we can do is to put the auth data in a static buffer
and feed that to curl. We end up rewriting the auth data into our buffer
over and over, but at least we don't re-malloc it. Like this:
diff --git a/http.c b/http.c
index f3f83d7..374c3bb 100644
--- a/http.c
+++ b/http.c
@@ -211,12 +211,12 @@ static int http_options(const char *var, const char *value, void *cb)
static void init_curl_http_auth(CURL *result)
{
if (http_auth.username) {
- struct strbuf up = STRBUF_INIT;
+ static struct strbuf up = STRBUF_INIT;
credential_fill(&http_auth);
+ strbuf_reset(&up);
strbuf_addf(&up, "%s:%s",
http_auth.username, http_auth.password);
- curl_easy_setopt(result, CURLOPT_USERPWD,
- strbuf_detach(&up, NULL));
+ curl_easy_setopt(result, CURLOPT_USERPWD, up.buf);
}
}
By the way, this touches on an area that I noticed while refactoring the
http auth code a while ago, but decided not to tackle at the time. We
fill in the auth information early, and then never bother to revisit it
as URLs change. So for example, if I got a redirect from host A to host
B, we would continue to use the credential for host A and host B. Which
is maybe convenient, and maybe a security issue.
It has been that way since the beginning of git, and nobody has seemed
to care. So maybe it is not worth dealing with. But if we did want to,
the right way would be to keep several credentials on hand, and match
each URL to them as we were about to request it. That would also provide
a fix to the problem we are fixing here. I don't know if it is worth
doing or not.
-Peff
next prev parent reply other threads:[~2012-04-12 7:09 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-04-01 18:48 Cannot clone the git repository shared over http with authorization Artur R. Czechowski
2012-04-01 19:45 ` Clemens Buchacher
2012-04-01 20:53 ` Clemens Buchacher
2012-04-02 8:31 ` Jeff King
2012-04-10 9:53 ` Clemens Buchacher
2012-04-10 9:53 ` [PATCH 1/2] http auth fails with multiple curl handles Clemens Buchacher
2012-04-10 9:53 ` [PATCH 2/2] fix http auth " Clemens Buchacher
2012-04-12 7:09 ` Jeff King [this message]
2012-04-12 22:50 ` Junio C Hamano
2012-04-13 6:16 ` Jeff King
2012-04-13 6:18 ` [PATCH 1/2] http: clean up leak in init_curl_http_auth Jeff King
2012-04-13 6:19 ` [PATCH 2/2] http: use newer curl options for setting credentials Jeff King
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120412070910.GA31122@sigill.intra.peff.net \
--to=peff@peff.net \
--cc=drizzd@aon.at \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).