source: tools/suggest/suggest.py @ c3e4516

abac0-leakabac0-meicompt_changesmei-idmei-rt0-nmei_rt0tvf-new-xml
Last change on this file since c3e4516 was c3e4516, checked in by Ted Faber <faber@…>, 12 years ago

Whoops. Remove debug

  • Property mode set to 100644
File size: 4.2 KB
Line 
1#!/usr/local/bin/python
2
3import ABAC
4import Creddy
5
6import os
7import re
8import copy
9import base64
10
11from tempfile import mkdtemp
12from shutil import rmtree
13
14class proof:
15    def __init__(self, name, prover, role, principal, creds):
16        self.name = name
17        self.prover = prover
18        self.role = role
19        self.principal = principal
20        self.ctxt = ABAC.Context()
21        self.keyid_to_cn = { }
22        self.cn_to_keyid = { }
23        attrs = []
24        try:
25            d = mkdtemp()
26            for c in creds:
27                cc = self.pem_to_der(c)
28                succ = self.ctxt.load_id_chunk(cc) 
29                if succ == ABAC.ABAC_CERT_SUCCESS: 
30                    try:
31                        fn = os.path.join(d, 'file.pem')
32                        f = open(fn, 'w')
33                        f.write(cc)
34                        f.close()
35                        cid = Creddy.ID(fn)
36                        base_cn = cn = re.sub('_ID.pem$','',cid.cert_filename())
37                        i = 0
38                        while cn in self.cn_to_keyid:
39                            cn = '%s%03d' % (base_cn, i)
40                            i += 1
41                        self.cn_to_keyid[cn] = cid.keyid()
42                        self.keyid_to_cn[cid.keyid()] = cn
43                    except EnvironmentError, e:
44                        print >>sys.stderr, '%s: %s' % (e.filename, e.strerror)
45                else:
46                    attrs.append(cc)
47            for c in attrs:
48                self.ctxt.load_attribute_chunk(c) 
49        finally:
50            rmtree(d)
51
52
53    @staticmethod
54    def pem_to_der(c):
55        pat = '-----BEGIN CERTIFICATE-----(.*)-----END CERTIFICATE'
56        m = re.match(pat, c, re.DOTALL)
57        if m: return base64.b64decode(m.group(1))
58        else: return c
59
60    def replace_keyids(self, s):
61        for k, v in self.keyid_to_cn.items():
62            s = re.sub(k, v, s)
63        return s
64
65    def __str__(self):
66        s = 'Name: %s\n' % self.name
67        s += 'Prover: %s\n' % self.prover
68        s += 'Principal: %s\n' % self.principal
69        s += 'Role: %s\n' % self.role
70        s += 'Creds: \n'
71        for c in self.ctxt.credentials():
72            s += self.replace_keyids(
73                    '%s <- %s\n' % ( c.head().string(), c.tail().string()))
74        return s
75
76def read_proofs(fn):
77    proofs = []
78    try:
79        f = open(fn, 'r')
80        creds = []
81        for line in f:
82            line = line.strip()
83            if line == '<proof>':
84                prover = None
85                principal = None
86                role = None
87                creds = []
88            elif line == '</proof>' :
89                p = proof(name, prover, role, principal, creds)
90                ok, pp = p.ctxt.query(role, principal)
91                if not ok: proofs.append(p)
92           
93            m = re.match('<comment>(.*)</comment>', line)
94            if m is not None:
95                name = m.group(1)
96
97            m = re.match('<principal>([0-9a-f]+)</principal>', line)
98            if m is not None:
99                principal = m.group(1)
100
101            m = re.match('<prover>([0-9a-f]+)</prover>', line)
102            if m is not None:
103                prover = m.group(1)
104
105            m = re.match('<attribute>(.*)</attribute>', line)
106            if m is not None:
107                role = m.group(1)
108
109            m = re.match('<credential>(.*)</credential>', line)
110            if m is not None:
111                creds.append(base64.b64decode(m.group(1)))
112        f.close()
113    except EnvironmentError, e:
114        return None
115    return proofs
116
117def interpret_proof(p):
118    roles = set()
119    direct_roles = {}
120    groles = set()
121    principals = set()
122    goals = set()
123    attrs = set()
124    ok, proof = p.ctxt.query(p.role, p.principal)
125    for c in p.ctxt.credentials():
126        role = c.tail()
127        if role.is_principal():
128            if role.string() != p.principal: 
129                principals.add(role.string())
130            else:
131                assigner, r = c.head().string().split('.')
132                direct_roles[r] = assigner
133        else: 
134            r = role.string()
135            for s in r.split('&'):
136                roles.add(s.strip())
137            groles.add(r)
138
139        role = c.head()
140        roles.add(role.string())
141        groles.add(role.string())
142
143    for r in groles:
144        ok, proof =  p.ctxt.query(p.role, r)
145        if ok :
146            goals.add(r)
147    for r in roles:
148        ok, proof = p.ctxt.query(r, p.principal)
149        if ok:
150            attrs.add(r)
151
152    split_goals = [ [s.strip() for s in g.split('&')] for g in goals ]
153    plans = []
154    for sg in split_goals:
155        p = []
156        for g in sg:
157            if g.count('.') == 2:
158                # linking role
159                pr, rr, lr = g.split('.')
160                if lr in direct_roles:
161                    p.append('add %s.%s to %s' % (pr, rr, direct_roles[lr]))
162                else:
163                    p.append('someone with %s.%s must delegate %s to %s' % \
164                            (pr, rr, lr, p.principal))
165            elif g.count('.') == 1:
166                p.append('add %s to %s' % (g, principal))
167        plans.append('\n'.join(p))
168
169    return plans
170
171
172proofs = read_proofs('./auth.log')
173plans = interpret_proof(proofs[0])
174for p in proofs:
175    plans = interpret_proof(p)
176    print "%s needs to have %s" % (p.principal, p.role)
177    print "accompilsh this by: "
178    first = True
179    for pl in plans:
180        if not first: print '---'
181        else: first = False
182        print pl
Note: See TracBrowser for help on using the repository browser.