Mercurial > hg-stable
changeset 35845:bbd4027b019b stable
tests: comprehensively test HTTP server permissions checking
We didn't have test coverage for numerous web.* config options. We
add that test coverage.
Included in the tests are tests for custom commands. We have commands
that are supposedly read-only and perform writes and a variation of
each that does and does not define its operation type in
hgweb_mod.perms.
The tests reveal a handful of security bugs related to permissions
checking. Subsequent commits will address these security bugs.
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Tue, 20 Feb 2018 19:09:01 -0800 |
parents | 2c647da851ed |
children | 742ce6fbc109 |
files | tests/test-http-permissions.t |
diffstat | 1 files changed, 1452 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/tests/test-http-permissions.t Sun Feb 18 10:40:49 2018 -0800 +++ b/tests/test-http-permissions.t Tue Feb 20 19:09:01 2018 -0800 @@ -1,5 +1,42 @@ #require killdaemons + $ cat > fakeremoteuser.py << EOF + > import os + > from mercurial.hgweb import hgweb_mod + > from mercurial import wireproto + > class testenvhgweb(hgweb_mod.hgweb): + > def __call__(self, env, respond): + > # Allow REMOTE_USER to define authenticated user. + > if r'REMOTE_USER' in os.environ: + > env[r'REMOTE_USER'] = os.environ[r'REMOTE_USER'] + > # Allow REQUEST_METHOD to override HTTP method + > if r'REQUEST_METHOD' in os.environ: + > env[r'REQUEST_METHOD'] = os.environ[r'REQUEST_METHOD'] + > return super(testenvhgweb, self).__call__(env, respond) + > hgweb_mod.hgweb = testenvhgweb + > + > @wireproto.wireprotocommand('customreadnoperm') + > def customread(repo, proto): + > return b'read-only command no defined permissions\n' + > @wireproto.wireprotocommand('customwritenoperm') + > def customwritenoperm(repo, proto): + > return b'write command no defined permissions\n' + > hgweb_mod.perms['customreadwithperm'] = 'pull' + > @wireproto.wireprotocommand('customreadwithperm') + > def customreadwithperm(repo, proto): + > return b'read-only command w/ defined permissions\n' + > hgweb_mod.perms['customwritewithperm'] = 'push' + > @wireproto.wireprotocommand('customwritewithperm') + > def customwritewithperm(repo, proto): + > return b'write command w/ defined permissions\n' + > EOF + + $ cat >> $HGRCPATH << EOF + > [extensions] + > fakeremoteuser = $TESTTMP/fakeremoteuser.py + > strip = + > EOF + $ hg init test $ cd test $ echo a > a @@ -12,9 +49,837 @@ $ cd test2 $ echo a >> a $ hg ci -mb + $ hg book bm -r 0 $ cd ../test -expect authorization error: all users denied +web.deny_read=* prevents access to wire protocol for all users + + $ cat > .hg/hgrc <<EOF + > [web] + > deny_read = * + > EOF + + $ hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' + 200 Script output follows + + lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx compression=$BUNDLE2_COMPRESSIONS$ (no-eol) + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=stream_out' + 401 read not authorized + + 0 + read not authorized + [1] + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases' + 401 read not authorized + + 0 + read not authorized + [1] + +TODO batch command doesn't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases' + 200 Script output follows + + cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 1 + publishing True (no-eol) + +TODO custom commands don't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadnoperm' + 200 Script output follows + + read-only command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadwithperm' + 401 read not authorized + + 0 + read not authorized + [1] + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm' + 200 Script output follows + + write command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm' + 401 read not authorized + + 0 + read not authorized + [1] + + $ hg --cwd ../test2 pull http://localhost:$HGPORT/ + pulling from http://localhost:$HGPORT/ + searching for changes + no changes found + abort: authorization failed + [255] + + $ killdaemons.py + +web.deny_read=* with REMOTE_USER set still locks out clients + + $ REMOTE_USER=authed_user hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' + 200 Script output follows + + lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx compression=$BUNDLE2_COMPRESSIONS$ (no-eol) + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=stream_out' + 401 read not authorized + + 0 + read not authorized + [1] + +TODO batch command doesn't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases' + 200 Script output follows + + cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 1 + publishing True (no-eol) + +TODO custom commands don't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadnoperm' + 200 Script output follows + + read-only command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadwithperm' + 401 read not authorized + + 0 + read not authorized + [1] + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm' + 200 Script output follows + + write command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm' + 401 read not authorized + + 0 + read not authorized + [1] + + $ hg --cwd ../test2 pull http://localhost:$HGPORT/ + pulling from http://localhost:$HGPORT/ + searching for changes + no changes found + abort: authorization failed + [255] + + $ killdaemons.py + +web.deny_read=<user> denies access to unauthenticated user + + $ cat > .hg/hgrc <<EOF + > [web] + > deny_read = baduser1,baduser2 + > EOF + + $ hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases' + 401 read not authorized + + 0 + read not authorized + [1] + +TODO batch command doesn't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases' + 200 Script output follows + + cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 1 + publishing True (no-eol) + +TODO custom commands don't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadnoperm' + 200 Script output follows + + read-only command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadwithperm' + 401 read not authorized + + 0 + read not authorized + [1] + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm' + 200 Script output follows + + write command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm' + 401 read not authorized + + 0 + read not authorized + [1] + + $ hg --cwd ../test2 pull http://localhost:$HGPORT/ + pulling from http://localhost:$HGPORT/ + searching for changes + no changes found + abort: authorization failed + [255] + + $ killdaemons.py + +web.deny_read=<user> denies access to users in deny list + + $ REMOTE_USER=baduser2 hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases' + 401 read not authorized + + 0 + read not authorized + [1] + +TODO batch command doesn't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases' + 200 Script output follows + + cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 1 + publishing True (no-eol) + +TODO custom commands don't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadnoperm' + 200 Script output follows + + read-only command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadwithperm' + 401 read not authorized + + 0 + read not authorized + [1] + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm' + 200 Script output follows + + write command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm' + 401 read not authorized + + 0 + read not authorized + [1] + + $ hg --cwd ../test2 pull http://localhost:$HGPORT/ + pulling from http://localhost:$HGPORT/ + searching for changes + no changes found + abort: authorization failed + [255] + + $ killdaemons.py + +web.deny_read=<user> allows access to authenticated users not in list + + $ REMOTE_USER=gooduser hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases' + 200 Script output follows + + cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 1 + publishing True (no-eol) + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases' + 200 Script output follows + + cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 1 + publishing True (no-eol) + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadnoperm' + 200 Script output follows + + read-only command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadwithperm' + 200 Script output follows + + read-only command w/ defined permissions + +TODO custom commands don't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm' + 200 Script output follows + + write command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm' + 405 push requires POST request + + 0 + push requires POST request + [1] + + $ hg --cwd ../test2 pull http://localhost:$HGPORT/ + pulling from http://localhost:$HGPORT/ + searching for changes + no changes found + + $ killdaemons.py + +web.allow_read=* allows reads for unauthenticated users + + $ cat > .hg/hgrc <<EOF + > [web] + > allow_read = * + > EOF + + $ hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases' + 200 Script output follows + + cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 1 + publishing True (no-eol) + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases' + 200 Script output follows + + cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 1 + publishing True (no-eol) + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadnoperm' + 200 Script output follows + + read-only command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadwithperm' + 200 Script output follows + + read-only command w/ defined permissions + +TODO custom commands don't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm' + 200 Script output follows + + write command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm' + 405 push requires POST request + + 0 + push requires POST request + [1] + + $ hg --cwd ../test2 pull http://localhost:$HGPORT/ + pulling from http://localhost:$HGPORT/ + searching for changes + no changes found + + $ killdaemons.py + +web.allow_read=* allows read for authenticated user + + $ REMOTE_USER=authed_user hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases' + 200 Script output follows + + cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 1 + publishing True (no-eol) + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases' + 200 Script output follows + + cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 1 + publishing True (no-eol) + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadnoperm' + 200 Script output follows + + read-only command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadwithperm' + 200 Script output follows + + read-only command w/ defined permissions + +TODO custom commands don't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm' + 200 Script output follows + + write command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm' + 405 push requires POST request + + 0 + push requires POST request + [1] + + $ hg --cwd ../test2 pull http://localhost:$HGPORT/ + pulling from http://localhost:$HGPORT/ + searching for changes + no changes found + + $ killdaemons.py + +web.allow_read=<user> does not allow unauthenticated users to read + + $ cat > .hg/hgrc <<EOF + > [web] + > allow_read = gooduser + > EOF + + $ hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases' + 401 read not authorized + + 0 + read not authorized + [1] + +TODO batch command doesn't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases' + 200 Script output follows + + cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 1 + publishing True (no-eol) + +TODO custom commands don't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadnoperm' + 200 Script output follows + + read-only command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadwithperm' + 401 read not authorized + + 0 + read not authorized + [1] + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm' + 200 Script output follows + + write command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm' + 401 read not authorized + + 0 + read not authorized + [1] + + $ hg --cwd ../test2 pull http://localhost:$HGPORT/ + pulling from http://localhost:$HGPORT/ + searching for changes + no changes found + abort: authorization failed + [255] + + $ killdaemons.py + +web.allow_read=<user> does not allow user not in list to read + + $ REMOTE_USER=baduser hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases' + 401 read not authorized + + 0 + read not authorized + [1] + +TODO batch command doesn't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases' + 200 Script output follows + + cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 1 + publishing True (no-eol) + +TODO custom commands don't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadnoperm' + 200 Script output follows + + read-only command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadwithperm' + 401 read not authorized + + 0 + read not authorized + [1] + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm' + 200 Script output follows + + write command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm' + 401 read not authorized + + 0 + read not authorized + [1] + + $ hg --cwd ../test2 pull http://localhost:$HGPORT/ + pulling from http://localhost:$HGPORT/ + searching for changes + no changes found + abort: authorization failed + [255] + + $ killdaemons.py + +web.allow_read=<user> allows read from user in list + + $ REMOTE_USER=gooduser hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases' + 200 Script output follows + + cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 1 + publishing True (no-eol) + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases' + 200 Script output follows + + cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 1 + publishing True (no-eol) + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadnoperm' + 200 Script output follows + + read-only command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadwithperm' + 200 Script output follows + + read-only command w/ defined permissions + +TODO custom commands don't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm' + 200 Script output follows + + write command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm' + 405 push requires POST request + + 0 + push requires POST request + [1] + + $ hg --cwd ../test2 pull http://localhost:$HGPORT/ + pulling from http://localhost:$HGPORT/ + searching for changes + no changes found + + $ killdaemons.py + +web.deny_read takes precedence over web.allow_read + + $ cat > .hg/hgrc <<EOF + > [web] + > allow_read = baduser + > deny_read = baduser + > EOF + + $ REMOTE_USER=baduser hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases' + 401 read not authorized + + 0 + read not authorized + [1] + +TODO batch command doesn't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases' + 200 Script output follows + + cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 1 + publishing True (no-eol) + +TODO custom commands don't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadnoperm' + 200 Script output follows + + read-only command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadwithperm' + 401 read not authorized + + 0 + read not authorized + [1] + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm' + 200 Script output follows + + write command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm' + 401 read not authorized + + 0 + read not authorized + [1] + + $ hg --cwd ../test2 pull http://localhost:$HGPORT/ + pulling from http://localhost:$HGPORT/ + searching for changes + no changes found + abort: authorization failed + [255] + + $ killdaemons.py + +web.allow-pull=false denies read access to repo + + $ cat > .hg/hgrc <<EOF + > [web] + > allow-pull = false + > EOF + + $ hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' + 200 Script output follows + + lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx compression=$BUNDLE2_COMPRESSIONS$ (no-eol) + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=listkeys' --requestheader 'x-hgarg-1=namespace=phases' + 401 pull not authorized + + 0 + pull not authorized + [1] + +TODO batch command doesn't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=listkeys+namespace%3Dphases' + 200 Script output follows + + cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 1 + publishing True (no-eol) + +TODO custom commands don't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadnoperm' + 200 Script output follows + + read-only command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadwithperm' + 401 pull not authorized + + 0 + pull not authorized + [1] + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm' + 200 Script output follows + + write command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm' + 405 push requires POST request + + 0 + push requires POST request + [1] + + $ hg --cwd ../test2 pull http://localhost:$HGPORT/ + pulling from http://localhost:$HGPORT/ + searching for changes + no changes found + abort: authorization failed + [255] + + $ killdaemons.py + +Attempting a write command with HTTP GET fails + + $ cat > .hg/hgrc <<EOF + > EOF + + $ REQUEST_METHOD=GET hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b' + 405 push requires POST request + + 0 + push requires POST request + [1] + +TODO batch command doesn't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b' + 200 Script output follows + + 1 + + $ hg bookmarks + bm 0:cb9a9f314b8b + $ hg bookmark -d bm + +TODO custom commands don't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm' + 200 Script output follows + + write command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm' + 405 push requires POST request + + 0 + push requires POST request + [1] + + $ killdaemons.py + +Attempting a write command with an unknown HTTP verb fails + + $ REQUEST_METHOD=someverb hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b' + 405 push requires POST request + + 0 + push requires POST request + [1] + +TODO batch command doesn't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b' + 200 Script output follows + + 1 + + $ hg bookmarks + bm 0:cb9a9f314b8b + $ hg bookmark -d bm + +TODO custom commands don't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm' + 200 Script output follows + + write command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm' + 405 push requires POST request + + 0 + push requires POST request + [1] + + $ killdaemons.py + +Pushing on a plaintext channel is disabled by default + + $ cat > .hg/hgrc <<EOF + > EOF + + $ REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b' + 403 ssl required + + 0 + ssl required + [1] + +TODO batch command doesn't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b' + 200 Script output follows + + 1 + + $ hg bookmarks + bm 0:cb9a9f314b8b + $ hg book -d bm + +TODO custom commands don't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm' + 200 Script output follows + + write command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm' + 403 ssl required + + 0 + ssl required + [1] + +Reset server to remove REQUEST_METHOD hack to test hg client + + $ killdaemons.py + $ hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/ + pushing to http://localhost:$HGPORT/ + searching for changes + no changes found + abort: HTTP Error 403: ssl required + [255] + + $ hg --cwd ../test2 push http://localhost:$HGPORT/ + pushing to http://localhost:$HGPORT/ + searching for changes + abort: HTTP Error 403: ssl required + [255] + + $ killdaemons.py + +web.deny_push=* denies pushing to unauthenticated users $ cat > .hg/hgrc <<EOF > [web] @@ -22,9 +887,54 @@ > deny_push = * > EOF + $ REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b' + 401 push not authorized + + 0 + push not authorized + [1] + +TODO batch command doesn't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b' + 200 Script output follows + + 1 + + $ hg bookmarks + bm 0:cb9a9f314b8b + $ hg book -d bm + +TODO custom commands don't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm' + 200 Script output follows + + write command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm' + 401 push not authorized + + 0 + push not authorized + [1] + +Reset server to remove REQUEST_METHOD hack to test hg client + + $ killdaemons.py $ hg serve -p $HGPORT -d --pid-file hg.pid $ cat hg.pid > $DAEMON_PIDS + $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/ + pushing to http://localhost:$HGPORT/ + searching for changes + no changes found + abort: authorization failed + [255] + $ hg --cwd ../test2 push http://localhost:$HGPORT/ pushing to http://localhost:$HGPORT/ searching for changes @@ -33,16 +943,178 @@ $ killdaemons.py -expect authorization error: some users denied, users must be authenticated +web.deny_push=* denies pushing to authenticated users + + $ REMOTE_USER=someuser REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b' + 401 push not authorized + + 0 + push not authorized + [1] + +TODO batch command doesn't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b' + 200 Script output follows + + 1 + + $ hg bookmarks + bm 0:cb9a9f314b8b + $ hg book -d bm + +TODO custom commands don't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm' + 200 Script output follows + + write command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm' + 401 push not authorized + + 0 + push not authorized + [1] + +Reset server to remove REQUEST_METHOD hack to test hg client + + $ killdaemons.py + $ REMOTE_USER=someuser hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/ + pushing to http://localhost:$HGPORT/ + searching for changes + no changes found + abort: authorization failed + [255] + + $ hg --cwd ../test2 push http://localhost:$HGPORT/ + pushing to http://localhost:$HGPORT/ + searching for changes + abort: authorization failed + [255] + + $ killdaemons.py + +web.deny_push=<user> denies pushing to user in list $ cat > .hg/hgrc <<EOF > [web] > push_ssl = false - > deny_push = unperson + > deny_push = baduser > EOF - $ hg serve -p $HGPORT -d --pid-file hg.pid + $ REMOTE_USER=baduser REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b' + 401 push not authorized + + 0 + push not authorized + [1] + +TODO batch command doesn't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b' + 200 Script output follows + + 1 + + $ hg bookmarks + bm 0:cb9a9f314b8b + $ hg book -d bm + +TODO custom commands don't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm' + 200 Script output follows + + write command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm' + 401 push not authorized + + 0 + push not authorized + [1] + +Reset server to remove REQUEST_METHOD hack to test hg client + + $ killdaemons.py + $ REMOTE_USER=baduser hg serve -p $HGPORT -d --pid-file hg.pid $ cat hg.pid > $DAEMON_PIDS + + $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/ + pushing to http://localhost:$HGPORT/ + searching for changes + no changes found + abort: authorization failed + [255] + + $ hg --cwd ../test2 push http://localhost:$HGPORT/ + pushing to http://localhost:$HGPORT/ + searching for changes + abort: authorization failed + [255] + + $ killdaemons.py + +web.deny_push=<user> denies pushing to user not in list because allow-push isn't set + + $ REMOTE_USER=gooduser REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b' + 401 push not authorized + + 0 + push not authorized + [1] + +TODO batch command doesn't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b' + 200 Script output follows + + 1 + + $ hg bookmarks + bm 0:cb9a9f314b8b + $ hg book -d bm + +TODO custom commands don't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm' + 200 Script output follows + + write command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm' + 401 push not authorized + + 0 + push not authorized + [1] + +Reset server to remove REQUEST_METHOD hack to test hg client + + $ killdaemons.py + $ REMOTE_USER=gooduser hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/ + pushing to http://localhost:$HGPORT/ + searching for changes + no changes found + abort: authorization failed + [255] + $ hg --cwd ../test2 push http://localhost:$HGPORT/ pushing to http://localhost:$HGPORT/ searching for changes @@ -50,3 +1122,379 @@ [255] $ killdaemons.py + +web.allow-push=* allows pushes from unauthenticated users + + $ cat > .hg/hgrc <<EOF + > [web] + > push_ssl = false + > allow-push = * + > EOF + + $ REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b' + 200 Script output follows + + 1 + + $ hg bookmarks + bm 0:cb9a9f314b8b + $ hg book -d bm + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm' + 200 Script output follows + + write command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm' + 200 Script output follows + + write command w/ defined permissions + +Reset server to remove REQUEST_METHOD hack to test hg client + + $ killdaemons.py + $ hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/ + pushing to http://localhost:$HGPORT/ + searching for changes + no changes found + exporting bookmark bm + [1] + + $ hg book -d bm + + $ hg --cwd ../test2 push http://localhost:$HGPORT/ + pushing to http://localhost:$HGPORT/ + searching for changes + remote: adding changesets + remote: adding manifests + remote: adding file changes + remote: added 1 changesets with 1 changes to 1 files + + $ hg strip -r 1: + saved backup bundle to $TESTTMP/test/.hg/strip-backup/ba677d0156c1-eea704d7-backup.hg + + $ killdaemons.py + +web.allow-push=* allows pushes from authenticated users + + $ REMOTE_USER=someuser REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b' + 200 Script output follows + + 1 + + $ hg bookmarks + bm 0:cb9a9f314b8b + $ hg book -d bm + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm' + 200 Script output follows + + write command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm' + 200 Script output follows + + write command w/ defined permissions + +Reset server to remove REQUEST_METHOD hack to test hg client + + $ killdaemons.py + $ REMOTE_USER=someuser hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/ + pushing to http://localhost:$HGPORT/ + searching for changes + no changes found + exporting bookmark bm + [1] + + $ hg book -d bm + + $ hg --cwd ../test2 push http://localhost:$HGPORT/ + pushing to http://localhost:$HGPORT/ + searching for changes + remote: adding changesets + remote: adding manifests + remote: adding file changes + remote: added 1 changesets with 1 changes to 1 files + + $ hg strip -r 1: + saved backup bundle to $TESTTMP/test/.hg/strip-backup/ba677d0156c1-eea704d7-backup.hg + + $ killdaemons.py + +web.allow-push=<user> denies push to user not in list + + $ cat > .hg/hgrc <<EOF + > [web] + > push_ssl = false + > allow-push = gooduser + > EOF + + $ REMOTE_USER=baduser REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b' + 401 push not authorized + + 0 + push not authorized + [1] + +TODO batch command doesn't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b' + 200 Script output follows + + 1 + + $ hg bookmarks + bm 0:cb9a9f314b8b + $ hg book -d bm + +TODO custom commands don't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm' + 200 Script output follows + + write command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm' + 401 push not authorized + + 0 + push not authorized + [1] + +Reset server to remove REQUEST_METHOD hack to test hg client + + $ killdaemons.py + $ REMOTE_USER=baduser hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/ + pushing to http://localhost:$HGPORT/ + searching for changes + no changes found + abort: authorization failed + [255] + + $ hg --cwd ../test2 push http://localhost:$HGPORT/ + pushing to http://localhost:$HGPORT/ + searching for changes + abort: authorization failed + [255] + + $ killdaemons.py + +web.allow-push=<user> allows push from user in list + + $ REMOTE_USER=gooduser REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b' + 200 Script output follows + + 1 + + $ hg bookmarks + bm 0:cb9a9f314b8b + $ hg book -d bm + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b' + 200 Script output follows + + 1 + + $ hg bookmarks + bm 0:cb9a9f314b8b + $ hg book -d bm + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm' + 200 Script output follows + + write command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm' + 200 Script output follows + + write command w/ defined permissions + +Reset server to remove REQUEST_METHOD hack to test hg client + + $ killdaemons.py + $ REMOTE_USER=gooduser hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/ + pushing to http://localhost:$HGPORT/ + searching for changes + no changes found + exporting bookmark bm + [1] + + $ hg book -d bm + + $ hg --cwd ../test2 push http://localhost:$HGPORT/ + pushing to http://localhost:$HGPORT/ + searching for changes + remote: adding changesets + remote: adding manifests + remote: adding file changes + remote: added 1 changesets with 1 changes to 1 files + + $ hg strip -r 1: + saved backup bundle to $TESTTMP/test/.hg/strip-backup/ba677d0156c1-eea704d7-backup.hg + + $ killdaemons.py + +web.deny_push takes precedence over web.allow_push + + $ cat > .hg/hgrc <<EOF + > [web] + > push_ssl = false + > allow-push = someuser + > deny_push = someuser + > EOF + + $ REMOTE_USER=someuser REQUEST_METHOD=POST hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b' + 401 push not authorized + + 0 + push not authorized + [1] + +TODO batch command doesn't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b' + 200 Script output follows + + 1 + + $ hg bookmarks + bm 0:cb9a9f314b8b + $ hg book -d bm + +TODO custom commands don't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm' + 200 Script output follows + + write command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm' + 401 push not authorized + + 0 + push not authorized + [1] + +Reset server to remove REQUEST_METHOD hack to test hg client + + $ killdaemons.py + $ REMOTE_USER=someuser hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/ + pushing to http://localhost:$HGPORT/ + searching for changes + no changes found + abort: authorization failed + [255] + + $ hg --cwd ../test2 push http://localhost:$HGPORT/ + pushing to http://localhost:$HGPORT/ + searching for changes + abort: authorization failed + [255] + + $ killdaemons.py + +web.allow-push has no effect if web.deny_read is set + + $ cat > .hg/hgrc <<EOF + > [web] + > push_ssl = false + > allow-push = * + > deny_read = * + > EOF + + $ REQUEST_METHOD=POST REMOTE_USER=someuser hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=pushkey' --requestheader 'x-hgarg-1=namespace=bookmarks&key=bm&old=&new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b' + 401 read not authorized + + 0 + read not authorized + [1] + +TODO batch command doesn't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=batch' --requestheader 'x-hgarg-1=cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b' + 200 Script output follows + + 1 + + $ hg bookmarks + bm 0:cb9a9f314b8b + $ hg book -d bm + +TODO custom commands don't check permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadnoperm' + 200 Script output follows + + read-only command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customreadwithperm' + 401 read not authorized + + 0 + read not authorized + [1] + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritenoperm' + 200 Script output follows + + write command no defined permissions + + $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=customwritewithperm' + 401 read not authorized + + 0 + read not authorized + [1] + +Reset server to remove REQUEST_METHOD hack to test hg client + + $ killdaemons.py + $ REMOTE_USER=someuser hg serve -p $HGPORT -d --pid-file hg.pid + $ cat hg.pid > $DAEMON_PIDS + + $ hg --cwd ../test2 push -B bm http://localhost:$HGPORT/ + pushing to http://localhost:$HGPORT/ + searching for changes + abort: authorization failed + [255] + + $ hg --cwd ../test2 push http://localhost:$HGPORT/ + pushing to http://localhost:$HGPORT/ + searching for changes + abort: authorization failed + [255] + + $ killdaemons.py