changeset 34989:1a314176da9c stable

subrepo: use per-type config options to enable subrepos We change subrepos.allowed from a list of allowed subrepo types to a combination of a master switch and per-type boolean flag. If the master switch is set, subrepos can be disabled wholesale. If subrepos are globally enabled, then per-type options are consulted. Mercurial repos are enabled by default. Everything else is disabled by default.
author Gregory Szorc <gregory.szorc@gmail.com>
date Mon, 06 Nov 2017 22:32:41 -0800
parents bd725a71f274
children cabc840ffdee
files mercurial/configitems.py mercurial/help/config.txt mercurial/subrepo.py tests/test-convert-git.t tests/test-mq-subrepo-svn.t tests/test-subrepo-git.t tests/test-subrepo-svn.t tests/test-subrepo.t
diffstat 8 files changed, 88 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/configitems.py	Mon Nov 06 14:56:17 2017 -0500
+++ b/mercurial/configitems.py	Mon Nov 06 22:32:41 2017 -0800
@@ -814,6 +814,15 @@
 coreconfigitem('subrepos', 'allowed',
     default=dynamicdefault,  # to make backporting simpler
 )
+coreconfigitem('subrepos', 'hg:allowed',
+    default=dynamicdefault,
+)
+coreconfigitem('subrepos', 'git:allowed',
+    default=dynamicdefault,
+)
+coreconfigitem('subrepos', 'svn:allowed',
+    default=dynamicdefault,
+)
 coreconfigitem('templates', '.*',
     default=None,
     generic=True,
--- a/mercurial/help/config.txt	Mon Nov 06 14:56:17 2017 -0500
+++ b/mercurial/help/config.txt	Mon Nov 06 22:32:41 2017 -0800
@@ -1899,20 +1899,40 @@
 This section contains options that control the behavior of the
 subrepositories feature. See also :hg:`help subrepos`.
 
+Security note: auditing in Mercurial is known to be insufficient to
+prevent clone-time code execution with carefully constructed Git
+subrepos. It is unknown if a similar detect is present in Subversion
+subrepos. Both Git and Subversion subrepos are disabled by default
+out of security concerns. These subrepo types can be enabled using
+the respective options below.
+
 ``allowed``
-    List of subrepository types (hg, git, svn) allowed in the working
-    directory.
-
-    When disallowed, any commands including :hg:`update` will fail if
-    subrepositories are involved.
-
-    Security note: auditing in Mercurial is known to be insufficient
-    to prevent clone-time code execution with carefully constructed
-    Git subrepos. It is unknown if a similar defect is present in
-    Subversion subrepos, so both are disabled by default out of an
-    abundance of caution. Re-enable such subrepos via this setting
-    with caution.
-    (default: `hg`)
+    Whether subrepositories are allowed in the working directory.
+
+    When false, commands involving subrepositories (like :hg:`update`)
+    will fail for all subrepository types.
+    (default: true)
+
+``hg:allowed``
+    Whether Mercurial subrepositories are allowed in the working
+    directory. This option only has an effect if ``subrepos.allowed``
+    is true.
+    (default: true)
+
+``git:allowed``
+    Whether Git subrepositories are allowed in the working directory.
+    This option only has an effect if ``subrepos.allowed`` is true.
+
+    See the security note above before enabling Git subrepos.
+    (default: false)
+
+``svn:allowed``
+    Whether Subversion subrepositories are allowed in the working
+    directory. This option only has an effect if ``subrepos.allowed``
+    is true.
+
+    See the security note above before enabling Subversion subrepos.
+    (default: false)
 
 ``templatealias``
 -----------------
--- a/mercurial/subrepo.py	Mon Nov 06 14:56:17 2017 -0500
+++ b/mercurial/subrepo.py	Mon Nov 06 22:32:41 2017 -0800
@@ -365,10 +365,24 @@
     if repo.wvfs.islink(path):
         raise error.Abort(_("subrepo '%s' traverses symbolic link") % path)
 
+SUBREPO_ALLOWED_DEFAULTS = {
+    'hg': True,
+    'git': False,
+    'svn': False,
+}
+
 def _checktype(ui, kind):
-    if kind not in ui.configlist('subrepos', 'allowed', ['hg']):
-        raise error.Abort(_("subrepo type %s not allowed") % kind,
+    # subrepos.allowed is a master kill switch. If disabled, subrepos are
+    # disabled period.
+    if not ui.configbool('subrepos', 'allowed', True):
+        raise error.Abort(_('subrepos not enabled'),
                           hint=_("see 'hg help config.subrepos' for details"))
+
+    default = SUBREPO_ALLOWED_DEFAULTS.get(kind, False)
+    if not ui.configbool('subrepos', '%s:allowed' % kind, default):
+        raise error.Abort(_('%s subrepos not allowed') % kind,
+                          hint=_("see 'hg help config.subrepos' for details"))
+
     if kind not in types:
         raise error.Abort(_('unknown subrepo type %s') % kind)
 
--- a/tests/test-convert-git.t	Mon Nov 06 14:56:17 2017 -0500
+++ b/tests/test-convert-git.t	Mon Nov 06 22:32:41 2017 -0800
@@ -8,7 +8,7 @@
   $ echo "convert=" >> $HGRCPATH
   $ cat >> $HGRCPATH <<EOF
   > [subrepos]
-  > allowed = hg, git
+  > git:allowed = true
   > EOF
   $ GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
   $ GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
--- a/tests/test-mq-subrepo-svn.t	Mon Nov 06 14:56:17 2017 -0500
+++ b/tests/test-mq-subrepo-svn.t	Mon Nov 06 22:32:41 2017 -0800
@@ -6,7 +6,8 @@
   > [diff]
   > nodates = 1
   > [subrepos]
-  > allowed = hg, svn
+  > allowed = true
+  > svn:allowed = true
   > EOF
 
 fn to create new repository, and cd into it
--- a/tests/test-subrepo-git.t	Mon Nov 06 14:56:17 2017 -0500
+++ b/tests/test-subrepo-git.t	Mon Nov 06 22:32:41 2017 -0800
@@ -45,7 +45,7 @@
 git subrepo is disabled by default
 
   $ hg commit -m 'new git subrepo'
-  abort: subrepo type git not allowed
+  abort: git subrepos not allowed
   (see 'hg help config.subrepos' for details)
   [255]
 
@@ -53,7 +53,7 @@
 
   $ cat >> $HGRCPATH <<EOF
   > [subrepos]
-  > allowed = hg, git
+  > git:allowed = true
   > EOF
 
   $ hg commit -m 'new git subrepo'
@@ -106,30 +106,22 @@
 
 clone with subrepo disabled (update should fail)
 
-  $ hg clone t -U tc2 --config subrepos.allowed=
-  $ hg update -R tc2 --config subrepos.allowed=
-  abort: subrepo type git not allowed
+  $ hg clone t -U tc2 --config subrepos.allowed=false
+  $ hg update -R tc2 --config subrepos.allowed=false
+  abort: subrepos not enabled
   (see 'hg help config.subrepos' for details)
   [255]
   $ ls tc2
   a
 
-  $ hg clone t tc3 --config subrepos.allowed=
+  $ hg clone t tc3 --config subrepos.allowed=false
   updating to branch default
-  abort: subrepo type git not allowed
+  abort: subrepos not enabled
   (see 'hg help config.subrepos' for details)
   [255]
   $ ls tc3
   a
 
-  $ hg clone t tc4 --config subrepos.allowed=hg
-  updating to branch default
-  abort: subrepo type git not allowed
-  (see 'hg help config.subrepos' for details)
-  [255]
-  $ ls tc4
-  a
-
 update to previous substate
 
   $ cd tc
--- a/tests/test-subrepo-svn.t	Mon Nov 06 14:56:17 2017 -0500
+++ b/tests/test-subrepo-svn.t	Mon Nov 06 22:32:41 2017 -0800
@@ -61,7 +61,7 @@
 svn subrepo is disabled by default
 
   $ hg ci -m1
-  abort: subrepo type svn not allowed
+  abort: svn subrepos not allowed
   (see 'hg help config.subrepos' for details)
   [255]
 
@@ -69,7 +69,7 @@
 
   $ cat >> $HGRCPATH <<EOF
   > [subrepos]
-  > allowed = hg, svn
+  > svn:allowed = true
   > EOF
 
   $ hg ci -m1
--- a/tests/test-subrepo.t	Mon Nov 06 14:56:17 2017 -0500
+++ b/tests/test-subrepo.t	Mon Nov 06 22:32:41 2017 -0800
@@ -488,30 +488,40 @@
 
 clone with subrepo disabled (update should fail)
 
-  $ hg clone t -U tc2 --config subrepos.allowed=
-  $ hg update -R tc2 --config subrepos.allowed=
-  abort: subrepo type hg not allowed
+  $ hg clone t -U tc2 --config subrepos.allowed=false
+  $ hg update -R tc2 --config subrepos.allowed=false
+  abort: subrepos not enabled
   (see 'hg help config.subrepos' for details)
   [255]
   $ ls tc2
   a
 
-  $ hg clone t tc3 --config subrepos.allowed=
+  $ hg clone t tc3 --config subrepos.allowed=false
   updating to branch default
-  abort: subrepo type hg not allowed
+  abort: subrepos not enabled
   (see 'hg help config.subrepos' for details)
   [255]
   $ ls tc3
   a
 
-  $ hg clone t tc4 --config subrepos.allowed=git
-  updating to branch default
-  abort: subrepo type hg not allowed
+And again with just the hg type disabled
+
+  $ hg clone t -U tc4 --config subrepos.hg:allowed=false
+  $ hg update -R tc4 --config subrepos.hg:allowed=false
+  abort: hg subrepos not allowed
   (see 'hg help config.subrepos' for details)
   [255]
   $ ls tc4
   a
 
+  $ hg clone t tc5 --config subrepos.hg:allowed=false
+  updating to branch default
+  abort: hg subrepos not allowed
+  (see 'hg help config.subrepos' for details)
+  [255]
+  $ ls tc5
+  a
+
 push
 
   $ cd tc