ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/experimental/server/ACL/ACL.java
Revision: 1.8
Committed: Mon Dec 31 02:57:00 2001 UTC (22 years, 4 months ago) by tdb
Branch: MAIN
Changes since 1.7: +1 -0 lines
Log Message:
Added an ACLDatagramSocket. Operation is much the same as the
ACLServerSocket. Also tweaked the toString() to keep the i-scream bits as
well as the more useful stuff.

File Contents

# User Rev Content
1 tdb 1.1 //---PACKAGE DECLARATION---
2     //package uk.org.iscream.cms.server.util;
3    
4     //---IMPORTS---
5     import uk.org.iscream.cms.server.util.*;
6 tdb 1.3 import java.util.ArrayList;
7 tdb 1.7 import java.util.StringTokenizer;
8 tdb 1.1 import java.net.InetAddress;
9 tdb 1.4 import java.io.Serializable;
10 tdb 1.1
11     /**
12 tdb 1.2 * Access Control List for use primarily
13     * with the ACLServerSocket. It could, however
14     * have other uses as it has a fairly generic
15     * behaviour. Rules are added using the add
16     * method, and then checks can be made using
17     * the relevant check method.
18 tdb 1.1 *
19 tdb 1.6 * @author $Author: tdb $
20     * @version $Id: ACL.java,v 1.5 2001/12/23 01:05:35 tdb Exp $
21 tdb 1.1 */
22 tdb 1.4 public class ACL implements Serializable {
23 tdb 1.1
24     //---FINAL ATTRIBUTES---
25    
26     /**
27     * The current CVS revision of this class
28     */
29 tdb 1.6 public static final String REVISION = "$Revision: 1.5 $";
30 tdb 1.2
31     /**
32     * static to be used when adding an ALLOW rule to the ACL.
33     */
34 tdb 1.1 public static final boolean ALLOW = true;
35 tdb 1.2
36     /**
37     * static to be used when adding a DENY rule to the ACL.
38     */
39 tdb 1.1 public static final boolean DENY = false;
40    
41     //---STATIC METHODS---
42    
43     //---CONSTRUCTORS---
44    
45 tdb 1.2 /**
46     * Construct a new Access Control List. The default
47     * mode is to ALLOW anything that isn't explicitly
48     * blocked by a rule.
49     */
50 tdb 1.1 public ACL() {
51     // default to ACL.ALLOW
52     this(ACL.ALLOW);
53     }
54    
55 tdb 1.2 /**
56     * Construct a new Access Control List with a given
57     * default mode. This mode specifies what should
58     * happen if a check does not match any rules.
59     *
60     * @param defaultMode the default mode for non-matched checks
61     */
62 tdb 1.1 public ACL(boolean defaultMode) {
63     _defaultMode = defaultMode;
64     }
65    
66     //---PUBLIC METHODS---
67    
68 tdb 1.2 /**
69     * Add a new rule to the ACL immediately after the
70     * previous rule. The rule can either be an ACL.ALLOW
71     * rule, or an ACL.DENY rule. The expression can
72     * contain a wildcard (a * only). Rules can only be
73     * added to the end of the list.
74     *
75     * param allow whether this is an ALLOW or DENY rule
76     * param expression what this rule matches using wildcards
77     */
78 tdb 1.1 public void add(boolean allow, String expression) {
79 tdb 1.7 // default to expecting it to be an IP
80     // we will try to disprove this :)
81     boolean ip = true;
82     short[] ipaddr = {-1, -1, -1, -1};
83     int i = 0;
84     String s = "";
85     // tokenize the expression on fullstops, so we can break
86     // up the quads of an IP (if it's an IP!)
87     StringTokenizer st = new StringTokenizer(expression, ".");
88     while(st.hasMoreTokens() && i++ < 4) {
89     s = st.nextToken();
90     // if it's a wildcard, we'll skip to the next one
91     // as no more checks are required
92     if(s.equals("*")) {
93     continue;
94     }
95     // attempt to parse it into a short
96     try {
97     short n = Short.parseShort(s);
98     // if it's an int but outside of the
99     // valid range, it can't be an IP
100     if(n < 0 || n > 255) {
101     ip = false;
102     // give up checking further
103     break;
104     }
105     ipaddr[i-1] = n;
106     }
107     // if it didn't parse as an int it can't be an IP
108     catch (NumberFormatException e) {
109     ip = false;
110     // give up checking further
111     break;
112     }
113     }
114     // we've done 4 parts, so if there's any
115     // more this can't be an IP
116     if(st.hasMoreTokens()) {
117     ip = false;
118     }
119     // if we've done less than 4, see if the last one
120     // was a wildcard - if it isn't then it's not an IP
121     // -- this allows 129.12.*
122     if(i < 4 && !s.equals("*")) {
123     ip = false;
124     }
125     // if we had one or less entries it can't be an IP
126     // -- this disallows * matching as an IP due
127     // to the rule above
128     if(i <= 1) {
129     ip = false;
130     }
131     // finally print out what we've found.
132     System.out.println("IP("+ip+"): "+expression);
133     if(ip) {
134     for(int j=0; j < ipaddr.length; j++) {
135     System.out.print(ipaddr[j] + " ");
136     }
137     System.out.println();
138     }
139     _acl.add(new ACLRule(allow, expression, ipaddr, ip));
140 tdb 1.1 }
141    
142 tdb 1.2 /**
143     * Check to see if a string is permitted by the
144     * ACL. Useful for testing, and non-Socket uses
145     * of this class.
146     *
147     * @param address the string to check
148     * @return whether the address was permitted by the ACL
149     */
150 tdb 1.1 public boolean check(String address) {
151 tdb 1.3 for(int i=0; i < _acl.size(); i++) {
152     ACLRule rule = (ACLRule) _acl.get(i);
153     if(StringUtils.wildcardCheck(address, rule._expression)) {
154     return rule._allow;
155 tdb 1.1 }
156     }
157     return _defaultMode;
158     }
159    
160 tdb 1.2 /**
161     * Check to see if an InetAddress is permitted
162     * by the ACL. Perfect for Socket uses of this
163     * class. It should be made clear that this will
164     * check both the hostname AND IP address against
165     * each rule in turn. The hostname will always be
166     * checked BEFORE the IP address.
167     *
168     * @param address the InetAddress to check
169     * @return whether the InetAddress was permitted by the ACL
170     */
171 tdb 1.1 public boolean check(InetAddress address) {
172 tdb 1.7 String hostname = address.getHostName();
173     String ip = address.getHostAddress();
174     short[] ipaddr = ipStringToShort(ip);
175 tdb 1.3 for(int i=0; i < _acl.size(); i++) {
176     ACLRule rule = (ACLRule) _acl.get(i);
177 tdb 1.7 if(rule._iprule) {
178     System.out.println("checking ip rule "+rule._expression);
179     //if(StringUtils.wildcardCheck(ip, rule._expression)) {
180     if(compareShorts(ipaddr, rule._ipaddr)) {
181     return rule._allow;
182     }
183 tdb 1.1 }
184 tdb 1.7 else {
185     System.out.println("checking name rule: "+rule._expression);
186     if(StringUtils.wildcardCheck(hostname, rule._expression)) {
187     return rule._allow;
188     }
189 tdb 1.1 }
190 tdb 1.7
191 tdb 1.1 }
192     return _defaultMode;
193     }
194    
195 tdb 1.2 /**
196 tdb 1.5 * Gives a String representation of this ACL.
197 tdb 1.2 *
198     * @return A String representation of this ACL.
199     */
200 tdb 1.5 public String toString() {
201     StringBuffer acl = new StringBuffer();
202 tdb 1.8 acl.append(FormatName.getName(_name, getClass().getName(), REVISION));
203 tdb 1.5 acl.append("{");
204 tdb 1.3 for(int i=0; i < _acl.size(); i++) {
205 tdb 1.6 acl.append((ACLRule) _acl.get(i));
206 tdb 1.5 acl.append(",");
207 tdb 1.1 }
208 tdb 1.3 if(_defaultMode) {
209 tdb 1.5 acl.append("DEFAULT=ALLOW");
210 tdb 1.3 }
211     else {
212 tdb 1.5 acl.append("DEFAULT=DENY");
213 tdb 1.3 }
214 tdb 1.5 acl.append("}");
215     return acl.toString();
216 tdb 1.1 }
217    
218     //---PRIVATE METHODS---
219    
220 tdb 1.7 private short[] ipStringToShort(String ip) {
221     short[] ipaddr = {-1, -1, -1, -1};
222     StringTokenizer st = new StringTokenizer(ip, ".");
223     for(int i=0; i < 4 && st.hasMoreTokens(); i++) {
224     try {
225     ipaddr[i] = Short.parseShort(st.nextToken());
226     }
227     catch(NumberFormatException e) {
228     // do nothing?
229     }
230     }
231     return ipaddr;
232     }
233    
234     private boolean compareShorts(short[] first, short[] second) {
235     if(first.length != second.length) {
236     System.out.println("not equal length");
237     return false;
238     }
239     for(int i=0; i < first.length; i++) {
240     // -- might want to consider specify which is the wildcard one?
241     System.out.println(i + ":" + first[i] + "," + second[i]);
242     if(first[i] == -1 || second[i] == -1) {
243     continue;
244     }
245     if(first[i] != second[i]) {
246     System.out.println("not equal");
247     return false;
248     }
249     }
250     System.out.println("equal");
251     return true;
252     }
253    
254 tdb 1.1 //---ACCESSOR/MUTATOR METHODS---
255    
256     //---ATTRIBUTES---
257    
258     /**
259     * This is the friendly identifier of the
260     * component this class is running in.
261     * eg, a Filter may be called "filter1",
262     * If this class does not have an owning
263     * component, a name from the configuration
264     * can be placed here. This name could also
265     * be changed to null for utility classes.
266     */
267     private String _name = null;
268 tdb 1.2
269     /**
270 tdb 1.3 * The ACL is stored in this ArrayList.
271 tdb 1.2 */
272 tdb 1.3 private ArrayList _acl = new ArrayList();
273 tdb 1.2
274     /**
275     * The default mode of this ACL.
276     */
277 tdb 1.1 private boolean _defaultMode;
278    
279     //---STATIC ATTRIBUTES---
280    
281     //---INNER CLASSES---
282    
283 tdb 1.2 /**
284     * Wrapper class for an ACL rule.
285     */
286 tdb 1.4 private class ACLRule implements Serializable {
287 tdb 1.1
288 tdb 1.2 /**
289     * Construct an ACL rule.
290     *
291     * @param allow whether this is an ALLOW or DENY rule
292     * @param expression what this rule matches
293 tdb 1.7 * @param iprule whether this is an IP rule
294 tdb 1.2 */
295 tdb 1.7 private ACLRule(boolean allow, String expression, short[] ipaddr, boolean iprule) {
296 tdb 1.1 _allow = allow;
297     _expression = expression;
298 tdb 1.7 _ipaddr = ipaddr;
299     _iprule = iprule;
300 tdb 1.6 }
301    
302     /**
303     * Returns a String representation of this rule.
304     *
305     * @return A String representation of this rule.
306     */
307     public String toString() {
308     if(_allow) {
309     return _expression + "=ALLOW";
310     }
311     else {
312     return _expression + "=DENY";
313     }
314 tdb 1.1 }
315    
316 tdb 1.2 /**
317     * Whether this is an ALLOW or DENY rule.
318     */
319 tdb 1.1 private boolean _allow;
320 tdb 1.2
321     /**
322     * What this rule matches.
323     */
324 tdb 1.1 private String _expression;
325 tdb 1.7
326     private short[] _ipaddr;
327    
328     /**
329     * Whether this is an IP rule.
330     */
331     private boolean _iprule;
332 tdb 1.1
333     }
334    
335     }