25 |
25 |
26 def fail(message): |
26 def fail(message): |
27 sys.stderr.write("mercurial-server: %s\n" % message) |
27 sys.stderr.write("mercurial-server: %s\n" % message) |
28 sys.exit(-1) |
28 sys.exit(-1) |
29 |
29 |
30 def checkDots(path): |
30 config.initExe() |
|
31 |
|
32 for k,v in config.getEnv(): |
|
33 os.environ[k.upper()] = v |
|
34 |
|
35 if len(sys.argv) == 3 and sys.argv[1] == "--base64": |
|
36 ruleset.rules.set(user = base64.b64decode(sys.argv[2])) |
|
37 elif len(sys.argv) == 2: |
|
38 ruleset.rules.set(user = sys.argv[1]) |
|
39 else: |
|
40 fail("hg-ssh wrongly called, is authorized_keys corrupt? (%s)" |
|
41 % sys.argv) |
|
42 |
|
43 os.chdir(config.getReposPath()) |
|
44 |
|
45 for f in config.getAccessPaths(): |
|
46 if os.path.isfile(f): |
|
47 ruleset.rules.readfile(f) |
|
48 |
|
49 alloweddots = config.getAllowedDots() |
|
50 |
|
51 def dotException(pathtail): |
|
52 for ex in alloweddots: |
|
53 splex = ex.split("/") |
|
54 if len(pathtail) >= len(splex) and pathtail[:len(splex)] == splex: |
|
55 return True |
|
56 return False |
|
57 |
|
58 def checkDots(path, pathtail = []): |
31 head, tail = os.path.split(path) |
59 head, tail = os.path.split(path) |
32 if tail.startswith("."): |
60 pathtail = [tail] + pathtail |
33 fail("paths cannot contain dot file components") |
61 if tail.startswith(".") and not dotException(pathtail): |
|
62 fail("paths cannot contain dot file components") |
34 if head: |
63 if head: |
35 checkDots(head) |
64 checkDots(head, pathtail) |
36 |
65 |
37 def getrepo(op, repo): |
66 def getrepo(op, repo): |
38 # First canonicalise, then check the string, then the rules |
67 # First canonicalise, then check the string, then the rules |
39 repo = repo.strip().rstrip("/") |
68 repo = repo.strip().rstrip("/") |
40 if len(repo) == 0: |
69 if len(repo) == 0: |
44 checkDots(repo) |
73 checkDots(repo) |
45 ruleset.rules.set(repo=repo) |
74 ruleset.rules.set(repo=repo) |
46 if not ruleset.rules.allow(op, branch=None, file=None): |
75 if not ruleset.rules.allow(op, branch=None, file=None): |
47 fail("access denied") |
76 fail("access denied") |
48 return repo |
77 return repo |
49 |
|
50 config.initExe() |
|
51 |
|
52 for k,v in config.getEnv(): |
|
53 os.environ[k.upper()] = v |
|
54 |
|
55 if len(sys.argv) == 3 and sys.argv[1] == "--base64": |
|
56 ruleset.rules.set(user = base64.b64decode(sys.argv[2])) |
|
57 elif len(sys.argv) == 2: |
|
58 ruleset.rules.set(user = sys.argv[1]) |
|
59 else: |
|
60 fail("hg-ssh wrongly called, is authorized_keys corrupt? (%s)" |
|
61 % sys.argv) |
|
62 |
|
63 os.chdir(config.getReposPath()) |
|
64 |
|
65 for f in config.getAccessPaths(): |
|
66 if os.path.isfile(f): |
|
67 ruleset.rules.readfile(f) |
|
68 |
78 |
69 cmd = os.environ.get('SSH_ORIGINAL_COMMAND', None) |
79 cmd = os.environ.get('SSH_ORIGINAL_COMMAND', None) |
70 if cmd is None: |
80 if cmd is None: |
71 fail("direct logins on the hg account prohibited") |
81 fail("direct logins on the hg account prohibited") |
72 elif cmd.startswith('hg -R ') and cmd.endswith(' serve --stdio'): |
82 elif cmd.startswith('hg -R ') and cmd.endswith(' serve --stdio'): |