transport: refactor protocol whitelist code
authorJeff King <peff@peff.net>
Tue, 22 Sep 2015 22:03:49 +0000 (18:03 -0400)
committerJunio C Hamano <gitster@pobox.com>
Fri, 25 Sep 2015 22:28:36 +0000 (15:28 -0700)
The current callers only want to die when their transport is
prohibited. But future callers want to query the mechanism
without dying.

Let's break out a few query functions, and also save the
results in a static list so we don't have to re-parse for
each query.

Based-on-a-patch-by: Blake Burkhart <bburky@bburky.com>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
transport.c
transport.h
index 94fe8658f2bfa7775e667f7c28264c3dbe7f63b7..647d2c2afaadb4f39dd74b182db969eaf0623aa0 100644 (file)
@@ -909,18 +909,40 @@ static int external_specification_len(const char *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;
-       const char *v = getenv("GIT_ALLOW_PROTOCOL");
+       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;
+               }
+       }
 
-       if (!v)
-               return;
+       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);
+}
 
-       string_list_split(&allowed, v, ':', -1);
-       if (!unsorted_string_list_has_string(&allowed, type))
+void transport_check_allowed(const char *type)
+{
+       if (!is_transport_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)
index f7df6ec1d2a1f17e9932e531110cc3fe4bdbb81c..ed84da2aa4f39d8974164ca0ef7f0c10642d4824 100644 (file)
@@ -132,13 +132,24 @@ struct transport {
 /* Returns a transport suitable for the url */
 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,
- * and die otherwise. type should generally be the URL scheme,
- * as described in Documentation/git.txt
+ * and die otherwise.
  */
 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 */
 
 /* The program to use on the remote side to send a pack */