[PATCH 2 of 2 v2] hg-ssh: more flexible permissions for hg-ssh
Wagner Bruna
wagner.bruna+mercurial at gmail.com
Tue May 22 09:38:44 CDT 2012
On 21-05-2012 20:29, David Schleimer wrote:
> # HG changeset patch
> # User David Schleimer <dschleimer at fb.com>
> # Date 1337642370 25200
> # Node ID 6be86d4b3a0c424272600164500b6329b43ab946
> # Parent b52b7fe0dd08b257dfc69c8a5de503cec94f4b76
> hg-ssh: more flexible permissions for hg-ssh
>
> This allows more flexible control over the permissions granted to a
> ssh key when using hg-ssh as the command in an authorized_keys file.
>
> Specifically, it allows you to restrict a key to read-only access, as
> well as allowing you to grant a key access to any repo, instead of
> needing to whitelist repos.
>
> diff --git a/contrib/hg-ssh b/contrib/hg-ssh
> --- a/contrib/hg-ssh
> +++ b/contrib/hg-ssh
> @@ -35,9 +35,21 @@
>
> def main():
> cwd = os.getcwd()
> + allrepos = False
> + readonly = False
> + args = sys.argv[1:]
> + while len(args):
> + if args[0] == '--all-repos':
> + allrepos = True
> + args.pop(0)
> + elif args[0] == '--read-only':
> + readonly = True
> + args.pop(0)
> + else:
> + break
> allowed_paths = [os.path.normpath(os.path.join(cwd,
> os.path.expanduser(path)))
> - for path in sys.argv[1:]]
> + for path in args]
> orig_cmd = os.getenv('SSH_ORIGINAL_COMMAND', '?')
> try:
> cmdargv = shlex.split(orig_cmd)
> @@ -48,10 +60,12 @@
> if cmdargv[:2] == ['hg', '-R'] and cmdargv[3:] == ['serve', '--stdio']:
> path = cmdargv[2]
> repo = os.path.normpath(os.path.join(cwd, os.path.expanduser(path)))
> - if repo in allowed_paths:
> - dispatch.dispatch(dispatch.request(['-R', repo,
> - 'serve',
> - '--stdio']))
> + if repo in allowed_paths or allrepos:
> + cmd = ['-R', repo, 'serve', '--stdio']
> + if readonly:
> + cmd += ['--config',
> + 'hooks.prechangegroup=python:__main__.rejectpush']
I believe a prepushkey hook should be added here as well. Also, I'd suggest
using "hooks.prechangegroup.hg-ssh", to add a bit more information to the
error message.
BTW, an alternative approach could be adding a --user parameter to hg-ssh, to
check it against web.deny_push / web.allow_push for authorization. This would
be simpler for users: each ssh key would simply authenticate a single user,
leaving authorization to the existing (and documented) configuration mechanisms.
Regards,
Wagner
> + dispatch.dispatch(dispatch.request(cmd))
> else:
> sys.stderr.write('Illegal repository "%s"\n' % repo)
> sys.exit(255)
> @@ -59,5 +73,11 @@
> sys.stderr.write('Illegal command "%s"\n' % orig_cmd)
> sys.exit(255)
>
> +def rejectpush(ui, **kwargs):
> + ui.warn("Permission denied\n")
> + # mercurial hooks use unix process conventions for hook return values
> + # so a truthy return means failure
> + return True
> +
> if __name__ == '__main__':
> main()
(...)
More information about the Mercurial-devel
mailing list