|
|
e2bedf |
diff --git a/contrib/hg-ssh b/contrib/hg-ssh
|
|
|
e2bedf |
index 5ec5100..c643f97 100755
|
|
|
e2bedf |
--- a/contrib/hg-ssh
|
|
|
e2bedf |
+++ b/contrib/hg-ssh
|
|
|
e2bedf |
@@ -32,7 +32,7 @@ command="hg-ssh --read-only repos/*"
|
|
|
e2bedf |
# enable importing on demand to reduce startup time
|
|
|
e2bedf |
from mercurial import demandimport; demandimport.enable()
|
|
|
e2bedf |
|
|
|
e2bedf |
-from mercurial import dispatch
|
|
|
e2bedf |
+from mercurial import dispatch, ui as uimod
|
|
|
e2bedf |
|
|
|
e2bedf |
import sys, os, shlex
|
|
|
e2bedf |
|
|
|
e2bedf |
@@ -61,14 +61,15 @@ def main():
|
|
|
e2bedf |
repo = os.path.normpath(os.path.join(cwd, os.path.expanduser(path)))
|
|
|
e2bedf |
if repo in allowed_paths:
|
|
|
e2bedf |
cmd = ['-R', repo, 'serve', '--stdio']
|
|
|
e2bedf |
+ req = dispatch.request(cmd)
|
|
|
e2bedf |
if readonly:
|
|
|
e2bedf |
- cmd += [
|
|
|
e2bedf |
- '--config',
|
|
|
e2bedf |
- 'hooks.prechangegroup.hg-ssh=python:__main__.rejectpush',
|
|
|
e2bedf |
- '--config',
|
|
|
e2bedf |
- 'hooks.prepushkey.hg-ssh=python:__main__.rejectpush'
|
|
|
e2bedf |
- ]
|
|
|
e2bedf |
- dispatch.dispatch(dispatch.request(cmd))
|
|
|
e2bedf |
+ if not req.ui:
|
|
|
e2bedf |
+ req.ui = uimod.ui()
|
|
|
e2bedf |
+ req.ui.setconfig('hooks', 'pretxnopen.hg-ssh',
|
|
|
e2bedf |
+ 'python:__main__.rejectpush', 'hg-ssh')
|
|
|
e2bedf |
+ req.ui.setconfig('hooks', 'prepushkey.hg-ssh',
|
|
|
e2bedf |
+ 'python:__main__.rejectpush', 'hg-ssh')
|
|
|
e2bedf |
+ dispatch.dispatch(req)
|
|
|
e2bedf |
else:
|
|
|
e2bedf |
sys.stderr.write('Illegal repository "%s"\n' % repo)
|
|
|
e2bedf |
sys.exit(255)
|
|
|
e2bedf |
diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
|
|
|
e2bedf |
index fa2532d..99e1d5b 100644
|
|
|
e2bedf |
--- a/mercurial/dispatch.py
|
|
|
e2bedf |
+++ b/mercurial/dispatch.py
|
|
|
e2bedf |
@@ -87,6 +87,36 @@ def _runcatch(req):
|
|
|
e2bedf |
pass # happens if called in a thread
|
|
|
e2bedf |
|
|
|
e2bedf |
try:
|
|
|
e2bedf |
+ realcmd = None
|
|
|
e2bedf |
+ try:
|
|
|
e2bedf |
+ cmdargs = fancyopts.fancyopts(req.args[:], commands.globalopts, {})
|
|
|
e2bedf |
+ cmd = cmdargs[0]
|
|
|
e2bedf |
+ aliases, entry = cmdutil.findcmd(cmd, commands.table, False)
|
|
|
e2bedf |
+ realcmd = aliases[0]
|
|
|
e2bedf |
+ except (error.UnknownCommand, error.AmbiguousCommand,
|
|
|
e2bedf |
+ IndexError, fancyopts.getopt.GetoptError):
|
|
|
e2bedf |
+ # Don't handle this here. We know the command is
|
|
|
e2bedf |
+ # invalid, but all we're worried about for now is that
|
|
|
e2bedf |
+ # it's not a command that server operators expect to
|
|
|
e2bedf |
+ # be safe to offer to users in a sandbox.
|
|
|
e2bedf |
+ pass
|
|
|
e2bedf |
+ if realcmd == 'serve' and '--stdio' in cmdargs:
|
|
|
e2bedf |
+ # We want to constrain 'hg serve --stdio' instances pretty
|
|
|
e2bedf |
+ # closely, as many shared-ssh access tools want to grant
|
|
|
e2bedf |
+ # access to run *only* 'hg -R $repo serve --stdio'. We
|
|
|
e2bedf |
+ # restrict to exactly that set of arguments, and prohibit
|
|
|
e2bedf |
+ # any repo name that starts with '--' to prevent
|
|
|
e2bedf |
+ # shenanigans wherein a user does something like pass
|
|
|
e2bedf |
+ # --debugger or --config=ui.debugger=1 as a repo
|
|
|
e2bedf |
+ # name. This used to actually run the debugger.
|
|
|
e2bedf |
+ if (len(req.args) != 4 or
|
|
|
e2bedf |
+ req.args[0] != '-R' or
|
|
|
e2bedf |
+ req.args[1].startswith('--') or
|
|
|
e2bedf |
+ req.args[2] != 'serve' or
|
|
|
e2bedf |
+ req.args[3] != '--stdio'):
|
|
|
e2bedf |
+ raise error.Abort(
|
|
|
e2bedf |
+ _('potentially unsafe serve --stdio invocation: %r') %
|
|
|
e2bedf |
+ (req.args,))
|
|
|
e2bedf |
try:
|
|
|
e2bedf |
# enter the debugger before command execution
|
|
|
e2bedf |
if '--debugger' in req.args:
|
|
|
e2bedf |
diff --git a/tests/test-hup.t b/tests/test-hup.t
|
|
|
e2bedf |
deleted file mode 100644
|
|
|
e2bedf |
index 9745643..0000000
|
|
|
e2bedf |
--- a/tests/test-hup.t
|
|
|
e2bedf |
+++ /dev/null
|
|
|
e2bedf |
@@ -1,28 +0,0 @@
|
|
|
e2bedf |
-Test hangup signal in the middle of transaction
|
|
|
e2bedf |
-
|
|
|
e2bedf |
- $ "$TESTDIR/hghave" serve fifo || exit 80
|
|
|
e2bedf |
- $ hg init
|
|
|
e2bedf |
- $ mkfifo p
|
|
|
e2bedf |
- $ hg serve --stdio < p 1>out 2>&1 &
|
|
|
e2bedf |
- $ P=$!
|
|
|
e2bedf |
-
|
|
|
e2bedf |
-Do test while holding fifo open
|
|
|
e2bedf |
-
|
|
|
e2bedf |
- $ (
|
|
|
e2bedf |
- > echo lock
|
|
|
e2bedf |
- > echo addchangegroup
|
|
|
e2bedf |
- > while [ ! -s .hg/store/journal ]; do sleep 0; done
|
|
|
e2bedf |
- > kill -HUP $P
|
|
|
e2bedf |
- > ) > p
|
|
|
e2bedf |
-
|
|
|
e2bedf |
- $ wait
|
|
|
e2bedf |
- $ cat out
|
|
|
e2bedf |
- 0
|
|
|
e2bedf |
- 0
|
|
|
e2bedf |
- adding changesets
|
|
|
e2bedf |
- transaction abort!
|
|
|
e2bedf |
- rollback completed
|
|
|
e2bedf |
- killed!
|
|
|
e2bedf |
-
|
|
|
e2bedf |
- $ echo .hg/* .hg/store/*
|
|
|
e2bedf |
- .hg/00changelog.i .hg/journal.bookmarks .hg/journal.branch .hg/journal.desc .hg/journal.dirstate .hg/requires .hg/store .hg/store/00changelog.i .hg/store/00changelog.i.a .hg/store/journal.phaseroots
|
|
|
e2bedf |
diff --git a/tests/test-ssh.t b/tests/test-ssh.t
|
|
|
e2bedf |
index f1584af..ad60b0e 100644
|
|
|
e2bedf |
--- a/tests/test-ssh.t
|
|
|
e2bedf |
+++ b/tests/test-ssh.t
|
|
|
e2bedf |
@@ -291,6 +291,19 @@ Test (non-)escaping of remote paths with spaces when cloning (issue3145):
|
|
|
e2bedf |
abort: destination 'a repo' is not empty
|
|
|
e2bedf |
[255]
|
|
|
e2bedf |
|
|
|
e2bedf |
+Make sure hg is really paranoid in serve --stdio mode. It used to be
|
|
|
e2bedf |
+possible to get a debugger REPL by specifying a repo named --debugger.
|
|
|
e2bedf |
+ $ hg -R --debugger serve --stdio
|
|
|
e2bedf |
+ abort: potentially unsafe serve --stdio invocation: ['-R', '--debugger', 'serve', '--stdio']
|
|
|
e2bedf |
+ [255]
|
|
|
e2bedf |
+ $ hg -R --config=ui.debugger=yes serve --stdio
|
|
|
e2bedf |
+ abort: potentially unsafe serve --stdio invocation: ['-R', '--config=ui.debugger=yes', 'serve', '--stdio']
|
|
|
e2bedf |
+ [255]
|
|
|
e2bedf |
+Abbreviations of 'serve' also don't work, to avoid shenanigans.
|
|
|
e2bedf |
+ $ hg -R narf serv --stdio
|
|
|
e2bedf |
+ abort: potentially unsafe serve --stdio invocation: ['-R', 'narf', 'serv', '--stdio']
|
|
|
e2bedf |
+ [255]
|
|
|
e2bedf |
+
|
|
|
e2bedf |
Test hg-ssh using a helper script that will restore PYTHONPATH (which might
|
|
|
e2bedf |
have been cleared by a hg.exe wrapper) and invoke hg-ssh with the right
|
|
|
e2bedf |
parameters:
|
|
|
e2bedf |
@@ -382,3 +395,4 @@ Test hg-ssh in read-only mode:
|
|
|
e2bedf |
Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
|
|
|
e2bedf |
Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
|
|
|
e2bedf |
Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
|
|
|
e2bedf |
+ changegroup-in-remote hook: HG_NODE=f9f0a8007dba27625503c51182b535f85fd4bb6b HG_SOURCE=serve HG_URL=remote:ssh:
|