author | Paul Crowley <paul@lshift.net> |
Mon, 16 Jun 2008 17:24:53 +0100 | |
changeset 36 | b3237aabd0fe |
parent 33 | 18e93dbdaf12 |
child 39 | f5055ce263c7 |
permissions | -rw-r--r-- |
18
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
1 |
# Copyright 2008 LShift Ltd |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
2 |
# Author(s): |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
3 |
# Paul Crowley <paul@lshift.net> |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
4 |
# |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
5 |
# This software may be used and distributed according to the terms |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
6 |
# of the GNU General Public License, incorporated herein by reference. |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
7 |
|
32 | 8 |
import sys |
18
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
9 |
import re |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
10 |
|
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
11 |
allowedchars = "A-Za-z0-9_-" |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
12 |
|
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
13 |
goodpathre = re.compile("([%s]+/)*[%s]+$" % (allowedchars, allowedchars)) |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
14 |
def goodpath(path): |
19
62ee928ac9b3
fixes following actual testing
Paul Crowley <paul@lshift.net>
parents:
18
diff
changeset
|
15 |
return goodpathre.match(path) is not None |
18
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
16 |
|
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
17 |
goodglobre = re.compile("[*/%s]+$" % allowedchars) |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
18 |
|
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
19 |
def goodglob(pattern): |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
20 |
return goodglobre.match(pattern) is not None |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
21 |
|
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
22 |
# Don't put anything except *A-Za-z0-9_- in rule globs or |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
23 |
# it will match nothing. No regexp metachars, not even . |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
24 |
# We may fix this later. |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
25 |
def globmatcher(pattern): |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
26 |
if not goodglob(pattern): |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
27 |
#fail("Bad glob pattern in auth config: %s" % pattern) |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
28 |
# FIXME: report it somehow |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
29 |
return lambda x: False |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
30 |
# Substitution cunning so ** can be different from * |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
31 |
pattern = pattern.replace("*", "[]") |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
32 |
pattern = pattern.replace("[][]", "[/%s]*" % allowedchars) |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
33 |
pattern = pattern.replace("[]", "[%s]*" % allowedchars) |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
34 |
rex = re.compile(pattern + "$") |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
35 |
# None matches everything |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
36 |
return lambda x: x is None or rex.match(x) is not None |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
37 |
|
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
38 |
def rule(pairs): |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
39 |
matchers = [(k, globmatcher(v)) for k, v in pairs] |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
40 |
def c(**kw): |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
41 |
for k, m in matchers: |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
42 |
if k not in kw or not m(kw[k]): |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
43 |
return False |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
44 |
return True |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
45 |
return c |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
46 |
|
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
47 |
class Ruleset(object): |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
48 |
'''Class representing the rules in a rule file''' |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
49 |
|
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
50 |
levels = ["init", "write", "read", "deny"] |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
51 |
|
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
52 |
def __init__(self): |
32 | 53 |
# The user called "root" automatically has the highest |
54 |
# privilege |
|
55 |
self.rules = [(self.levels[0], rule([('user', 'root')]))] |
|
21
59540181a4bb
simplify by allowing some params to be preset in rules
Paul Crowley <paul@ciphergoth.org>
parents:
18
diff
changeset
|
56 |
self.preset = {} |
18
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
57 |
|
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
58 |
def add(self, action, conditions): |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
59 |
self.rules.append((action, conditions)) |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
60 |
|
21
59540181a4bb
simplify by allowing some params to be preset in rules
Paul Crowley <paul@ciphergoth.org>
parents:
18
diff
changeset
|
61 |
|
59540181a4bb
simplify by allowing some params to be preset in rules
Paul Crowley <paul@ciphergoth.org>
parents:
18
diff
changeset
|
62 |
def set(self, **kw): |
59540181a4bb
simplify by allowing some params to be preset in rules
Paul Crowley <paul@ciphergoth.org>
parents:
18
diff
changeset
|
63 |
self.preset.update(kw) |
59540181a4bb
simplify by allowing some params to be preset in rules
Paul Crowley <paul@ciphergoth.org>
parents:
18
diff
changeset
|
64 |
|
18
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
65 |
def matchrule(self, **kw): |
21
59540181a4bb
simplify by allowing some params to be preset in rules
Paul Crowley <paul@ciphergoth.org>
parents:
18
diff
changeset
|
66 |
d = self.preset.copy() |
59540181a4bb
simplify by allowing some params to be preset in rules
Paul Crowley <paul@ciphergoth.org>
parents:
18
diff
changeset
|
67 |
d.update(**kw) |
18
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
68 |
for a, c in self.rules: |
21
59540181a4bb
simplify by allowing some params to be preset in rules
Paul Crowley <paul@ciphergoth.org>
parents:
18
diff
changeset
|
69 |
if c(**d): |
18
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
70 |
return a |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
71 |
return None |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
72 |
|
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
73 |
def allow(self, level, **kw): |
19
62ee928ac9b3
fixes following actual testing
Paul Crowley <paul@lshift.net>
parents:
18
diff
changeset
|
74 |
a = self.matchrule(**kw) |
18
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
75 |
return a in self.levels and self.levels.index(a) <= self.levels.index(level) |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
76 |
|
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
77 |
@classmethod |
19
62ee928ac9b3
fixes following actual testing
Paul Crowley <paul@lshift.net>
parents:
18
diff
changeset
|
78 |
def readfile(cls, fn): |
18
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
79 |
res = cls() |
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
80 |
try: |
32 | 81 |
f = open(fn) |
82 |
try: |
|
83 |
for l in f: |
|
84 |
l = l.strip() |
|
85 |
if len(l) == 0 or l.startswith("#"): |
|
86 |
continue |
|
87 |
l = l.split() |
|
88 |
res.add(l[0], rule([c.split("=", 1) for c in l[1:]])) |
|
89 |
finally: |
|
90 |
f.close() |
|
91 |
except Exception, e: |
|
92 |
print >> sys.stderr, "Failure reading rules file:", e |
|
93 |
return cls() |
|
18
538d6b198f4a
Big change to support file conditions; format of hg-ssh-access.conf
Paul Crowley <paul@lshift.net>
parents:
diff
changeset
|
94 |
return res |
32 | 95 |