[issue3336] HTTP push should use credentials if supplied or ask for them if POST fails with 401 after GET got 200
Daniel Neugebauer
bugs at mercurial.selenic.com
Sun Mar 25 10:59:57 CDT 2012
New submission from Daniel Neugebauer <energiequant at energiequant.de>:
I'm serving a semi-public repository through Apache + mod_wsgi + hgwebdir
which has write access restricted in Apache by using the following
directives:
<Location /repos/hg/main/>
AuthType Basic
AuthName "Mercurial repository"
AuthUserFile /mnt/data/hg/access/users
AuthGroupFile /mnt/data/hg/access/groups
<Limit GET>
Allow from all
</Limit>
<Limit POST PUT>
Require group main-rw
</Limit>
</Location>
This allows read access for anonymous users while it restricts write
operations (not in Mercurial but Apache) to logged-in users of group "main-
rw".
If I clone a repository, I'm not asked for credentials (as intended). If I
try to push, I'm only getting "abort: authorization failed", no matter if I
specify credentials in the URL or not (tried directly on the command line
and also in hgrc as default path).
On server-side, I can see the commands "capabilities", "heads" and
"branchmap" being run through GET requests, then one POST request with
command "unbundle" which fails with HTTP status code 401. The client aborts
at this point. The access log would show the username supplied in a request
if present but doesn't list anything for these requests, so the client
simply doesn't send credentials although they are explicitely included in
the URL I supply to it (http://user:pass@repository.domain.com/repos/hg/
main).
Looking at the source code, there currently doesn't seem to be a way to ask
for credentials when GETs were successful but a later POST fails. It surely
would be nice if Mercurial would do so or at least try to use the already
supplied credentials (I don't really understand why they are omitted in the
request, especially since I get a message "pushing to http://user:***@..."
nevertheless which just isn't what actually appears to happen).
The following traceback is for Mercurial 2.1.1:
$ hg push --trace http://user:pass@repository.domain.com/repos/hg/main
pushing to http://user:***@repository.domain.com/repos/hg/main
searching for changes
Traceback (most recent call last):
File "/usr/lib64/python2.7/site-packages/mercurial/dispatch.py", line 87,
in _runcatch
return _dispatch(req)
File "/usr/lib64/python2.7/site-packages/mercurial/dispatch.py", line
683, in _dispatch
cmdpats, cmdoptions)
File "/usr/lib64/python2.7/site-packages/mercurial/dispatch.py", line
465, in runcommand
ret = _runcommand(ui, options, cmd, d)
File "/usr/lib64/python2.7/site-packages/mercurial/extensions.py", line
184, in wrap
return wrapper(origfn, *args, **kwargs)
File "/usr/lib64/python2.7/site-packages/hgext/zeroconf/__init__.py",
line 171, in cleanupafterdispatch
return orig(ui, options, cmd, cmdfunc)
File "/usr/lib64/python2.7/site-packages/mercurial/dispatch.py", line
737, in _runcommand
return checkargs()
File "/usr/lib64/python2.7/site-packages/mercurial/dispatch.py", line
691, in checkargs
return cmdfunc()
File "/usr/lib64/python2.7/site-packages/mercurial/dispatch.py", line
680, in <lambda>
d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
File "/usr/lib64/python2.7/site-packages/mercurial/util.py", line 456, in
check
return func(*args, **kwargs)
File "/usr/lib64/python2.7/site-packages/mercurial/extensions.py", line
139, in wrap
util.checksignature(origfn), *args, **kwargs)
File "/usr/lib64/python2.7/site-packages/mercurial/util.py", line 456, in
check
return func(*args, **kwargs)
File "/usr/lib64/python2.7/site-packages/hgext/mq.py", line 3337, in
mqcommand
return orig(ui, repo, *args, **kwargs)
File "/usr/lib64/python2.7/site-packages/mercurial/util.py", line 456, in
check
return func(*args, **kwargs)
File "/usr/lib64/python2.7/site-packages/mercurial/commands.py", line
4431, in push
newbranch=opts.get('new_branch'))
File "/usr/lib64/python2.7/site-packages/mercurial/localrepo.py", line
1669, in push
ret = remote.unbundle(cg, remoteheads, 'push')
File "/usr/lib64/python2.7/site-packages/mercurial/wireproto.py", line
304, in unbundle
ret, output = self._callpush("unbundle", cg, heads=heads)
File "/usr/lib64/python2.7/site-packages/mercurial/httprepo.py", line
199, in _callpush
r = self._call(cmd, data=fp, headers=headers, **args)
File "/usr/lib64/python2.7/site-packages/mercurial/httprepo.py", line
169, in _call
fp = self._callstream(cmd, **args)
File "/usr/lib64/python2.7/site-packages/mercurial/httprepo.py", line
120, in _callstream
raise util.Abort(_('authorization failed'))
Abort: authorization failed
abort: authorization failed
----------
messages: 19452
nosy: dneuge
priority: feature
status: unread
title: HTTP push should use credentials if supplied or ask for them if POST fails with 401 after GET got 200
____________________________________________________
Mercurial issue tracker <bugs at mercurial.selenic.com>
<http://mercurial.selenic.com/bts/issue3336>
____________________________________________________
More information about the Mercurial-devel
mailing list