http: add support for specifying the SSL version

Teach git about a new option, "http.sslVersion", which permits one to specify the SSL version to use when negotiating SSL connections. The setting can be overridden by the GIT_SSL_VERSION environment variable. Signed-off-by: Elia Pinto <gitter.spiros@gmail.com> Helped-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Elia Pinto committed Aug 14, 2015 at 21:37 UTC 01861cb7a27b948bc0218877311f531f25386691
3 files changed +56 -1
Documentation/config.txt
+23
@@ -1576,6 +1576,29 @@ http.saveCookies::
1576 If set, store cookies received during requests to the file specified by
1577 http.cookieFile. Has no effect if http.cookieFile is unset.
1578
1579 +http.sslVersion::
1580 + The SSL version to use when negotiating an SSL connection, if you
1581 + want to force the default. The available and default version
1582 + depend on whether libcurl was built against NSS or OpenSSL and the
1583 + particular configuration of the crypto library in use. Internally
1584 + this sets the 'CURLOPT_SSL_VERSION' option; see the libcurl
1585 + documentation for more details on the format of this option and
1586 + for the ssl version supported. Actually the possible values of
1587 + this option are:
1588 +
1589 + - sslv2
1590 + - sslv3
1591 + - tlsv1
1592 + - tlsv1.0
1593 + - tlsv1.1
1594 + - tlsv1.2
1595 +
1596 ++
1597 +Can be overridden by the 'GIT_SSL_VERSION' environment variable.
1598 +To force git to use libcurl's default ssl version and ignore any
1599 +explicit http.sslversion option, set 'GIT_SSL_VERSION' to the
1600 +empty string.
1601 +
1602 http.sslCipherList::
1603 A list of SSL ciphers to use when negotiating an SSL connection.
1604 The available ciphers depend on whether libcurl was built against
contrib/completion/git-completion.bash
+1
@@ -2118,6 +2118,7 @@ _git_config ()
2118 http.postBuffer
2119 http.proxy
2120 http.sslCipherList
2121 + http.sslVersion
2122 http.sslCAInfo
2123 http.sslCAPath
2124 http.sslCert
http.c
+32 -1
@@ -37,6 +37,20 @@ static int curl_ssl_verify = -1;
37 static int curl_ssl_try;
38 static const char *ssl_cert;
39 static const char *ssl_cipherlist;
40 +static const char *ssl_version;
41 +static struct {
42 + const char *name;
43 + long ssl_version;
44 +} sslversions[] = {
45 + { "sslv2", CURL_SSLVERSION_SSLv2 },
46 + { "sslv3", CURL_SSLVERSION_SSLv3 },
47 + { "tlsv1", CURL_SSLVERSION_TLSv1 },
48 +#if LIBCURL_VERSION_NUM >= 0x072200
49 + { "tlsv1.0", CURL_SSLVERSION_TLSv1_0 },
50 + { "tlsv1.1", CURL_SSLVERSION_TLSv1_1 },
51 + { "tlsv1.2", CURL_SSLVERSION_TLSv1_2 },
52 +#endif
53 +};
54 #if LIBCURL_VERSION_NUM >= 0x070903
55 static const char *ssl_key;
56 #endif
@@ -190,6 +204,8 @@ static int http_options(const char *var, const char *value, void *cb)
204 }
205 if (!strcmp("http.sslcipherlist", var))
206 return git_config_string(&ssl_cipherlist, var, value);
207 + if (!strcmp("http.sslversion", var))
208 + return git_config_string(&ssl_version, var, value);
209 if (!strcmp("http.sslcert", var))
210 return git_config_string(&ssl_cert, var, value);
211 #if LIBCURL_VERSION_NUM >= 0x070903
@@ -364,9 +380,24 @@ static CURL *get_curl_handle(void)
380 if (http_proactive_auth)
381 init_curl_http_auth(result);
382
383 + if (getenv("GIT_SSL_VERSION"))
384 + ssl_version = getenv("GIT_SSL_VERSION");
385 + if (ssl_version && *ssl_version) {
386 + int i;
387 + for (i = 0; i < ARRAY_SIZE(sslversions); i++) {
388 + if (!strcmp(ssl_version, sslversions[i].name)) {
389 + curl_easy_setopt(result, CURLOPT_SSLVERSION,
390 + sslversions[i].ssl_version);
391 + break;
392 + }
393 + }
394 + if (i == ARRAY_SIZE(sslversions))
395 + warning("unsupported ssl version %s: using default",
396 + ssl_version);
397 + }
398 +
399 if (getenv("GIT_SSL_CIPHER_LIST"))
400 ssl_cipherlist = getenv("GIT_SSL_CIPHER_LIST");
369 -
401 if (ssl_cipherlist != NULL && *ssl_cipherlist)
402 curl_easy_setopt(result, CURLOPT_SSL_CIPHER_LIST,
403 ssl_cipherlist);