Skip to content

Commit bfcf969

Browse files
committed
Merge branch 'js/https-proxy-config' into jch
A handful of options to configure SSL when talking to proxies have been added. * js/https-proxy-config: http: add environment variable support for HTTPS proxies http: add client cert support for HTTPS proxies
2 parents d2071bc + af02651 commit bfcf969

File tree

2 files changed

+90
-5
lines changed

2 files changed

+90
-5
lines changed

Documentation/config/http.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,27 @@ http.proxyAuthMethod::
2929
* `ntlm` - NTLM authentication (compare the --ntlm option of `curl(1)`)
3030
--
3131

32+
http.proxySSLCert::
33+
The pathname of a file that stores a client certificate to use to authenticate
34+
with an HTTPS proxy. Can be overridden by the `GIT_PROXY_SSL_CERT` environment
35+
variable.
36+
37+
http.proxySSLKey::
38+
The pathname of a file that stores a private key to use to authenticate with
39+
an HTTPS proxy. Can be overridden by the `GIT_PROXY_SSL_KEY` environment
40+
variable.
41+
42+
http.proxySSLCertPasswordProtected::
43+
Enable Git's password prompt for the proxy SSL certificate. Otherwise OpenSSL
44+
will prompt the user, possibly many times, if the certificate or private key
45+
is encrypted. Can be overriden by the `GIT_PROXY_SSL_CERT_PASSWORD_PROTECTED`
46+
environment variable.
47+
48+
http.proxySSLCAInfo::
49+
Pathname to the file containing the certificate bundle that should be used to
50+
verify the proxy with when using an HTTPS proxy. Can be overriden by the
51+
`GIT_PROXY_SSL_CAINFO` environment variable.
52+
3253
http.emptyAuth::
3354
Attempt authentication without seeking a username or password. This
3455
can be used to attempt GSS-Negotiate authentication without specifying

http.c

Lines changed: 69 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ static long curl_low_speed_time = -1;
8686
static int curl_ftp_no_epsv;
8787
static const char *curl_http_proxy;
8888
static const char *http_proxy_authmethod;
89+
90+
static const char *http_proxy_ssl_cert;
91+
static const char *http_proxy_ssl_key;
92+
static const char *http_proxy_ssl_ca_info;
93+
static struct credential proxy_cert_auth = CREDENTIAL_INIT;
94+
static int proxy_ssl_cert_password_required;
95+
8996
static struct {
9097
const char *name;
9198
long curlauth_param;
@@ -365,6 +372,20 @@ static int http_options(const char *var, const char *value, void *cb)
365372
if (!strcmp("http.proxyauthmethod", var))
366373
return git_config_string(&http_proxy_authmethod, var, value);
367374

375+
if (!strcmp("http.proxysslcert", var))
376+
return git_config_string(&http_proxy_ssl_cert, var, value);
377+
378+
if (!strcmp("http.proxysslkey", var))
379+
return git_config_string(&http_proxy_ssl_key, var, value);
380+
381+
if (!strcmp("http.proxysslcainfo", var))
382+
return git_config_string(&http_proxy_ssl_ca_info, var, value);
383+
384+
if (!strcmp("http.proxysslcertpasswordprotected", var)) {
385+
proxy_ssl_cert_password_required = git_config_bool(var, value);
386+
return 0;
387+
}
388+
368389
if (!strcmp("http.cookiefile", var))
369390
return git_config_pathname(&curl_cookie_file, var, value);
370391
if (!strcmp("http.savecookies", var)) {
@@ -565,6 +586,21 @@ static int has_cert_password(void)
565586
return 1;
566587
}
567588

589+
#if LIBCURL_VERSION_NUM >= 0x073400
590+
static int has_proxy_cert_password(void)
591+
{
592+
if (http_proxy_ssl_cert == NULL || proxy_ssl_cert_password_required != 1)
593+
return 0;
594+
if (!proxy_cert_auth.password) {
595+
proxy_cert_auth.protocol = xstrdup("cert");
596+
proxy_cert_auth.username = xstrdup("");
597+
proxy_cert_auth.path = xstrdup(http_proxy_ssl_cert);
598+
credential_fill(&proxy_cert_auth);
599+
}
600+
return 1;
601+
}
602+
#endif
603+
568604
#if LIBCURL_VERSION_NUM >= 0x071900
569605
static void set_curl_keepalive(CURL *c)
570606
{
@@ -924,8 +960,14 @@ static CURL *get_curl_handle(void)
924960
#if LIBCURL_VERSION_NUM >= 0x073400
925961
curl_easy_setopt(result, CURLOPT_PROXY_CAINFO, NULL);
926962
#endif
927-
} else if (ssl_cainfo != NULL)
928-
curl_easy_setopt(result, CURLOPT_CAINFO, ssl_cainfo);
963+
} else if (ssl_cainfo != NULL || http_proxy_ssl_ca_info != NULL) {
964+
if (ssl_cainfo != NULL)
965+
curl_easy_setopt(result, CURLOPT_CAINFO, ssl_cainfo);
966+
#if LIBCURL_VERSION_NUM >= 0x073400
967+
if (http_proxy_ssl_ca_info != NULL)
968+
curl_easy_setopt(result, CURLOPT_PROXY_CAINFO, http_proxy_ssl_ca_info);
969+
#endif
970+
}
929971

930972
if (curl_low_speed_limit > 0 && curl_low_speed_time > 0) {
931973
curl_easy_setopt(result, CURLOPT_LOW_SPEED_LIMIT,
@@ -1018,9 +1060,18 @@ static CURL *get_curl_handle(void)
10181060
CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4);
10191061
#endif
10201062
#if LIBCURL_VERSION_NUM >= 0x073400
1021-
else if (starts_with(curl_http_proxy, "https"))
1022-
curl_easy_setopt(result,
1023-
CURLOPT_PROXYTYPE, CURLPROXY_HTTPS);
1063+
else if (starts_with(curl_http_proxy, "https")) {
1064+
curl_easy_setopt(result, CURLOPT_PROXYTYPE, CURLPROXY_HTTPS);
1065+
1066+
if (http_proxy_ssl_cert)
1067+
curl_easy_setopt(result, CURLOPT_PROXY_SSLCERT, http_proxy_ssl_cert);
1068+
1069+
if (http_proxy_ssl_key)
1070+
curl_easy_setopt(result, CURLOPT_PROXY_SSLKEY, http_proxy_ssl_key);
1071+
1072+
if (has_proxy_cert_password())
1073+
curl_easy_setopt(result, CURLOPT_PROXY_KEYPASSWD, proxy_cert_auth.password);
1074+
}
10241075
#endif
10251076
if (strstr(curl_http_proxy, "://"))
10261077
credential_from_url(&proxy_auth, curl_http_proxy);
@@ -1160,6 +1211,13 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)
11601211
max_requests = DEFAULT_MAX_REQUESTS;
11611212
#endif
11621213

1214+
set_from_env(&http_proxy_ssl_cert, "GIT_PROXY_SSL_CERT");
1215+
set_from_env(&http_proxy_ssl_key, "GIT_PROXY_SSL_KEY");
1216+
set_from_env(&http_proxy_ssl_ca_info, "GIT_PROXY_SSL_CAINFO");
1217+
1218+
if (getenv("GIT_PROXY_SSL_CERT_PASSWORD_PROTECTED"))
1219+
proxy_ssl_cert_password_required = 1;
1220+
11631221
if (getenv("GIT_CURL_FTP_NO_EPSV"))
11641222
curl_ftp_no_epsv = 1;
11651223

@@ -1230,6 +1288,12 @@ void http_cleanup(void)
12301288
}
12311289
ssl_cert_password_required = 0;
12321290

1291+
if (proxy_cert_auth.password != NULL) {
1292+
memset(proxy_cert_auth.password, 0, strlen(proxy_cert_auth.password));
1293+
FREE_AND_NULL(proxy_cert_auth.password);
1294+
}
1295+
proxy_ssl_cert_password_required = 0;
1296+
12331297
FREE_AND_NULL(cached_accept_language);
12341298
}
12351299

0 commit comments

Comments
 (0)