source: fedd/abac-src/ttg/process/TTG.java @ 2f14616

version-1.30
Last change on this file since 2f14616 was 8780cbec, checked in by Jay Jacobs <Jay.Jacobs@…>, 15 years ago

ABAC sources from Cobham

  • Property mode set to 100644
File size: 13.6 KB
Line 
1package com.nailabs.abac.process;
2
3import com.nailabs.abac.trust.*;
4import com.nailabs.abac.test.*;
5import com.nailabs.abac.credential.*;
6import edu.stanford.peer.rbtm.credential.*;
7import edu.stanford.peer.rbtm.engine.*;
8
9import edu.stanford.rt.credential.CredentialDomain;
10import edu.stanford.rt.credential.CredentialStore;
11import edu.stanford.rt.credential.RTContext;
12import edu.stanford.rt.parser.RTParser;
13import java.io.ByteArrayInputStream;
14import java.io.InputStream;
15import java.util.*;
16
17/**
18 * A trust target graph (TTG) is used to represent the state of a trust
19 * negotiation in process (one per graph).
20 * @version     $Id: TTG.java,v 1.50 2003/02/26 00:45:11 jjacobs Exp $ 
21
22 */
23public class TTG extends Observable implements Observer { 
24    /** The top-level trust target the system is trying to solve. */
25    protected TargetNode root;
26
27    /** An index of TTGNodes based on their trust targets */
28    protected Hashtable indexByTT = new Hashtable();
29
30    /** The old change list for this graph */
31    protected Message oldDelta =  new Message();
32
33    /** The current change list for this graph */
34    protected Message newDelta = new Message();
35
36    /** A set of all previoussent credentials */
37    protected HashSet outCache = new HashSet();
38
39    /** A graph engine for storing remotely held credential */
40    protected GraphEngine oppoCreds = null;
41
42    /** An RTML parser for de-serializing RTML evidence */
43    protected RTParser parser = null;
44   
45    /** An RTML context for incoming opponent's credentials */
46    protected RTContext rtc = null;
47
48    /** A context for a single trust negotiation */
49    protected NegotiationContext context;
50
51    /** Create a trust target graph for a specific negotiation */
52    public TTG(NegotiationContext context){
53        this.context = context;
54        if(context.getFrontier() instanceof RtmlFrontier) {
55            try {
56                parser = new RTParser();
57                rtc = new RTContext(parser);
58                oppoCreds = new RtmlEngine(new CredentialStore(parser));
59            }
60            catch(Exception ex) {
61                debug("rtml", ex.getMessage());
62            }
63        } else {
64            oppoCreds = new GraphEngine();
65        }
66    }
67
68    /** Propagates node state change information to a graph observer */
69    public void update(Observable o, Object arg) {
70        //if(o instanceof TTGNode) {
71        setChanged();
72        notifyObservers(arg);
73        //}
74        //else {
75        //debug("update", "received unexpected observation from " + arg);
76        //}
77    }
78
79    /**
80     * This returns an internal list of all node in the trust target graph.
81     * WARNING: this should be a privileged function for production use. Also,
82     * any changes to the TTG will invalidate this iterator!
83     */
84    public Iterator getNodes() {
85        return indexByTT.values().iterator();
86    }
87
88    public TTGNode getNode(Goal key) {
89        TTGNode node = getNodeByHash(key);
90        if(node == null) {
91            node = TTGNode.createNode(key);
92            putNodeByHash(node);
93            debug("node", "initialized node for " + key);
94        }
95        else {
96            debug("node", "found node for " + key);
97
98        }
99        return node;
100    }
101
102    /** Access a trust target node by the goal it represents */
103    public TTGNode getNodeByHash(Goal key) {
104        return (TTGNode)indexByTT.get(key.toString());
105    }
106
107    /** Entry point for global or local changes. */
108    public void putNodeByHash(TTGNode node) {
109        indexByTT.put(node.getGoal().toString(), node);
110        debug("node", "putting " + node.getGoal());
111        node.init(context);
112        context.getStrategy().addToWorklist(node);
113        context.getStrategy().addNewNode(node);
114        setChanged();
115        notifyObservers((Object)node);
116   
117    }
118
119    public void putRoot(TargetNode node) {
120        debug("root", "putting root" + node);
121        root = node;
122        setChanged();
123        notifyObservers((Object)node);
124    }
125
126    /** A method to reset the change list at the end of a processing cycle */
127    public void reset() { 
128        //consolidate credentials
129        Iterator i = newDelta.getEvidence();
130        while(i.hasNext()) {
131            Object potential = i.next();
132            if(outCache.contains(potential)) {
133                i.remove();
134            } else {
135                outCache.add(potential);
136            }
137        }
138        oldDelta = newDelta;    // swap out the deltas
139        newDelta = new Message();     
140        setChanged();           // notify observers of the changed message
141        notifyObservers((Object)oldDelta);
142    }
143
144    /** Accessor method for the change list on the graph and resets the list */
145    public Message getChanges() {
146        return newDelta;
147    }
148   
149    public boolean verifyEvidence(Operation op) {
150        Entity self = context.getSelf();
151        if(op instanceof LinkingImplicationEdge) {
152            return false;
153        }
154        if((op instanceof ImplicationEdge)) { 
155            Goal g = ((EdgeOperation)op).getParent();
156            debug("message", "verifying operation " + op);
157            return(self.equals(g.getVerifier()));
158        }
159        debug("message", "not verifying operation " + op);
160        return false;
161    }
162
163    /** boolean query to determine whether the sepcified goal needs evidence */
164    public boolean provideEvidence(Operation edge) {
165        Goal g = ((EdgeOperation)edge).getParent();
166        Entity self = context.getSelf();
167        return (!self.equals(g.getVerifier()));
168    }
169
170    /** Update this graph with changes contained in the specified message */
171    public void update(Message msg) throws Exception {
172        setChanged();
173        //notifyObservers("<Update location=\"remote\">\n");
174        notifyObservers("location = remote");
175        Iterator ev = msg.getEvidence();
176        while(ev.hasNext()) {
177            Object eObj = ev.next();
178            if(eObj instanceof String) {
179                String xml = (String) eObj;
180                InputStream in = new ByteArrayInputStream(xml.getBytes());
181                CredentialDomain domain = 
182                    parser.parseCredentialDomain(in, rtc);
183                ((RtmlEngine)oppoCreds).addDomain(domain);
184                debug("message", "received evidence = " + domain);
185            }
186            else {
187                StaticCredential credential = (StaticCredential)eObj;
188                Debug.rbtmStart();
189                oppoCreds.addCredential(credential);       
190                Debug.rbtmStop();
191                debug("message", "received evidence = " + credential);
192            }
193        }
194        Iterator operations = msg.getOperations();
195        while(operations.hasNext()) {
196            Operation op = (Operation)operations.next();
197            debug("message", "performing op " + op);
198            if(verifyEvidence(op)) {
199                EdgeOperation edgeOp = (EdgeOperation)op;
200                TrustTarget parent = (TrustTarget)edgeOp.getParent();
201                TrustTarget child = (TrustTarget)edgeOp.getChild();
202                HashSet evidence = null;
203               
204                //try {
205                EntityExpression parentRole = parent.getTargetRole();
206                EntityExpression childRole = child.getTargetRole();
207                debug("message", "chain search from " + 
208                      parentRole + " to " + childRole);
209                Debug.rbtmStart();               
210                oppoCreds.backwardSearch(parentRole);
211                if(parentRole.equals(childRole)) {
212                    debug("message", "roles are equal bailing out now!");
213                } else {
214                    evidence = oppoCreds.getChain(parentRole, childRole);
215                    // }
216                    Debug.rbtmStop();
217                    //} catch(Exception ex) {
218                    //ex.printStackTrace();
219                    //throw(new java.rmi.RemoteException("Unjustified implication!!"));
220                }
221                edgeOp.setEvidence(evidence);
222                debug("message", "evidence = " + evidence);
223            }
224            setChanged();
225            notifyObservers((Object)op);
226            op.perform(this);
227        } 
228        setChanged();
229        //notifyObservers("</Update>\n");
230    }
231
232
233    /**
234     * Accessor method for of root of graph. This is necessary to traverse
235     * the graph.
236     * @returns the root node which may be any TTGNode descendent.
237     */
238    public TargetNode getRoot() {
239        return root;
240    }
241
242
243    // Methods in this section are recorded in the delta list
244
245    /**
246     * Insert a new root node for this graph.
247     * <I>This is a global operation</I>
248     */
249    public void setRoot(TrustTarget target) {
250        debug("root", "setting root = " + target);
251        NodeOperation op = new NodeOperation
252            (target, target.getInitialProcessingState(context), true);
253        setChanged();
254        notifyObservers(op);
255        op.perform(this);
256        newDelta.addOperation(op);
257    }
258   
259    /**
260     * Mark a node in the graph as opponent processed.
261     */
262    public void setOpponentProcessed(Goal id) {
263        //TTGNode node = getNode(id);
264        //ProcessingState state = node.getProcessingState();
265        //state.opponentProcess(state);
266        setNode(id, new ProcessingState(false, true));
267    }
268
269    /**
270     * Mark a node in the graph as verifier processed.
271     */
272    public void setVerifierProcessed(Goal id) {
273        //TTGNode node = getNode(id);
274        //ProcessingState state = node.getProcessingState();
275        //state.verifierProcess();
276        setNode(id, new ProcessingState(true, false));
277    }
278
279
280    /**
281     * Add a root or modify a node to this TTG and replicate the changes on
282     * the opponent's TTG.
283     * <I>This is a global operation</I>
284     */
285    public void setNode(Goal id, ProcessingState state)
286    {
287        ProcessingState copy = new ProcessingState();
288        copy.update(state);
289        NodeOperation nodeOp = new NodeOperation(id, copy); 
290        context.getStrategy().scheduleOperation(nodeOp);
291    }
292
293    /** actually performs the node operation on this graph */
294    public void performNode(NodeOperation nodeOp) {
295        // This is slightly different than perform edge although they
296        // could possibly be merged into a single performOperation method
297        nodeOp.perform(this);
298        newDelta.addOperation((Operation)nodeOp);
299        setChanged();
300        notifyObservers((Object)nodeOp);
301    }
302
303    /** actually performs a previously scheduled edge operation */
304    public void performEdge(EdgeOperation edgeOp) 
305    {
306        if(edgeOp instanceof LinkingImplicationEdge) {
307            setChanged();
308            notifyObservers("location = async");
309        }
310        setChanged();
311        notifyObservers((Object)edgeOp);
312        edgeOp.perform(this);
313        if(edgeOp instanceof ImplicationEdge && provideEvidence(edgeOp)) {
314            debug("message", " %%%% adding evidence for " + edgeOp.toString());
315            newDelta.addOperation((Operation)edgeOp);
316        } else {
317            debug("message", " %%%% not adding evidence for" + 
318                  edgeOp.toString());
319            newDelta.addOperationWithoutEvidence((Operation)edgeOp);
320        }
321        if(edgeOp instanceof LinkingImplicationEdge) {
322            setChanged();
323            notifyObservers("location = sync");
324        }
325    }
326
327    /**
328     * Add a new control edge to this TTG and replicate the changes on the
329     * opponent's TTG.
330     * <I>This is a global operation</I>
331     */
332    public void addControlEdge(Goal parent, Goal child)
333    {
334        TTGNode cnode = getNodeByHash(child);
335        ProcessingState state =  (cnode == null)? 
336            child.getInitialProcessingState(context): null;
337        EdgeOperation edgeOp = new ControlEdge(parent, child, state);
338        context.getStrategy().scheduleOperation(edgeOp);
339    }
340
341    /**
342     * Add a new implication edge to this TTG and replicate the changes on the
343     * opponent's TTG.
344     * <I>This is a global operation</I>
345     */
346    public void addImplicationEdge(Goal parent, Goal child, HashSet creds) {
347        TTGNode cnode = getNodeByHash(child);
348        //debug("node", "implication cnode = " + cnode);
349        ProcessingState state = (cnode == null)? 
350            child.getInitialProcessingState(context): null;
351        ImplicationEdge edgeOp = 
352            new ImplicationEdge(parent, child,  state, creds);
353        context.getStrategy().scheduleOperation(edgeOp);
354    }
355
356    /**
357     * Add a new intersection edge to this TTG and replicate the edge on the
358     * opponent's TTG. <i>This is a global operation</i>
359     */
360    public void addIntersectionEdge(TrustTarget parent, TrustTarget child) {
361        TargetNode cnode = (TargetNode)getNodeByHash(child);
362        debug("node", "implication cnode = " + cnode); 
363        ProcessingState state = (cnode == null)? 
364            child.getInitialProcessingState(context): null;
365        IntersectionEdge edgeOp = new IntersectionEdge(parent, child,  state);
366        context.getStrategy().scheduleOperation(edgeOp);       
367    }
368
369    public void addLinkingMonitorEdge(TrustTarget parent, LinkingGoal child) {
370        TTGNode cnode = getNodeByHash(child);
371        ProcessingState state =  (cnode == null)? 
372            child.getInitialProcessingState(context): null;
373        EdgeOperation edgeOp = new LinkingMonitorEdge(parent, child, state);
374        context.getStrategy().scheduleOperation(edgeOp);
375    }
376
377    public void addLinkingSolutionEdge(LinkingGoal monitor, TrustTarget soln) {
378        TTGNode cnode = getNodeByHash(soln);
379        ProcessingState state =  (cnode == null)? 
380            soln.getInitialProcessingState(context): null;
381        EdgeOperation edgeOp = new LinkingSolutionEdge(monitor, soln, state);
382        context.getStrategy().scheduleOperation(edgeOp);
383    }
384
385    public void addLinkingImplicationEdge(TrustTarget parent, TrustTarget child)
386    {
387        TTGNode cnode = getNodeByHash(child);
388        ProcessingState state =  (cnode == null)? 
389            child.getInitialProcessingState(context): null;
390        EdgeOperation edgeOp = 
391            new LinkingImplicationEdge(parent, child, state);
392        context.getStrategy().scheduleOperation(edgeOp);
393    }
394
395    /** Friendly debugging convenience method */
396    protected void debug(String level, String message) {
397        StringBuffer buff = new StringBuffer("TTG[");
398        buff.append(context.getSelf()).append("]: ").append(message);
399        Debug.debug(level, buff.toString());
400    }
401
402
403    public String toString() {
404        StringBuffer buff = new StringBuffer("[TTG EntityID=");
405        buff.append(context.getSelf().toString()).append("\n");
406        Iterator i = indexByTT.keySet().iterator();
407        while(i.hasNext()) {
408            buff.append("\t").append(i.next()).append("\n");
409        }
410        buff.append("]");
411        return buff.toString();
412    }
413
414}
415
416
417
418
419
420
421
Note: See TracBrowser for help on using the repository browser.