transport: add from_user parameter to is_transport_allowed
Add a from_user parameter to is_transport_allowed() to allow http to be able to distinguish between protocol restrictions for redirects versus initial requests. CURLOPT_REDIR_PROTOCOLS can now be set differently from CURLOPT_PROTOCOLS to disallow use of protocols with the "user" policy in redirects. This change allows callers to query if a transport protocol is allowed, given that the caller knows that the protocol is coming from the user (1) or not from the user (0) such as redirects in libcurl. If unknown a -1 should be provided which falls back to reading `GIT_PROTOCOL_FROM_USER` to determine if the protocol came from the user. Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Brandon Williams committed
Dec 14, 2016 at 14:39 UTC
a768a02265f3b8f43e37f66a0a3affba92c830c7
4 files changed
+29
-13
http.c
+7
-7
@@ -489,17 +489,17 @@ static void set_curl_keepalive(CURL *c)
489
}
490
#endif
491
492
-static long get_curl_allowed_protocols(void)
492
+static long get_curl_allowed_protocols(int from_user)
493
{
494
long allowed_protocols = 0;
495
496
- if (is_transport_allowed("http"))
496
+ if (is_transport_allowed("http", from_user))
497
allowed_protocols |= CURLPROTO_HTTP;
498
- if (is_transport_allowed("https"))
498
+ if (is_transport_allowed("https", from_user))
499
allowed_protocols |= CURLPROTO_HTTPS;
500
- if (is_transport_allowed("ftp"))
500
+ if (is_transport_allowed("ftp", from_user))
501
allowed_protocols |= CURLPROTO_FTP;
502
- if (is_transport_allowed("ftps"))
502
+ if (is_transport_allowed("ftps", from_user))
503
allowed_protocols |= CURLPROTO_FTPS;
504
505
return allowed_protocols;
@@ -588,9 +588,9 @@ static CURL *get_curl_handle(void)
588
#endif
589
#if LIBCURL_VERSION_NUM >= 0x071304
590
curl_easy_setopt(result, CURLOPT_REDIR_PROTOCOLS,
591
- get_curl_allowed_protocols());
591
+ get_curl_allowed_protocols(0));
592
curl_easy_setopt(result, CURLOPT_PROTOCOLS,
593
- get_curl_allowed_protocols());
593
+ get_curl_allowed_protocols(-1));
594
#else
595
warning("protocol restrictions not applied to curl redirects because\n"
596
"your curl version is too old (>= 7.19.4)");
t/t5812-proto-disable-http.sh
+7
@@ -30,5 +30,12 @@ test_expect_success 'curl limits redirects' '
30
test_must_fail git clone "$HTTPD_URL/loop-redir/smart/repo.git"
31
'
32
33
+test_expect_success 'http can be limited to from-user' '
34
+ git -c protocol.http.allow=user \
35
+ clone "$HTTPD_URL/smart/repo.git" plain.git &&
36
+ test_must_fail git -c protocol.http.allow=user \
37
+ clone "$HTTPD_URL/smart-redir-perm/repo.git" redir.git
38
+'
39
+
40
stop_httpd
41
test_done
transport.c
+5
-3
@@ -676,7 +676,7 @@ static enum protocol_allow_config get_protocol_config(const char *type)
676
return PROTOCOL_ALLOW_USER_ONLY;
677
}
678
679
-int is_transport_allowed(const char *type)
679
+int is_transport_allowed(const char *type, int from_user)
680
{
681
const struct string_list *whitelist = protocol_whitelist();
682
if (whitelist)
@@ -688,7 +688,9 @@ int is_transport_allowed(const char *type)
688
case PROTOCOL_ALLOW_NEVER:
689
return 0;
690
case PROTOCOL_ALLOW_USER_ONLY:
691
- return git_env_bool("GIT_PROTOCOL_FROM_USER", 1);
691
+ if (from_user < 0)
692
+ from_user = git_env_bool("GIT_PROTOCOL_FROM_USER", 1);
693
+ return from_user;
694
}
695
696
die("BUG: invalid protocol_allow_config type");
@@ -696,7 +698,7 @@ int is_transport_allowed(const char *type)
698
699
void transport_check_allowed(const char *type)
700
{
699
- if (!is_transport_allowed(type))
701
+ if (!is_transport_allowed(type, -1))
702
die("transport '%s' not allowed", type);
703
}
704
transport.h
+10
-3
@@ -142,10 +142,17 @@ struct transport {
142
struct transport *transport_get(struct remote *, const char *);
143
144
/*
145
- * Check whether a transport is allowed by the environment. Type should
146
- * generally be the URL scheme, as described in Documentation/git.txt
145
+ * Check whether a transport is allowed by the environment.
146
+ *
147
+ * Type should generally be the URL scheme, as described in
148
+ * Documentation/git.txt
149
+ *
150
+ * from_user specifies if the transport was given by the user. If unknown pass
151
+ * a -1 to read from the environment to determine if the transport was given by
152
+ * the user.
153
+ *
154
*/
148
-int is_transport_allowed(const char *type);
155
+int is_transport_allowed(const char *type, int from_user);
156
157
/*
158
* Check whether a transport is allowed by the environment,