diff mercurial/hgweb/hgweb_mod.py @ 36760:7bf80d9d9543

merge with stable There were a handful of merge conflicts in the wire protocol code due to significant refactoring in default. When resolving the conflicts, I tried to produce the minimal number of changes to make the incoming security patches work with the new code. I will send some follow-up commits to get the security patches better integrated into default.
author Gregory Szorc <gregory.szorc@gmail.com>
date Tue, 06 Mar 2018 14:32:14 -0800
parents 2442927cdd96 2ecb0fc535b1
children c638a13093cf
line wrap: on
line diff
--- a/mercurial/hgweb/hgweb_mod.py	Sun Mar 04 21:16:36 2018 -0500
+++ b/mercurial/hgweb/hgweb_mod.py	Tue Mar 06 14:32:14 2018 -0800
@@ -37,6 +37,7 @@
     templater,
     ui as uimod,
     util,
+    wireproto,
     wireprotoserver,
 )
 
@@ -46,15 +47,8 @@
     wsgicgi,
 )
 
-perms = {
-    'changegroup': 'pull',
-    'changegroupsubset': 'pull',
-    'getbundle': 'pull',
-    'stream_out': 'pull',
-    'listkeys': 'pull',
-    'unbundle': 'push',
-    'pushkey': 'push',
-}
+# Aliased for API compatibility.
+perms = wireproto.permissions
 
 archivespecs = util.sortdict((
     ('zip', ('application/zip', 'zip', '.zip', None)),
@@ -367,13 +361,21 @@
             try:
                 if query:
                     raise ErrorResponse(HTTP_NOT_FOUND)
-                if cmd in perms:
-                    self.check_perm(rctx, req, perms[cmd])
+
+                # TODO fold this into parsehttprequest
+                req.checkperm = lambda op: self.check_perm(rctx, req, op)
+                protohandler['proto'].checkperm = req.checkperm
+
+                # Assume commands with no defined permissions are writes /
+                # for pushes. This is the safest from a security perspective
+                # because it doesn't allow commands with undefined semantics
+                # from bypassing permissions checks.
+                req.checkperm(perms.get(cmd, 'push'))
+
+                return protohandler['dispatch']()
             except ErrorResponse as inst:
                 return protohandler['handleerror'](inst)
 
-            return protohandler['dispatch']()
-
         # translate user-visible url structure to internal structure
 
         args = query.split('/', 2)