diff mercurial/wireprotoserver.py @ 36807:c638a13093cf

wireprotoserver: check permissions in main dispatch function The permissions checking code merged from stable is out of place in the refactored hgweb_mod module. This commit moves the main call to wireprotoserver. We still have some lingering code in hgweb_mod. This will get addressed later. Differential Revision: https://phab.mercurial-scm.org/D2717
author Gregory Szorc <gregory.szorc@gmail.com>
date Tue, 06 Mar 2018 15:08:33 -0800
parents 7574c8173d5e
children 0b18604db95e
line wrap: on
line diff
--- a/mercurial/wireprotoserver.py	Tue Mar 06 15:02:53 2018 -0800
+++ b/mercurial/wireprotoserver.py	Tue Mar 06 15:08:33 2018 -0800
@@ -179,7 +179,8 @@
     return {
         'cmd': cmd,
         'proto': proto,
-        'dispatch': lambda: _callhttp(repo, req, proto, cmd),
+        'dispatch': lambda checkperm: _callhttp(repo, req, proto, cmd,
+                                                checkperm),
         'handleerror': lambda ex: _handlehttperror(ex, req, cmd),
     }
 
@@ -223,7 +224,7 @@
     opts = {'level': ui.configint('server', 'zliblevel')}
     return HGTYPE, util.compengines['zlib'], opts
 
-def _callhttp(repo, req, proto, cmd):
+def _callhttp(repo, req, proto, cmd, checkperm):
     def genversion2(gen, engine, engineopts):
         # application/mercurial-0.2 always sends a payload header
         # identifying the compression engine.
@@ -241,6 +242,12 @@
                            'over HTTP'))
         return []
 
+    # 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.
+    checkperm(wireproto.permissions.get(cmd, 'push'))
+
     rsp = wireproto.dispatch(repo, proto, cmd)
 
     if isinstance(rsp, bytes):