##// END OF EJS Templates
dispatch: protect against malicious 'hg serve --stdio' invocations (sec)...
dispatch: protect against malicious 'hg serve --stdio' invocations (sec) Some shared-ssh installations assume that 'hg serve --stdio' is a safe command to run for minimally trusted users. Unfortunately, the messy implementation of argument parsing here meant that trying to access a repo named '--debugger' would give the user a pdb prompt, thereby sidestepping any hoped-for sandboxing. Serving repositories over HTTP(S) is unaffected. We're not currently hardening any subcommands other than 'serve'. If your service exposes other commands to users with arbitrary repository names, it is imperative that you defend against repository names of '--debugger' and anything starting with '--config'. The read-only mode of hg-ssh stopped working because it provided its hook configuration to "hg serve --stdio" via --config parameter. This is banned for security reasons now. This patch switches it to directly call ui.setconfig(). If your custom hosting infrastructure relies on passing --config to "hg serve --stdio", you'll need to find a different way to get that configuration into Mercurial, either by using ui.setconfig() as hg-ssh does in this patch, or by placing an hgrc file someplace where Mercurial will read it. mitrandir@fb.com provided some extra fixes for the dispatch code and for hg-ssh in places that I overlooked.

File last commit:

r31890:ca7af5d1 default
r32050:77eaf953 4.1.3 stable
Show More
test-chg.t
132 lines | 3.1 KiB | text/troff | Tads3Lexer
Yuya Nishihara
test-chg: run only with chg...
r29274 #require chg
Yuya Nishihara
test-chg: add basic tests for server lifecycle...
r29275 $ cp $HGRCPATH $HGRCPATH.orig
Jun Wu
chgserver: handle ParseError during validate...
r28516 init repo
Yuya Nishihara
test-chg: run only with chg...
r29274 $ chg init foo
Jun Wu
chgserver: handle ParseError during validate...
r28516 $ cd foo
ill-formed config
Yuya Nishihara
test-chg: run only with chg...
r29274 $ chg status
Jun Wu
chgserver: handle ParseError during validate...
r28516 $ echo '=brokenconfig' >> $HGRCPATH
Yuya Nishihara
test-chg: run only with chg...
r29274 $ chg status
Jun Wu
chgserver: handle ParseError during validate...
r28516 hg: parse error at * (glob)
[255]
Jun Wu
chgserver: remove _clearenvaliases...
r29088
Yuya Nishihara
test-chg: add basic tests for server lifecycle...
r29275 $ cp $HGRCPATH.orig $HGRCPATH
Jun Wu
chg: support long socket path...
r30677
long socket path
$ sockpath=$TESTTMP/this/path/should/be/longer/than/one-hundred-and-seven/characters/where/107/is/the/typical/size/limit/of/unix-domain-socket
$ mkdir -p $sockpath
$ bakchgsockname=$CHGSOCKNAME
$ CHGSOCKNAME=$sockpath/server
$ export CHGSOCKNAME
$ chg root
$TESTTMP/foo
$ rm -rf $sockpath
$ CHGSOCKNAME=$bakchgsockname
$ export CHGSOCKNAME
Yuya Nishihara
test-chg: add basic tests for server lifecycle...
r29275 $ cd ..
Yuya Nishihara
pager: wrap _runcommand() no matter if stdout is redirected...
r30847 pager
-----
$ cat >> fakepager.py <<EOF
> import sys
> for line in sys.stdin:
> sys.stdout.write('paged! %r\n' % line)
> EOF
enable pager extension globally, but spawns the master server with no tty:
$ chg init pager
$ cd pager
$ cat >> $HGRCPATH <<EOF
> [extensions]
> pager =
> [pager]
> pager = python $TESTTMP/fakepager.py
> EOF
$ chg version > /dev/null
$ touch foo
$ chg ci -qAm foo
pager should be enabled if the attached client has a tty:
$ chg log -l1 -q --config ui.formatted=True
paged! '0:1f7b0de80e11\n'
$ chg log -l1 -q --config ui.formatted=False
0:1f7b0de80e11
$ cd ..
Yuya Nishihara
test-chg: add basic tests for server lifecycle...
r29275 server lifecycle
----------------
chg server should be restarted on code change, and old server will shut down
automatically. In this test, we use the following time parameters:
- "sleep 1" to make mtime different
- "sleep 2" to notice mtime change (polling interval is 1 sec)
set up repository with an extension:
$ chg init extreload
$ cd extreload
$ touch dummyext.py
$ cat <<EOF >> .hg/hgrc
> [extensions]
> dummyext = dummyext.py
> EOF
isolate socket directory for stable result:
$ OLDCHGSOCKNAME=$CHGSOCKNAME
$ mkdir chgsock
$ CHGSOCKNAME=`pwd`/chgsock/server
warm up server:
$ CHGDEBUG= chg log 2>&1 | egrep 'instruction|start'
Jun Wu
chg: start server at a unique address...
r30620 chg: debug: start cmdserver at $TESTTMP/extreload/chgsock/server.* (glob)
Yuya Nishihara
test-chg: add basic tests for server lifecycle...
r29275
new server should be started if extension modified:
$ sleep 1
$ touch dummyext.py
$ CHGDEBUG= chg log 2>&1 | egrep 'instruction|start'
chg: debug: instruction: unlink $TESTTMP/extreload/chgsock/server-* (glob)
chg: debug: instruction: reconnect
Jun Wu
chg: start server at a unique address...
r30620 chg: debug: start cmdserver at $TESTTMP/extreload/chgsock/server.* (glob)
Yuya Nishihara
test-chg: add basic tests for server lifecycle...
r29275
old server will shut down, while new server should still be reachable:
$ sleep 2
$ CHGDEBUG= chg log 2>&1 | (egrep 'instruction|start' || true)
socket file should never be unlinked by old server:
(simulates unowned socket by updating mtime, which makes sure server exits
at polling cycle)
$ ls chgsock/server-*
chgsock/server-* (glob)
$ touch chgsock/server-*
$ sleep 2
$ ls chgsock/server-*
chgsock/server-* (glob)
since no server is reachable from socket file, new server should be started:
(this test makes sure that old server shut down automatically)
$ CHGDEBUG= chg log 2>&1 | egrep 'instruction|start'
Jun Wu
chg: start server at a unique address...
r30620 chg: debug: start cmdserver at $TESTTMP/extreload/chgsock/server.* (glob)
Yuya Nishihara
test-chg: add basic tests for server lifecycle...
r29275
shut down servers and restore environment:
$ rm -R chgsock
$ CHGSOCKNAME=$OLDCHGSOCKNAME
$ cd ..