12 |
12 |
13 """ |
13 """ |
14 hg-ssh - limit access to hg repositories reached via ssh. Part of |
14 hg-ssh - limit access to hg repositories reached via ssh. Part of |
15 mercurial-server. |
15 mercurial-server. |
16 |
16 |
17 This script is called by hg-ssh-wrapper with no arguments - everything |
17 It is called by ssh due to an entry in the authorized_keys file, |
18 should be in enviroment variables: |
18 with the name for the key passed on the command line. |
19 |
|
20 HG_ACCESS_RULES_PATH identifies the paths to the rule files |
|
21 REMOTE_USER the remote user (which is the key used by ssh) |
|
22 SSH_ORIGINAL_COMMAND the command the user was trying to run |
|
23 |
19 |
24 It uses SSH_ORIGINAL_COMMAND to determine what the user was trying to |
20 It uses SSH_ORIGINAL_COMMAND to determine what the user was trying to |
25 do and to what repository, and then checks each rule in the rule file |
21 do and to what repository, and then checks each rule in the rule file |
26 in turn for a matching rule which decides what to do, defaulting to |
22 in turn for a matching rule which decides what to do, defaulting to |
27 disallowing the action. |
23 disallowing the action. |
33 |
29 |
34 from mercurial import dispatch |
30 from mercurial import dispatch |
35 |
31 |
36 import sys, os, os.path |
32 import sys, os, os.path |
37 import base64 |
33 import base64 |
38 from mercurialserver import ruleset, paths |
34 from mercurialserver import config, ruleset |
39 |
35 |
40 def fail(message): |
36 def fail(message): |
41 sys.stderr.write("mercurial-server: %s\n" % message) |
37 sys.stderr.write("mercurial-server: %s\n" % message) |
42 sys.exit(-1) |
38 sys.exit(-1) |
43 |
39 |
69 if not ruleset.rules.allow(op, branch=None, file=None): |
65 if not ruleset.rules.allow(op, branch=None, file=None): |
70 fail("access denied") |
66 fail("access denied") |
71 checkParents(repo) |
67 checkParents(repo) |
72 return repo |
68 return repo |
73 |
69 |
74 paths.setExePath() |
70 config.initExe() |
75 |
71 |
76 if len(sys.argv) == 3 and sys.argv[1] == "--base64": |
72 if len(sys.argv) == 3 and sys.argv[1] == "--base64": |
77 ruleset.rules.set(user = base64.b64decode(sys.argv[2])) |
73 ruleset.rules.set(user = base64.b64decode(sys.argv[2])) |
78 elif len(sys.argv) == 2: |
74 elif len(sys.argv) == 2: |
79 ruleset.rules.set(user = sys.argv[1]) |
75 ruleset.rules.set(user = sys.argv[1]) |
80 else: |
76 else: |
81 fail("hg-ssh wrongly called, is authorized_keys corrupt? (%s)" |
77 fail("hg-ssh wrongly called, is authorized_keys corrupt? (%s)" |
82 % sys.argv) |
78 % sys.argv) |
83 |
79 |
84 # Use a different hgrc for remote pulls - this way you can set |
80 for k,v in config.getEnv(): |
85 # up access.py for everything at once without affecting local operations |
81 os.environ[k] = v |
86 |
82 |
87 os.environ['HGRCPATH'] = paths.getHgrcPaths() |
83 os.chdir(config.getReposPath()) |
88 |
84 |
89 os.chdir(paths.getReposPath()) |
85 for f in config.getAccessPaths(): |
90 |
|
91 for f in paths.getAccessPaths(): |
|
92 if os.path.isfile(f): |
86 if os.path.isfile(f): |
93 ruleset.rules.readfile(f) |
87 ruleset.rules.readfile(f) |
94 |
88 |
95 cmd = os.environ.get('SSH_ORIGINAL_COMMAND', None) |
89 cmd = os.environ.get('SSH_ORIGINAL_COMMAND', None) |
96 if cmd is None: |
90 if cmd is None: |