[PATCH] hg-ssh: more flexible permissions for hg-ssh
Matt Mackall
mpm at selenic.com
Fri May 18 17:29:29 CDT 2012
On Fri, 2012-05-18 at 14:21 -0700, David Schleimer wrote:
> # HG changeset patch
> # User David Schleimer <dschleimer at fb.com>
> # Date 1337376000 25200
> # Node ID cbfb26903ff5a57cc53e8abc5ca64a06c5fa0bb1
> # Parent 9acb5cd19162bdb1053429df9ce9a13c2d15aea8
> 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.
..and a bunch of other refactoring that makes this too complicated to
properly evaluate.
The very last thing I want to see is an obfuscated security-related
patch.
Please break this up:
- add a main()
- factor out a rejectpatch() helper
- etc.
> diff --git a/contrib/hg-ssh b/contrib/hg-ssh
> --- a/contrib/hg-ssh
> +++ b/contrib/hg-ssh
> @@ -33,25 +33,51 @@
>
> import sys, os, shlex
>
> -cwd = os.getcwd()
> -allowed_paths = [os.path.normpath(os.path.join(cwd, os.path.expanduser(path)))
> - for path in sys.argv[1:]]
> -orig_cmd = os.getenv('SSH_ORIGINAL_COMMAND', '?')
> -try:
> - cmdargv = shlex.split(orig_cmd)
> -except ValueError, e:
> - sys.stderr.write('Illegal command "%s": %s\n' % (orig_cmd, e))
> - sys.exit(255)
> +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 sys.argv[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 args]
> + orig_cmd = os.getenv('SSH_ORIGINAL_COMMAND', '?')
> + try:
> + cmdargv = shlex.split(orig_cmd)
> + except ValueError, e:
> + sys.stderr.write('Illegal command "%s": %s\n' % (orig_cmd, e))
> + sys.exit(255)
>
> -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 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 or allrepos:
> + cmd = ['-R', repo, 'serve', '--stdio']
> + if readonly:
> + cmd = ['--config',
> + 'hooks.prechangegroup=python:__main__.rejectpush'] + cmd
> + dispatch.dispatch(dispatch.request(cmd))
> + else:
> + sys.stderr.write('Illegal repository "%s"\n' % repo)
> + sys.exit(255)
> else:
> - sys.stderr.write('Illegal repository "%s"\n' % repo)
> + sys.stderr.write('Illegal command "%s"\n' % orig_cmd)
> sys.exit(255)
> -else:
> - sys.stderr.write('Illegal command "%s"\n' % orig_cmd)
> - sys.exit(255)
>
> +def rejectpush(ui, repo, hooktype):
> + ui.warn('Permissions denied')
> + # mercurial uses unix process conventions for hook return values
> + # so a truthy return means failure
> + return True
> +
> +if __name__ == '__main__':
> + main()
--
Mathematics is the supreme nostalgia of our time.
More information about the Mercurial-devel
mailing list