Commit 467e2cb1 by Carlos Martín Nieto

curl: ask for proxy credentials

parent 60d717c6
......@@ -23,6 +23,7 @@ typedef struct {
git_cert_x509 cert_info;
git_strarray cert_info_strings;
git_proxy_options proxy;
git_cred *proxy_cred;
} curl_stream;
static int seterr_curl(curl_stream *s)
......@@ -31,21 +32,94 @@ static int seterr_curl(curl_stream *s)
return -1;
}
GIT_INLINE(int) error_no_credentials(void)
{
giterr_set(GITERR_NET, "proxy authentication required, but no callback provided");
return GIT_EAUTH;
}
static int apply_proxy_creds(curl_stream *s)
{
CURLcode res;
git_cred_userpass_plaintext *userpass;
if (!s->proxy_cred)
return GIT_ENOTFOUND;
userpass = (git_cred_userpass_plaintext *) s->proxy_cred;
if ((res = curl_easy_setopt(s->handle, CURLOPT_PROXYUSERNAME, userpass->username)) != CURLE_OK)
return seterr_curl(s);
if ((res = curl_easy_setopt(s->handle, CURLOPT_PROXYPASSWORD, userpass->password)) != CURLE_OK)
return seterr_curl(s);
return 0;
}
static int ask_and_apply_proxy_creds(curl_stream *s)
{
int error;
git_proxy_options *opts = &s->proxy;
if (!opts->credentials)
return error_no_credentials();
/* TODO: see if PROXYAUTH_AVAIL helps us here */
git_cred_free(s->proxy_cred);
s->proxy_cred = NULL;
giterr_clear();
error = opts->credentials(&s->proxy_cred, opts->url, NULL, GIT_CREDTYPE_USERPASS_PLAINTEXT, opts->payload);
if (error == GIT_PASSTHROUGH)
return error_no_credentials();
if (error < 0) {
if (!giterr_last())
giterr_set(GITERR_NET, "proxy authentication was aborted by the user");
return error;
}
if (s->proxy_cred->credtype != GIT_CREDTYPE_USERPASS_PLAINTEXT) {
giterr_set(GITERR_NET, "credentials callback returned invalid credential type");
return -1;
}
return apply_proxy_creds(s);
}
static int curls_connect(git_stream *stream)
{
curl_stream *s = (curl_stream *) stream;
long sockextr;
int failed_cert = 0;
long sockextr, connect_last = 0;
int failed_cert = 0, error;
bool retry_connect;
CURLcode res;
res = curl_easy_perform(s->handle);
/* Apply any credentials we've already established */
error = apply_proxy_creds(s);
if (error < 0 && error != GIT_ENOTFOUND)
return seterr_curl(s);
do {
retry_connect = 0;
res = curl_easy_perform(s->handle);
curl_easy_getinfo(s->handle, CURLINFO_HTTP_CONNECTCODE, &connect_last);
/* HTTP 407 Proxy Authentication Required */
if (connect_last == 407) {
if ((error = ask_and_apply_proxy_creds(s)) < 0)
return error;
retry_connect = true;
}
} while (retry_connect);
if (res != CURLE_OK && res != CURLE_PEER_FAILED_VERIFICATION)
return seterr_curl(s);
if (res == CURLE_PEER_FAILED_VERIFICATION)
failed_cert = 1;
if ((res = curl_easy_getinfo(s->handle, CURLINFO_LASTSOCKET, &sockextr)) != CURLE_OK)
if ((res = curl_easy_getinfo(s->handle, CURLINFO_LASTSOCKET, &sockextr)) != CURLE_OK) {
return seterr_curl(s);
}
s->socket = sockextr;
......@@ -109,6 +183,9 @@ static int curls_set_proxy(git_stream *stream, const git_proxy_options *proxy_op
if ((res = curl_easy_setopt(s->handle, CURLOPT_PROXY, s->proxy.url)) != CURLE_OK)
return seterr_curl(s);
if ((res = curl_easy_setopt(s->handle, CURLOPT_PROXYAUTH, CURLAUTH_ANY)) != CURLE_OK)
return seterr_curl(s);
return 0;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment