Clover Coverage Report
Coverage timestamp: Sun Mar 23 2008 08:24:39 GMT
1,641   2,383   393   37.3
672   1,953   0.27   44
44     9.91  
1    
 
 
  Handler       Line # 117 1641 393 17.4% 0.17394994
 
No Tests
 
1    /*
2    * Copyright (c) 2006, University of Kent
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    * 1. Neither the name of the University of Kent 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    * 2. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20    * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21    * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22    * PURPOSE ARE DISCLAIMED.
23    *
24    * 3. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25    * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26    * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27    * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28    * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29    * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30    * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31    * POSSIBILITY OF SUCH DAMAGE.
32    *
33    * 4. YOU AGREE THAT THE EXCLUSIONS IN PARAGRAPHS 2 AND 3 ABOVE ARE REASONABLE
34    * IN THE CIRCUMSTANCES. IN PARTICULAR, YOU ACKNOWLEDGE (1) THAT THIS
35    * SOFTWARE HAS BEEN MADE AVAILABLE TO YOU FREE OF CHARGE, (2) THAT THIS
36    * SOFTWARE IS NOT "PRODUCT" QUALITY, BUT HAS BEEN PRODUCED BY A RESEARCH
37    * GROUP WHO DESIRE TO MAKE THIS SOFTWARE FREELY AVAILABLE TO PEOPLE WHO WISH
38    * TO USE IT, AND (3) THAT BECAUSE THIS SOFTWARE IS NOT OF "PRODUCT" QUALITY
39    * IT IS INEVITABLE THAT THERE WILL BE BUGS AND ERRORS, AND POSSIBLY MORE
40    * SERIOUS FAULTS, IN THIS SOFTWARE.
41    *
42    * 5. This license is governed, except to the extent that local laws
43    * necessarily apply, by the laws of England and Wales.
44    */
45    /*
46    * PermisWebService.java
47    *
48    * Created on 30 January 2006, 14:34
49    *
50    * By Linying Su
51    *
52    * To change this template, choose Tools | Options and locate the template under
53    * the Source Creation and Management node. Right-click the template and choose
54    * Open. You can then make changes to the template in the Source Editor.
55    */
56   
57    package issrg.utils.handler;
58   
59    import issrg.pba.Action;
60    import issrg.pba.Credentials;
61    import issrg.pba.Obligations;
62    import issrg.pba.PbaException;
63    import issrg.pba.Response;
64    import issrg.pba.Subject;
65    import issrg.pba.RawCredential;
66    import issrg.pba.rbac.AbsoluteValidityPeriod;
67    import issrg.pba.rbac.Argument;
68    import issrg.pba.rbac.BadURLException;
69    import issrg.pba.rbac.Clock;
70    import issrg.pba.rbac.CustomisePERMIS;
71    import issrg.pba.rbac.ExpirableCredentials;
72    import issrg.pba.rbac.IntersectionValidityPeriod;
73    import issrg.pba.rbac.LDAPDNPrincipal;
74    import issrg.pba.rbac.PermisAction;
75    import issrg.pba.rbac.PermisArgument;
76    import issrg.pba.rbac.PermisSubject;
77    import issrg.pba.rbac.PermisTarget;
78    import issrg.pba.rbac.RoleBasedCredentials;
79    import issrg.pba.rbac.SetOfSubsetsCredentials;
80    import issrg.pba.rbac.SignatureVerifier;
81    import issrg.pba.rbac.SimpleSignatureVerifier;
82    import issrg.pba.rbac.Time;
83    import issrg.pba.rbac.URLHandler;
84    import issrg.pba.rbac.WebDAVURLHandler;
85    import issrg.pba.rbac.ValidityPeriod;
86    import issrg.pba.rbac.x509.RepositoryACPolicyFinder;
87    import issrg.pba.rbac.xmlpolicy.ifstatement.EnvironmentNode;
88    import issrg.simplePERMIS.SimplePERMISToken;
89    import issrg.simplePERMIS.SimplePERMISPolicyFinder;
90    import issrg.utils.repository.AttributeRepository;
91    import issrg.utils.repository.MultiRepository;
92    import issrg.utils.repository.VirtualRepository;
93    import issrg.saml.voms.VOMSSAMLURLHandler;
94    import java.io.*;
95    import java.util.*;
96    import issrg.utils.RFC2253NameParser;
97    import issrg.utils.RFC2253ParsingException;
98    import issrg.security.*;
99    import javax.xml.parsers.*;
100    import javax.xml.parsers.DocumentBuilderFactory;
101    import javax.xml.parsers.ParserConfigurationException;
102    import org.w3c.dom.*;
103    import issrg.config.files.*;
104    import org.apache.commons.codec.binary.Base64;
105    import org.apache.log4j.*;
106    import org.apache.commons.logging.Log;
107    import org.apache.commons.logging.LogFactory;
108    import java.lang.reflect.*;
109   
110    import issrg.pba.rbac.PolicyFinder;
111    import netscape.ldap.*;
112   
113    /**
114    *
115    * @author Linying Su
116    */
 
117    public class Handler extends Clock {
118   
119    private static Log logger = LogFactory.getLog(Handler.class.getName());
120   
121    private issrg.pba.rbac.PermisRBAC pba = null;
122    static final Date STARTUP=new GregorianCalendar().getTime();
123    private Date time=STARTUP; // by default the clock is set to the time of the application startup
124    private Document doc = null;
125    private Handler theClock = null;
126   
127    private String ac_type = "attributeCertificateAttribute";
128    private String pkc_type = "userCertificate;binary";
129   
130    private static int PDP = 0;
131    private static int CVS = 1;
132   
133    public static int POLICY_PATH = 31;
134    private static int POLICY_BINARY = 32;
135    public static int XML_POLICY = 41;
136    public static int AC_POLICY = 42;
137    public static int PKC = 100;
138    public static int AC = 101;
139   
140    /**
141    * Creates a new instance of PermisWebService
142    */
143   
 
144  2 toggle public Handler() throws HandlerServiceException {
145   
146  2 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
147  2 factory.setValidating(false);
148  2 try {
149  2 this.doc = factory.newDocumentBuilder().newDocument();
150    } catch (ParserConfigurationException pe) {
151  0 throw new HandlerServiceException("error:"+pe);
152    }
153   
154  2 try {
155  2 URLHandler.addProtocol(new WebDAVURLHandler(80,"http"));
156  2 URLHandler.addProtocol(new VOMSSAMLURLHandler("voms+saml+https",null));
157  2 CustomisePERMIS.configureX509Flavour();
158  2 CustomisePERMIS.setAuthTokenParser("issrg.pba.MultiAuthzTokenParser");
159    } catch (ClassNotFoundException ce) {
160  0 throw new HandlerServiceException("error: "+ce);
161    } catch (PbaException pe) {
162  0 throw new HandlerServiceException("error: "+pe);
163    }
164    }
165   
166    /**
167    * This method is used to set log information by a configuration file
168    * @param configFile, which is the configuratin file name
169    * This file contains e.g.
170    *
171    * log-level = debug
172    * layout = %-5p - %m%n [optional]
173    * log-file = /home/log/permis.log [optional]
174    */
175   
 
176  0 toggle public void setLogLevel(String configFile) throws HandlerServiceException {
177  0 Logger root = Logger.getRootLogger();
178  0 Logger log = null;
179  0 Appender appender;
180  0 Level level;
181  0 log = Logger.getLogger(Handler.class);
182  0 String priority = "debug";
183  0 String file = null;
184  0 Layout layout = new PatternLayout("%d{dd MM yyyy HH:mm:ss} %-5p %c %x - %m%n");
185  0 String fileName = configFile;
186  0 issrg.utils.handler.Config config = new issrg.utils.handler.Config();
187  0 Properties props = new Properties();
188  0 try {
189  0 InputStream in = new FileInputStream(config.getURL(fileName));
190  0 props.load(in);
191  0 in.close();
192  0 priority = props.getProperty("log-level");
193  0 file = props.getProperty("log-file");
194  0 String lay = props.getProperty("layout");
195  0 if (lay!=null) layout = new PatternLayout(lay);
196  0 if (file==null) {
197  0 appender = new WriterAppender(layout, System.out);
198    } else {
199  0 appender = new org.apache.log4j.FileAppender(layout, file);
200    }
201    } catch (Exception e) {
202  0 appender = new WriterAppender(layout, System.out);
203    }
204  0 root.removeAllAppenders();
205  0 BasicConfigurator.configure(appender);
206  0 level = Level.toLevel(priority.toUpperCase());
207  0 log.setLevel(level);
208    }
209   
210    /**
211    * This method is to construct PermisRBAC with the configuration file
212    * @param inputFilename, which is the configuration file name
213    * @param mode, which indicates what type of token parser will be used. This parameter can have any value at this implementation.
214    */
215   
 
216  2 toggle public void initialise(String inputFilename,int mode) throws HandlerServiceException {
217  2 String soa = null;
218  2 String oid = null;
219  2 String xml = null;
220  2 AttributeRepository [] ar = null;
221  2 issrg.utils.repository.VirtualRepository vr = null;
222  2 SignatureVerifier sv=null;
223  2 Hashtable files = new Hashtable();
224  2 InputStream in = null;
225  2 try{
226  2 issrg.utils.handler.Config config = new issrg.utils.handler.Config();
227  2 in = new FileInputStream(config.getURL(inputFilename));
228    }catch(IOException ioe){
229  0 throw new HandlerServiceException("error:"+ioe);
230    }catch (issrg.utils.handler.ConfigException ce) {
231  0 throw new HandlerServiceException("error:"+ce);
232    }
233  2 files.put(inputFilename, inputFilename);
234  2 logger.info("Processing instructions from "+inputFilename);
235  2 Hashtable setup = new Hashtable();
236   
237  2 String prev=""; // this is the instruction in the previous loop
238   
239   
240  2 BufferedReader br=new BufferedReader(new InputStreamReader(in));
241  2 String s=null;
242  2 int line=0;
243  2 try{
244  2 while(true){
245  15 try{
246  15 s=br.readLine();
247  15 boolean breakNow=s==null;
248  15 if (breakNow){
249  2 s="ini: clear"; // this line will cause the final processing of the data collected since the last "ini:"
250    }else{
251  13 line++;
252  13 logger.debug("# "+line+"\r\n"+s+"\r\n# ");
253    }
254   
255  15 if (s==""){
256  0 logger.debug("empty line - ignored");
257  15 }else if (s.trim().startsWith("#")){
258  0 logger.debug("comment - ignored");
259  15 }else if (s.length()<6){
260  0 logger.debug("ill parameter - ignored");
261    }else{
262  15 logger.debug("parameter from the configuration = "+s);
263  15 String instruction = s.substring(0, 4).intern();
264  15 boolean newInstr = instruction!="...:";
265  15 if (newInstr) prev=instruction;
266  11 else instruction=prev.intern();
267   
268  15 String rhs = s.substring(4);
269   
270  15 int idx=rhs.indexOf("=");
271  15 String var=rhs, val="";
272  15 if (idx>0){ // found an assignment - then split it into variable and value
273  11 var=rhs.substring(0, idx).trim().intern();
274  11 if ((idx+1)<rhs.length()) val=rhs.substring(idx+1);
275    }
276  15 rhs=rhs.trim().intern();
277   
278    // now rhs is the right-hand-side of the instruction
279    // var is the variable in the assignment, val is the value of the variable.
280   
281  15 if (instruction=="inc:"){ // include another batch file
282  0 logger.debug("include batch "+rhs);
283  0 this.initialise(rhs,mode); // call it recursively
284  0 logger.debug("# resume processing of "+inputFilename);
285  15 }else if (instruction=="ini:"){ // setting initialisation parameters for PERMIS RBAC
286  15 if (newInstr){ // a new "ini:" instruction group encountered, or end of file
287    // now is the time to go through all the combinations
288    // ignore
289  4 if (breakNow) break; // end of file reached
290    }
291  13 if (rhs=="init"){
292  2 logger.debug("initialising PERMIS RBAC...");
293   
294    //theClock = (PermisWebService)CustomisePERMIS.getSystemClock();
295   
296  2 try{
297  2 soa = (String)setup.get("soa");
298  2 oid = (String)setup.get("oid");
299  2 xml = (String)setup.get("xml");
300  2 String rootca = (String)setup.get("rootca");
301  2 byte [] rootcaPKC = null;
302  2 Vector url = (Vector)setup.get("url");
303  2 Vector pkc = (Vector)setup.get("pkc");
304  2 Vector ac = (Vector)setup.get("ac");
305  2 String acattribute = (String)setup.get("acattribute");
306  2 String pkcattribute = (String)setup.get("pkcattribute");
307   
308  2 if (acattribute==null) acattribute=CustomisePERMIS.getAttributeCertificateAttribute();
309    else {
310  1 logger.debug("ac type is "+acattribute);
311  1 CustomisePERMIS.setAttributeCertificateAttribute(acattribute);
312    }
313   
314  2 if (pkcattribute==null) pkcattribute=CustomisePERMIS.getUserCertificateAttribute();
315  1 else CustomisePERMIS.setUserCertificateAttribute(pkcattribute);
316   
317  0 if (xml==null && (soa==null || oid==null)) throw new Exception("Mandatory parameters missing: SOA DN and OID of the Policy must be specified");
318   
319  2 if (rootca!=null && pkc==null) pkc=new Vector();
320  2 if (rootca!=null) pkc.add(0, rootca);
321   
322  2 ar = new AttributeRepository[(url==null?0:url.size())+(ac==null?0:1)];
323  2 AttributeRepository [] pr = new AttributeRepository[(url==null?0:url.size())+(pkc==null?0:1)];
324   
325  2 if (url!=null){
326  1 logger.debug("# connecting to repositories by url");
327  2 for (int i=0; i<url.size(); i++){
328  1 logger.debug("# "+url.get(i)+"...");
329  1 ar[i]=URLHandler.getRepositoryByURL((String)url.get(i));
330  1 logger.debug(ar[i].getClass().getName()+" is refererd");
331  1 pr[i]=ar[i];
332  1 logger.debug("ok");
333    }
334  1 logger.debug("# done");
335    }
336   
337  2 if (ac!=null){
338  2 logger.debug("# loading ACs from files...");
339  2 vr=new issrg.utils.repository.VirtualRepository();
340  2 ar[ar.length-1]=vr;
341  5 for(int i=ac.size(); i-->0; ){
342  3 logger.debug("# "+ac.get(i)+"...");
343  3 issrg.utils.handler.Config name = new issrg.utils.handler.Config();
344  3 String fName = name.getURL((String)ac.get(i));
345  3 File f=new File(fName);
346  3 byte [] b=new byte[(int)f.length()];
347  3 new FileInputStream(f).read(b);
348  3 String holderDN = issrg.ac.AttributeCertificate.getHolderDN(b);
349  3 vr.populate(holderDN, acattribute, b);
350  3 logger.debug("ok");
351    }
352  2 logger.debug("# done");
353    }
354   
355  2 if (pkc!=null){ // now rootca is always the first in the list
356  1 logger.debug("# loading PKCs from files...");
357  1 vr=new issrg.utils.repository.VirtualRepository();
358  1 pr[pr.length-1]=vr;
359  2 for(int i=pkc.size(); i-->0; ){ // rootca PKC will always be loaded last
360  1 logger.debug("# "+pkc.get(i)+"...");
361  1 issrg.utils.handler.Config name = new issrg.utils.handler.Config();
362  1 String fName = name.getURL((String)pkc.get(i));
363  1 File f=new File(fName);
364  1 rootcaPKC=new byte[(int)f.length()];
365  1 new FileInputStream(f).read(rootcaPKC);
366  1 vr.populate(new iaik.x509.X509Certificate(rootcaPKC).getSubjectDN().getName(), pkcattribute, rootcaPKC);
367  1 logger.debug("ok");
368    }
369  1 logger.debug("# done");
370    // now rootcaPKC is the byte array pointing to the last PKC read - the root CA PKC
371    }
372   
373  2 if (rootcaPKC!=null){
374  1 logger.debug("# setting signature verification...");
375  1 DefaultVerifier dv = new DefaultVerifier();
376  1 dv.setRootCA(rootcaPKC);
377  1 dv.setPKCRepository(new PKCRepository(new MultiRepository(pr)));
378  1 sv=new SimpleSignatureVerifier(dv);
379  1 logger.debug("# done");
380    } else{
381  1 logger.debug("# signature verification is disabled");
382    }
383  2 logger.info("# creating PERMIS RBAC object...");
384   
385  2 MultiRepository mr = new MultiRepository(ar);
386   
387  2 if (xml==null) {
388  2 this.pba = new issrg.pba.rbac.PermisRBAC(new RepositoryACPolicyFinder(mr, oid, new LDAPDNPrincipal(soa), sv), mr, null);
389   
390    } else {
391  0 SimplePERMISPolicyFinder finder = new SimplePERMISPolicyFinder(xml);
392  0 this.pba = new issrg.pba.rbac.PermisRBAC(finder,mr,null);
393    }
394  2 logger.debug("# done");
395    } catch (Exception pe){
396  0 logger.debug("# failed");
397  0 pe.printStackTrace();
398    } catch (Throwable te) {
399  0 logger.debug("# failed");
400  0 te.printStackTrace();
401    }
402  11 } else if (rhs=="clear"){
403  0 logger.debug("reset initialisation parameters for PERMIS RBAC");
404  0 setup = new Hashtable();
405    } else{
406  11 logger.debug("setting initialisation parameters for PERMIS RBAC");
407    //soa | oid | rootca | url | pkc | ac | xml
408  11 if (var=="soa" || var=="oid" || var=="rootca" || var=="acattribute" || var=="pkcattribute" || var=="xml"){
409  0 if (setup.get(var)!=null) logger.debug("# "+var+" is already set to "+setup.get(var)+" - ignored");
410  7 else setup.put(var, val);
411  4 } else if (var=="url" || var=="pkc" || var=="ac"){
412  4 Vector v=(Vector)setup.get(var);
413  4 if (v==null){
414  3 logger.debug("# set "+var+" to "+val);
415  3 v=new Vector();
416  3 setup.put(var, v);
417    } else{
418  1 logger.debug("# add "+val+" to collection of "+var);
419    }
420  4 if (var=="url") {
421  1 issrg.utils.ParsedURL pu=issrg.utils.ParsedURL.parseURL(val);
422  1 if (pu!=null) v.add(val);
423  3 } else v.add(val);
424    } else{
425  0 throw new Exception("unknown setting: "+var);
426    }
427    }
428    } else{
429  0 throw new Exception("Invalid instruction line");
430    }
431    }
432    }catch(PbaException pe){
433  0 logger.debug("Error occured while processing line "+line+": "+pe.getMessage());
434    // don't print the stack trace and don't break the loop - PbaExceptions are part of testing
435    }
436    }
437    }catch(Exception e){
438  0 logger.debug("Stopped @ "+line+": "+s);
439  0 e.printStackTrace();
440    }
441  2 files.remove(inputFilename);
442    }
443   
 
444  0 toggle public void initialise(int type,int format,
445    String policy,
446    String soa,
447    String oid,
448    String acattribute,
449    String pkcattribute,
450    String rootca,
451    String url) throws HandlerServiceException {
452  0 logger.info("to initialise PERMIS with a set of specifications");
453  0 try {
454  0 byte [] rootcaPKC = null;
455  0 AttributeRepository [] ar = null;
456  0 AttributeRepository [] pr = null;
457  0 issrg.utils.repository.VirtualRepository vr = null;
458  0 SignatureVerifier sv=null;
459  0 Vector pkc = null;
460  0 Vector ac = null;
461  0 Vector urls = null;
462  0 if (acattribute==null) acattribute=CustomisePERMIS.getAttributeCertificateAttribute();
463    else {
464  0 CustomisePERMIS.setAttributeCertificateAttribute(acattribute);
465    }
466  0 logger.debug("ac type is "+acattribute);
467  0 if (pkcattribute==null) pkcattribute=CustomisePERMIS.getUserCertificateAttribute();
468    else {
469  0 CustomisePERMIS.setUserCertificateAttribute(pkcattribute);
470    }
471  0 logger.debug("pkc type is "+pkcattribute);
472  0 if (rootca!=null) {
473  0 pkc=new Vector();
474  0 pkc.add(0, rootca);
475    }
476   
477  0 if (format==this.AC_POLICY && policy!=null) {
478  0 ac=new Vector();
479  0 ac.add(0,policy);
480  0 logger.debug(policy+ " is added");
481    }
482   
483  0 if (url!=null) {
484  0 issrg.utils.ParsedURL pu=issrg.utils.ParsedURL.parseURL(url);
485  0 if (pu!=null) urls.add(url);
486  0 ar = new AttributeRepository[(urls==null?0:urls.size())+(ac==null?0:1)];
487  0 pr = new AttributeRepository[(urls==null?0:urls.size())+(pkc==null?0:1)];
488  0 logger.debug("# connecting to repositories...");
489  0 for (int i=urls.size(); i-->0;){
490  0 logger.debug("# "+urls.get(i)+"...");
491  0 ar[i]=URLHandler.getRepositoryByURL((String)urls.get(i));
492  0 pr[i]=ar[i];
493  0 logger.debug("ok");
494    }
495  0 logger.debug("# done");
496    }
497   
498  0 if (ar==null) {
499  0 ar = new AttributeRepository[1];
500    }
501   
502  0 if (ac!=null){
503  0 logger.debug("# loading ACs from ...");
504  0 vr=new issrg.utils.repository.VirtualRepository();
505  0 ar[ar.length-1]=vr;
506  0 byte [] b = null;
507  0 for(int i=ac.size(); i-->0; ){
508  0 logger.debug("# "+ac.get(i)+"...");
509  0 if (type==this.POLICY_PATH) {
510  0 issrg.utils.handler.Config name = new issrg.utils.handler.Config();
511  0 String fName = name.getURL((String)ac.get(i));
512  0 File f=new File(fName);
513  0 b=new byte[(int)f.length()];
514  0 new FileInputStream(f).read(b);
515  0 } else if (type==this.POLICY_BINARY) {
516  0 logger.debug("load binary");
517  0 byte [] acp=new byte[policy.length()];
518  0 acp = policy.getBytes();
519  0 Base64 base64 = new Base64();
520  0 b = base64.decode(acp);
521  0 } else throw new HandlerServiceException("invalid policy type");
522  0 String holderDN = issrg.ac.AttributeCertificate.getHolderDN(b);
523  0 logger.debug("policy holder : "+holderDN);
524  0 vr.populate(holderDN, acattribute, b);
525  0 logger.debug("ok");
526    }
527  0 logger.debug("# done");
528    }
529   
530  0 if (pr==null) {
531  0 pr = new AttributeRepository[1];
532    }
533   
534  0 if (pkc!=null){ // now rootca is always the first in the list
535  0 logger.debug("# loading PKCs from files...");
536  0 vr=new issrg.utils.repository.VirtualRepository();
537  0 pr[pr.length-1]=vr;
538  0 for(int i=pkc.size(); i-->0; ){ // rootca PKC will always be loaded last
539  0 logger.debug("# "+pkc.get(i)+"...");
540  0 issrg.utils.handler.Config name = new issrg.utils.handler.Config();
541  0 String fName = name.getURL((String)pkc.get(i));
542  0 File f=new File(fName);
543  0 rootcaPKC=new byte[(int)f.length()];
544  0 new FileInputStream(f).read(rootcaPKC);
545  0 vr.populate(new iaik.x509.X509Certificate(rootcaPKC).getSubjectDN().getName(), pkcattribute, rootcaPKC);
546  0 logger.debug("ok");
547    }
548  0 logger.debug("# done");
549    // now rootcaPKC is the byte array pointing to the last PKC read - the root CA PKC
550    }
551   
552  0 if (rootcaPKC!=null){
553  0 logger.debug("# setting signature verification...");
554  0 DefaultVerifier dv = new DefaultVerifier();
555  0 dv.setRootCA(rootcaPKC);
556  0 dv.setPKCRepository(new PKCRepository(new MultiRepository(pr)));
557  0 sv=new SimpleSignatureVerifier(dv);
558  0 logger.debug("# done");
559    } else{
560  0 logger.debug("# signature verification is disabled");
561    }
562   
563  0 logger.info("# creating PERMIS RBAC object...");
564  0 MultiRepository mr = null;
565  0 if (ar!=null) mr = new MultiRepository(ar);
566   
567  0 if (policy==null || format==this.AC_POLICY) {
568  0 logger.debug("using AC policy");
569  0 logger.debug("policy name = "+oid);
570  0 logger.debug("policy holder : "+soa);
571  0 if (soa==null || oid==null) throw new Exception("Mandatory parameters missing: SOA DN and OID of the Policy must be specified");
572  0 if (mr==null) throw new Exception("empty repository");
573  0 this.pba = new issrg.pba.rbac.PermisRBAC(new RepositoryACPolicyFinder(mr, oid, new LDAPDNPrincipal(soa), sv), mr, null);
574  0 logger.debug("# done");
575  0 } else if (type==this.POLICY_BINARY && format==this.XML_POLICY) {
576  0 logger.info("with the policy "+policy);
577  0 SimplePushedPolicyFinder finder = new SimplePushedPolicyFinder(policy);
578  0 this.pba = new issrg.pba.rbac.PermisRBAC(finder);
579  0 } else if (type==this.POLICY_PATH && format==this.XML_POLICY) {
580  0 logger.info("with the policy at "+policy);
581  0 SimplePERMISPolicyFinder finder = new SimplePERMISPolicyFinder(policy);
582  0 this.pba = new issrg.pba.rbac.PermisRBAC(finder);
583  0 } else throw new HandlerServiceException("unknown policy type");
584    } catch (IOException ie) {
585  0 throw new HandlerServiceException("error: "+ie);
586    } catch (PbaException pe) {
587  0 throw new HandlerServiceException("error: "+pe);
588    } catch (Throwable te) {
589  0 throw new HandlerServiceException("error: "+te);
590    }
591    }
592   
593   
594    /**
595    * This method returns the constructed PermisRBAC
596    * @return issrg.pba.rbac.PermisRBAC
597    */
598   
 
599  0 toggle public issrg.pba.rbac.PermisRBAC getPDP() {
600  0 return this.pba;
601    }
602   
603    /**
604    * This method returns a WS-Trust request security token, which takes DNIn as the X509SubjectName value.
605    * @param DNIn - this is a LDAP DN
606    * @param AC - a set of pushed ACs
607    * @param PKC - a set of pushed PKCs
608    * @param ldap - a set of ldap server configuration parameters i.e. url, base dn, port, password
609    * @return issrg.pba.rbac.PermisRBAC
610    */
611   
 
612  2 toggle public Element createRequestContext(String DNIn, String[] AC, String[] PKC, String[] ldap) throws HandlerServiceException {
613  0 if (logger.isDebugEnabled()) logger.debug("to create a WS-Trust request");
614  2 Element token = this.doc.createElement("wst:RequestSecurityToken");
615  2 token.setAttribute("xmlns:wst","http://schemas.xmlsoap.org/ws/2005/02/trust");
616  2 Element tokenType = this.doc.createElement("wst:TokenType");
617  2 Text text1 = this.doc.createTextNode("urn:oasis:names:tc:SAML:2.0:profiles:attribute:XACML");
618  2 tokenType.appendChild(text1);
619  2 Element requestType = this.doc.createElement("wst:RequestType");
620  2 Text text2 = this.doc.createTextNode("http://schemas.xmlsoap.org/ws/2005/02/trust/validate");
621  2 requestType.appendChild(text2);
622  2 Element claim = this.doc.createElement("wst:Claims");
623   
624  2 boolean pull = false;
625  0 if (AC==null && PKC==null) pull = true;
626  2 else if (AC==null && PKC.length<=0) pull = true;
627  0 else if (AC.length<=0 && PKC==null) pull = true;
628  0 else if (AC.length<=0 && PKC.length<=0) pull = true;
629   
630  2 if (pull) claim.setAttribute("Dialect","urn:oasis:names:tc:SAML:2.0:assertion:AuthnStatementType");
631  0 else claim.setAttribute("Dialect","urn:oasis:names:tc:SAML:2.0:assertion:AttributeStatementType");
632   
633  2 Element assertion = this.doc.createElement("saml:Assertion");
634  2 assertion.setAttribute("ID", "Permis-Credential-Validation-Service-V1.0");
635  2 assertion.setAttribute("IssueInstant", this.getTime().toString());
636  2 assertion.setAttribute("Version","2.0");
637  2 assertion.setAttribute("xmlns:saml","urn:oasis:names:tc:SAML:2.0:assertion");
638  2 Element issuer = this.doc.createElement("saml:Issuer");
639  2 Text text3 = this.doc.createTextNode("http://issrg.cs.kent.ac.uk/axis/services/PermisWebService");
640  2 issuer.appendChild(text3);
641  2 Element subject = this.doc.createElement("saml:Subject");
642  2 Element name = this.doc.createElement("saml:NameID");
643  2 name.setAttribute("Format","urn:oasis:names:tc:SAML:2.0:nameid-format:X509SubjectName");
644  2 Text text4 = this.doc.createTextNode(DNIn);
645  2 name.appendChild(text4);
646  2 subject.appendChild(name);
647  2 Element condition = this.doc.createElement("saml:Condition");
648  2 condition.setAttribute("NotBefore",this.getTime().toString());
649  2 condition.setAttribute("NotOnOrAfter",this.getTime().toString());
650  2 assertion.appendChild(issuer);
651  2 assertion.appendChild(subject);
652  2 assertion.appendChild(condition);
653   
654  2 if (AC!=null && AC.length>0) {
655  0 Element attributeStatement = this.doc.createElement("saml:AttributeStatement");
656  0 Element attribute = this.doc.createElement("saml:Attribute");
657  0 attribute.setAttribute("Name","X509AttributeCertificate");
658  0 Element attributeValue = this.doc.createElement("saml:AttributeValue");
659  0 for (int i=0; i<AC.length; i++) {
660  0 Element binarySecurityToken = this.doc.createElement("wsse:BinarySecurityToken");
661  0 binarySecurityToken.setAttribute("xmlns:wsse","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
662  0 binarySecurityToken.setAttribute("xmlns:wsu","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
663  0 binarySecurityToken.setAttribute("wsu:Id","binarytoken");
664  0 binarySecurityToken.setAttribute("ValueType","wsse:X509v3");
665  0 binarySecurityToken.setAttribute("EncodingType","wsse:Base64Binary");
666  0 Text ac = this.doc.createTextNode(AC[i]);
667  0 binarySecurityToken.appendChild(ac);
668  0 attributeValue.appendChild(binarySecurityToken);
669    }
670  0 attribute.appendChild(attributeValue);
671  0 attributeStatement.appendChild(attribute);
672  0 assertion.appendChild(attributeStatement);
673    }
674   
675  2 if (PKC!=null && PKC.length>0) {
676  0 Element attributeStatement = this.doc.createElement("saml:AttributeStatement");
677  0 Element attribute = this.doc.createElement("saml:Attribute");
678  0 attribute.setAttribute("Name","X509PKC");
679  0 Element attributeValue = this.doc.createElement("saml:AttributeValue");
680  0 for (int i=0; i<PKC.length; i++) {
681  0 Element binarySecurityToken = this.doc.createElement("wsse:BinarySecurityToken");
682  0 binarySecurityToken.setAttribute("xmlns:wsse","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
683  0 binarySecurityToken.setAttribute("xmlns:wsu","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
684  0 binarySecurityToken.setAttribute("wsu:Id","binarytoken");
685  0 binarySecurityToken.setAttribute("ValueType","wsse:X509v3");
686  0 binarySecurityToken.setAttribute("EncodingType","wsse:Base64Binary");
687  0 Text pkc = this.doc.createTextNode(PKC[i]);
688  0 binarySecurityToken.appendChild(pkc);
689  0 attributeValue.appendChild(binarySecurityToken);
690    }
691  0 attribute.appendChild(attributeValue);
692  0 attributeStatement.appendChild(attribute);
693  0 assertion.appendChild(attributeStatement);
694    }
695   
696  2 if (ldap!=null && ldap.length==4) {
697  0 Element attributeStatement = this.doc.createElement("saml:AttributeStatement");
698  0 Element attribute = this.doc.createElement("saml:Attribute");
699  0 attribute.setAttribute("Name","Repository");
700  0 Element attributeValue = this.doc.createElement("saml:AttributeValue");
701  0 Text ldapInfo = this.doc.createTextNode(ldap[0]+":"+ldap[2]+"/"+ldap[1]+"/"+ldap[3]);
702  0 attributeValue.appendChild(ldapInfo);
703  0 attribute.appendChild(attributeValue);
704  0 attributeStatement.appendChild(attribute);
705  0 assertion.appendChild(attributeStatement);
706    }
707   
708  2 claim.appendChild(assertion);
709  2 token.appendChild(tokenType);
710  2 token.appendChild(requestType);
711  2 token.appendChild(claim);
712  2 return token;
713    }
714   
715    /**
716    * This method returns a WS-Trust request security token, which takes DNIn as the X509SubjectName value.
717    * @param DNIn - this is a LDAP DN
718    * @param AC - a set of pushed ACs
719    * @param PKC - a set of pushed PKCs
720    * @return issrg.pba.rbac.PermisRBAC
721    */
722   
 
723  2 toggle public Element createRequestContext(String DNIn, String[] AC, String[] PKC) throws HandlerServiceException {
724  2 logger.info("to create a WS-Trust request");
725  2 Element token = this.createRequestContext(DNIn, AC, PKC, null);
726  2 return token;
727    }
728   
 
729  2 toggle private Element extractAttributeStatement(Element xmlIn) throws Exception {
730  2 NodeList list0 = xmlIn.getChildNodes();
731  8 for (int i=0; i<list0.getLength(); i++) {
732  6 Node node0 = list0.item(i);
733  0 if (Text.class.isAssignableFrom(node0.getClass())) continue;
734  6 if (node0.getNodeName().equals("wst:RequestedSecurityToken")) {
735  2 NodeList list1 = node0.getChildNodes();
736  4 for (int j=0; j<list1.getLength(); j++) {
737  2 Node node1 = list1.item(j);
738  0 if (Text.class.isAssignableFrom(node1.getClass())) continue;
739  2 if (node1.getNodeName().equals("saml:Assertion")) {
740  2 NodeList list2 = node1.getChildNodes();
741   
742  2 for (int k=0; k<list2.getLength(); k++) {
743  0 Node node2 = list2.item(k);
744  0 if (Text.class.isAssignableFrom(node2.getClass())) continue;
745  0 if (node2.getNodeName().equals("saml:Conditions")) {
746  0 Element nd2 = (Element)node2;
747  0 String notB = nd2.getAttribute("NotBefore");
748  0 String notA = nd2.getAttribute("NotOnOrAfter");
749   
750  0 Date current = new Date();
751  0 PermisCalendar pcNotBefore = new PermisCalendar(notB);
752  0 PermisCalendar pcNotAfter = new PermisCalendar(notA);
753   
754  0 GregorianCalendar notBefore = new GregorianCalendar(pcNotBefore.getYear(),
755    pcNotBefore.getMonth()-1,
756    pcNotBefore.getDay(),
757    pcNotBefore.getHour(),
758    pcNotBefore.getMinute(),
759    pcNotBefore.getSecond());
760   
761  0 GregorianCalendar notAfter = new GregorianCalendar(pcNotAfter.getYear(),
762    pcNotAfter.getMonth()-1,
763    pcNotAfter.getDay(),
764    pcNotAfter.getHour(),
765    pcNotAfter.getMinute(),
766    pcNotAfter.getSecond());
767   
768  0 logger.debug("curent "+current.toString());
769   
770  0 Date before = notBefore.getTime();
771  0 Date after = notAfter.getTime();
772  0 logger.debug("not before "+before.toString());
773  0 logger.debug("not on or after "+after.toString());
774  0 if (current.after(after) || current.equals(after)) {
775  0 logger.debug("the current date/time is on or after the validity period");
776  0 return null;
777    }
778  0 if (current.before(before)) {
779  0 logger.debug("the current date/time is before the validity period");
780  0 return null;
781    }
782    }
783    }
784   
785  2 for (int k=0; k<list2.getLength(); k++) {
786  0 Node node2 = list2.item(k);
787  0 if (Text.class.isAssignableFrom(node2.getClass())) continue;
788  0 if (node2.getNodeName().equals("saml:AttributeStatement")) {
789  0 return (Element)node2;
790    }
791    }
792    }
793    }
794    }
795    }
796  2 return null;
797    }
798   
799    /**
800    * This method returns an XACML request context containing subject or resource attributes
801    * It call the Permis CVS in pull model.
802    * @param DNIn represents the object DN; type can be "Subject" or "Resource"
803    * @return the XACML request context
804    */
805   
 
806  2 toggle public Element getCreds(String DNIn, String type) throws Exception {
807  2 Element request = this.doc.createElement("Request");
808  2 request.setAttribute("xmlns","urn:oasis:names:tc:xacml:1.0:context");
809  2 request.setAttribute("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance");
810  2 request.setAttribute("xmlns:permis","http://issrg.cs.kent.ac.uk");
811  2 Element typeTag = this.doc.createElement(type);
812  2 if (type.equals("Resource")) {
813  0 Element attribute = this.doc.createElement("Attribute");
814  0 String id = new String("urn:oasis:names:tc:xacml:1.0:resource:resource-id");
815  0 attribute.setAttribute("AttributeId",id);
816  0 attribute.setAttribute("DataType","http://www.w3.org/2001/XMLSchema#string");
817  0 Element value = this.doc.createElement("AttributeValue");
818  0 Text text = this.doc.createTextNode(DNIn);
819  0 value.appendChild(text);
820  0 attribute.appendChild(value);
821  0 typeTag.appendChild(attribute);
822  2 } else if (type.equals("Subject")) {
823  2 Element attribute = this.doc.createElement("Attribute");
824  2 String id = new String("urn:oasis:names:tc:xacml:1.0:subject:subject-id");
825  2 attribute.setAttribute("AttributeId",id);
826  2 attribute.setAttribute("DataType","http://www.w3.org/2001/XMLSchema#string");
827  2 Element value = this.doc.createElement("AttributeValue");
828  2 Text text = this.doc.createTextNode(DNIn);
829  2 value.appendChild(text);
830  2 attribute.appendChild(value);
831  2 typeTag.appendChild(attribute);
832    }
833  2 Element context = this.createRequestContext(DNIn,null,new String[0]);
834   
835    //here asking the XAVML CVS for validation
836  2 String response = this.getCreds(context);
837  2 XMLParser parser = new XMLParser(response);
838  2 Element msg = parser.getXmlElement();
839   
840  2 Element statement = this.extractAttributeStatement(msg);
841  2 if (statement==null) {
842  2 request.appendChild(typeTag);
843  2 return request;
844    }
845  0 NodeList list = statement.getChildNodes();
846  0 for (int i=0; i<list.getLength(); i++) {
847  0 Node node = list.item(i);
848  0 if (Text.class.isAssignableFrom(node.getClass())) continue;
849  0 if (node.getNodeName().equals("saml:Attribute")) {
850  0 Element ele = (Element)node;
851  0 String name = ele.getAttribute("Name");
852  0 Element attribute = this.doc.createElement("Attribute");
853  0 String id = new String("permis:"+name);
854  0 attribute.setAttribute("AttributeId",id);
855  0 attribute.setAttribute("DataType","http://www.w3.org/2001/XMLSchema#string");
856  0 NodeList list1 = node.getChildNodes();
857  0 for (int j=0; j<list1.getLength(); j++) {
858  0 Node node1 = list1.item(j);
859  0 if (Text.class.isAssignableFrom(node1.getClass())) continue;
860  0 if (node1.getNodeName().equals("saml:AttributeValue")) {
861  0 Element value = this.doc.createElement("AttributeValue");
862  0 NodeList list2 = node1.getChildNodes();
863  0 for (int k=0; k<list2.getLength(); k++) {
864  0 Node node2 = list2.item(k);
865  0 if (Text.class.isAssignableFrom(node2.getClass())) {
866  0 String val = node2.getNodeValue();
867  0 val = val.trim();
868  0 Text text = this.doc.createTextNode(val);
869  0 value.appendChild(text);
870    }
871    }
872  0 attribute.appendChild(value);
873    }
874    }
875  0 typeTag.appendChild(attribute);
876    }
877    }
878  0 request.appendChild(typeTag);
879  0 return request;
880    }
881   
882    //this method is used in the case of pushed parsed credentials (not ACs)
883    //in the VOMS case, the issuer is the VOMS server
884    //and voms_attribute may be of type vo_name, vo_group, vo_role
885    // the method returns an Element, to be merged into the XACMLrequestcCntext
 
886  0 toggle public Element getCreds(String userDN, String voms_attribute, String atrtibute_type, String issuer)throws Exception {
887  0 logger.info("validate the VOMS subject credentials");
888  0 Vector newCreds = new Vector();
889  0 Subject s = null;
890   
891  0 try {
892    //would be better if we find the voms-server DN
893  0 SimplePERMISToken principal = new SimplePERMISToken(userDN, issuer, atrtibute_type, voms_attribute);
894   
895  0 newCreds.add(principal);
896   
897  0 PolicyFinder pfinder=((issrg.pba.rbac.PermisRBAC)pba).getPolicyFinder();
898  0 issrg.simplePERMIS.SimplePERMISTokenParser fred = new issrg.simplePERMIS.SimplePERMISTokenParser();
899   
900  0 Map rules = pfinder.getParsedPolicy().getAuthTokenParsingRules();
901  0 fred.setAuthTokenParsingRules(rules);
902  0 issrg.pba.ParsedToken parsed = fred.decode(principal); //we can add validity period here, with another decode method
903   
904   
905  0 Object[] x=new Object[1];
906  0 x[0]=parsed;
907   
908    // create the subject, i.e. the entity (the roles) recognized by permis to take the decisions.
909  0 s = this.pba.getCreds(principal.getHolderEntry().getEntryName(), x/*newCreds.toArray()*/);
910   
911  0 Credentials creds=s.exportCreds();
912   
913    //to see the result of credential validation
914  0 if (logger.isDebugEnabled()) logger.debug("the result of pba.getcreds "+ creds.toString()+"\n");
915   
916   
917  0 Element samlAssertion = null;
918  0 samlAssertion = this.getSamlAssertion(creds, userDN);
919   
920  0 Element response = this.getResponse(samlAssertion,null,"valid",null);
921    //a request context should be created including this response saml information
922    //an element type should be returned to subjectPIP to be merged with other info
923  0 String toReturn=new EncodeXML().encode(response,0);
924   
925  0 Element elem=createElementForVOMS(toReturn,userDN);
926    // System.out.println("getCredsforVOMS element returned to Subject PIP"+ new EncodeXML().encode(elem,0));
927  0 return elem;
928   
929   
930    } catch (Exception e) {
931  0 Element response = this.getResponse(null,null,"invalid",e.getLocalizedMessage());
932  0 String toReturn=new EncodeXML().encode(response,0);
933  0 Element elem=createElementForVOMS(toReturn,userDN);
934  0 return elem;
935    }
936    }
937   
 
938  0 toggle public Element createSubjectIDElement(String DNIn){
939  0 Element request = this.doc.createElement("Request");
940  0 request.setAttribute("xmlns","urn:oasis:names:tc:xacml:1.0:context");
941  0 request.setAttribute("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance");
942  0 request.setAttribute("xmlns:permis","http://issrg.cs.kent.ac.uk");
943  0 Element typeTag = this.doc.createElement("Subject");
944   
945  0 Element attribute = this.doc.createElement("Attribute");
946  0 String id = new String("urn:oasis:names:tc:xacml:1.0:subject:subject-id");
947  0 attribute.setAttribute("AttributeId",id);
948  0 attribute.setAttribute("DataType","http://www.w3.org/2001/XMLSchema#string");
949  0 Element value = this.doc.createElement("AttributeValue");
950   
951  0 Text text = this.doc.createTextNode(DNIn);
952  0 value.appendChild(text);
953  0 attribute.appendChild(value);
954  0 typeTag.appendChild(attribute);
955   
956  0 request.appendChild(typeTag);
957  0 return request;
958    }
959   
960    //this function creates an XACML request context from VOMS credentials SAML response
 
961  0 toggle Element createElementForVOMS(String xmlValue, String DNIn){
962   
963  0 Element request = this.doc.createElement("Request");
964  0 request.setAttribute("xmlns","urn:oasis:names:tc:xacml:1.0:context");
965  0 request.setAttribute("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance");
966  0 request.setAttribute("xmlns:permis","http://issrg.cs.kent.ac.uk");
967  0 Element typeTag = this.doc.createElement("Subject");
968   
969    /* Element attribute = this.doc.createElement("Attribute");
970    String id = new String("urn:oasis:names:tc:xacml:1.0:subject:subject-id");
971    attribute.setAttribute("AttributeId",id);
972    attribute.setAttribute("DataType","http://www.w3.org/2001/XMLSchema#string");
973    Element value = this.doc.createElement("AttributeValue");
974   
975    Text text = this.doc.createTextNode(DNIn);
976    value.appendChild(text);
977    attribute.appendChild(value);
978    typeTag.appendChild(attribute);*/
979   
980    //Element context = this.createRequestContext(DNIn,null,new String[0]);
981   
982    //here asking the XAVML CVS for validation
983    //shouldnot ask for any getcreds since we have already got the response in the
984    //xmlValue String
985    //String response = this.getCreds(context);
986   
987   
988   
989  0 XMLParser parser = new XMLParser(xmlValue);
990  0 Element msg=null;
991  0 Element statement=null;
992   
993  0 try {
994  0 msg = parser.getXmlElement();
995    //System.out.println("message "+ new EncodeXML().encode(msg,0));
996    } catch (HandlerServiceException ex) {
997  0 ex.printStackTrace();
998    }
999   
1000  0 try {
1001  0 statement = this.extractAttributeStatement(msg);
1002    } catch (Exception ex) {
1003  0 ex.printStackTrace();
1004    }
1005   
1006  0 if (statement==null) {
1007    // System.out.println("statement=nul appending "+typeTag);
1008  0 request.appendChild(typeTag);
1009  0 return request;
1010    }
1011  0 NodeList list = statement.getChildNodes();
1012  0 for (int i=0; i<list.getLength(); i++) {
1013  0 Node node = list.item(i);
1014  0 if (Text.class.isAssignableFrom(node.getClass())) continue;
1015  0 if (node.getNodeName().equals("saml:Attribute")) {
1016  0 Element ele = (Element)node;
1017  0 String name = ele.getAttribute("Name");
1018  0 Element attribute2 = this.doc.createElement("Attribute");
1019  0 String id2 = new String("permis:"+name);
1020  0 attribute2.setAttribute("AttributeId",id2);
1021   
1022  0 attribute2.setAttribute("DataType","http://www.w3.org/2001/XMLSchema#string");
1023   
1024    //System.out.println("adding to the request context "+"permis:"+attribute2.getAttribute("AttributeId") +" "+attribute2.getAttribute("DataType"));
1025  0 NodeList list1 = node.getChildNodes();
1026  0 for (int j=0; j<list1.getLength(); j++) {
1027  0 Node node1 = list1.item(j);
1028  0 if (Text.class.isAssignableFrom(node1.getClass())) continue;
1029  0 if (node1.getNodeName().equals("saml:AttributeValue")) {
1030  0 Element value2 = this.doc.createElement("AttributeValue");
1031  0 NodeList list2 = node1.getChildNodes();
1032  0 for (int k=0; k<list2.getLength(); k++) {
1033  0 Node node2 = list2.item(k);
1034  0 if (Text.class.isAssignableFrom(node2.getClass())) {
1035  0 String val = node2.getNodeValue();
1036  0 val = val.trim();
1037  0 Text text2 = this.doc.createTextNode(val);
1038    // System.out.println("adding to the request context "+text2);
1039  0 value2.appendChild(text2);
1040    }
1041    }
1042  0 attribute2.appendChild(value2);
1043    }
1044    }
1045  0 typeTag.appendChild(attribute2);
1046    }
1047    }
1048  0 request.appendChild(typeTag);
1049  0 return request;
1050   
1051    }
1052   
1053    /**
1054    * This method returns an XACML request context containing subject or resource attributes
1055    * It call the Permis CVS in pull or push model depending on the ws-trust request.
1056    * @param DNIn represents the object DN;
1057    * @param context represents a ws-trust request object
1058    * @param type can be "Subject" or "Resource"
1059    * @return the XACML request context
1060    */
1061   
 
1062  0 toggle public Element getCreds(String DNIn, Element context, String type) throws Exception {
1063  0 logger.info("to validate the subject credentials");
1064  0 Element request = this.doc.createElement("Request");
1065  0 request.setAttribute("xmlns","urn:oasis:names:tc:xacml:1.0:context");
1066  0 request.setAttribute("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance");
1067  0 request.setAttribute("xmlns:permis","http://issrg.cs.kent.ac.uk");
1068  0 Element typeTag = this.doc.createElement(type);
1069  0 if (type.equals("Resource")) {
1070  0 Element attribute = this.doc.createElement("Attribute");
1071  0 String id = new String("urn:oasis:names:tc:xacml:1.0:resource:resource-id");
1072  0 attribute.setAttribute("AttributeId",id);
1073  0 attribute.setAttribute("DataType","http://www.w3.org/2001/XMLSchema#string");
1074  0 Element value = this.doc.createElement("AttributeValue");
1075  0 Text text = this.doc.createTextNode(DNIn);
1076  0 value.appendChild(text);
1077  0 attribute.appendChild(value);
1078  0 typeTag.appendChild(attribute);
1079  0 } else if (type.equals("Subject")) {
1080  0 Element attribute = this.doc.createElement("Attribute");
1081  0 String id = new String("urn:oasis:names:tc:xacml:1.0:subject:subject-id");
1082  0 attribute.setAttribute("AttributeId",id);
1083  0 attribute.setAttribute("DataType","http://www.w3.org/2001/XMLSchema#string");
1084  0 Element value = this.doc.createElement("AttributeValue");
1085  0 Text text = this.doc.createTextNode(DNIn);
1086  0 value.appendChild(text);
1087  0 attribute.appendChild(value);
1088  0 typeTag.appendChild(attribute);
1089    }
1090  0 String response = this.getCreds(context);
1091  0 XMLParser parser = new XMLParser(response);
1092  0 Element msg = parser.getXmlElement();
1093  0 Element statement = this.extractAttributeStatement(msg);
1094  0 if (statement==null) {
1095  0 request.appendChild(typeTag);
1096  0 return request;
1097    }
1098  0 NodeList list = statement.getChildNodes();
1099  0 for (int i=0; i<list.getLength(); i++) {
1100  0 Node node = list.item(i);
1101  0 if (Text.class.isAssignableFrom(node.getClass())) continue;
1102  0 if (node.getNodeName().equals("saml:Attribute")) {
1103  0 Element ele = (Element)node;
1104  0 String name = ele.getAttribute("Name");
1105  0 Element attribute = this.doc.createElement("Attribute");
1106  0 String id = new String("permis:"+name);
1107  0 attribute.setAttribute("AttributeId",id);
1108  0 attribute.setAttribute("DataType","http://www.w3.org/2001/XMLSchema#string");
1109  0 NodeList list1 = node.getChildNodes();
1110  0 for (int j=0; j<list1.getLength(); j++) {
1111  0 Node node1 = list1.item(j);
1112  0 if (Text.class.isAssignableFrom(node1.getClass())) continue;
1113  0 if (node1.getNodeName().equals("saml:AttributeValue")) {
1114  0 Element value = this.doc.createElement("AttributeValue");
1115  0 NodeList list2 = node1.getChildNodes();
1116  0 for (int k=0; k<list2.getLength(); k++) {
1117  0 Node node2 = list2.item(k);
1118  0 if (Text.class.isAssignableFrom(node2.getClass())) {
1119  0 String val = node2.getNodeValue();
1120  0 val = val.trim();
1121  0 Text text = this.doc.createTextNode(val);
1122  0 value.appendChild(text);
1123    }
1124    }
1125  0 attribute.appendChild(value);
1126    }
1127    }
1128  0 typeTag.appendChild(attribute);
1129    }
1130    }
1131  0 request.appendChild(typeTag);
1132  0 return request;
1133    }
1134    /**
1135    * This method returns an XACML request context for a resource or action in the form of XML Element
1136    * @param attrValue represents the attribute value; type can be "Action" or "Resource"
1137    * @return the XACML request context
1138    */
1139   
 
1140  0 toggle public Element createSimpleContext(String attrValue, String type) throws Exception {
1141  0 Element request = this.doc.createElement("Request");
1142  0 request.setAttribute("xmlns","urn:oasis:names:tc:xacml:1.0:context");
1143  0 request.setAttribute("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance");
1144  0 request.setAttribute("xmlns:permis","http://issrg.cs.kent.ac.uk");
1145  0 Element typeTag = this.doc.createElement(type);
1146  0 if (type.equals("Resource")) {
1147  0 Element attribute = this.doc.createElement("Attribute");
1148  0 String id = new String("urn:oasis:names:tc:xacml:1.0:resource:resource-id");
1149  0 attribute.setAttribute("AttributeId",id);
1150  0 attribute.setAttribute("DataType","http://www.w3.org/2001/XMLSchema#string");
1151  0 Element value = this.doc.createElement("AttributeValue");
1152  0 Text text = this.doc.createTextNode(attrValue);
1153  0 value.appendChild(text);
1154  0 attribute.appendChild(value);
1155  0 typeTag.appendChild(attribute);
1156  0 } else if (type.equals("Action")) {
1157  0 Element attribute = this.doc.createElement("Attribute");
1158  0 String id = new String("urn:oasis:names:tc:xacml:1.0:action:action-id");
1159  0 attribute.setAttribute("AttributeId",id);
1160  0 attribute.setAttribute("DataType","http://www.w3.org/2001/XMLSchema#string");
1161  0 Element value = this.doc.createElement("AttributeValue");
1162  0 Text text = this.doc.createTextNode(attrValue);
1163  0 value.appendChild(text);
1164  0 attribute.appendChild(value);
1165  0 typeTag.appendChild(attribute);
1166    }
1167  0 request.appendChild(typeTag);
1168  0 return request;
1169    }
1170   
1171    /**
1172    * This method returns a string XML, which represents WS-Trust security tokens
1173    * @param contextIn, which represent a wst:RequestSecurityToken element
1174    * @return wst:RequestSecurityTokenResponse
1175    */
 
1176  2 toggle public String getCreds(Element contextIn) throws Exception {
1177  2 logger.info("to get credentials");
1178  2 Interpreter inter = new Interpreter(contextIn);
1179  2 String DNIn = inter.getSubjectDN();
1180  2 logger.info("from "+DNIn);
1181  2 String ValidLDAPDN = RFC2253NameParser.toCanonicalDN(DNIn);
1182  2 if (ValidLDAPDN==null) {
1183  0 Element response = this.getResponse(null,inter.getContextRef(),"invalid","invalid DN");
1184  0 return new EncodeXML().encode(response,0);
1185    }
1186   
1187  2 ArrayList listOfACs = new ArrayList();
1188  2 if (inter.getModel()==Interpreter.PULL) {
1189  2 logger.info("in pull model");
1190  2 SubjectAttributeReference[] subAttRefs = inter.getSubAttrRefs();
1191  2 for (int i=0; i<subAttRefs.length; i++) {
1192  0 String url = subAttRefs[i].getReference();
1193  0 URL urlC = new URL(url);
1194  0 String method = urlC.getMethod();
1195  0 String address = urlC.getAddress();
1196  0 String port = urlC.getPort();
1197  0 String base = urlC.getBaseDN();
1198  0 if (base==null) base="dc=issrg,dc=uok";
1199  0 if (port==null) port="-1";
1200  0 int pN = new Integer(port).intValue();
1201  0 ArrayList list = this.getAttributeCertificates(ValidLDAPDN,method,address,pN,base);
1202  0 if (list!=null) listOfACs.addAll(list);
1203    }
1204  0 } else if (inter.getModel()==Interpreter.PUSH) {
1205  0 logger.info("in push model");
1206  0 AttributeStatement[] statement = inter.getAttributeStatements();
1207  0 for (int i=0; i<statement.length; i++) {
1208  0 AttributeStatement attSt = statement[i];
1209  0 String type = attSt.getAttributeName();
1210  0 String url = attSt.getRepository();
1211  0 String[] certificates = attSt.getBinaryTokens();
1212  0 ArrayList localList = new ArrayList();
1213  0 logger.debug("push "+certificates.length+" certificates");
1214  0 for (int j=0; j<certificates.length; j++) {
1215  0 String binary = certificates[j];
1216  0 logger.debug(binary);
1217  0 if (binary==null) continue;
1218  0 byte [] b=new byte[binary.length()];
1219  0 b = binary.getBytes();
1220  0 Base64 base64 = new Base64();
1221  0 byte [] ac = base64.decode(b);
1222  0 String AcDN = issrg.ac.AttributeCertificate.getHolderDN(ac);
1223  0 logger.debug(" DN included in the AC = "+AcDN);
1224  0 String ValidLDAPDN1 = RFC2253NameParser.toCanonicalDN(AcDN);
1225  0 if (ValidLDAPDN1==null) continue;
1226  0 if (type.equals("X509AttributeCertificate") && !DNIn.toLowerCase().equals(AcDN.toLowerCase())) continue;
1227  0 Binary cert = new Binary(ac);
1228  0 if (type.equals("X509AttributeCertificate")) listOfACs.add(cert);
1229  0 localList.add(cert);
1230    }
1231  0 if (url!=null) {
1232  0 Binary [] localACs = new Binary[localList.size()];
1233  0 localACs = (Binary[])localList.toArray(localACs);
1234  0 byte[][] creds = new byte[localACs.length][];
1235  0 for (int k=0; k<localACs.length; k++) creds[k] = localACs[k].getBinaryValue();
1236  0 URL urlC = new URL(url);
1237  0 String method = urlC.getMethod();
1238  0 String address = urlC.getAddress();
1239  0 String port = urlC.getPort();
1240  0 String base = urlC.getBaseDN();
1241  0 if (base==null) base="dc=issrg,dc=uok";
1242  0 if (port==null) port="-1";
1243  0 int pN = new Integer(port).intValue();
1244  0 try {
1245  0 if (type.equals("X509AttributeCertificate")) this.addAttributeCertificates(DNIn,creds,method,address,pN,base);
1246  0 if (type.equals("X509PKC")) this.addPKCs(DNIn,creds,method,address,pN,base);
1247    }
1248    catch (Exception e) {
1249  0 Element response = this.getResponse(null,inter.getContextRef(),"invalid","can not store the ACs in "+url);
1250  0 return new EncodeXML().encode(response,0);
1251    }
1252    }
1253    }
1254  0 } else if (inter.getModel()==Interpreter.INDETERMINATE) {
1255  0 Element response = this.getResponse(null,inter.getContextRef(),"invalid","invalid request context");
1256  0 return new EncodeXML().encode(response,0);
1257    }
1258   
1259  2 LDAPDNPrincipal user = new LDAPDNPrincipal(ValidLDAPDN);
1260    //logger.debug("used DN: "+DNIn);
1261    //LDAPDNPrincipal user = new LDAPDNPrincipal(DNIn);
1262  2 try {
1263  2 Subject subject = null;
1264  2 Binary [] ACs = new Binary[listOfACs.size()];
1265  2 ACs = (Binary[])listOfACs.toArray(ACs);
1266  2 if (ACs.length==0) {
1267  2 long start = System.nanoTime();
1268  2 subject=this.pba.getCreds(user);
1269  2 long end = System.nanoTime();;
1270  2 end = end - start;
1271  2 logger.debug(subject.exportCreds().toString());
1272  2 logger.info("getCreds (in the pull mode) is made in "+end+" nanoseconds");
1273    } else {
1274  0 byte[][] creds = new byte[ACs.length][];
1275  0 RawCredential [] rawCreds = new RawCredential[ACs.length];
1276  0 for (int i=0; i<ACs.length; i++) {
1277  0 creds[i] = ACs[i].getBinaryValue();
1278  0 if (CustomisePERMIS.isMultiParserUsed()) {
1279  0 rawCreds[i] = new RawCredential(creds[i],"issrg.pba.rbac.x509.RoleBasedACParser");
1280    }
1281    }
1282   
1283  0 long start = System.nanoTime();
1284  0 if (CustomisePERMIS.isMultiParserUsed()) subject=this.pba.getCreds(user,rawCreds);
1285  0 else subject=this.pba.getCreds(user,creds);
1286  0 long end = System.nanoTime();
1287  0 end = end - start;
1288  0 logger.info("getCreds (in the push mode) is made in "+end+" nanoseconds");
1289    }
1290  2 if (subject==null) {
1291  0 Element response = this.getResponse(null,inter.getContextRef(),"invalid","Subject is null");
1292  0 return new EncodeXML().encode(response,0);
1293    }
1294   
1295   
1296  2 Credentials creds=subject.exportCreds();
1297   
1298  2 Element samlAssertion = null;
1299  2 samlAssertion = this.getSamlAssertion(creds, DNIn);
1300  2 logger.debug(new EncodeXML().encode(samlAssertion,0));
1301  2 Element response = this.getResponse(samlAssertion,inter.getContextRef(),"valid",null);
1302  2 return new EncodeXML().encode(response,0);
1303    } catch (Exception e) {
1304  0 Element response = this.getResponse(null,inter.getContextRef(),"invalid",e.getLocalizedMessage());
1305  0 return new EncodeXML().encode(response,0);
1306    }
1307    }
1308   
 
1309  2 toggle private Element getSamlAssertion(Credentials creds,String DNIn) throws Exception {
1310  2 Element subAtts = null;
1311  2 ArrayList list = this.getAttributesAndValidityPeriods(creds);
1312  2 subAtts = doc.createElement("saml:Assertion");
1313  2 subAtts.setAttribute("ID", "Permis-Credential-Validation-Service-V1.0");
1314  2 subAtts.setAttribute("IssueInstant", this.getTime().toString());
1315  2 subAtts.setAttribute("Version","2.0");
1316  2 subAtts.setAttribute("xmlns:saml","urn:oasis:names:tc:SAML:2.0:assertion");
1317  2 if (list.size()<1) return subAtts;
1318  0 Element issuer = doc.createElement("saml:Issuer");
1319  0 Text text1 = doc.createTextNode("http://issrg.cs.kent.ac.uk/axis/services/PermisWebService");
1320  0 issuer.appendChild(text1);
1321  0 subAtts.appendChild(issuer);
1322  0 Element subject = doc.createElement("saml:Subject");
1323  0 Element identifier = doc.createElement("saml:NameID");
1324  0 identifier.setAttribute("Format", "urn:oasis:names:tc:SAML:2.0:nameid-format:X509SubjectName");
1325  0 Text text2 = doc.createTextNode(DNIn);
1326  0 identifier.appendChild(text2);
1327  0 subject.appendChild(identifier);
1328  0 subAtts.appendChild(subject);
1329  0 Element condition = doc.createElement("saml:Conditions");
1330  0 Element statement = doc.createElement("saml:AttributeStatement");
1331  0 Date notBefore = null, notAfter = null;
1332  0 for (Iterator i=list.iterator();i.hasNext();) {
1333  0 AttributeAndValidityPeriod pair = (AttributeAndValidityPeriod)i.next();
1334  0 Element attribute = doc.createElement("saml:Attribute");
1335  0 attribute.setAttribute("Name", pair.getRoleType());
1336  0 Element attributeValue = doc.createElement("saml:AttributeValue");
1337  0 Text text = doc.createTextNode(pair.getRoleValue().trim());
1338  0 attributeValue.appendChild(text);
1339  0 attribute.appendChild(attributeValue);
1340  0 statement.appendChild(attribute);
1341  0 if (notBefore==null) notBefore = pair.getNotBefore();
1342  0 else if (notBefore.before(pair.getNotBefore())) notBefore = pair.getNotBefore();
1343  0 if (notAfter==null) notAfter = pair.getNotAfter();
1344  0 else if (notAfter.after(pair.getNotAfter())) notAfter = pair.getNotAfter();
1345    }
1346  0 condition.setAttribute("NotBefore", notBefore.toString());
1347  0 condition.setAttribute("NotOnOrAfter", notAfter.toString());
1348  0 subAtts.appendChild(condition);
1349  0 subAtts.appendChild(statement);
1350  0 return subAtts;
1351    }
1352   
1353   
1354   
1355   
1356   
 
1357  2 toggle private Element getResponse(Element samlIn,String ctxRefIn, String status, String reason) throws Exception {
1358  2 Element res = doc.createElement("wst:RequestSecurityTokenResponse");
1359  2 res.setAttribute("xmlns:wst","http://schemas.xmlsoap.org/ws/2005/02/trust");
1360  2 if (ctxRefIn!=null)
1361  0 res.setAttribute("Context",ctxRefIn);
1362  2 Element tokenType = doc.createElement("wst:TokenType");
1363  2 Text text1 = doc.createTextNode("urn:oasis:names:tc:SAML:2.0:profiles:attribute:XACML");
1364  2 tokenType.appendChild(text1);
1365  2 res.appendChild(tokenType);
1366  2 if (status.equals("valid")) {
1367  2 Element requested = doc.createElement("wst:RequestedSecurityToken");
1368  2 requested.appendChild(samlIn);
1369  2 res.appendChild(requested);
1370    }
1371  2 Element statusCode = doc.createElement("wst:Status");
1372  2 Element code = doc.createElement("wst:Code");
1373  2 Text text2 = null;
1374  2 if (status.equals("valid")) {
1375  2 text2 = doc.createTextNode("http://schemas.xmlsoap.org/ws/2005/02/trust/status/valid");
1376    } else {
1377  0 text2 = doc.createTextNode("http://schemas.xmlsoap.org/ws/2005/02/trust/status/invalid");
1378    }
1379  2 code.appendChild(text2);
1380  2 statusCode.appendChild(code);
1381  2 if (reason!=null) {
1382  0 Element reasonCode = doc.createElement("wst:Reason");
1383  0 Text text3 = doc.createTextNode(reason);
1384  0 reasonCode.appendChild(text3);
1385  0 statusCode.appendChild(reasonCode);
1386    }
1387  2 res.appendChild(statusCode);
1388  2 return res;
1389    }
1390   
 
1391  2 toggle private ArrayList getAttributesAndValidityPeriods(Credentials creds) {
1392  2 ArrayList list = new ArrayList();
1393  2 AttributeAndValidityPeriod pair = null;
1394  2 if (ExpirableCredentials.class.isAssignableFrom(creds.getClass())) {
1395  0 ExpirableCredentials ecs = (ExpirableCredentials)creds;
1396  0 RoleBasedCredentials rbcs = (RoleBasedCredentials)ecs.getExpirable();
1397  0 ValidityPeriod vp = ecs.getValidityPeriod();
1398  0 pair = new AttributeAndValidityPeriod(rbcs, vp);
1399  0 list.add(pair);
1400    } else {
1401  2 SetOfSubsetsCredentials screds = (SetOfSubsetsCredentials)creds;
1402  2 Vector vector = screds.getValue();
1403  2 for (Iterator i=vector.iterator();i.hasNext();) {
1404  0 Credentials subsets = (Credentials)i.next();
1405  0 ArrayList subList = new ArrayList();
1406  0 subList = this.getAttributesAndValidityPeriods(subsets);
1407  0 list.addAll(subList);
1408    }
1409    }
1410  2 return list;
1411    }
1412   
1413    /**
1414    * The time is stopped forever, so the latch returns the same as getTime()
1415    */
1416   
 
1417  0 toggle public Date latch(){
1418  0 return this.getTime();
1419    }
1420   
1421    /**
1422    * The time is stopped forever, so the latch returns the same as getTime()
1423    */
1424   
 
1425  8 toggle public Date getTime(){
1426  8 return this.time;
1427    }
1428   
1429    /**
1430    * This method returns the time encoded as a string.
1431    *
1432    * @param timeString - the time to set; the format is the same as the string representation of time in the policy, e.g. "2005-09-25T23:59:59"
1433    * @return the Date representing the specified time.
1434    */
 
1435  0 toggle public Date toTime(String timeString) throws IllegalArgumentException{
1436  0 int [] t = new Time(timeString).getEvaluationTime();
1437  0 Calendar c = new GregorianCalendar();
1438  0 c.set(t[0], t[1], t[2], t[3], t[4], t[5]);
1439  0 return c.getTime();
1440    }
1441   
1442    /**
1443    * This method sets the current time. Initially the time is set to
1444    * the time of the application startup.
1445    *
1446    * @param time - the time to set.
1447    */
 
1448  0 toggle public void setTime(Date time){
1449  0 this.time=time;
1450    }
1451   
 
1452  0 toggle private byte[][] getUniqueValues(byte[][] valueIn) {
1453  0 ArrayList result = new ArrayList();
1454  0 result.add(valueIn[0]);
1455  0 for (int i=1; i<valueIn.length; i++) {
1456  0 boolean found = false;
1457  0 for (Iterator j=result.iterator();j.hasNext();) {
1458  0 byte[] node = (byte[])j.next();
1459  0 boolean equal = false;
1460  0 if (node.length==valueIn[i].length) {
1461  0 equal=true;
1462  0 for (int k=0; k<node.length; k++) {
1463  0 if (node[k]!=valueIn[i][k]) equal=false;
1464  0 if (!equal) break;
1465    }
1466  0 if (equal) found= true;
1467  0 if (found) break;
1468    }
1469    }
1470  0 if (!found) result.add(valueIn[i]);
1471    }
1472  0 byte[][] fr = new byte[result.size()][];
1473  0 fr = (byte[][])result.toArray(fr);
1474  0 return fr;
1475    }
1476   
 
1477  0 toggle private void addAttributeCertificates(String dn, byte[][] acIn, String method, String address, int port, String baseDN) throws Exception {
1478  0 if (acIn.length==0) return;
1479  0 byte[][] ac = this.getUniqueValues(acIn);
1480  0 if (method==null) method="ldap";
1481  0 if (!method.equals("ldap")) return;
1482  0 LDAPConnection ldap = new LDAPConnection();
1483  0 ldap.connect(address,port>0?port:389);
1484  0 ldap.bind("cn=root,dc=issrg,dc=uok","secret");
1485  0 LDAPEntry foundEntry = null;
1486  0 dn +=","+baseDN;
1487  0 try {
1488  0 foundEntry = ldap.read(dn);
1489    } catch (LDAPException ee) {
1490  0 int code = ee.getLDAPResultCode();
1491  0 if (code==ee.NO_SUCH_OBJECT) throw new Exception("no account");
1492  0 else throw new Exception("LDAP failure: "+ee);
1493    }
1494  0 LDAPAttributeSet set = foundEntry.getAttributeSet();
1495  0 boolean exist = false;
1496  0 for (int i=0;i<set.size();i++) {
1497  0 LDAPAttribute att = set.elementAt(i);
1498  0 if (att.getName().equals("attributeCertificateAttribute")) {
1499  0 exist = true;
1500  0 for (int k=0; k<ac.length; k++) {
1501  0 Enumeration values = att.getByteValues();
1502  0 boolean found = false;
1503  0 while (values.hasMoreElements()) {
1504  0 byte[] value = (byte[])values.nextElement();
1505  0 boolean eq = false;
1506  0 if (value.length==ac[k].length) {
1507  0 eq = true;
1508  0 for (int j=0;j<ac[k].length;j++) {
1509  0 if (ac[k][j]!=value[j]) {
1510  0 eq = false;
1511  0 break;
1512    }
1513    }
1514  0 if (eq) found = true;
1515    }
1516  0 if (found) break;
1517    }
1518  0 if (!found) {
1519  0 LDAPAttribute attr = new LDAPAttribute("attributeCertificateAttribute",ac[k]);
1520  0 LDAPModification singleChange = new LDAPModification( LDAPModification.ADD, attr);
1521  0 ldap.modify(dn, singleChange );
1522    }
1523    }
1524    }
1525    }
1526  0 if (!exist) {
1527  0 for (int k=0; k<ac.length; k++) {
1528  0 LDAPAttribute attr = new LDAPAttribute("attributeCertificateAttribute",ac[k]);
1529  0 LDAPModification singleChange = new LDAPModification( LDAPModification.ADD, attr);
1530  0 ldap.modify(dn, singleChange );
1531    }
1532    }
1533    }
1534   
 
1535  0 toggle private void addPKCs(String dn, byte[][] acIn, String method, String address, int port, String baseDN) throws Exception {
1536  0 if (acIn.length==0) return;
1537  0 byte[][] ac = this.getUniqueValues(acIn);
1538  0 if (method==null) method="ldap";
1539  0 if (!method.equals("ldap")) return;
1540  0 LDAPConnection ldap = new LDAPConnection();
1541  0 ldap.connect(address,port>0?port:389);
1542  0 ldap.bind("cn=root,dc=issrg,dc=uok","secret");
1543  0 LDAPEntry foundEntry = null;
1544  0 dn +=","+baseDN;
1545  0 try {
1546  0 foundEntry = ldap.read(dn);
1547    } catch (LDAPException ee) {
1548  0 int code = ee.getLDAPResultCode();
1549  0 if (code==ee.NO_SUCH_OBJECT) throw new Exception("no account");
1550  0 else throw new Exception("LDAP failure: "+ee);
1551    }
1552  0 LDAPAttributeSet set = foundEntry.getAttributeSet();
1553  0 boolean exist = false;
1554  0 for (int i=0;i<set.size();i++) {
1555  0 LDAPAttribute att = set.elementAt(i);
1556  0 if (att.getName().equals("userCertificate")) {
1557  0 exist = true;
1558  0 for (int k=0; k<ac.length; k++) {
1559  0 Enumeration values = att.getByteValues();
1560  0 boolean found = false;
1561  0 while (values.hasMoreElements()) {
1562  0 byte[] value = (byte[])values.nextElement();
1563  0 boolean eq = false;
1564  0 if (value.length==ac[k].length) {
1565  0 eq = true;
1566  0 for (int j=0;j<ac[k].length;j++) {
1567  0 if (ac[k][j]!=value[j]) {
1568  0 eq = false;
1569  0 break;
1570    }
1571    }
1572  0 if (eq) found = true;
1573    }
1574  0 if (found) break;
1575    }
1576  0 if (!found) {
1577  0 LDAPAttribute attr = new LDAPAttribute("userCertificate",ac[k]);
1578  0 LDAPModification singleChange = new LDAPModification( LDAPModification.ADD, attr);
1579  0 ldap.modify(dn, singleChange );
1580    }
1581    }
1582    }
1583    }
1584  0 if (!exist) {
1585  0 for (int k=0; k<ac.length; k++) {
1586  0 LDAPAttribute attr = new LDAPAttribute("userCertificate",ac[k]);
1587  0 LDAPModification singleChange = new LDAPModification( LDAPModification.ADD, attr);
1588  0 ldap.modify(dn, singleChange );
1589    }
1590    }
1591    }
1592   
 
1593  0 toggle private ArrayList getAttributeCertificates(String dn, String method, String address, int port, String baseDN) throws Exception {
1594  0 ArrayList result=null;
1595  0 if (method==null) method="ldap";
1596  0 if (!method.equals("ldap")) return null;
1597  0 LDAPConnection ldap = new LDAPConnection();
1598  0 ldap.connect(address,port>0?port:389);
1599  0 ldap.bind("cn=root,dc=issrg,dc=uok","secret");
1600  0 LDAPEntry foundEntry = null;
1601  0 dn +=","+baseDN;
1602  0 try {
1603  0 foundEntry = ldap.read(dn);
1604    } catch (LDAPException ee) {
1605  0 return null;
1606    }
1607  0 LDAPAttributeSet set = foundEntry.getAttributeSet();
1608  0 for (int i=0;i<set.size();i++) {
1609  0 LDAPAttribute att = set.elementAt(i);
1610  0 if (att.getName().equals("attributeCertificateAttribute")) {
1611  0 result = new ArrayList();
1612  0 Enumeration enums = att.getByteValues();
1613  0 while (enums.hasMoreElements()) {
1614  0 byte[] ac = (byte[])enums.nextElement();
1615  0 Binary cert = new Binary(ac);
1616  0 result.add(cert);
1617    }
1618    }
1619    }
1620  0 return result;
1621    }
1622   
1623    /**
1624    * This method is used to get all of the environmental attributes in the current policy
1625    * @return an <Attributes> element. For example,
1626    * <Attributes xmlns="urn:oasis:names:tc:xacml:1.0:context">
1627    * <Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:environment:balance.student[id(S)]"
1628    * DataType="http://www.w3.org/2001/XMLSchema#integer"/>
1629    * <Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:environment:balance.staff[id(S)]"
1630    * DataType="http://www.w3.org/2001/XMLSchema#integer"/>
1631    * </Attributes>
1632    */
1633   
 
1634  0 toggle public Element getAttributes() throws HandlerServiceException {
1635  0 Element attribute = this.doc.createElement("Attributes");
1636  0 attribute.setAttribute("xmlns","urn:oasis:names:tc:xacml:1.0:context");
1637  0 logger.debug("to get environmental attributes in the policy");
1638  0 EnvironmentNode [] nodes = this.pba.getEnvAttributes();
1639  0 ArrayList list = new ArrayList();
1640  0 for (int i=0; i<nodes.length; i++) {
1641  0 EnvironmentNode node = nodes[i];
1642  0 Map map = node.getAttributes();
1643  0 String name = (String)map.get(node.PARAMETER_ATTRIBUTE);
1644  0 if (list.contains(name)) continue;
1645  0 list.add(name);
1646  0 String type = node.getType();
1647  0 type = type.toLowerCase();
1648  0 Element attr = this.doc.createElement("Attribute");
1649  0 attr.setAttribute("AttributeId",name);
1650  0 attr.setAttribute("DataType","http://www.w3.org/2001/XMLSchema#"+type);
1651  0 attribute.appendChild(attr);
1652    }
1653  0 return attribute;
1654    }
1655   
1656    /**
1657    * This method provides an XACML interface to call PERMIS PDP for authz decisions
1658    * @param reqCtx, which is an XACML request context
1659    * @return an XACML response context in the form of XML Element
1660    */
1661   
 
1662  0 toggle public Element decision(Element reqCtx) throws HandlerServiceException {
1663  0 Date date = new Date();
1664  0 long start = date.getTime();
1665  0 Subject subject = null;
1666  0 PermisTarget target = null;
1667  0 Action act = null;
1668  0 Hashtable env = null;
1669  0 String policy = this.pba.getPolicyFinder().getPolicyOID();
1670  0 Element response = this.doc.createElement("Response");
1671  0 Element result = this.doc.createElement("Result");
1672  0 result.setAttribute("ResourceId",this.getId(reqCtx,"Resource"));
1673  0 Element status = this.doc.createElement("Status");
1674  0 Element statuscode = this.doc.createElement("StatusCode");
1675  0 Element decision = this.doc.createElement("Decision");
1676  0 String textCode = null;
1677  0 String statusCode = null;
1678  0 try {
1679  0 if (policy!=null) subject = this.getSubject(reqCtx,policy);
1680  0 else subject = this.getSubject(reqCtx,"dummy");
1681  0 if (subject!=null) logger.debug("the credentails are "+subject.exportCreds().toString());
1682  0 if (subject!=null) logger.info("Permis subject is created");
1683  0 target = this.createTarget(reqCtx);
1684  0 if (target!=null) logger.debug("the target is "+target.getName());
1685  0 if (target!=null) logger.info("Permis target is created");
1686  0 act = this.createAction(reqCtx);
1687  0 if (act!=null) logger.info("Permis action is created");
1688  0 env = this.createEnvironment(reqCtx);
1689  0 if (env!=null) logger.info("Permis environment is created");
1690  0 if (target!=null) result.setAttribute("ResourceId",target.getName());
1691  0 Response res = this.pba.authzDecision(subject,act,target,env);
1692  0 logger.info("Permis authorisation decision is made");
1693  0 if (res.isAuthorised()) {
1694  0 textCode = "Permit";
1695  0 statusCode = "urn:oasis:names:tc:xacml:1.0:status:ok";
1696  0 Text text = this.doc.createTextNode(textCode);
1697  0 text.setNodeValue(textCode);
1698  0 decision.appendChild(text);
1699  0 result.appendChild(decision);
1700  0 statuscode.setAttribute("Value",statusCode);
1701  0 status.appendChild(statuscode);
1702  0 result.appendChild(status);
1703  0 Obligations obls = res.getObligations();
1704  0 if (obls!=null) {
1705  0 String obligations = obls.toString();
1706  0 Text obl = this.doc.createTextNode(obligations);
1707  0 result.appendChild(obl);
1708    }
1709    } else {
1710  0 textCode = "Deny";
1711  0 statusCode = "urn:oasis:names:tc:xacml:1.0:status:ok";
1712  0 Text text = this.doc.createTextNode(textCode);
1713  0 decision.appendChild(text);
1714  0 result.appendChild(decision);
1715  0 statuscode.setAttribute("Value",statusCode);
1716  0 status.appendChild(statuscode);
1717  0 result.appendChild(status);
1718    }
1719    } catch (PbaException pe) {
1720  0 logger.debug(pe.getMessage());
1721  0 if (pe.getMessage().equals("Target is out of target domain")) {
1722  0 textCode = "NotApplicable";
1723  0 statusCode = "urn:oasis:names:tc:xacml:1.0:status:ok";
1724  0 } else if (pe.getMessage().equals("Subject, Action and Target should not be null")) {
1725  0 textCode = "Indeterminate";
1726  0 statusCode = "urn:oasis:names:tc:xacml:1.0:status:missing-attribute";
1727  0 } else if (pe.getMessage().equals("Cannot use the subject: created by a different object")) {
1728  0 textCode = "Indeterminate";
1729  0 statusCode = "urn:oasis:names:tc:xacml:1.0:status:processing-error";
1730  0 } else if (pe.getMessage().equals("Unacceptable Action for this policy")) {
1731  0 textCode = "NotApplicable";
1732  0 statusCode = "urn:oasis:names:tc:xacml:1.0:status:ok";
1733  0 } else if (pe.getMessage().equals("Unacceptable Action for this policy")) {
1734  0 textCode = "NotApplicable";
1735  0 statusCode = "urn:oasis:names:tc:xacml:1.0:status:ok";
1736  0 } else if (pe.getMessage().startsWith("Unacceptable Action for this Policy:")) {
1737  0 textCode = "NotAppicable";
1738  0 statusCode = "urn:oasis:names:tc:xacml:1.0:status:ok";
1739  0 } else if (pe.getMessage().equals("Cannot make a decision: some obligation must be enforced")) {
1740  0 textCode = "Indeterminate";
1741  0 statusCode = "urn:oasis:names:tc:xacml:1.0:status:processing-error";
1742    } else {
1743  0 textCode = "Indeterminate";
1744  0 statusCode = "urn:oasis:names:tc:xacml:1.0:status:processing-error";
1745    }
1746  0 Text text = this.doc.createTextNode(textCode);
1747  0 decision.appendChild(text);
1748  0 result.appendChild(decision);
1749  0 statuscode.setAttribute("Value",statusCode);
1750  0 status.appendChild(statuscode);
1751  0 result.appendChild(status);
1752  0 response.appendChild(result);
1753  0 date = new Date();
1754  0 long end = date.getTime();
1755  0 end = end - start;
1756  0 logger.info("this decision is made in "+end+" milliseconds");
1757  0 return response;
1758    } catch (SubjectException se) {
1759  0 logger.debug(se.getMessage());
1760  0 textCode = "Indeterminate";
1761  0 statusCode = "urn:oasis:names:tc:xacml:1.0:status:processing-error";
1762  0 Text text = this.doc.createTextNode(textCode);
1763  0 decision.appendChild(text);
1764  0 result.appendChild(decision);
1765  0 statuscode.setAttribute("Value",statusCode);
1766  0 status.appendChild(statuscode);
1767  0 result.appendChild(status);
1768  0 response.appendChild(result);
1769  0 date = new Date();
1770  0 long end = date.getTime();
1771  0 end = end - start;
1772  0 logger.info("this decision is made in "+end+" milliseconds");
1773  0 return response;
1774    } catch (TargetException te) {
1775  0 logger.debug(te.getMessage());
1776  0 textCode = "Indeterminate";
1777  0 Text text = this.doc.createTextNode(textCode);
1778  0 decision.appendChild(text);
1779  0 result.appendChild(decision);
1780  0 if (te.getMessage().equals("bad URL") || te.getMessage().equals("syntax error")) {
1781  0 statusCode = "urn:oasis:names:tc:xacml:1.0:status:syntax-error";
1782    } else {
1783  0 statusCode = "urn:oasis:names:tc:xacml:1.0:status:missing-attribute";
1784    }
1785  0 statuscode.setAttribute("Value", statusCode);
1786  0 status.appendChild(statuscode);
1787  0 result.appendChild(status);
1788  0 response.appendChild(result);
1789  0 date = new Date();
1790  0 long end = date.getTime();
1791  0 end = end - start;
1792  0 logger.info("this decision is made in "+end+" milliseconds");
1793  0 return response;
1794    } catch (ActionException ae) {
1795  0 logger.debug(ae.getMessage());
1796  0 textCode = "Indeterminate";
1797  0 statusCode = "urn:oasis:names:tc:xacml:1.0:status:syntax-error";
1798  0 Text text = this.doc.createTextNode(textCode);
1799  0 decision.appendChild(text);
1800  0 result.appendChild(decision);
1801  0 statuscode.setAttribute("Value",statusCode);
1802  0 status.appendChild(statuscode);
1803  0 result.appendChild(status);
1804  0 response.appendChild(result);
1805  0 date = new Date();
1806  0 long end = date.getTime();
1807  0 end = end - start;
1808  0 logger.info("this decision is made in "+end+" milliseconds");
1809  0 return response;
1810    } catch (EnvironmentException ee) {
1811  0 logger.debug(ee.getMessage());
1812  0 textCode = "Indeterminate";
1813  0 statusCode = "urn:oasis:names:tc:xacml:1.0:status:syntax-error";
1814  0 Text text = this.doc.createTextNode(textCode);
1815  0 decision.appendChild(text);
1816  0 result.appendChild(decision);
1817  0 statuscode.setAttribute("Value",statusCode);
1818  0 status.appendChild(statuscode);
1819  0 result.appendChild(status);
1820  0 response.appendChild(result);
1821  0 date = new Date();
1822  0 long end = date.getTime();
1823  0 end = end - start;
1824  0 logger.info("this decision is made in "+end+" milliseconds");
1825  0 return response;
1826    }
1827  0 response.appendChild(result);
1828  0 String responseText = new EncodeXML().encode(response,0);
1829  0 XMLParser parser = new XMLParser(responseText);
1830  0 Element msg = parser.getXmlElement();
1831  0 date = new Date();
1832  0 long end = date.getTime();
1833  0 end = end - start;
1834  0 logger.info("this decision is made in "+end+" milliseconds");
1835  0 return msg;
1836    }
1837   
1838    // get a local attribute name. The namespace (prefix) of the attribute is indicated by namespace
1839   
 
1840  0 toggle private String getName(String fullName, String namespace) {
1841  0 String template = new String(namespace+":");
1842  0 int len = template.length();
1843  0 int index = fullName.indexOf(template);
1844  0 if (index>-1) return fullName.substring(index+len);
1845  0 else return fullName;
1846    }
1847   
1848    // get a local attribute name. The namespace (prefix) of the attribute is indicated by namespace
1849   
 
1850  0 toggle private String getPermisName(String fullName, String namespace) {
1851  0 String template = new String(namespace+":");
1852  0 int len = template.length();
1853  0 int index = fullName.indexOf(template);
1854  0 if (index>-1) return fullName.substring(index+len);
1855  0 else return null;
1856    }
1857   
1858    /**
1859    * This method get subject/resource Id from a request context.
1860    * @param reqCtx is a XACML request context, type is either "Subject" or "Resource"
1861    * @return the Id, if the <Subject> or <Resourec> contains such atribute
1862    * otherwise, return null
1863    */
1864   
 
1865  0 toggle public String getId(Element reqCtx, String type) {
1866  0 String dn = null;
1867  0 if (reqCtx.getNodeName().equals("Request")) {
1868  0 NodeList list = reqCtx.getChildNodes();
1869  0 for (int i=0; i<list.getLength(); i++) {
1870  0 Node node = list.item(i);
1871  0 if (Text.class.isAssignableFrom(node.getClass())) continue;
1872  0 if (node.getNodeName().equals(type)) {
1873  0 NodeList list1 = node.getChildNodes();
1874  0 for (int j=0; j<list1.getLength(); j++) {
1875  0 Node node1 = list1.item(j);
1876  0 if (Text.class.isAssignableFrom(node1.getClass())) continue;
1877  0 if (node1.getNodeName().equals("Attribute")) {
1878  0 Element ele = (Element)node1;
1879  0 String oid = ele.getAttribute("AttributeId");
1880  0 if (oid.equals("urn:oasis:names:tc:xacml:1.0:subject:subject-id") && type.equals("Subject")) {
1881  0 dn = (String)this.getAttributeValue(node1);
1882  0 dn = dn.trim();
1883  0 } else if (oid.equals("urn:oasis:names:tc:xacml:1.0:resource:resource-id") && type.equals("Resource")) {
1884  0 dn = (String)this.getAttributeValue(node1);
1885  0 dn = dn.trim();
1886    }
1887    }
1888    }
1889    }
1890    }
1891    }
1892  0 return dn;
1893    }
1894   
 
1895  0 toggle private Object getAttributeValue(Node parentNode) {
1896  0 NodeList list = parentNode.getChildNodes();
1897  0 for (int i=0; i<list.getLength(); i++) {
1898  0 Node node = list.item(i);
1899  0 if (Text.class.isAssignableFrom(node.getClass())) continue;
1900  0 if (node.getNodeName().equals("AttributeValue")) {
1901  0 NodeList list1 = node.getChildNodes();
1902  0 if (list1.getLength()!=1) return null;
1903  0 return list1.item(0).getNodeValue();
1904    }
1905    }
1906  0 return null;
1907    }
1908   
 
1909  0 toggle private String getActionType(Element reqCtx) throws HandlerServiceException {
1910  0 if (reqCtx.getNodeName().equals("Request")) {
1911  0 NodeList list = reqCtx.getChildNodes();
1912  0 for (int i=0; i<list.getLength(); i++) {
1913  0 Node node = list.item(i);
1914  0 if (Text.class.isAssignableFrom(node.getClass())) continue;
1915  0 if (node.getNodeName().equals("Action")) {
1916  0 NodeList list1 = node.getChildNodes();
1917  0 for (int j=0; j<list1.getLength(); j++) {
1918  0 Node node1 = list1.item(j);
1919  0 if (Text.class.isAssignableFrom(node1.getClass())) continue;
1920  0 if (node1.getNodeName().equals("Attribute")) {
1921  0 Element ele = (Element)node1;
1922  0 String attrName = ele.getAttribute("AttributeId");
1923  0 if (attrName.equals("urn:oasis:names:tc:xacml:1.0:action:action-id") ||
1924    attrName.equals("globus:operation") ) {
1925  0 String attrType = ele.getAttribute("DataType");
1926  0 if (!attrType.equals("http://www.w3.org/2001/XMLSchema#string")) throw new HandlerServiceException("wrong action type attribute data type");
1927  0 NodeList list2 = node1.getChildNodes();
1928  0 for (int k=0; k<list2.getLength(); k++) {
1929  0 Node node2 = list2.item(k);
1930  0 if (Text.class.isAssignableFrom(node2.getClass())) continue;
1931  0 if (node2.getNodeName().equals("AttributeValue")) {
1932  0 NodeList list3 = node2.getChildNodes();
1933  0 if (list3.getLength()!=1) throw new HandlerServiceException("invalid attribute value");
1934  0 if (Text.class.isAssignableFrom(list3.item(0).getClass())) {
1935  0 String value = list3.item(0).getNodeValue();
1936  0 value = value.trim();
1937  0 return value;
1938    }
1939    }
1940    }
1941    }
1942    }
1943    }
1944    }
1945    }
1946    }
1947  0 throw new HandlerServiceException("invalid request context");
1948    }
1949   
 
1950  0 toggle private Vector getActionParameters(Element reqCtx) throws HandlerServiceException {
1951  0 Vector arguments=new Vector();
1952  0 if (reqCtx.getNodeName().equals("Request")) {
1953  0 NodeList list = reqCtx.getChildNodes();
1954  0 for (int i=0; i<list.getLength(); i++) {
1955  0 Node node = list.item(i);
1956  0 if (Text.class.isAssignableFrom(node.getClass())) continue;
1957  0 if (node.getNodeName().equals("Action")) {
1958  0 NodeList list1 = node.getChildNodes();
1959  0 for (int j=0; j<list1.getLength(); j++) {
1960  0 Node node1 = list1.item(j);
1961  0 if (Text.class.isAssignableFrom(node1.getClass())) continue;
1962  0 if (node1.getNodeName().equals("Attribute")) {
1963  0 Element ele = (Element)node1;
1964  0 String dataType = null;
1965  0 String arg = ele.getAttribute("AttributeId");
1966  0 String attrType = ele.getAttribute("DataType");
1967  0 if (attrType.equals("http://www.w3.org/2001/XMLSchema#string")) dataType="String";
1968  0 else if (attrType.equals("http://www.w3.org/2001/XMLSchema#integer")) dataType="Integer";
1969  0 else if (attrType.equals("http://www.w3.org/2001/XMLSchema#double")) dataType="Double";
1970  0 else if (attrType.equals("http://www.w3.org/2001/XMLSchema#date") ||
1971    attrType.equals("http://www.w3.org/2001/XMLSchema#time") ||
1972    attrType.equals("http://www.w3.org/2001/XMLSchema#dateTime"))
1973  0 dataType = "String";
1974  0 else throw new HandlerServiceException("wrong action parameter data type");
1975  0 NodeList list2 = node1.getChildNodes();
1976  0 for (int k=0; k<list2.getLength(); k++) {
1977  0 Node node2 = list2.item(k);
1978  0 if (Text.class.isAssignableFrom(node2.getClass())) continue;
1979  0 if (node2.getNodeName().equals("AttributeValue")) {
1980  0 NodeList list3 = node2.getChildNodes();
1981  0 if (list3.getLength()!=1) throw new HandlerServiceException("invalid action attribute value");
1982  0 if (Text.class.isAssignableFrom(list3.item(0).getClass())) {
1983  0 String value = list3.item(0).getNodeValue();
1984  0 value = value.trim();
1985  0 if (!arg.equals("urn:oasis:names:tc:xacml:1.0:action:action-id")) arguments.add(new PermisArgument(dataType, value));
1986    }
1987    }
1988    }
1989    }
1990    }
1991    }
1992    }
1993    }
1994  0 return arguments;
1995    }
1996   
1997    /**
1998    * This method creates a Permis environment object.
1999    * @param reqCtx is a XACML request context
2000    * @return the Hashtable as the Permis environment. This Hashtable could be empty if the request context does not contain any environmental attribute
2001    */
2002   
 
2003  0 toggle public Hashtable createEnvironment(Element reqCtx) throws EnvironmentException {
2004  0 Hashtable env = new Hashtable();
2005  0 if (reqCtx.getNodeName().equals("Request")) {
2006  0 NodeList list = reqCtx.getChildNodes();
2007  0 for (int i=0; i<list.getLength(); i++) {
2008  0 Node node = list.item(i);
2009  0 if (Text.class.isAssignableFrom(node.getClass())) continue;
2010  0 if (node.getNodeName().equals("Environment")) {
2011  0 NodeList list1 = node.getChildNodes();
2012  0 for (int j=0; j<list1.getLength(); j++) {
2013  0 Node node1 = list1.item(j);
2014  0 if (Text.class.isAssignableFrom(node1.getClass())) continue;
2015  0 if (node1.getNodeName().equals("Attribute")) {
2016  0 Element ele = (Element)node1;
2017  0 String arg = ele.getAttribute("AttributeId");
2018  0 String type = ele.getAttribute("DataType");
2019  0 NodeList list2 = node1.getChildNodes();
2020  0 for (int k=0; k<list2.getLength(); k++) {
2021  0 Node node2 = list2.item(k);
2022  0 if (Text.class.isAssignableFrom(node2.getClass())) continue;
2023  0 if (node2.getNodeName().equals("AttributeValue")) {
2024  0 NodeList list3 = node2.getChildNodes();
2025  0 if (list3.getLength()!=1) throw new EnvironmentException("invalid environment attribute value");
2026  0 if (Text.class.isAssignableFrom(list3.item(0).getClass())) {
2027  0 String value = list3.item(0).getNodeValue();
2028  0 value = value.trim();
2029  0 if (arg.intern()=="clock"){
2030  0 theClock.setTime(theClock.toTime(value));
2031    } else {
2032  0 logger.debug(arg+":"+value+":"+type);
2033  0 if (type.equals("http://www.w3.org/2001/XMLSchema#string")) env.put(arg, value);
2034  0 else if (type.equals("http://www.w3.org/2001/XMLSchema#integer")) env.put(arg, new Integer(value));
2035  0 else if (type.equals("http://www.w3.org/2001/XMLSchema#double")) env.put(arg, new Double(value));
2036  0 else if (type.equals("http://www.w3.org/2001/XMLSchema#time")) env.put(arg, value);
2037  0 else if (type.equals("http://www.w3.org/2001/XMLSchema#date")) env.put(arg, value);
2038  0 else if (type.equals("http://www.w3.org/2001/XMLSchema#dateTime")) env.put(arg, value);
2039  0 else throw new EnvironmentException("wrong environment attribute data type");
2040    }
2041    }
2042    }
2043    }
2044    }
2045    }
2046    }
2047    }
2048    }
2049  0 return env;
2050    }
2051   
2052    /**
2053    * This method creates a Permis Action object.
2054    * @param reqCtx is a XACML request context
2055    * @return the Action object.
2056    */
2057   
 
2058  0 toggle public Action createAction(Element reqCtx) throws ActionException {
2059  0 try {
2060  0 String operation = this.getActionType(reqCtx);
2061  0 logger.debug("action: "+operation);
2062  0 Argument[] arguments = (Argument[])this.getActionParameters(reqCtx).toArray(new Argument[0]);
2063  0 for (int i=0; i<arguments.length; i++) {
2064  0 logger.debug("parameter "+i+1+":"+arguments[i].getType()+" "+arguments[i].getValue());
2065    }
2066  0 Action act = new PermisAction(operation, arguments);
2067  0 return act;
2068    } catch (HandlerServiceException pe) {
2069  0 throw new ActionException("invalid request context");
2070    }
2071    }
2072   
2073    /**
2074    * This method creates a Permis target object.
2075    * @param reqCtx is a XACML request context. this context should contain at least the resource-id attribute
2076    * i.e. urn:oasis:names:tc:xacml:1.0:resource:resource-id
2077    * @return the Target object.
2078    */
2079   
 
2080  0 toggle public PermisTarget createTarget(Element reqCtx) throws TargetException {
2081  0 PermisTarget target = null;
2082  0 String tgt = this.getId(reqCtx,"Resource");
2083  0 logger.debug("Resource DN: "+tgt);
2084  0 try {
2085  0 if (tgt!=null) {
2086  0 String proto = null;
2087  0 try{
2088  0 proto=URLHandler.getProtocolName(tgt);
2089    } catch(BadURLException bue){ /* ignore it */ }
2090  0 if (proto!=null && URLHandler.getURLHandler(proto)!=null){ // it is a URL then
2091  0 target = new PermisTarget(tgt);
2092    } else{ // well, it must be a LDAP DN then
2093  0 target = new PermisTarget(tgt, null); // this time it is treated as a DN + a null array of object classes
2094    }
2095    } else {
2096  0 throw new TargetException("missing resource-id attribute");
2097    }
2098    } catch (BadURLException be) {
2099  0 throw new TargetException("bad URL");
2100    } catch (RFC2253ParsingException re) {
2101  0 throw new TargetException("syntax error");
2102    }
2103  0 return target;
2104    }
2105   
2106    /**
2107    * This method creates a Permis subject object.
2108    * @param reqCtx is a XACML request context. policyId is the policy OID
2109    * @return the PermisSubject object.
2110    */
2111   
 
2112  0 toggle public PermisSubject getSubject(Element reqCtx, String policyId) throws SubjectException {
2113  0 ArrayList roleBasedCreds = new ArrayList();
2114  0 String subjectDN = this.getId(reqCtx,"Subject");
2115  0 logger.debug("Subject DN: "+subjectDN);
2116  0 LDAPDNPrincipal DN = null;
2117  0 if (subjectDN==null) subjectDN = new String();
2118  0 try {
2119  0 DN = new LDAPDNPrincipal(subjectDN);
2120    } catch (RFC2253ParsingException re) {
2121  0 throw new SubjectException("invalid subject DN");
2122    }
2123  0 PermisSubject subject = null;
2124  0 NodeList list = reqCtx.getChildNodes();
2125  0 for (int i=0; i<list.getLength(); i++) {
2126  0 Node node = list.item(i);
2127  0 if (Text.class.isAssignableFrom(node.getClass())) continue;
2128  0 if (node.getNodeName().equals("Subject")) {
2129  0 NodeList list1 = node.getChildNodes();
2130  0 for (int j=0; j<list1.getLength(); j++) {
2131  0 Node node1 = list1.item(j);
2132  0 if (Text.class.isAssignableFrom(node1.getClass())) continue;
2133  0 if (node1.getNodeName().equals("Attribute")) {
2134  0 Element ele = (Element)node1;
2135  0 String attrType = ele.getAttribute("DataType");
2136  0 if (!attrType.equals("http://www.w3.org/2001/XMLSchema#string"))
2137  0 throw new SubjectException("wrong subject attribute data type");
2138  0 String attribute = ele.getAttribute("AttributeId");
2139  0 String value = (String)this.getAttributeValue(node1);
2140  0 value = value.trim();
2141  0 String name = this.getPermisName(attribute,"permis");
2142  0 RoleBasedCredentials creds = null;
2143  0 if (name!=null) {
2144  0 creds = new RoleBasedCredentials(name,value);
2145  0 logger.debug(name+":"+value);
2146  0 roleBasedCreds.add(creds);
2147    }
2148    }
2149    }
2150    }
2151    }
2152  0 if (roleBasedCreds.isEmpty()) return subject;
2153  0 RoleBasedCredentials[] roleBaseCredentials = new RoleBasedCredentials[roleBasedCreds.size()];
2154  0 roleBaseCredentials = (RoleBasedCredentials[])roleBasedCreds.toArray(roleBaseCredentials);
2155  0 ExpirableCredentials[] expirableCredentials = new ExpirableCredentials[roleBaseCredentials.length];
2156  0 Calendar cal = new GregorianCalendar();
2157  0 cal.add(Calendar.MONTH,-1);
2158  0 int year = cal.get(Calendar.YEAR);
2159  0 int month = cal.get(Calendar.MONTH);
2160  0 int day = cal.get(Calendar.DAY_OF_MONTH);
2161  0 int hour = cal.get(Calendar.HOUR_OF_DAY);
2162  0 int min = cal.get(Calendar.MINUTE);
2163  0 int sec = cal.get(Calendar.SECOND);
2164  0 GregorianCalendar gBefore = new GregorianCalendar(year,month,day,hour,min,sec);
2165  0 Date dateBefore = gBefore.getTime();
2166  0 cal = new GregorianCalendar();
2167  0 cal.add(Calendar.MONTH,1);
2168  0 year = cal.get(Calendar.YEAR);
2169  0 month = cal.get(Calendar.MONTH);
2170  0 day = cal.get(Calendar.DAY_OF_MONTH);
2171  0 hour = cal.get(Calendar.HOUR_OF_DAY);
2172  0 min = cal.get(Calendar.MINUTE);
2173  0 sec = cal.get(Calendar.SECOND);
2174  0 GregorianCalendar gAfter = new GregorianCalendar(year,month,day,hour,min,sec);
2175  0 Date dateAfter = gAfter.getTime();
2176  0 AbsoluteValidityPeriod avp = new AbsoluteValidityPeriod(dateBefore,dateAfter);
2177  0 IntersectionValidityPeriod vp = new IntersectionValidityPeriod(avp,avp);
2178  0 for (int i=0; i<roleBaseCredentials.length; i++) {
2179  0 expirableCredentials[i] = new ExpirableCredentials(roleBaseCredentials[i],vp);
2180    }
2181  0 SetOfSubsetsCredentials setOfSubsetsCredentials = new SetOfSubsetsCredentials(expirableCredentials);
2182  0 subject = (PermisSubject) new HandlerSubject(this.pba,DN,null,policyId,setOfSubsetsCredentials);
2183  0 return subject;
2184    }
2185   
2186    //to create a subject in the push model
2187    /**
2188    * This method creates a Permis subject object.
2189    * @param reqCtx is a XACML request context.
2190    * @param issuer is the DN of the issuer.
2191    * @return the PermisSubject object.
2192    */
2193   
 
2194  0 toggle public Subject createSubject(Element reqCtx, String issuer, Object[] creds, String[] parsers) throws SubjectException {
2195  0 Vector newCreds = new Vector();
2196  0 String subjectDN = this.getId(reqCtx,"Subject");
2197  0 logger.debug("Subject DN: "+subjectDN);
2198  0 LDAPDNPrincipal DN = null;
2199  0 SimplePERMISToken subjectToken=null;
2200  0 if (subjectDN==null) subjectDN = new String("");
2201  0 try {
2202  0 DN = new LDAPDNPrincipal(subjectDN);
2203    } catch (RFC2253ParsingException re) {
2204  0 throw new SubjectException("invalid subject DN");
2205    }
2206  0 Subject subject = null;
2207  0 NodeList list = reqCtx.getChildNodes();
2208  0 for (int i=0; i<list.getLength(); i++) {
2209  0 Node node = list.item(i);
2210  0 if (Text.class.isAssignableFrom(node.getClass())) continue;
2211  0 if (node.getNodeName().equals("Subject")) {
2212  0 NodeList list1 = node.getChildNodes();
2213  0 for (int j=0; j<list1.getLength(); j++) {
2214  0 Node node1 = list1.item(j);
2215  0 if (Text.class.isAssignableFrom(node1.getClass())) continue;
2216  0 if (node1.getNodeName().equals("Attribute")) {
2217  0 Element ele = (Element)node1;
2218  0 String attrType = ele.getAttribute("DataType");
2219  0 if (!attrType.equals("http://www.w3.org/2001/XMLSchema#string"))
2220  0 throw new SubjectException("wrong subject attribute data type");
2221  0 String attribute = ele.getAttribute("AttributeId");
2222  0 String value = (String)this.getAttributeValue(node1);
2223  0 value = value.trim();
2224  0 String name = this.getPermisName(attribute,"permis");
2225  0 if (name!=null) {
2226  0 logger.debug(name+":"+value);
2227  0 subjectToken = new SimplePERMISToken(DN.getName(),issuer, name, value);
2228  0 RawCredential cred = null;
2229  0 if (CustomisePERMIS.isMultiParserUsed()) {
2230  0 cred = new RawCredential(subjectToken,"issrg.simplePERMIS.SimplePERMISTokenParser");
2231  0 newCreds.add(cred);
2232  0 } else newCreds.add(subjectToken);
2233    }
2234    }
2235    }
2236    }
2237    }
2238  0 if (creds != null)
2239  0 for (int i=0; i<creds.length; i++) {
2240  0 RawCredential cred = null;
2241  0 if (CustomisePERMIS.isMultiParserUsed()) {
2242  0 cred = new RawCredential(creds[i],parsers[i]);
2243  0 newCreds.add(cred);
2244  0 } else newCreds.add(creds[i]);
2245    }
2246  0 try{
2247  0 Date date = new Date();
2248  0 long start = date.getTime();
2249  0 subject = this.pba.getCreds(DN, newCreds.toArray());
2250  0 date = new Date();
2251  0 long end = date.getTime();
2252  0 end = end - start;
2253  0 logger.info("getCreds (push mode) is made in "+end+" milliseconds");
2254    }catch(PbaException pbaE){
2255  0 throw new SubjectException("invalid subject:"+pbaE);
2256    }
2257  0 return subject;
2258    }
2259   
2260    /**
2261    * this method returns the subject DN from a WS-Trust request token
2262    */
2263   
 
2264  0 toggle public String getSubjectDN(Object token) throws Exception {
2265  0 if (Element.class.isAssignableFrom(token.getClass())) {
2266  0 Element contextIn = (Element)token;
2267  0 Interpreter inter = new Interpreter(contextIn);
2268  0 String DNIn = inter.getSubjectDN();
2269  0 String ValidLDAPDN = RFC2253NameParser.toCanonicalDN(DNIn);
2270  0 if (ValidLDAPDN==null) {
2271  0 throw new Exception("get an invalid DN");
2272    }
2273  0 return ValidLDAPDN;
2274    } else {
2275  0 throw new Exception("this is not a WS-Trust request token");
2276    }
2277    }
2278   
2279    /**
2280    * this method returns an XACML request context, in which the given action and resource are used
2281    * as the action-id and resource-id value, and the given subject is the Subject section in the context.
2282    * @param actionIn
2283    * @param resourceIn
2284    * @param subject
2285    */
2286   
 
2287  0 toggle public Element createRequestContext(String actionIn, String resourceIn, Element subject) throws Exception {
2288  0 if (actionIn==null && resourceIn==null) return subject;
2289  0 else if (actionIn==null) {
2290  0 Element resource = this.createSimpleContext(resourceIn,"Resource");
2291  0 Merge merger = new Merge();
2292  0 Element reqCtx = merger.merge(subject,resource);
2293  0 return reqCtx;
2294  0 } else if (resourceIn==null) {
2295  0 Element action = this.createSimpleContext(actionIn,"Action");
2296  0 Merge merger = new Merge();
2297  0 Element reqCtx = merger.merge(subject,action);
2298  0 return reqCtx;
2299    } else {
2300  0 Element resource = this.createSimpleContext(resourceIn,"Resource");
2301  0 Element action = this.createSimpleContext(actionIn,"Action");
2302  0 Merge merger = new Merge();
2303  0 Element tmp = merger.merge(subject,resource);
2304  0 Element reqCtx = merger.merge(tmp,action);
2305  0 return reqCtx;
2306    }
2307    }
2308   
2309   
2310    /**
2311    * this method returns a set of base64 strings, which represent ACs or PKCs
2312    * @param list a list of binary ACs or PKCs.
2313    */
2314   
 
2315  0 toggle public String[] getBase64(ArrayList list) {
2316  0 Binary [] fr = new Binary[list.size()];
2317  0 fr = (Binary[])list.toArray(fr);
2318  0 String[] results = new String[fr.length];
2319  0 for (int i=0; i<fr.length; i++) {
2320  0 byte[] b = fr[i].getBinaryValue();
2321  0 Base64 base64 = new Base64();
2322  0 byte [] bb = base64.encode(b);
2323  0 results[i] = new String(bb);
2324    }
2325  0 return results;
2326    }
2327   
2328   
2329    /**
2330    * this method returns a list of certificates (AC or PKC) from a LDAP server
2331    * @param type tells what type of certificate is returned i.e. AC or PKC
2332    * @param dn the subject DN of the certificates
2333    * @param method ldap method, which can be LDAP or ldaps
2334    * @param address the address of the LDAP server (i.e. 129.12.16.148 or issrg-beta.cs.kent.ac.uk)
2335    * @param port the port of the LDAP server
2336    * @param baseDN the base DN of the LDAP server
2337    * @param passwd the password of a user account
2338    */
2339   
 
2340  0 toggle public ArrayList getCertificates(int type,String dn, String method, String address, int port) throws Exception {
2341  0 String certificate_type = null;
2342  0 if (type==this.AC) certificate_type = this.ac_type;
2343  0 else if (type==this.PKC) certificate_type = this.pkc_type;
2344  0 ArrayList result=null;
2345  0 LDAPConnection ldap = new LDAPConnection();
2346  0 ldap.connect(address,port);
2347  0 if (logger.isDebugEnabled()) logger.debug("connect to ldap server");
2348  0 if (logger.isDebugEnabled()) logger.debug("bind to anonymous user");
2349  0 LDAPEntry foundEntry = null;
2350  0 try {
2351  0 foundEntry = ldap.read(dn);
2352  0 if (logger.isDebugEnabled()) logger.debug("get the LDAP entry at "+dn);
2353    } catch (LDAPException ee) {
2354  0 return null;
2355    }
2356  0 LDAPAttributeSet set = foundEntry.getAttributeSet();
2357  0 for (int i=0;i<set.size();i++) {
2358  0 LDAPAttribute att = set.elementAt(i);
2359  0 if (att.getName().equals(certificate_type)) {
2360  0 result = new ArrayList();
2361  0 Enumeration enums = att.getByteValues();
2362  0 while (enums.hasMoreElements()) {
2363  0 byte[] ac = (byte[])enums.nextElement();
2364  0 Binary cert = new Binary(ac);
2365  0 result.add(cert);
2366    }
2367  0 if (logger.isDebugEnabled()) logger.debug("get a "+certificate_type+ " attribute");
2368    }
2369    }
2370  0 return result;
2371    }
2372   
2373    /**
2374    * this method is used to set LDAP attribute names for holding ACs and PKCs
2375    */
2376   
 
2377  0 toggle public void setAttributeType(String acType,String pkcType) {
2378  0 this.ac_type = acType;
2379  0 this.pkc_type = pkcType;
2380    }
2381    }
2382   
2383