diff mercurial/ui.py @ 3537:3b07e223534b

Only read .hg/hgrc files from trusted users/groups The list of trusted users and groups is specified in the [trusted] section of a hgrc; the current user is always trusted; "*" can be used to trust all users/groups. Global hgrc files are always read. On Windows (and other systems that don't have the pwd and grp modules), all .hg/hgrc files are read. This is essentially the same patch that was previously applied as revision 494521a3f142.
author Alexis S. L. Carvalho <alexis@cecm.usp.br>
date Thu, 26 Oct 2006 19:25:44 +0200
parents c3345b0f2fcd
children 9b52239dc740
line wrap: on
line diff
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -39,6 +39,8 @@ class ui(object):
             self.debugflag = debug
             self.interactive = interactive
             self.traceback = traceback
+            self.trusted_users = {}
+            self.trusted_groups = {}
             self.cdata = util.configparser()
             self.readconfig(util.rcpath())
             self.updateopts(verbose, debug, quiet, interactive)
@@ -46,6 +48,8 @@ class ui(object):
             # parentui may point to an ui object which is already a child
             self.parentui = parentui.parentui or parentui
             self.readhooks = self.parentui.readhooks[:]
+            self.trusted_users = parentui.trusted_users.copy()
+            self.trusted_groups = parentui.trusted_groups.copy()
             self.cdata = dupconfig(self.parentui.cdata)
             if self.parentui.overlay:
                 self.overlay = dupconfig(self.parentui.overlay)
@@ -82,12 +86,32 @@ class ui(object):
         elif self.verbose and self.quiet:
             self.quiet = self.verbose = False
 
+    def _is_trusted(self, fp, f, warn=True):
+        tusers = self.trusted_users
+        tgroups = self.trusted_groups
+        if (tusers or tgroups) and '*' not in tusers and '*' not in tgroups:
+            st = util.fstat(fp)
+            user = util.username(st.st_uid)
+            group = util.groupname(st.st_gid)
+            if user not in tusers and group not in tgroups:
+                if warn:
+                    self.warn(_('Not reading file %s from untrusted '
+                                'user %s, group %s\n') % (f, user, group))
+                return False
+        return True
+
     def readconfig(self, fn, root=None):
         if isinstance(fn, basestring):
             fn = [fn]
         for f in fn:
             try:
-                self.cdata.read(f)
+                fp = open(f)
+            except IOError:
+                continue
+            if not self._is_trusted(fp, f):
+                continue
+            try:
+                self.cdata.readfp(fp, f)
             except ConfigParser.ParsingError, inst:
                 raise util.Abort(_("Failed to parse %s\n%s") % (f, inst))
         # override data from config files with data set with ui.setconfig
@@ -144,6 +168,16 @@ class ui(object):
             if name is None or name == 'interactive':
                 self.interactive = self.configbool("ui", "interactive", True)
 
+        # update trust information
+        if section is None or section == 'trusted':
+            user = util.username()
+            if user is not None:
+                self.trusted_users[user] = 1
+                for user in self.configlist('trusted', 'users'):
+                    self.trusted_users[user] = 1
+                for group in self.configlist('trusted', 'groups'):
+                    self.trusted_groups[group] = 1
+
     def setconfig(self, section, name, value):
         if not self.overlay:
             self.overlay = util.configparser()