source: java/net/deterlab/abac/CredentialGraph.java @ f0ae3d8

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

Merge branch 'native_java' of abac.deterlab.net:/var/local/git/abac into native_java

  • Property mode set to 100644
File size: 6.6 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>synchronizedDirectedGraph(
27                new DirectedSparseGraph<Role,Credential>());
28        pq = new Query(g);
29    }
30
31    /**
32     * Returns a Query object which can be used to query the graph. This object
33     * becomes invalid if the graph is modified.
34     */
35    public Query querier() {
36        derive_implied_edges();
37        return new Query(g);
38    }
39
40    /**
41     * Add a role to the graph./
42     */
43    public void add_vertex(Role role) {
44        g.addVertex(role);
45    }
46
47    /**
48     * Remove a role from the grpah if it exists.
49     */
50    public void remove_vertex(Role role) {
51        g.removeVertex(role);
52    }
53
54    /**
55     * Get a list of all roles known to the graph.
56     */
57    public Collection<Role> roles() {
58        return g.getVertices();
59    }
60
61    /**
62     * Add a credential to the graph.
63     */
64    public void add_credential(Credential cred) {
65        Role tail = cred.tail();
66        Role head = cred.head();
67
68        /* explicitly add the vertices, otherwise get a null pointer exception */
69        if ( !g.containsVertex(tail)) 
70            g.addVertex(tail);
71        if ( !g.containsVertex(tail)) 
72            g.addVertex(head);
73
74        if (!g.containsEdge(cred))
75            g.addEdge(cred, tail, head);
76
77        // add the prereqs of an intersection to the graph
78        if (tail.is_intersection())
79            for (Role prereq : tail.prereqs())
80                g.addVertex(prereq);
81
82        m_dirty = true;
83    }
84
85    /**
86     * Remove a credential from the graph.
87     */
88    public void remove_credential(Credential cred) {
89        if (g.containsEdge(cred))
90            g.removeEdge(cred);
91        m_dirty = true;
92    }
93
94    /**
95     * Add a role w/o an edge
96     */
97    public void add_vertex(Role v) {
98        if (!g.containsVertex(v)) {
99            g.addVertex(v);
100            m_dirty = true;
101        }
102    }
103
104    public void remove_vertex(Role v) {
105        if (g.containsVertex(v)) {
106            g.removeVertex(v);
107            m_dirty = true;
108        }
109    }
110
111    /**
112     * Returns a collection of the credentials in the graph.
113     */
114    public Collection<Credential> credentials() {
115        Collection<Credential> creds = new HashSet<Credential>();
116
117        // only return creds with a cert: all others are derived edges
118        for (Credential cred : g.getEdges())
119            if (cred.cert() != null)
120                creds.add(cred);
121
122        return creds;
123    }
124
125    public Collection<Role> roles() {
126        return g.getVertices();
127    }
128
129    /**
130     * Derive the implied edges in the graph, according to RT0 derivation rules.
131     * They are added to this graph. See "Distributed Credential Chain Discovery
132     * in Trust Management" by Ninghui Li et al. for details. Note that a
133     * derived linking edge can imply a new intersection edge and vice versa.
134     * Therefore we iteratively derive edges, giving up when an iteration
135     * produces 0 new edges.
136     */
137    protected synchronized void derive_implied_edges() {
138        // nothing to do on a clean graph
139        if (!m_dirty)
140            return;
141
142        clear_old_edges();
143
144        // iteratively derive links. continue as long as new links are added
145        while (derive_links_iter() > 0)
146            ;
147        m_dirty = false;
148    }
149
150    /**
151     * Single iteration of deriving implied edges. Returns the number of new
152     * links added.
153     */
154    protected int derive_links_iter() {
155        int count = 0;
156
157        /* for every node in the graph.. */
158        for (Role vertex : g.getVertices()) {
159            if (vertex.is_intersection()) {
160                // for each prereq edge:
161                //     find set of principals that have the prereq
162                // find the intersection of all sets (i.e., principals that satisfy all prereqs)
163                // for each principal in intersection:
164                //     add derived edge
165
166                Set<Role> principals = null;
167
168                for (Role prereq : vertex.prereqs()) {
169                    Set<Role> cur_principals = pq.find_principals(prereq);
170
171                    if (principals == null)
172                        principals = cur_principals;
173                    else
174                        // no, they couldn't just call it "intersection"
175                        principals.retainAll(cur_principals);
176
177                    if (principals.size() == 0)
178                        break;
179                }
180
181                // add em
182                for (Role principal : principals)
183                    if (add_derived_edge(vertex, principal))
184                        ++count;
185            }
186
187            else if (vertex.is_linking()) {
188                // make the rest of the code a bit clearer
189                Role A_r1_r2 = vertex;
190
191                Role A_r1 = new Role(A_r1_r2.A_r1());
192                String r2 = A_r1_r2.r2();
193
194                /* locate the node A.r1 */
195                if (!g.containsVertex(A_r1)) continue; /* boring: nothing of the form A.r1 */
196
197                /* for each B that satisfies A_r1 */
198                for (Role principal : pq.find_principals(A_r1)) {
199                    Role B_r2 = new Role(principal + "." + r2);
200                    if (!g.containsVertex(B_r2)) continue;
201
202                    if (add_derived_edge(A_r1_r2, B_r2))
203                        ++count;
204                }
205            }
206        }
207
208        return count;
209    }
210
211    /**
212     * Add a derived edge in the graph. Returns true only if the edge does not
213     * exist.
214     */
215    protected boolean add_derived_edge(Role head, Role tail) {
216        // edge exists: return false
217        if (g.findEdge(tail, head) != null)
218            return false;
219
220        // add the new edge
221        Credential derived_edge = new Credential(head, tail);
222        derived_edges.add(derived_edge);
223        g.addEdge(derived_edge, tail, head);
224
225        return true;
226    }
227
228    /**
229     * Clear the derived edges that currently exist in the graph. This is done
230     * before the edges are rederived. The derived edges in filtered graphs are
231     * also cleared.
232     */
233    protected void clear_old_edges() { 
234        for (Credential i: derived_edges) 
235            g.removeEdge(i);
236        derived_edges = new HashSet<Credential>();
237    }
238}
Note: See TracBrowser for help on using the repository browser.