Clover Coverage Report
Coverage timestamp: Sun Mar 23 2008 08:24:39 GMT
48   318   17   9.6
24   97   0.44   5
5     4.2  
1    
 
 
  AccessPolicy       Line # 65 48 17 80.5% 0.8051948
 
No Tests
 
1    /*
2    * Copyright (c) 2000-2005, University of Salford
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions are met:
7    *
8    * Redistributions of source code must retain the above copyright notice, this
9    * list of conditions and the following disclaimer.
10    *
11    * Redistributions in binary form must reproduce the above copyright notice,
12    * this list of conditions and the following disclaimer in the documentation
13    * and/or other materials provided with the distribution.
14    *
15    * Neither the name of the University of Salford nor the names of its
16    * contributors may be used to endorse or promote products derived from this
17    * software without specific prior written permission.
18    *
19    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20    * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21    * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22    * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23    * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24    * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25    * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26    * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27    * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28    * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29    * POSSIBILITY OF SUCH DAMAGE.
30    */
31   
32    package issrg.pba.rbac.policies;
33   
34    import issrg.pba.DecisionWithObligationException;
35    import issrg.pba.Obligations;
36    import issrg.utils.repository.Entry;
37    import issrg.pba.PbaException;
38    import issrg.pba.Response;
39    import issrg.pba.PERMISResponse;
40    import issrg.pba.rbac.xmlpolicy.XMLPolicyParser;
41    import java.util.Map;
42    import java.util.Hashtable;
43    import java.util.Vector;
44    import org.apache.log4j.*;// added for logging
45    /**
46    * This is the class representing the Target Access Policy. It delivers the
47    * decision
48    * on whether a user with a certain set of credentials is allowed to access a
49    * target.
50    * <p>
51    * It knows the rules for accessing targets, and can make a decision based on
52    * those rules, when passed the set of credentials, the action and the target
53    * parameters.
54    * <p>
55    * It is aware of the Target domains and all Target Access Policy statements,
56    * including the IF statement.
57    * <p>
58    *
59    * @see AccessRule
60    *
61    * @author A Otenko
62    * @version 1.0
63    */
64   
 
65    public class AccessPolicy {
66    private Logger logger = Logger.getLogger(AccessPolicy.class);
67    /**
68    * This is where the action policy is stored for internal purposes
69    */
70    protected XMLPolicyParser.ActionPolicyNode actionPolicy;
71   
72    /**
73    * This is where the target domain policy is stored for internal purposes
74    */
75    protected XMLPolicyParser.DomainPolicyNode targetPolicy;
76   
77    /**
78    * This is where the Access Rules are stored
79    */
80    protected java.util.Map rules;
81   
82    /**
83    * This is added for MSoD.
84    *
85    */
86    MSoDPolicySet msodPolicySet;
87   
88    /**
89    * This is used to determine where the parameters start in the action
90    * definition String array. It is 1 now, but can be 0 if we decide to remove
91    * the return type of the action.
92    */
93    private final static int SHIFT_ACTIONS=1;
94   
 
95  0 toggle protected AccessPolicy(){}
96   
97    /**
98    * This constructor creates the object out of a set of the access Rules. There
99    * are two special kinds of rules. One of the rules is
100    * the Action Policy that defines the methods. To find it among the rules,
101    * the XMLPolicyParser.ActionPolicyNode.class is used as the key, and the
102    * value is assumed to be an XMLPolicyParser.ActionPolicyNode object
103    * containing the
104    * action definitions accessible by the action name.
105    *
106    * <p>The other special rule is the Target Policy, specifying the domains of
107    * targets. To find it among the rules, XMLPolicyParser.DomainPolicyNode.class
108    * is used as the key and the value is assumed to be a
109    * XMLPolicyParser.DomainPolicyNode
110    *
111    * <p>All the other rules are indexed by Action name and constitute Vectors
112    * of AccessRule objects. There is a special action with an empty name ("").
113    * The entry for this action contains the rules that allow any action to be
114    * executed, without explicitly naming them. So to make a decision, the
115    * AccessPolicy finds all the rules that belong to the named action
116    * (i.e.&nbsp;the TargetAccess names the action explicitly) and all the rules
117    * that do not name any action (i.e.&nbsp;the TargetAccess allows any action
118    * to be executed, if the condition is met). If there is a rule that can be
119    * satisfied (the Subject has the required Credentials and the IF-condition
120    * evaluates to true, if present), then access can be granted.
121    *
122    * @param accessRules is a map of rules, created by the PolicyParser; the map
123    * is indexed by Action name, and contains
124    * Vectors of Target access rules for each of them, including the
125    * specification of what targets can execute this action, and what is the
126    * minimal set of credentials for gaining that access;
127    */
 
128  24 toggle public AccessPolicy(java.util.Map accessRules) {
129  24 rules = accessRules;
130  24 actionPolicy = (XMLPolicyParser.ActionPolicyNode)accessRules.get(XMLPolicyParser.ActionPolicyNode.class);
131  24 targetPolicy = (XMLPolicyParser.DomainPolicyNode)accessRules.get(XMLPolicyParser.DomainPolicyNode.class);
132    }
133   
134   
135    /**
136    * This constructor is for MSoD.
137    * DONT YOU EVER COPY PASTE IN YOUR LIFE! IT IS A SIN!
138    */
 
139  4 toggle public AccessPolicy(java.util.Map accessRules, MSoDPolicySet msodPS) {
140  4 this(accessRules); // this is the right way to ensure this constructor does the same as the other one
141  4 msodPolicySet = msodPS; // added for MSoD
142    //rules = accessRules;
143    //actionPolicy = (XMLPolicyParser.ActionPolicyNode)accessRules.get(XMLPolicyParser.ActionPolicyNode.class);
144    //targetPolicy = (XMLPolicyParser.DomainPolicyNode)accessRules.get(XMLPolicyParser.DomainPolicyNode.class);
145    }
146   
147   
148    /**
149    * This method performs the actual access control. Given a set of credentials,
150    * it checks whether there is any statement in the TargetAccessPolicy that
151    * allows to perform the given Action on the given Target. After matching
152    * the set of credentials and the Target domain, the IF statement is
153    * evaluated,
154    * involving the Environment and the arguments to the Action.
155    *
156    * <p>Note that the IF statement is the interpretation tree, which is built
157    * by the PolicyParser, and it can evaluate itself.
158    *
159    * <p>To find the rules, the rule set provided to the constructor is searched
160    * for rules mentioning the Action explicitly, and for the rules implying the
161    * Action (i.e.&nbsp;the rules allowing "any" action).
162    *
163    * @param creds is the set of credentials the user possesses
164    * @param a is the action the user wants to perform (name + action ADI)
165    * @param t is the target the user wants to perform (name + target ADI);
166    * Target must return TargetADI implementing Entry interface
167    * @param environment is the collection of environmental parameters to the
168    * action; contextual ADI
169    *
170    * @return true, if the requested access can be granted; false, if the access
171    * is denied by the policy
172    * @throws PbaException in any case of error; for example, malformed
173    * parameters
174    * to the method, or an error in decision evaluation, thrown by an Access
175    * Rule
176    * @throws DecisionWithObligationException, if the policy requires some
177    * Obligations to be enforced along with the decision; either handle this
178    * case specially to enforce the obligations, or use response method
179    * @see AccessPolicy#response
180    */
 
181  0 toggle public boolean decision(issrg.pba.Credentials creds, issrg.pba.Action a,
182    issrg.pba.Target t, java.util.Map environment)
183    throws PbaException{
184  0 Response resp = response(creds,a,t,environment);
185  0 Obligations oblgs=resp.getObligations();
186  0 if((oblgs!=null)||(oblgs.isEmpty()==false)){
187    //thorw an error here, telling that the decision shall be enforced with obligations.
188  0 throw new DecisionWithObligationException("There are obligations associated with this decision, which must be fulfiled with the enforcement of the decision.",resp);
189    }
190   
191  0 return resp.isAuthorised();
192   
193    }
194   
195    /**
196    * This method makes a decision, and returns a response regarding to the
197    * request represented by a set of Credentials, an Action, the Target and
198    * the Environment. The response may contain obligations.
199    *
200    * @param creds is the set of credentials the user possesses
201    * @param a is the action the user wants to perform (name + action ADI)
202    * @param t is the target the user wants to perform (name + target ADI);
203    * Target
204    * must return TargetADI implementing Entry interface
205    * @param environment is the collection of environmental parameters to the
206    * action; contextual ADI
207    *
208    * @return a Response that contains the authorisation decision and the
209    * obligations that must be enforced along with it.
210    */
 
211  1359 toggle public Response response(issrg.pba.Credentials creds, issrg.pba.Action a,
212    issrg.pba.Target t, java.util.Map environment)
213    throws PbaException{
214   
215    //System.out.println("\t\t*** ACCESS POLICY INVOCATION ***\n\t"+rules); //*****
216   
217  1359 Object targetADI = t.getTargetADI();
218   
219  1359 PERMISResponse sd;
220   
221  1359 if (!(targetADI instanceof Entry) || !targetPolicy.getCoverageDomain().contains((Entry)targetADI)){
222  241 logger.debug("Target is out of target domain");
223  241 throw new TargetOutOfDomainException("Target is out of target domain");
224    }
225  1118 logger.debug("target check : pass");
226  1118 if ((a==null) ^ (actionPolicy==null)){
227    // the condition reads: the action cannot be null, if actionPolicy is not null
228    // however, it must be null, if the actionPolicy is null
229  0 logger.debug("Unacceptable Action for this Policy");
230  0 throw new PbaException("Unacceptable Action for this Policy");
231    }
232  1118 logger.debug("action check : pass");
233  1118 Map actionADI = new Hashtable();
234  1118 String aName="\0"; // the default action name, if the action is null
235    // the first loop (see below) will always skip in that case
236    // (because the actionPolicy would be null)
237   
238  1118 if (a!=null){
239    // actionPolicy is not null here
240  1118 aName=a.getActionName();
241  1118 String [] paramNames = actionPolicy.getActionDefinition(aName);
242  1118 Object o = a.getContextualADI(); // this should be an array of actual parameters, within Permis RBAC
243  1118 if (o==null) o=new Object[0];
244  1118 Object [] o1;
245   
246    //String hihix = (!(o instanceof Object[]))?"contextual ADI is not an Argument[]: "+o:
247    // (paramNames==null?"paramNames==null":
248    // (
249    // ((o1=((Argument[])o)).length!=paramNames.length-SHIFT_ACTIONS)?
250    // ("array lengths do not match: "+o1.length+"!="+paramNames.length+"-"+SHIFT_ACTIONS)
251    // :null
252    // )
253    // );
254  0 if (!(o instanceof Object[]) || // is it an array of parameters?
255    paramNames==null || // is there such an action?
256    (o1 = (Object [])o).length!=paramNames.length-SHIFT_ACTIONS){ // are the arrays of actual parameters and argument names of the same length?
257  60 logger.debug("Unacceptable Action for this Policy "+aName);
258  60 throw new PbaException("Unacceptable Action for this Policy: "+aName);
259    }
260  1058 logger.debug("action parameters check : pass");
261    // prepare the actionADI now
262    // array index ranges are checked
263  1814 for (int i=0; i<o1.length; i++){
264  756 actionADI.put(paramNames[i+SHIFT_ACTIONS], o1[i]);
265    }
266    }
267   
268  2940 for(String bName=""; aName!=null; aName=bName, bName=null){ // loop twice: once for the real action name, the second time for "" name: any Action
269    // look for rules applicable to this action (either aName or AnyAction)
270   
271  1999 Vector accessRules = (Vector)rules.get(aName); // they are vectors there
272    //System.out.println("access rules for action: "+aName+" - "+accessRules);//***************
273    /**
274    * TODO: check class cast there ^^^ and throw an exception on error
275    */
276   
277  1999 if (accessRules==null){
278  943 continue; // it may happen that there is no rule for this action
279    // alone, but there can be a rule for AnyAction; or vice versa
280    }
281   
282  4429 for (int i=accessRules.size(); i-->0; ){
283  3490 AccessRule ar = (AccessRule)accessRules.get(i);
284  3490 logger.debug("access rule = "+ar.toString());
285  3490 if (ar.decide(creds, targetADI, actionADI, environment)){
286    //System.out.println("granted access because: "+ar); //************** this should be turned into a logging message - by which authority access has been granted
287   
288    //return true; // found one rule that is applicable and grants access
289   
290    //@todo this is where we found the rule that can be applied to the current request.
291   
292  117 logger.debug("permit");
293    // This line is changed to insert MSoD. added for MSoD
294  117 if (msodPolicySet == null) {
295  83 return new PERMISResponse(true, ar.getObligations());
296    }
297    else {
298  34 return new PERMISResponse(
299    !msodPolicySet.separationOfDutiesApplies(creds, /*ar.getCreds(),*/ /*subject, */a, t, environment) ,
300    ar.getObligations());
301    //when msodPolicySet.separationOfDutiesApplies() returns true, it means a Separation of Duty rule applies here,
302    // this rule should forbid the user to get the access, i.e. the access request should be forbidden.
303    // So please note that "true" here means to deny access, "false" here means to grant access.
304    }
305    }
306   
307    //System.out.println("access rule "+ar+" denied access"); //**************
308    }
309    }
310   
311   
312  941 return new PERMISResponse(false);
313   
314    //return false;
315    }
316    }
317   
318