Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(107)

Unified Diff: gclient.py

Issue 562953002: Rough verification code to ensure deps hosts \in allowed_hosts. (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Fixed docs + iannucci suggestions. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tests/gclient_test.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gclient.py
diff --git a/gclient.py b/gclient.py
index 3007487a5930d0f09aeac1260defe3be12bd4360..bbe6d582b8aaa12e412e8ce3a9eb51288739e0dc 100755
--- a/gclient.py
+++ b/gclient.py
@@ -342,6 +342,11 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
# A cache of the files affected by the current operation, necessary for
# hooks.
self._file_list = []
+ # List of host names from which dependencies are allowed.
+ # Default is an empty set, meaning unspecified in DEPS file, and hence all
+ # hosts will be allowed. Non-empty set means whitelist of hosts.
+ # allowed_hosts var is scoped to its DEPS file, and so it isn't recursive.
+ self._allowed_hosts = frozenset()
# If it is not set to True, the dependency wasn't processed for its child
# dependency, i.e. its DEPS wasn't read.
self._deps_parsed = False
@@ -687,6 +692,18 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
rel_deps.add(os.path.normpath(os.path.join(self.name, d)))
self.recursedeps = rel_deps
+ if 'allowed_hosts' in local_scope:
+ try:
+ self._allowed_hosts = frozenset(local_scope.get('allowed_hosts'))
+ except TypeError: # raised if non-iterable
+ pass
+ if not self._allowed_hosts:
+ logging.warning("allowed_hosts is specified but empty %s",
+ self._allowed_hosts)
+ raise gclient_utils.Error(
+ 'ParseDepsFile(%s): allowed_hosts must be absent '
+ 'or a non-empty iterable' % self.name)
+
# Convert the deps into real Dependency.
deps_to_add = []
for name, url in deps.iteritems():
@@ -756,6 +773,21 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
print('Using parent\'s revision date %s since we are in a '
'different repository.' % options.revision)
+ def findDepsFromNotAllowedHosts(self):
+ """Returns a list of depenecies from not allowed hosts.
+
+ If allowed_hosts is not set, allows all hosts and returns empty list.
+ """
+ if not self._allowed_hosts:
+ return []
+ bad_deps = []
+ for dep in self._dependencies:
+ if isinstance(dep.url, basestring):
+ parsed_url = urlparse.urlparse(dep.url)
+ if parsed_url.netloc and parsed_url.netloc not in self._allowed_hosts:
+ bad_deps.append(dep)
+ return bad_deps
+
# Arguments number differs from overridden method
# pylint: disable=W0221
def run(self, revision_overrides, command, args, work_queue, options):
@@ -1053,6 +1085,11 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
@property
@gclient_utils.lockedmethod
+ def allowed_hosts(self):
+ return self._allowed_hosts
+
+ @property
+ @gclient_utils.lockedmethod
def file_list(self):
return tuple(self._file_list)
@@ -1077,7 +1114,8 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
out = []
for i in ('name', 'url', 'parsed_url', 'safesync_url', 'custom_deps',
'custom_vars', 'deps_hooks', 'file_list', 'should_process',
- 'processed', 'hooks_ran', 'deps_parsed', 'requirements'):
+ 'processed', 'hooks_ran', 'deps_parsed', 'requirements',
+ 'allowed_hosts'):
# First try the native property if it exists.
if hasattr(self, '_' + i):
value = getattr(self, '_' + i, False)
@@ -2086,6 +2124,27 @@ def CMDhookinfo(parser, args):
return 0
+def CMDverify(parser, args):
+ """Verifies the DEPS file deps are only from allowed_hosts."""
+ (options, args) = parser.parse_args(args)
+ client = GClient.LoadCurrentConfig(options)
+ if not client:
+ raise gclient_utils.Error('client not configured; see \'gclient config\'')
+ client.RunOnDeps(None, [])
+ # Look at each first-level dependency of this gclient only.
+ for dep in client.dependencies:
+ bad_deps = dep.findDepsFromNotAllowedHosts()
+ if not bad_deps:
+ continue
+ print "There are deps from not allowed hosts in file %s" % dep.deps_file
+ for bad_dep in bad_deps:
+ print "\t%s at %s" % (bad_dep.name, bad_dep.url)
+ print "allowed_hosts:", ', '.join(dep.allowed_hosts)
+ sys.stdout.flush()
+ raise gclient_utils.Error(
+ 'dependencies from disallowed hosts; check your DEPS file.')
+ return 0
+
class OptionParser(optparse.OptionParser):
gclientfile_default = os.environ.get('GCLIENT_FILE', '.gclient')
« no previous file with comments | « no previous file | tests/gclient_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698