source: java/net/deterlab/abac/CredentialGraph.java @ 622bdbc

abac0-leakabac0-meicompt_changesgec13mei-idmei-rt0-nmei_rt0mei_rt2mei_rt2_fix_1meiyap-rt1meiyap1rt2tvf-new-xml
Last change on this file since 622bdbc was 622bdbc, checked in by Ted Faber <faber@…>, 13 years ago

Safety first

  • Property mode set to 100644
File size: 5.8 KB
Line 
1package net.deterlab.abac;
2
3import org.apache.commons.collections15.*;
4import org.apache.commons.collections15.functors.*;
5
6import edu.uci.ics.jung.graph.*;
7import edu.uci.ics.jung.graph.event.*;
8import edu.uci.ics.jung.graph.util.*;
9
10import java.awt.geom.Point2D;
11import java.io.*;
12import java.util.*;
13
14/**
15 * Represents a global graph of credentials in the form of principals and
16 * attributes.
17 */
18public class CredentialGraph {
19    protected Graph<Role,Credential> g = null;
20    protected java.util.Set<Credential> derived_edges = new HashSet<Credential>();
21    protected Query pq;
22    protected boolean m_dirty;
23
24    public CredentialGraph() {
25        /* create the graph */
26        g = Graphs.<Role,Credential>synchronizedForest(
27                new DelegateForest(
28                    new DirectedSparseGraph<Role,Credential>()));
29        pq = new Query(g);
30    }
31
32    /**
33     * Returns a Query object which can be used to query the graph. This object
34     * becomes invalid if the graph is modified.
35     */
36    public Query querier() {
37        derive_implied_edges();
38        return new Query(g);
39    }
40
41    /**
42     * Add a credential to the graph.
43     */
44    public void add_credential(Credential cred) {
45        Role tail = cred.tail();
46        Role head = cred.head();
47
48        /* explicitly add the vertices, otherwise get a null pointer exception */
49        g.addVertex(tail);
50        g.addVertex(head);
51
52        g.addEdge(cred, tail, head);
53
54        // add the prereqs of an intersection to the graph
55        if (tail.is_intersection())
56            for (Role prereq : tail.prereqs())
57                g.addVertex(prereq);
58
59        m_dirty = true;
60    }
61
62    /**
63     * Remove a credential from the graph.
64     */
65    public void remove_credential(Credential cred) {
66        if (g.containsEdge(cred))
67            g.removeEdge(cred);
68        m_dirty = true;
69    }
70
71    /**
72     * Returns a collection of the credentials in the graph.
73     */
74    public Collection<Credential> credentials() {
75        Collection<Credential> creds = new HashSet<Credential>();
76
77        // only return creds with a cert: all others are derived edges
78        for (Credential cred : g.getEdges())
79            if (cred.cert() != null)
80                creds.add(cred);
81
82        return creds;
83    }
84
85    /**
86     * Derive the implied edges in the graph, according to RT0 derivation rules.
87     * They are added to this graph. See "Distributed Credential Chain Discovery
88     * in Trust Management" by Ninghui Li et al. for details. Note that a
89     * derived linking edge can imply a new intersection edge and vice versa.
90     * Therefore we iteratively derive edges, giving up when an iteration
91     * produces 0 new edges.
92     */
93    protected synchronized void derive_implied_edges() {
94        // nothing to do on a clean graph
95        if (!m_dirty)
96            return;
97
98        clear_old_edges();
99
100        // iteratively derive links. continue as long as new links are added
101        while (derive_links_iter() > 0)
102            ;
103        m_dirty = false;
104    }
105
106    /**
107     * Single iteration of deriving implied edges. Returns the number of new
108     * links added.
109     */
110    protected int derive_links_iter() {
111        int count = 0;
112
113        /* for every node in the graph.. */
114        for (Role vertex : g.getVertices()) {
115            if (vertex.is_intersection()) {
116                // for each prereq edge:
117                //     find set of principals that have the prereq
118                // find the intersection of all sets (i.e., principals that satisfy all prereqs)
119                // for each principal in intersection:
120                //     add derived edge
121
122                Set<Role> principals = null;
123
124                for (Role prereq : vertex.prereqs()) {
125                    Set<Role> cur_principals = pq.find_principals(prereq);
126
127                    if (principals == null)
128                        principals = cur_principals;
129                    else
130                        // no, they couldn't just call it "intersection"
131                        principals.retainAll(cur_principals);
132
133                    if (principals.size() == 0)
134                        break;
135                }
136
137                // add em
138                for (Role principal : principals)
139                    if (add_derived_edge(vertex, principal))
140                        ++count;
141            }
142
143            else if (vertex.is_linking()) {
144                // make the rest of the code a bit clearer
145                Role A_r1_r2 = vertex;
146
147                Role A_r1 = new Role(A_r1_r2.A_r1());
148                String r2 = A_r1_r2.r2();
149
150                /* locate the node A.r1 */
151                if (!g.containsVertex(A_r1)) continue; /* boring: nothing of the form A.r1 */
152
153                /* for each B that satisfies A_r1 */
154                for (Role principal : pq.find_principals(A_r1)) {
155                    Role B_r2 = new Role(principal + "." + r2);
156                    if (!g.containsVertex(B_r2)) continue;
157
158                    if (add_derived_edge(A_r1_r2, B_r2))
159                        ++count;
160                }
161            }
162        }
163
164        return count;
165    }
166
167    /**
168     * Add a derived edge in the graph. Returns true only if the edge does not
169     * exist.
170     */
171    protected boolean add_derived_edge(Role head, Role tail) {
172        // edge exists: return false
173        if (g.findEdge(tail, head) != null)
174            return false;
175
176        // add the new edge
177        Credential derived_edge = new Credential(head, tail);
178        derived_edges.add(derived_edge);
179        g.addEdge(derived_edge, tail, head);
180
181        return true;
182    }
183
184    /**
185     * Clear the derived edges that currently exist in the graph. This is done
186     * before the edges are rederived. The derived edges in filtered graphs are
187     * also cleared.
188     */
189    protected void clear_old_edges() { 
190        for (Credential i: derived_edges) 
191            g.removeEdge(i);
192        derived_edges = new HashSet<Credential>();
193    }
194}
Note: See TracBrowser for help on using the repository browser.