* [PATCH v5 2/5] http: handle proxy proactive authentication
@ 2012-03-13 14:03 Nelson Benitez Leon
2012-04-09 21:39 ` Junio C Hamano
2012-04-13 20:56 ` Jeff King
0 siblings, 2 replies; 13+ messages in thread
From: Nelson Benitez Leon @ 2012-03-13 14:03 UTC (permalink / raw)
To: git; +Cc: peff, sam
If http_proactive_auth flag is set and there is a username
but no password in the proxy url, then interactively ask for
the password.
This makes possible to not have the password written down in
http_proxy env var or in http.proxy config option.
Also take care that CURLOPT_PROXY don't include username or
password, as we now set them in the new set_proxy_auth() function
where we use their specific cURL options.
Signed-off-by: Nelson Benitez Leon <nbenitezl@gmail.com>
---
http.c | 27 ++++++++++++++++++++++++++-
1 files changed, 26 insertions(+), 1 deletions(-)
diff --git a/http.c b/http.c
index be88acb..e7410f8 100644
--- a/http.c
+++ b/http.c
@@ -44,6 +44,7 @@ static const char *curl_http_proxy;
static const char *curl_cookie_file;
static struct credential cre_url = CREDENTIAL_INIT;
static struct credential http_auth = CREDENTIAL_INIT;
+static struct credential proxy_auth = CREDENTIAL_INIT;
static int http_proactive_auth;
static const char *user_agent;
@@ -233,6 +234,20 @@ static int has_cert_password(void)
return 1;
}
+static void set_proxy_auth(CURL *result)
+{
+ if (proxy_auth.username && proxy_auth.password) {
+#if LIBCURL_VERSION_NUM >= 0x071901
+ curl_easy_setopt(result, CURLOPT_PROXYUSERNAME, proxy_auth.username);
+ curl_easy_setopt(result, CURLOPT_PROXYPASSWORD, proxy_auth.password);
+#else
+ struct strbuf userpwd = STRBUF_INIT;
+ strbuf_addf(&userpwd, "%s:%s", proxy_auth.username, proxy_auth.password);
+ curl_easy_setopt(result, CURLOPT_PROXYUSERPWD, strbuf_detach(&userpwd, NULL));
+#endif
+ }
+}
+
static CURL *get_curl_handle(const char *url)
{
CURL *result = curl_easy_init();
@@ -317,8 +332,18 @@ static CURL *get_curl_handle(const char *url)
free(env_proxy_var);
}
if (curl_http_proxy) {
- curl_easy_setopt(result, CURLOPT_PROXY, curl_http_proxy);
+ if (!proxy_auth.host) /* check to parse only once */
+ credential_from_url(&proxy_auth, curl_http_proxy);
+
+ if (http_proactive_auth && proxy_auth.username && !proxy_auth.password)
+ /* proxy string has username but no password, ask for password */
+ credential_fill(&proxy_auth);
+
+ struct strbuf proxyhost = STRBUF_INIT;
+ strbuf_addf(&proxyhost, "%s://%s", proxy_auth.protocol, proxy_auth.host);
+ curl_easy_setopt(result, CURLOPT_PROXY, strbuf_detach(&proxyhost, NULL));
curl_easy_setopt(result, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
+ set_proxy_auth(result);
}
return result;
--
1.7.7.6
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v5 2/5] http: handle proxy proactive authentication
2012-03-13 14:03 [PATCH v5 2/5] http: handle proxy proactive authentication Nelson Benitez Leon
@ 2012-04-09 21:39 ` Junio C Hamano
2012-04-10 0:59 ` Junio C Hamano
2012-04-13 20:56 ` Jeff King
1 sibling, 1 reply; 13+ messages in thread
From: Junio C Hamano @ 2012-04-09 21:39 UTC (permalink / raw)
To: Nelson Benitez Leon; +Cc: git, peff, sam, spearce
Nelson Benitez Leon <nelsonjesus.benitez@seap.minhap.es> writes:
> if (curl_http_proxy) {
> - curl_easy_setopt(result, CURLOPT_PROXY, curl_http_proxy);
> + if (!proxy_auth.host) /* check to parse only once */
> + credential_from_url(&proxy_auth, curl_http_proxy);
> +
> + if (http_proactive_auth && proxy_auth.username && !proxy_auth.password)
> + /* proxy string has username but no password, ask for password */
> + credential_fill(&proxy_auth);
> +
> + struct strbuf proxyhost = STRBUF_INIT;
> + strbuf_addf(&proxyhost, "%s://%s", proxy_auth.protocol, proxy_auth.host);
> + curl_easy_setopt(result, CURLOPT_PROXY, strbuf_detach(&proxyhost, NULL));
How well has this code been tested? The documentation for CURLOPT_PROXY
says this:
CURLOPT_PROXY
Set HTTP proxy to use. The parameter should be a char * to a zero
terminated string holding the host name or dotted IP address. To
specify port number in this string, append :[port] to the end of the
host name. The proxy string may be prefixed with [protocol]:// since
any such prefix will be ignored. The proxy's port number may optionally
be specified with the separate option. If not specified, libcurl will
default to using port 1080 for proxies. CURLOPT_PROXYPORT.
If the user has been happily using "127.0.0.1:4321" in curl_http_proxy
(i.e. without the meaningless <proto>:// part), the original code would
have called curl_easy_setopt with that string, and that would have been
how everything used to work.
If you haven't figured out proxy_auth.host at this point in the codepath,
you call credential_from_url() but the function only knows how to parse
the value for
"<proto>://[<user>[:<pass>]@]<host>[:<port>]/..."
Specifically, it will punt with anything without "://" in it.
And then you use proxy_auth.protocol and proxy_auth.host to build
proxyhost.buf that presumably mimick the original curl_http_proxy (but
without the credential part).
I haven't formed an opinion on what the proper solution should be, but
either the credential_from_url() function needs to be updated to accept
the scp style [user@]<host>:<port> argument, or this specific caller
should take the responsibility to do special case the syntax.
> curl_easy_setopt(result, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
> + set_proxy_auth(result);
> }
>
> return result;
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 2/5] http: handle proxy proactive authentication
2012-04-09 21:39 ` Junio C Hamano
@ 2012-04-10 0:59 ` Junio C Hamano
2012-04-12 15:54 ` Junio C Hamano
0 siblings, 1 reply; 13+ messages in thread
From: Junio C Hamano @ 2012-04-10 0:59 UTC (permalink / raw)
To: Nelson Benitez Leon; +Cc: git, peff, sam, spearce
Junio C Hamano <gitster@pobox.com> writes:
> I haven't formed an opinion on what the proper solution should be, but
> either the credential_from_url() function needs to be updated to accept
> the scp style [user@]<host>:<port> argument, or this specific caller
> should take the responsibility to do special case the syntax.
Well, calling the above "scp" style is a mistake (it is not scp style at
all), but the patch to teach the credentail_from_url() to handle the proxy
specification may look like this:
credential.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/credential.c b/credential.c
index 62d1c56..482ae88 100644
--- a/credential.c
+++ b/credential.c
@@ -324,11 +324,13 @@ void credential_from_url(struct credential *c, const char *url)
* (1) proto://<host>/...
* (2) proto://<user>@<host>/...
* (3) proto://<user>:<pass>@<host>/...
+ * or "proto://"-less variants of the above for *_proxy variables.
*/
proto_end = strstr(url, "://");
- if (!proto_end)
- return;
- cp = proto_end + 3;
+ if (proto_end)
+ cp = proto_end + 3;
+ else
+ cp = url;
at = strchr(cp, '@');
colon = strchr(cp, ':');
slash = strchrnul(cp, '/');
@@ -348,7 +350,7 @@ void credential_from_url(struct credential *c, const char *url)
host = at + 1;
}
- if (proto_end - url > 0)
+ if (proto_end && proto_end != url)
c->protocol = xmemdupz(url, proto_end - url);
if (slash - host > 0)
c->host = url_decode_mem(host, slash - host);
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v5 2/5] http: handle proxy proactive authentication
2012-04-10 0:59 ` Junio C Hamano
@ 2012-04-12 15:54 ` Junio C Hamano
2012-04-12 20:58 ` Jeff King
0 siblings, 1 reply; 13+ messages in thread
From: Junio C Hamano @ 2012-04-12 15:54 UTC (permalink / raw)
To: Jeff King; +Cc: Nelson Benitez Leon, git, sam, spearce
Junio C Hamano <gitster@pobox.com> writes:
> Junio C Hamano <gitster@pobox.com> writes:
>
>> I haven't formed an opinion on what the proper solution should be, but
>> either the credential_from_url() function needs to be updated to accept
>> the scp style [user@]<host>:<port> argument, or this specific caller
>> should take the responsibility to do special case the syntax.
>
> Well, calling the above "scp" style is a mistake (it is not scp style at
> all), but the patch to teach the credentail_from_url() to handle the proxy
> specification may look like this:
Jeff, do you have an opinion on this? I briefly wondered if we also want
to teach the traditional [user@]host:/path/to/repo to this function (it is
not a URL in RFC1738 sense, but it is in the remote.$name.url sense), but
because SSH does its own thing interacting with agents, perhaps it may not
help to teach our credential layer to store and supply cached passphrases
(or passwords, if the authentication is done by merely sending password
over the encrypted channel).
A safer approach might be to keep externally visible API to this function
as before, but add another function only for the use of http_proxy and
friends (whose kosher format is "host:address" without the "<scheme>://"
part), and call it from the codepath broken by the patch.
> credential.c | 10 ++++++----
> 1 file changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/credential.c b/credential.c
> index 62d1c56..482ae88 100644
> --- a/credential.c
> +++ b/credential.c
> @@ -324,11 +324,13 @@ void credential_from_url(struct credential *c, const char *url)
> * (1) proto://<host>/...
> * (2) proto://<user>@<host>/...
> * (3) proto://<user>:<pass>@<host>/...
> + * or "proto://"-less variants of the above for *_proxy variables.
> */
> proto_end = strstr(url, "://");
> - if (!proto_end)
> - return;
> - cp = proto_end + 3;
> + if (proto_end)
> + cp = proto_end + 3;
> + else
> + cp = url;
> at = strchr(cp, '@');
> colon = strchr(cp, ':');
> slash = strchrnul(cp, '/');
> @@ -348,7 +350,7 @@ void credential_from_url(struct credential *c, const char *url)
> host = at + 1;
> }
>
> - if (proto_end - url > 0)
> + if (proto_end && proto_end != url)
> c->protocol = xmemdupz(url, proto_end - url);
> if (slash - host > 0)
> c->host = url_decode_mem(host, slash - host);
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 2/5] http: handle proxy proactive authentication
2012-04-12 15:54 ` Junio C Hamano
@ 2012-04-12 20:58 ` Jeff King
2012-04-12 21:25 ` Junio C Hamano
0 siblings, 1 reply; 13+ messages in thread
From: Jeff King @ 2012-04-12 20:58 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Nelson Benitez Leon, git, sam, spearce
On Thu, Apr 12, 2012 at 08:54:22AM -0700, Junio C Hamano wrote:
> >> I haven't formed an opinion on what the proper solution should be, but
> >> either the credential_from_url() function needs to be updated to accept
> >> the scp style [user@]<host>:<port> argument, or this specific caller
> >> should take the responsibility to do special case the syntax.
> >
> > Well, calling the above "scp" style is a mistake (it is not scp style at
> > all), but the patch to teach the credentail_from_url() to handle the proxy
> > specification may look like this:
>
> Jeff, do you have an opinion on this? I briefly wondered if we also want
> to teach the traditional [user@]host:/path/to/repo to this function (it is
> not a URL in RFC1738 sense, but it is in the remote.$name.url sense), but
> because SSH does its own thing interacting with agents, perhaps it may not
> help to teach our credential layer to store and supply cached passphrases
> (or passwords, if the authentication is done by merely sending password
> over the encrypted channel).
My first instinct was "that is not a URL, and should be handled outside
this function". In particular, it has no protocol field, and that is an
important part of the credential-matching process. It would be up to the
caller to supply something sane in the protocol portion. In this case,
it would probably be "http" (unless we want to distinguish http proxies
from http end-points in the credential store, but I doubt that is
useful). But for an ssh-style URL, it would be "ssh". So already the
abstraction is a little bit leaky.
As far as parsing ssh goes, I'm not sure that is unambiguous with the
proxy syntax. If you see "127.0.0.1:1234", is that short for
"http://127.0.0.1:1234/" (what the proxy code wants), or for
"ssh://127.0.0.1/1234" (what ssh code would want)? The former seems less
odd to me, as it really is just a URL missing some components. The
latter is a true alternative syntax.
Like you said, I don't think we will ever want to handle ssh
credentials, though. There is already a solution for people who don't
want to input ssh passwords, and it is much more advanced and
well-supported within the community than what we would provide.
> A safer approach might be to keep externally visible API to this function
> as before, but add another function only for the use of http_proxy and
> friends (whose kosher format is "host:address" without the "<scheme>://"
> part), and call it from the codepath broken by the patch.
I think that would be cleaner conceptually, but it also means
reimplementing the user/password-parsing logic. And given that I don't
think we want to handle ssh, and that the semantics in your patch are
the only sane ones to me, it is not so bad. The caller just needs to be
aware of filling in the "protocol" field. Perhaps we could have an
alternate version that supplies a "default protocol" parameter. The
presence of that parameter would activate this code-path and
automatically fill in the protocol field.
-Peff
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 2/5] http: handle proxy proactive authentication
2012-04-12 20:58 ` Jeff King
@ 2012-04-12 21:25 ` Junio C Hamano
2012-04-12 22:05 ` Jeff King
0 siblings, 1 reply; 13+ messages in thread
From: Junio C Hamano @ 2012-04-12 21:25 UTC (permalink / raw)
To: Jeff King; +Cc: Nelson Benitez Leon, git, sam, spearce
Jeff King <peff@peff.net> writes:
> My first instinct was "that is not a URL, and should be handled outside
> this function". In particular, it has no protocol field, and that is an
> important part of the credential-matching process. It would be up to the
> caller to supply something sane in the protocol portion. In this case,
> it would probably be "http"...
Outside git, these actually come from things like these:
http_proxy=127.0.0.1:1080
HTTPS_PROXY=127.0.0.1:1080
And http.proxy configuration variable we have is a substitute for
http_proxy. So if we want to keep the credentials for destination servers
and the credentials for proxies, "http.proxy" codepath should be asking
you with "http". If we are looking at HTTPS_PROXY, you should get "https".
The patch that broke the unauthenticated proxy access does neither.
> ... (unless we want to distinguish http proxies
> from http end-points in the credential store, but I doubt that is
> useful).
That is something we may want to think carefully about.
If it is better to separate them, then we can easily invent "http-proxy",
"https-proxy" etc. for them, e.g.
HTTPS_PROXY=http://127.0.0.1:1080
git fetch https://over.there.xz/repo/sito/ry.git
would ask you for a credential to access 127.0.0.1:1080 in "https-proxy"
domain, and another to access over.there.xz in "https" domain.
In either case, the last example will not use "http" anywhere, even though
the value of the proxy has noiseword "http://" in front of it, which is
ignored. So in that sense, even if we ignored the breakage for the proxy
specification without noiseword which Shawn noticed, the patch is broken,
as it asks credential for http://127.0.0.1:1080 and you parse it for "http"
protocol.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 2/5] http: handle proxy proactive authentication
2012-04-12 21:25 ` Junio C Hamano
@ 2012-04-12 22:05 ` Jeff King
2012-04-12 22:18 ` Junio C Hamano
0 siblings, 1 reply; 13+ messages in thread
From: Jeff King @ 2012-04-12 22:05 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Nelson Benitez Leon, git, sam, spearce
On Thu, Apr 12, 2012 at 02:25:12PM -0700, Junio C Hamano wrote:
> Outside git, these actually come from things like these:
>
> http_proxy=127.0.0.1:1080
> HTTPS_PROXY=127.0.0.1:1080
>
> And http.proxy configuration variable we have is a substitute for
> http_proxy. So if we want to keep the credentials for destination servers
> and the credentials for proxies, "http.proxy" codepath should be asking
> you with "http". If we are looking at HTTPS_PROXY, you should get "https".
> The patch that broke the unauthenticated proxy access does neither.
Hmm. Does the distinction between http and https actually matter to
curl? My reading of the code and documentation is that only "http" is
meaningful (actually, anything besides socks*:// gets converted to
http).
So as far as I can tell, these are equivalent:
http_proxy=http://127.0.0.1:1080
http_proxy=https://127.0.0.1:1080
http_proxy=foobar://127.0.0.1:1080
And furthermore, the decision to use http_proxy versus https_proxy is
about what the _target_ connection wants to do. So if you see this:
HTTPS_PROXY=127.0.0.1:1080
it is still an http proxy; it is just that it is used for requests going
to https:// servers, and it will ask to tunnel via CONNECT instead of
GET. But in either case, the conversation with the proxy is over
straight http.
So the value should always be "http" in that case. This is a credential
we are handing to the proxy, not to the target server, and it is done
over http, not https.
I can't see that there is a way to tell curl to speak SSL to the proxy
itself. Maybe I am missing it, but I couldn't find anything in the
code, nor make it work with "curl -x" to an "openssl s_server" instance.
> That is something we may want to think carefully about.
>
> If it is better to separate them, then we can easily invent "http-proxy",
> "https-proxy" etc. for them, e.g.
>
> HTTPS_PROXY=http://127.0.0.1:1080
> git fetch https://over.there.xz/repo/sito/ry.git
>
> would ask you for a credential to access 127.0.0.1:1080 in "https-proxy"
> domain, and another to access over.there.xz in "https" domain.
No, it should ask for the credential for 127.0.0.1:1080 in the "http"
domain, per the above discussion.
Not splitting "http" and "http-proxy" does have a slight confusion, as
the default proxy port is "1080". So a proxy of "http://127.0.0.1" would
mean "http://127.0.0.1:1080", whereas a regular request would mean
"http://127.0.0.1:80". The credential code includes the port as part of
the unique hostname, but since the default-port magic happens inside
curl, we have no access to it (short of re-implementing it ourselves).
In practice, I doubt it matters much; do people really have different
credentials for proxies and regular servers on the same host? And if so,
there is already a workaround by using the port number in the proxy
specification.
I really wish curl's credential-handling was implemented as a callback;
this would be much simpler if could let curl decipher the request and
come to us with the complete request (protocol, host, port, path, etc).
But even if we got such a feature in curl, we are stuck supporting the
old way for a while anyway.
-Peff
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 2/5] http: handle proxy proactive authentication
2012-04-12 22:05 ` Jeff King
@ 2012-04-12 22:18 ` Junio C Hamano
2012-04-12 22:42 ` Jeff King
0 siblings, 1 reply; 13+ messages in thread
From: Junio C Hamano @ 2012-04-12 22:18 UTC (permalink / raw)
To: Jeff King; +Cc: Nelson Benitez Leon, git, sam, spearce
Jeff King <peff@peff.net> writes:
> On Thu, Apr 12, 2012 at 02:25:12PM -0700, Junio C Hamano wrote:
>
>> Outside git, these actually come from things like these:
>>
>> http_proxy=127.0.0.1:1080
>> HTTPS_PROXY=127.0.0.1:1080
>>
>> And http.proxy configuration variable we have is a substitute for
>> http_proxy. So if we want to keep the credentials for destination servers
>> and the credentials for proxies, "http.proxy" codepath should be asking
>> you with "http". If we are looking at HTTPS_PROXY, you should get "https".
>> The patch that broke the unauthenticated proxy access does neither.
>
> Hmm. Does the distinction between http and https actually matter to
> curl? My reading of the code and documentation is that only "http" is
> meaningful (actually, anything besides socks*:// gets converted to
> http).
>
> So as far as I can tell, these are equivalent:
>
> http_proxy=http://127.0.0.1:1080
> http_proxy=https://127.0.0.1:1080
> http_proxy=foobar://127.0.0.1:1080
Yes, that is exactly what I was trying to say. The foobar:// part does
not matter; "http" in "http_proxy" is what matters, as it is how you can
specify two separate proxies depending on what destination you are going
via what protocol.
> Not splitting "http" and "http-proxy" does have a slight confusion, as
> the default proxy port is "1080". So a proxy of "http://127.0.0.1" would
> mean "http://127.0.0.1:1080", whereas a regular request would mean
> "http://127.0.0.1:80". The credential code includes the port as part of
> the unique hostname, but since the default-port magic happens inside
> curl, we have no access to it (short of re-implementing it ourselves).
Ok, so how about this as a replacement patch for what I have had for the
past few days?
credential.c | 44 +++++++++++++++++++++++++++++++-------------
credential.h | 1 +
http.c | 10 +++++++---
3 files changed, 39 insertions(+), 16 deletions(-)
diff --git a/credential.c b/credential.c
index 62d1c56..5803645 100644
--- a/credential.c
+++ b/credential.c
@@ -313,22 +313,17 @@ void credential_reject(struct credential *c)
c->approved = 0;
}
-void credential_from_url(struct credential *c, const char *url)
+static void credential_for_dest(struct credential *c, const char *dest)
{
- const char *at, *colon, *cp, *slash, *host, *proto_end;
-
- credential_clear(c);
+ const char *at, *colon, *cp, *slash, *host;
/*
* Match one of:
- * (1) proto://<host>/...
- * (2) proto://<user>@<host>/...
- * (3) proto://<user>:<pass>@<host>/...
+ * (1) <host>/...
+ * (2) <user>@<host>/...
+ * (3) <user>:<pass>@<host>/...
*/
- proto_end = strstr(url, "://");
- if (!proto_end)
- return;
- cp = proto_end + 3;
+ cp = dest;
at = strchr(cp, '@');
colon = strchr(cp, ':');
slash = strchrnul(cp, '/');
@@ -348,10 +343,9 @@ void credential_from_url(struct credential *c, const char *url)
host = at + 1;
}
- if (proto_end - url > 0)
- c->protocol = xmemdupz(url, proto_end - url);
if (slash - host > 0)
c->host = url_decode_mem(host, slash - host);
+
/* Trim leading and trailing slashes from path */
while (*slash == '/')
slash++;
@@ -363,3 +357,27 @@ void credential_from_url(struct credential *c, const char *url)
*p-- = '\0';
}
}
+
+void credential_for_destination(struct credential *c, const char *dest, const char *proto)
+{
+ credential_clear(c);
+ c->protocol = xstrdup(proto);
+ credential_for_dest(c, dest);
+}
+
+void credential_from_url(struct credential *c, const char *url)
+{
+ const char *proto_end;
+
+ credential_clear(c);
+
+ /*
+ * Strip "proto://" part and let credential_for_dest()
+ * parse the remainder.
+ */
+ proto_end = strstr(url, "://");
+ if (!proto_end)
+ return;
+ c->protocol = xmemdupz(url, proto_end - url);
+ credential_for_dest(c, proto_end + 3);
+}
diff --git a/credential.h b/credential.h
index 96ea41b..4b1c320 100644
--- a/credential.h
+++ b/credential.h
@@ -27,6 +27,7 @@ void credential_reject(struct credential *);
int credential_read(struct credential *, FILE *);
void credential_from_url(struct credential *, const char *url);
+void credential_for_destination(struct credential *, const char *dest, const char *proto);
int credential_match(const struct credential *have,
const struct credential *want);
diff --git a/http.c b/http.c
index 1c71edb..752b6ea 100644
--- a/http.c
+++ b/http.c
@@ -336,14 +336,18 @@ static CURL *get_curl_handle(const char *url)
if (curl_http_proxy) {
struct strbuf proxyhost = STRBUF_INIT;
- if (!proxy_auth.host) /* check to parse only once */
- credential_from_url(&proxy_auth, curl_http_proxy);
+ if (!proxy_auth.host) {
+ const char *cp;
+ cp = strstr(curl_http_proxy, "://");
+ cp = cp ? (cp + 3) : curl_http_proxy;
+ credential_for_destination(&proxy_auth, cp, "http-proxy");
+ }
if (http_proactive_auth && proxy_auth.username && !proxy_auth.password)
/* proxy string has username but no password, ask for password */
credential_fill(&proxy_auth);
- strbuf_addf(&proxyhost, "%s://%s", proxy_auth.protocol, proxy_auth.host);
+ strbuf_addstr(&proxyhost, proxy_auth.host);
curl_easy_setopt(result, CURLOPT_PROXY, strbuf_detach(&proxyhost, NULL));
curl_easy_setopt(result, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
set_proxy_auth(result);
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v5 2/5] http: handle proxy proactive authentication
2012-04-12 22:18 ` Junio C Hamano
@ 2012-04-12 22:42 ` Jeff King
2012-04-13 19:35 ` Junio C Hamano
0 siblings, 1 reply; 13+ messages in thread
From: Jeff King @ 2012-04-12 22:42 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Nelson Benitez Leon, git, sam, spearce
On Thu, Apr 12, 2012 at 03:18:01PM -0700, Junio C Hamano wrote:
> > So as far as I can tell, these are equivalent:
> >
> > http_proxy=http://127.0.0.1:1080
> > http_proxy=https://127.0.0.1:1080
> > http_proxy=foobar://127.0.0.1:1080
>
> Yes, that is exactly what I was trying to say. The foobar:// part does
> not matter; "http" in "http_proxy" is what matters, as it is how you can
> specify two separate proxies depending on what destination you are going
> via what protocol.
But you snipped the later part of my message, which is that the "http"
in "http_proxy" does _not_ matter. It is about which destinations to
apply the proxy to, not how you talk to the proxy (and the latter is what
should matter for the credentials).
> > Not splitting "http" and "http-proxy" does have a slight confusion, as
> > the default proxy port is "1080". So a proxy of "http://127.0.0.1" would
> > mean "http://127.0.0.1:1080", whereas a regular request would mean
> > "http://127.0.0.1:80". The credential code includes the port as part of
> > the unique hostname, but since the default-port magic happens inside
> > curl, we have no access to it (short of re-implementing it ourselves).
>
> Ok, so how about this as a replacement patch for what I have had for the
> past few days?
My other message argued "the http-proxy distinction might be important,
but probably isn't". But I didn't talk about "the http-proxy distinction
might break helpers". The stock helpers will be fine; they are totally
clueless about what the protocol means, and just treat it as a string to
be matched. But for something like osxkeychain, where it is converting
the protocol string into some OS-specific magic value, it does matter,
and http-proxy would cause it to exit in confusion.
It looks like OS X defines a SOCKS type and an HTTPProxy type for its
keychain API. So in either case, it should probably be updated to handle
these new types. And I guess that argues for making the distinction,
since at least one helper does want to care about it.
-Peff
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 2/5] http: handle proxy proactive authentication
2012-04-12 22:42 ` Jeff King
@ 2012-04-13 19:35 ` Junio C Hamano
2012-04-13 20:23 ` Jeff King
0 siblings, 1 reply; 13+ messages in thread
From: Junio C Hamano @ 2012-04-13 19:35 UTC (permalink / raw)
To: Jeff King; +Cc: Nelson Benitez Leon, git, sam, spearce
Jeff King <peff@peff.net> writes:
> But you snipped the later part of my message, which is that the "http"
> in "http_proxy" does _not_ matter. It is about which destinations to
> apply the proxy to, not how you talk to the proxy (and the latter is what
> should matter for the credentials).
Oh, yes, I am in violent agreement. The language the http clients
(browsers etc) talk to the proxy may be part of HTTP specification, but it
is definitely different from the "http" talked with the origin servers.
>> > Not splitting "http" and "http-proxy" does have a slight confusion,...
>>
>> Ok, so how about this as a replacement patch for what I have had for the
>> past few days?
>
> My other message argued "the http-proxy distinction might be important,
> but probably isn't". But I didn't talk about "the http-proxy distinction
> might break helpers". The stock helpers will be fine; they are totally
> clueless about what the protocol means, and just treat it as a string to
> be matched. But for something like osxkeychain, where it is converting
> the protocol string into some OS-specific magic value, it does matter,
> and http-proxy would cause it to exit in confusion.
>
> It looks like OS X defines a SOCKS type and an HTTPProxy type for its
> keychain API. So in either case, it should probably be updated to handle
> these new types. And I guess that argues for making the distinction,
> since at least one helper does want to care about it.
OK. Sounds like we are in agreement.
Nelson, care to re-roll the series, with fixes discussed in this thread
rolled into the second patch?
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 2/5] http: handle proxy proactive authentication
2012-04-13 19:35 ` Junio C Hamano
@ 2012-04-13 20:23 ` Jeff King
0 siblings, 0 replies; 13+ messages in thread
From: Jeff King @ 2012-04-13 20:23 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Nelson Benitez Leon, git, sam, spearce
On Fri, Apr 13, 2012 at 12:35:17PM -0700, Junio C Hamano wrote:
> > It looks like OS X defines a SOCKS type and an HTTPProxy type for its
> > keychain API. So in either case, it should probably be updated to handle
> > these new types. And I guess that argues for making the distinction,
> > since at least one helper does want to care about it.
>
> OK. Sounds like we are in agreement.
>
> Nelson, care to re-roll the series, with fixes discussed in this thread
> rolled into the second patch?
I think there is a bug in the patch you posted, though:
> diff --git a/http.c b/http.c
> index 1c71edb..752b6ea 100644
> --- a/http.c
> +++ b/http.c
> @@ -336,14 +336,18 @@ static CURL *get_curl_handle(const char *url)
> if (curl_http_proxy) {
> struct strbuf proxyhost = STRBUF_INIT;
>
> - if (!proxy_auth.host) /* check to parse only once */
> - credential_from_url(&proxy_auth, curl_http_proxy);
> + if (!proxy_auth.host) {
> + const char *cp;
> + cp = strstr(curl_http_proxy, "://");
> + cp = cp ? (cp + 3) : curl_http_proxy;
> + credential_for_destination(&proxy_auth, cp, "http-proxy");
> + }
What happens if the URL starts with "socks://"? We would want to
preserve that, and have our protocol end as "socks://".
> if (http_proactive_auth && proxy_auth.username && !proxy_auth.password)
> /* proxy string has username but no password, ask for password */
> credential_fill(&proxy_auth);
>
> - strbuf_addf(&proxyhost, "%s://%s", proxy_auth.protocol, proxy_auth.host);
> + strbuf_addstr(&proxyhost, proxy_auth.host);
> curl_easy_setopt(result, CURLOPT_PROXY, strbuf_detach(&proxyhost, NULL));
Same here. If we get "socks://127.0.0.1", we will feed "127.0.0.1" to
curl, which will then assume that it's http.
BTW, do we actually need to strip the username out of the URL? We do not
do so with regular URLs, and curl takes the auth we give it over what is
in the URL. Can this be simplified to just:
curl_easy_setopt(result, CURLOPT_PROXY, curl_http_proxy);
?
At any rate, I think the rule we want for parsing the url is to actually
parse the protocol from the url, and if it's not there, assume it's
http. And then convert all "http" to "http-proxy", because this is a
weird alternate use of "http". So we can just take your old patch to
relax the credential_from_url parsing, and then fix it up on the calling
side. Like this:
diff --git a/credential.c b/credential.c
index 62d1c56..813e3cf 100644
--- a/credential.c
+++ b/credential.c
@@ -324,11 +324,15 @@ void credential_from_url(struct credential *c, const char *url)
* (1) proto://<host>/...
* (2) proto://<user>@<host>/...
* (3) proto://<user>:<pass>@<host>/...
+ * or "proto://"-less variants of the above. They are not technically
+ * URLs, but the caller may have some context-specific knowledge about
+ * what protocol is in use.
*/
proto_end = strstr(url, "://");
- if (!proto_end)
- return;
- cp = proto_end + 3;
+ if (proto_end)
+ cp = proto_end + 3;
+ else
+ cp = url;
at = strchr(cp, '@');
colon = strchr(cp, ':');
slash = strchrnul(cp, '/');
@@ -348,7 +352,7 @@ void credential_from_url(struct credential *c, const char *url)
host = at + 1;
}
- if (proto_end - url > 0)
+ if (proto_end && proto_end != url)
c->protocol = xmemdupz(url, proto_end - url);
if (slash - host > 0)
c->host = url_decode_mem(host, slash - host);
diff --git a/http.c b/http.c
index 1c71edb..a164f79 100644
--- a/http.c
+++ b/http.c
@@ -334,17 +334,20 @@ static CURL *get_curl_handle(const char *url)
free(env_proxy_var);
}
if (curl_http_proxy) {
- struct strbuf proxyhost = STRBUF_INIT;
-
- if (!proxy_auth.host) /* check to parse only once */
+ if (!proxy_auth.host) {
credential_from_url(&proxy_auth, curl_http_proxy);
+ if (!proxy_auth.protocol ||
+ !strcmp(proxy_auth.protocol, "http")) {
+ free(proxy_auth.protocol);
+ proxy_auth.protocol = xstrdup("http-proxy");
+ }
+ }
if (http_proactive_auth && proxy_auth.username && !proxy_auth.password)
/* proxy string has username but no password, ask for password */
credential_fill(&proxy_auth);
- strbuf_addf(&proxyhost, "%s://%s", proxy_auth.protocol, proxy_auth.host);
- curl_easy_setopt(result, CURLOPT_PROXY, strbuf_detach(&proxyhost, NULL));
+ curl_easy_setopt(result, CURLOPT_PROXY, curl_http_proxy);
curl_easy_setopt(result, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
set_proxy_auth(result);
}
Note that curl will treat "foobar://" (or any protocol it does not
understand) as an http proxy. I didn't want to get into white-listing
"socks:// is ok, but foobar:// is really just http in disguise" based on
curl's internal rules. So you can use "foobar://" if you want, but it's
not going to share credentials with "http://" (even though curl will use
them in exactly the same way).
-Peff
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v5 2/5] http: handle proxy proactive authentication
2012-03-13 14:03 [PATCH v5 2/5] http: handle proxy proactive authentication Nelson Benitez Leon
2012-04-09 21:39 ` Junio C Hamano
@ 2012-04-13 20:56 ` Jeff King
2012-04-19 17:09 ` Junio C Hamano
1 sibling, 1 reply; 13+ messages in thread
From: Jeff King @ 2012-04-13 20:56 UTC (permalink / raw)
To: Nelson Benitez Leon; +Cc: git, sam
On Tue, Mar 13, 2012 at 03:03:54PM +0100, Nelson Benitez Leon wrote:
> Also take care that CURLOPT_PROXY don't include username or
> password, as we now set them in the new set_proxy_auth() function
> where we use their specific cURL options.
Did you test that this is necessary? We don't do it for the regular URL
case, and it makes the code much simpler if we can avoid munging what we
hand to curl.
> +static void set_proxy_auth(CURL *result)
> +{
> + if (proxy_auth.username && proxy_auth.password) {
> +#if LIBCURL_VERSION_NUM >= 0x071901
> + curl_easy_setopt(result, CURLOPT_PROXYUSERNAME, proxy_auth.username);
> + curl_easy_setopt(result, CURLOPT_PROXYPASSWORD, proxy_auth.password);
> +#else
Is that version check right? You are giving a hexadecimal number, so
7.19.1 would be 071301.
-Peff
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v5 2/5] http: handle proxy proactive authentication
2012-04-13 20:56 ` Jeff King
@ 2012-04-19 17:09 ` Junio C Hamano
0 siblings, 0 replies; 13+ messages in thread
From: Junio C Hamano @ 2012-04-19 17:09 UTC (permalink / raw)
To: Jeff King; +Cc: Nelson Benitez Leon, git, sam
Jeff King <peff@peff.net> writes:
> On Tue, Mar 13, 2012 at 03:03:54PM +0100, Nelson Benitez Leon wrote:
>
>> Also take care that CURLOPT_PROXY don't include username or
>> password, as we now set them in the new set_proxy_auth() function
>> where we use their specific cURL options.
>
> Did you test that this is necessary? We don't do it for the regular URL
> case, and it makes the code much simpler if we can avoid munging what we
> hand to curl.
>
>> +static void set_proxy_auth(CURL *result)
>> +{
>> + if (proxy_auth.username && proxy_auth.password) {
>> +#if LIBCURL_VERSION_NUM >= 0x071901
>> + curl_easy_setopt(result, CURLOPT_PROXYUSERNAME, proxy_auth.username);
>> + curl_easy_setopt(result, CURLOPT_PROXYPASSWORD, proxy_auth.password);
>> +#else
>
> Is that version check right? You are giving a hexadecimal number, so
> 7.19.1 would be 071301.
I notice that I missed this comment, and I think the version queued in
'pu' still has this incorrect.
CURLOPT_PROXYUSERNAME is marked as Introduced at 7.19.1 in
https://github.com/bagder/curl/blob/master/docs/libcurl/symbols-in-versions
so I agree that the above would need to be 0x071301.
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2012-04-19 17:09 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-03-13 14:03 [PATCH v5 2/5] http: handle proxy proactive authentication Nelson Benitez Leon
2012-04-09 21:39 ` Junio C Hamano
2012-04-10 0:59 ` Junio C Hamano
2012-04-12 15:54 ` Junio C Hamano
2012-04-12 20:58 ` Jeff King
2012-04-12 21:25 ` Junio C Hamano
2012-04-12 22:05 ` Jeff King
2012-04-12 22:18 ` Junio C Hamano
2012-04-12 22:42 ` Jeff King
2012-04-13 19:35 ` Junio C Hamano
2012-04-13 20:23 ` Jeff King
2012-04-13 20:56 ` Jeff King
2012-04-19 17:09 ` Junio C Hamano
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).