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

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

Make private protected to derive things.

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