Clover Coverage Report
Coverage timestamp: Sun Mar 23 2008 08:24:39 GMT
36   176   13   6
24   72   0.5   6
6     3  
1    
 
 
  LDAPDNPrincipal       Line # 44 36 13 80.3% 0.8030303
 
  (1)
 
1    /*
2    * Copyright (c) 2000-2005, University of Salford
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions are met:
7    *
8    * Redistributions of source code must retain the above copyright notice, this
9    * list of conditions and the following disclaimer.
10    *
11    * Redistributions in binary form must reproduce the above copyright notice,
12    * this list of conditions and the following disclaimer in the documentation
13    * and/or other materials provided with the distribution.
14    *
15    * Neither the name of the University of Salford nor the names of its
16    * contributors may be used to endorse or promote products derived from this
17    * software without specific prior written permission.
18    *
19    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20    * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21    * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22    * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23    * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24    * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25    * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26    * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27    * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28    * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29    * POSSIBILITY OF SUCH DAMAGE.
30    */
31   
32    package issrg.pba.rbac;
33   
34    import java.security.Principal;
35   
36    /**
37    * This class represents a Principal whose name is an LDAP DN corresponding to
38    * RFC2253.
39    *
40    * @author A Otenko
41    * @version 1.0
42    */
43   
 
44    public class LDAPDNPrincipal implements java.security.Principal {
45    public static final LDAPDNPrincipal WHOLE_WORLD_DN = new LDAPDNPrincipal(); // the static initializer below will set the right values
 
46  21 toggle static{
47  21 try{
48  21 WHOLE_WORLD_DN.name="";
49  21 WHOLE_WORLD_DN.parsedDN=new LDAPDNPrincipal("").parsedDN;
50    }catch(issrg.utils.RFC2253ParsingException rpe){
51    // this shouldn't happen
52    }
53    }
54   
55    private String name;
56    private String [][][] parsedDN;
57   
 
58  21 toggle protected LDAPDNPrincipal() {}
59   
60    /**
61    * This constructor builds the object out of the String representation of the
62    * DN. It
63    * uses <code>issrg.utils.RFC2253NameParser</code> to check if the name can be
64    * successfully parsed.
65    * If not, an <code>issrg.utils.RFC2253ParsingException</code> is thrown.
66    *
67    * @params ldapDN is the DN of the Principal
68    *
69    * @throws RFC2253ParsingException
70    *
71    * @see issrg.utils.RFC2253NameParser
72    * @see issrg.utils.RFC2253ParsingException
73    */
 
74  12222 toggle public LDAPDNPrincipal(String ldapDN) throws issrg.utils.RFC2253ParsingException {
75    //System.out.println("Building LDAP DN: "+ldapDN); //***********
76  12222 name = issrg.utils.RFC2253NameParser.toCanonicalDN(
77    parsedDN=issrg.utils.RFC2253NameParser.distinguishedName(ldapDN)
78    );
79   
80    //System.out.println("Built OK"); //***********
81    }
82   
83    /**
84    * This method returns the canonical representation of the Principal's DN,
85    * which may differ from the value you input to the constructor, but with
86    * equivalent meaning in terms of RFC2253.
87    *
88    * <p>Note that the <code>issrg.utils.RFC2253NameParser</code> does not have a
89    * registry of attribute names or OIDs, so it is not aware of what attribute
90    * values should be encoded as hexstrings (starting with '#'). After conversion
91    * of such values to the canonical representation there may be loss of comparison
92    * precision, if
93    * the values happen to contain US-ASCII characters, which will be compared
94    * as case-insensitive values, not as binary values.
95    *
96    * @return the canonical representation of the DN.
97    */
 
98  27710 toggle public String getName(){
99  27710 return name;
100    }
101   
102    /**
103    * Returns the DN as an array, specified by issrg.utils.RFC2253Parser
104    *
105    * @return an array of values representing the DN
106    */
 
107  49185 toggle public String [][][] getParsedDN(){
108  49185 return parsedDN;
109    }
110   
111    /**
112    * This method defines the equality comparison of the DNs.
113    *
114    * @param o is the object to compare
115    *
116    * @return true, if o is a Principal containing the DN equal to the one
117    * this object contains
118    */
 
119  4377 toggle public boolean equals(Object o){
120  4377 if (!(o instanceof Principal)){
121  0 return false;
122    }
123   
124  4377 LDAPDNPrincipal l;
125  4377 if (o instanceof LDAPDNPrincipal){
126  1908 l=(LDAPDNPrincipal)o;
127    }else{
128  2469 try{
129  2469 l=new LDAPDNPrincipal(((Principal)o).getName());
130    }catch (Exception e){
131  0 return false; // an invalid DN there
132    }
133    }
134   
135  4377 String [][][] dn = l.getParsedDN();
136  4377 boolean result = (dn.length == parsedDN.length); // to start with, they must be of the same length
137   
138  4377 next_RDN:
139  17976 for (int i=0; i<dn.length && result; i++){
140  0 if (result=(dn[i].length==parsedDN[i].length)){ // otherwise, the loop will be continued to the condition where "result" is checked
141  14653 boolean [] b = new boolean[dn[i].length];
142  14653 next_AVA:
143  28252 for (int j=0; j<parsedDN[i].length; j++){
144  14653 for (int k=0; k<dn[i].length; k++){
145  0 if (b[k]) continue;
146   
147  14653 if (dn[i][k][0].compareToIgnoreCase(parsedDN[i][j][0])==0){
148  14653 String v1=dn[i][k].length<3?dn[i][k][1]:dn[i][k][2];
149  14653 String v2=parsedDN[i][j].length<3?parsedDN[i][j][1]:parsedDN[i][j][2];
150   
151  14653 int c;
152  14653 if (parsedDN[i][j].length>=3 && dn[i][k].length>=3){ // both of the arrays are of length 3 then
153    // case-sensitive comparison should be done (the values are exact values input by the user for '#blablabla' binary strings)
154  0 c=v1.compareTo(v2);
155    }else{
156  14653 c=v1.compareToIgnoreCase(v2); // so the strings can be case-insensitive
157    }
158   
159  14653 if (c==0){// exact match
160  13599 b[k]=true; // actually, such position of this assignment means that the comparison lets the RDN contain several AVAs with the same attributename (not allowed by RFCs though)
161    // this syntax is wider, so it works fine with the RFC requirements
162  13599 continue next_AVA;
163    }
164    }
165   
166    // we are here only if no attribute with such name and value has been found
167  1054 result=false;
168  1054 break next_RDN;
169    }
170    }
171    }
172    }
173   
174  4377 return result;
175    }
176    }