Show More
@@ -357,22 +357,15 b' class hgweb(object):' | |||||
357 | protohandler = wireprotoserver.parsehttprequest(rctx.repo, req, query) |
|
357 | protohandler = wireprotoserver.parsehttprequest(rctx.repo, req, query) | |
358 |
|
358 | |||
359 | if protohandler: |
|
359 | if protohandler: | |
360 | cmd = protohandler['cmd'] |
|
|||
361 | try: |
|
360 | try: | |
362 | if query: |
|
361 | if query: | |
363 | raise ErrorResponse(HTTP_NOT_FOUND) |
|
362 | raise ErrorResponse(HTTP_NOT_FOUND) | |
364 |
|
363 | |||
365 | # TODO fold this into parsehttprequest |
|
364 | # TODO fold this into parsehttprequest | |
366 |
|
|
365 | checkperm = lambda op: self.check_perm(rctx, req, op) | |
367 |
protohandler['proto'].checkperm = |
|
366 | protohandler['proto'].checkperm = checkperm | |
368 |
|
367 | |||
369 | # Assume commands with no defined permissions are writes / |
|
368 | return protohandler['dispatch'](checkperm) | |
370 | # for pushes. This is the safest from a security perspective |
|
|||
371 | # because it doesn't allow commands with undefined semantics |
|
|||
372 | # from bypassing permissions checks. |
|
|||
373 | req.checkperm(perms.get(cmd, 'push')) |
|
|||
374 |
|
||||
375 | return protohandler['dispatch']() |
|
|||
376 | except ErrorResponse as inst: |
|
369 | except ErrorResponse as inst: | |
377 | return protohandler['handleerror'](inst) |
|
370 | return protohandler['handleerror'](inst) | |
378 |
|
371 |
@@ -179,7 +179,8 b' def parsehttprequest(repo, req, query):' | |||||
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 | |||
@@ -223,7 +224,7 b' def _httpresponsetype(ui, req, prefer_un' | |||||
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. | |
@@ -241,6 +242,12 b' def _callhttp(repo, req, proto, cmd):' | |||||
241 | 'over HTTP')) |
|
242 | 'over HTTP')) | |
242 | return [] |
|
243 | return [] | |
243 |
|
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')) | |||
|
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): |
General Comments 0
You need to be logged in to leave comments.
Login now