Merge branch 'jk/transfer-limit-redirection' into maint-2.3
This commit is contained in:
commit
f2df3104ce
@ -1071,11 +1071,6 @@ GIT_ICASE_PATHSPECS::
|
|||||||
|
|
||||||
- any external helpers are named by their protocol (e.g., use
|
- any external helpers are named by their protocol (e.g., use
|
||||||
`hg` to allow the `git-remote-hg` helper)
|
`hg` to allow the `git-remote-hg` helper)
|
||||||
+
|
|
||||||
Note that this controls only git's internal protocol selection.
|
|
||||||
If libcurl is used (e.g., by the `http` transport), it may
|
|
||||||
redirect to other protocols. There is not currently any way to
|
|
||||||
restrict this.
|
|
||||||
|
|
||||||
|
|
||||||
Discussion[[Discussion]]
|
Discussion[[Discussion]]
|
||||||
|
18
http.c
18
http.c
@ -8,6 +8,7 @@
|
|||||||
#include "credential.h"
|
#include "credential.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "pkt-line.h"
|
#include "pkt-line.h"
|
||||||
|
#include "transport.h"
|
||||||
|
|
||||||
int active_requests;
|
int active_requests;
|
||||||
int http_is_verbose;
|
int http_is_verbose;
|
||||||
@ -303,6 +304,7 @@ static void set_curl_keepalive(CURL *c)
|
|||||||
static CURL *get_curl_handle(void)
|
static CURL *get_curl_handle(void)
|
||||||
{
|
{
|
||||||
CURL *result = curl_easy_init();
|
CURL *result = curl_easy_init();
|
||||||
|
long allowed_protocols = 0;
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
die("curl_easy_init failed");
|
die("curl_easy_init failed");
|
||||||
@ -350,11 +352,27 @@ static CURL *get_curl_handle(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
curl_easy_setopt(result, CURLOPT_FOLLOWLOCATION, 1);
|
curl_easy_setopt(result, CURLOPT_FOLLOWLOCATION, 1);
|
||||||
|
curl_easy_setopt(result, CURLOPT_MAXREDIRS, 20);
|
||||||
#if LIBCURL_VERSION_NUM >= 0x071301
|
#if LIBCURL_VERSION_NUM >= 0x071301
|
||||||
curl_easy_setopt(result, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);
|
curl_easy_setopt(result, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);
|
||||||
#elif LIBCURL_VERSION_NUM >= 0x071101
|
#elif LIBCURL_VERSION_NUM >= 0x071101
|
||||||
curl_easy_setopt(result, CURLOPT_POST301, 1);
|
curl_easy_setopt(result, CURLOPT_POST301, 1);
|
||||||
#endif
|
#endif
|
||||||
|
#if LIBCURL_VERSION_NUM >= 0x071304
|
||||||
|
if (is_transport_allowed("http"))
|
||||||
|
allowed_protocols |= CURLPROTO_HTTP;
|
||||||
|
if (is_transport_allowed("https"))
|
||||||
|
allowed_protocols |= CURLPROTO_HTTPS;
|
||||||
|
if (is_transport_allowed("ftp"))
|
||||||
|
allowed_protocols |= CURLPROTO_FTP;
|
||||||
|
if (is_transport_allowed("ftps"))
|
||||||
|
allowed_protocols |= CURLPROTO_FTPS;
|
||||||
|
curl_easy_setopt(result, CURLOPT_REDIR_PROTOCOLS, allowed_protocols);
|
||||||
|
#else
|
||||||
|
if (transport_restrict_protocols())
|
||||||
|
warning("protocol restrictions not applied to curl redirects because\n"
|
||||||
|
"your curl version is too old (>= 7.19.4)");
|
||||||
|
#endif
|
||||||
|
|
||||||
if (getenv("GIT_CURL_VERBOSE"))
|
if (getenv("GIT_CURL_VERBOSE"))
|
||||||
curl_easy_setopt(result, CURLOPT_VERBOSE, 1);
|
curl_easy_setopt(result, CURLOPT_VERBOSE, 1);
|
||||||
|
@ -119,6 +119,10 @@ RewriteRule ^/smart-redir-perm/(.*)$ /smart/$1 [R=301]
|
|||||||
RewriteRule ^/smart-redir-temp/(.*)$ /smart/$1 [R=302]
|
RewriteRule ^/smart-redir-temp/(.*)$ /smart/$1 [R=302]
|
||||||
RewriteRule ^/smart-redir-auth/(.*)$ /auth/smart/$1 [R=301]
|
RewriteRule ^/smart-redir-auth/(.*)$ /auth/smart/$1 [R=301]
|
||||||
RewriteRule ^/smart-redir-limited/(.*)/info/refs$ /smart/$1/info/refs [R=301]
|
RewriteRule ^/smart-redir-limited/(.*)/info/refs$ /smart/$1/info/refs [R=301]
|
||||||
|
RewriteRule ^/ftp-redir/(.*)$ ftp://localhost:1000/$1 [R=302]
|
||||||
|
|
||||||
|
RewriteRule ^/loop-redir/x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-(.*) /$1 [R=302]
|
||||||
|
RewriteRule ^/loop-redir/(.*)$ /loop-redir/x-$1 [R=302]
|
||||||
|
|
||||||
<IfDefine SSL>
|
<IfDefine SSL>
|
||||||
LoadModule ssl_module modules/mod_ssl.so
|
LoadModule ssl_module modules/mod_ssl.so
|
||||||
|
@ -16,5 +16,18 @@ test_expect_success 'create git-accessible repo' '
|
|||||||
|
|
||||||
test_proto "smart http" http "$HTTPD_URL/smart/repo.git"
|
test_proto "smart http" http "$HTTPD_URL/smart/repo.git"
|
||||||
|
|
||||||
|
test_expect_success 'curl redirects respect whitelist' '
|
||||||
|
test_must_fail env GIT_ALLOW_PROTOCOL=http:https \
|
||||||
|
git clone "$HTTPD_URL/ftp-redir/repo.git" 2>stderr &&
|
||||||
|
{
|
||||||
|
test_i18ngrep "ftp.*disabled" stderr ||
|
||||||
|
test_i18ngrep "your curl version is too old"
|
||||||
|
}
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'curl limits redirects' '
|
||||||
|
test_must_fail git clone "$HTTPD_URL/loop-redir/smart/repo.git"
|
||||||
|
'
|
||||||
|
|
||||||
stop_httpd
|
stop_httpd
|
||||||
test_done
|
test_done
|
||||||
|
40
transport.c
40
transport.c
@ -909,18 +909,40 @@ static int external_specification_len(const char *url)
|
|||||||
return strchr(url, ':') - url;
|
return strchr(url, ':') - url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct string_list *protocol_whitelist(void)
|
||||||
|
{
|
||||||
|
static int enabled = -1;
|
||||||
|
static struct string_list allowed = STRING_LIST_INIT_DUP;
|
||||||
|
|
||||||
|
if (enabled < 0) {
|
||||||
|
const char *v = getenv("GIT_ALLOW_PROTOCOL");
|
||||||
|
if (v) {
|
||||||
|
string_list_split(&allowed, v, ':', -1);
|
||||||
|
string_list_sort(&allowed);
|
||||||
|
enabled = 1;
|
||||||
|
} else {
|
||||||
|
enabled = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return enabled ? &allowed : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int is_transport_allowed(const char *type)
|
||||||
|
{
|
||||||
|
const struct string_list *allowed = protocol_whitelist();
|
||||||
|
return !allowed || string_list_has_string(allowed, type);
|
||||||
|
}
|
||||||
|
|
||||||
void transport_check_allowed(const char *type)
|
void transport_check_allowed(const char *type)
|
||||||
{
|
{
|
||||||
struct string_list allowed = STRING_LIST_INIT_DUP;
|
if (!is_transport_allowed(type))
|
||||||
const char *v = getenv("GIT_ALLOW_PROTOCOL");
|
|
||||||
|
|
||||||
if (!v)
|
|
||||||
return;
|
|
||||||
|
|
||||||
string_list_split(&allowed, v, ':', -1);
|
|
||||||
if (!unsorted_string_list_has_string(&allowed, type))
|
|
||||||
die("transport '%s' not allowed", type);
|
die("transport '%s' not allowed", type);
|
||||||
string_list_clear(&allowed, 0);
|
}
|
||||||
|
|
||||||
|
int transport_restrict_protocols(void)
|
||||||
|
{
|
||||||
|
return !!protocol_whitelist();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct transport *transport_get(struct remote *remote, const char *url)
|
struct transport *transport_get(struct remote *remote, const char *url)
|
||||||
|
15
transport.h
15
transport.h
@ -132,13 +132,24 @@ struct transport {
|
|||||||
/* Returns a transport suitable for the url */
|
/* Returns a transport suitable for the url */
|
||||||
struct transport *transport_get(struct remote *, const char *);
|
struct transport *transport_get(struct remote *, const char *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check whether a transport is allowed by the environment. Type should
|
||||||
|
* generally be the URL scheme, as described in Documentation/git.txt
|
||||||
|
*/
|
||||||
|
int is_transport_allowed(const char *type);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check whether a transport is allowed by the environment,
|
* Check whether a transport is allowed by the environment,
|
||||||
* and die otherwise. type should generally be the URL scheme,
|
* and die otherwise.
|
||||||
* as described in Documentation/git.txt
|
|
||||||
*/
|
*/
|
||||||
void transport_check_allowed(const char *type);
|
void transport_check_allowed(const char *type);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns true if the user has attempted to turn on protocol
|
||||||
|
* restrictions at all.
|
||||||
|
*/
|
||||||
|
int transport_restrict_protocols(void);
|
||||||
|
|
||||||
/* Transport options which apply to git:// and scp-style URLs */
|
/* Transport options which apply to git:// and scp-style URLs */
|
||||||
|
|
||||||
/* The program to use on the remote side to send a pack */
|
/* The program to use on the remote side to send a pack */
|
||||||
|
Loading…
Reference in New Issue
Block a user