提交 f2df3104 编写于 作者: J Junio C Hamano

Merge branch 'jk/transfer-limit-redirection' into maint-2.3

...@@ -1071,11 +1071,6 @@ GIT_ICASE_PATHSPECS:: ...@@ -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]]
......
...@@ -8,6 +8,7 @@ ...@@ -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) ...@@ -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) ...@@ -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] ...@@ -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' ' ...@@ -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
...@@ -909,18 +909,40 @@ static int external_specification_len(const char *url) ...@@ -909,18 +909,40 @@ static int external_specification_len(const char *url)
return strchr(url, ':') - url; return strchr(url, ':') - url;
} }
void transport_check_allowed(const char *type) static const struct string_list *protocol_whitelist(void)
{ {
struct string_list allowed = STRING_LIST_INIT_DUP; static int enabled = -1;
const char *v = getenv("GIT_ALLOW_PROTOCOL"); 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;
}
}
if (!v) return enabled ? &allowed : NULL;
return; }
int is_transport_allowed(const char *type)
{
const struct string_list *allowed = protocol_whitelist();
return !allowed || string_list_has_string(allowed, type);
}
string_list_split(&allowed, v, ':', -1); void transport_check_allowed(const char *type)
if (!unsorted_string_list_has_string(&allowed, type)) {
if (!is_transport_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)
......
...@@ -132,13 +132,24 @@ struct transport { ...@@ -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 */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册