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

abac0-leakabac0-meicompt_changesgec13mei-idmei-rt0-nmei_rt0mei_rt2mei_rt2_fix_1meiyap-rt1meiyap1rt2tvf-new-xml
Last change on this file since cac4c76 was cac4c76, checked in by Mike Ryan <mikeryan@…>, 13 years ago

support for creating intersection roles and adding them to the
credential graph. Implied edges are properly created in the credential
graph, but they are not returned in queries.

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