ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/experimental/server/ACL/ACL.java
(Generate patch)

Comparing experimental/server/ACL/ACL.java (file contents):
Revision 1.5 by tdb, Sun Dec 23 01:05:35 2001 UTC vs.
Revision 1.10 by tdb, Mon Dec 31 19:25:39 2001 UTC

# Line 4 | Line 4
4   //---IMPORTS---
5   import uk.org.iscream.cms.server.util.*;
6   import java.util.ArrayList;
7 + import java.util.StringTokenizer;
8   import java.net.InetAddress;
9   import java.io.Serializable;
10  
# Line 75 | Line 76 | public class ACL implements Serializable {
76       * param expression what this rule matches using wildcards
77       */
78      public void add(boolean allow, String expression) {
79 <        _acl.add(new ACLRule(allow, expression));
79 >        // 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 >        // add the rule to our array
132 >        _acl.add(new ACLRule(allow, expression, ipaddr, ip));
133      }
134      
135      /**
# Line 99 | Line 153 | public class ACL implements Serializable {
153      /**
154       * Check to see if an InetAddress is permitted
155       * by the ACL. Perfect for Socket uses of this
156 <     * class. It should be made clear that this will
157 <     * check both the hostname AND IP address against
158 <     * each rule in turn. The hostname will always be
159 <     * checked BEFORE the IP address.
156 >     * class. A rule will either be for a name, or
157 >     * an IP address (this is determined in the add
158 >     * method), and the appropriate comparison will
159 >     * be performed.
160       *
161       * @param address the InetAddress to check
162       * @return whether the InetAddress was permitted by the ACL
163       */
164      public boolean check(InetAddress address) {
165 +        // gather the details first
166 +        String hostname = address.getHostName();
167 +        String ip = address.getHostAddress();
168 +        short[] ipaddr = ipStringToShort(ip);
169 +        // check each rule against this InetAddress
170          for(int i=0; i < _acl.size(); i++) {
171              ACLRule rule = (ACLRule) _acl.get(i);
172 <            if(StringUtils.wildcardCheck(address.getHostName(), rule._expression)) {
173 <                return rule._allow;
172 >            if(rule._iprule) {
173 >                // if this is an IP rule do a short comparison
174 >                if(compareShorts(ipaddr, rule._ipaddr)) {
175 >                    return rule._allow;
176 >                }
177              }
178 <            if(StringUtils.wildcardCheck(address.getHostAddress(), rule._expression)) {
179 <                return rule._allow;
178 >            else {
179 >                // if not do a full blown String comparsion
180 >                if(StringUtils.wildcardCheck(hostname, rule._expression)) {
181 >                    return rule._allow;
182 >                }
183              }
184 +            
185          }
186 +        // if we haven't matched a rule, return the default
187          return _defaultMode;
188      }
189      
# Line 127 | Line 194 | public class ACL implements Serializable {
194       */
195      public String toString() {
196          StringBuffer acl = new StringBuffer();
197 +        // put in the i-scream toString code
198 +        acl.append(FormatName.getName(_name, getClass().getName(), REVISION));
199          acl.append("{");
200 +        // put the value of each Rule in the result
201          for(int i=0; i < _acl.size(); i++) {
202 <            ACLRule rule = (ACLRule) _acl.get(i);
133 <            if(rule._allow) {
134 <                acl.append(rule._expression + "=ALLOW");
135 <            }
136 <            else {
137 <                acl.append(rule._expression + "=DENY");
138 <            }
202 >            acl.append((ACLRule) _acl.get(i));
203              acl.append(",");
204          }
205 +        // put the default mode in the result
206          if(_defaultMode) {
207              acl.append("DEFAULT=ALLOW");
208          }
# Line 150 | Line 215 | public class ACL implements Serializable {
215  
216   //---PRIVATE METHODS---
217  
218 +    /**
219 +     * Converts an IP address in String format into
220 +     * a short array of length 4. Any wildcards, *,
221 +     * found in the IP address are represented by
222 +     * a -1.
223 +     *
224 +     * @param ip The IP address in String format
225 +     * @return The IP address in a short[]
226 +     */
227 +    private short[] ipStringToShort(String ip) {
228 +        short[] ipaddr = {-1, -1, -1, -1};
229 +        StringTokenizer st = new StringTokenizer(ip, ".");
230 +        for(int i=0; i < 4 && st.hasMoreTokens(); i++) {
231 +            try {
232 +                ipaddr[i] = Short.parseShort(st.nextToken());
233 +            }
234 +            catch(NumberFormatException e) {
235 +                // do nothing?
236 +                // we just want to leave it as -1
237 +                // -- actually, maybe we want to do more checks in here?
238 +                //    although in this code context it'll probably be ok,
239 +                //    it might be worth verifying wildcards and that the
240 +                //    number is in range...
241 +            }
242 +        }
243 +        return ipaddr;
244 +    }
245 +    
246 +    /**
247 +     * Compares two short arrays. The array can contain a -1, which
248 +     * will always match any value -- it's a wildcard. They must be
249 +     * the same length to match. At the moment the order of the
250 +     * parameters does not matter.
251 +     *
252 +     * @param first The first array to compare
253 +     * @param second The second array to compare
254 +     * @result the result of the comparison
255 +     */
256 +    private boolean compareShorts(short[] first, short[] second) {
257 +        if(first.length != second.length) {
258 +            return false;
259 +        }
260 +        for(int i=0; i < first.length; i++) {
261 +            // -- might want to consider specify which is the wildcard one?
262 +            if(first[i] == -1 || second[i] == -1) {
263 +                continue;
264 +            }
265 +            if(first[i] != second[i]) {
266 +                return false;
267 +            }
268 +        }
269 +        return true;
270 +    }
271 +
272   //---ACCESSOR/MUTATOR METHODS---
273  
274   //---ATTRIBUTES---
# Line 189 | Line 308 | public class ACL implements Serializable {
308           *
309           * @param allow whether this is an ALLOW or DENY rule
310           * @param expression what this rule matches
311 +         * @param ipaddr the IP address wildcard this rule matches if it's an IP rule
312 +         * @param iprule whether this is an IP rule
313           */
314 <        private ACLRule(boolean allow, String expression) {
314 >        private ACLRule(boolean allow, String expression, short[] ipaddr, boolean iprule) {
315              _allow = allow;
316              _expression = expression;
317 +            _ipaddr = ipaddr;
318 +            _iprule = iprule;
319          }
320          
321          /**
322 +         * Returns a String representation of this rule.
323 +         *
324 +         * @return A String representation of this rule.
325 +         */
326 +        public String toString() {
327 +            if(_allow) {
328 +                return _expression + "=ALLOW";
329 +            }
330 +            else {
331 +                return _expression + "=DENY";
332 +            }
333 +        }
334 +        
335 +        /**
336           * Whether this is an ALLOW or DENY rule.
337           */
338          private boolean _allow;
# Line 204 | Line 341 | public class ACL implements Serializable {
341           * What this rule matches.
342           */
343          private String _expression;
344 +        
345 +        /**
346 +         * The IP wildcard, only valid if this
347 +         * is an IP rule.
348 +         */
349 +        private short[] _ipaddr;
350 +        
351 +        /**
352 +         * Whether this is an IP rule.
353 +         */
354 +        private boolean _iprule;
355          
356      }
357  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines