comparison mercurial/wireprotoserver.py @ 36799: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
comparison
equal deleted inserted replaced
36798:7574c8173d5e 36799:c638a13093cf
177 proto = httpv1protocolhandler(req, repo.ui) 177 proto = httpv1protocolhandler(req, repo.ui)
178 178
179 return { 179 return {
180 'cmd': cmd, 180 'cmd': cmd,
181 'proto': proto, 181 'proto': proto,
182 'dispatch': lambda: _callhttp(repo, req, proto, cmd), 182 'dispatch': lambda checkperm: _callhttp(repo, req, proto, cmd,
183 checkperm),
183 'handleerror': lambda ex: _handlehttperror(ex, req, cmd), 184 'handleerror': lambda ex: _handlehttperror(ex, req, cmd),
184 } 185 }
185 186
186 def _httpresponsetype(ui, req, prefer_uncompressed): 187 def _httpresponsetype(ui, req, prefer_uncompressed):
187 """Determine the appropriate response type and compression settings. 188 """Determine the appropriate response type and compression settings.
221 # setting a very high compression level could lead to flooding 222 # setting a very high compression level could lead to flooding
222 # the server's network or CPU. 223 # the server's network or CPU.
223 opts = {'level': ui.configint('server', 'zliblevel')} 224 opts = {'level': ui.configint('server', 'zliblevel')}
224 return HGTYPE, util.compengines['zlib'], opts 225 return HGTYPE, util.compengines['zlib'], opts
225 226
226 def _callhttp(repo, req, proto, cmd): 227 def _callhttp(repo, req, proto, cmd, checkperm):
227 def genversion2(gen, engine, engineopts): 228 def genversion2(gen, engine, engineopts):
228 # application/mercurial-0.2 always sends a payload header 229 # application/mercurial-0.2 always sends a payload header
229 # identifying the compression engine. 230 # identifying the compression engine.
230 name = engine.wireprotosupport().name 231 name = engine.wireprotosupport().name
231 assert 0 < len(name) < 256 232 assert 0 < len(name) < 256
238 if not wireproto.commands.commandavailable(cmd, proto): 239 if not wireproto.commands.commandavailable(cmd, proto):
239 req.respond(HTTP_OK, HGERRTYPE, 240 req.respond(HTTP_OK, HGERRTYPE,
240 body=_('requested wire protocol command is not available ' 241 body=_('requested wire protocol command is not available '
241 'over HTTP')) 242 'over HTTP'))
242 return [] 243 return []
244
245 # Assume commands with no defined permissions are writes /
246 # for pushes. This is the safest from a security perspective
247 # because it doesn't allow commands with undefined semantics
248 # from bypassing permissions checks.
249 checkperm(wireproto.permissions.get(cmd, 'push'))
243 250
244 rsp = wireproto.dispatch(repo, proto, cmd) 251 rsp = wireproto.dispatch(repo, proto, cmd)
245 252
246 if isinstance(rsp, bytes): 253 if isinstance(rsp, bytes):
247 req.respond(HTTP_OK, HGTYPE, body=rsp) 254 req.respond(HTTP_OK, HGTYPE, body=rsp)