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.6 by tdb, Mon Dec 24 04:17:29 2001 UTC vs.
Revision 1.12 by tdb, Tue Jan 8 13:31:34 2002 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 >        // try and convert the expression into an IP address
80 >        short[] ipaddr = ipStringToShort(expression);
81 >        // a result of null means it's not an IP address
82 >        // add either a name rule or an IP rule
83 >        if(ipaddr != null) {
84 >            _acl.add(new ACLRule(allow, expression, ipaddr, true));
85 >        }
86 >        else {
87 >            _acl.add(new ACLRule(allow, expression, ipaddr, false));
88 >        }
89      }
90      
91      /**
# Line 89 | Line 99 | public class ACL implements Serializable {
99      public boolean check(String address) {
100          for(int i=0; i < _acl.size(); i++) {
101              ACLRule rule = (ACLRule) _acl.get(i);
102 <            if(StringUtils.wildcardCheck(address, rule._expression)) {
102 >            if(StringUtils.wildcardMatch(address, rule._expression)) {
103                  return rule._allow;
104              }
105          }
# Line 99 | Line 109 | public class ACL implements Serializable {
109      /**
110       * Check to see if an InetAddress is permitted
111       * by the ACL. Perfect for Socket uses of this
112 <     * class. It should be made clear that this will
113 <     * check both the hostname AND IP address against
114 <     * each rule in turn. The hostname will always be
115 <     * checked BEFORE the IP address.
112 >     * class. A rule will either be for a name, or
113 >     * an IP address (this is determined in the add
114 >     * method), and the appropriate comparison will
115 >     * be performed.
116       *
117       * @param address the InetAddress to check
118       * @return whether the InetAddress was permitted by the ACL
119       */
120      public boolean check(InetAddress address) {
121 +        // gather the details first
122 +        String hostname = address.getHostName();
123 +        String ip = address.getHostAddress();
124 +        short[] ipaddr = ipStringToShort(ip);
125 +        // check each rule against this InetAddress
126          for(int i=0; i < _acl.size(); i++) {
127              ACLRule rule = (ACLRule) _acl.get(i);
128 <            if(StringUtils.wildcardCheck(address.getHostName(), rule._expression)) {
129 <                return rule._allow;
128 >            if(rule._iprule) {
129 >                // if this is an IP rule do a short comparison
130 >                // must specify the wildcarded rule first
131 >                if(compareShorts(rule._ipaddr, ipaddr)) {
132 >                    return rule._allow;
133 >                }
134              }
135 <            if(StringUtils.wildcardCheck(address.getHostAddress(), rule._expression)) {
136 <                return rule._allow;
135 >            else {
136 >                // if not do a full blown String comparsion
137 >                if(StringUtils.wildcardMatch(hostname, rule._expression)) {
138 >                    return rule._allow;
139 >                }
140              }
141 +            
142          }
143 +        // if we haven't matched a rule, return the default
144          return _defaultMode;
145      }
146      
# Line 127 | Line 151 | public class ACL implements Serializable {
151       */
152      public String toString() {
153          StringBuffer acl = new StringBuffer();
154 +        // put in the i-scream toString code
155 +        acl.append(FormatName.getName(_name, getClass().getName(), REVISION));
156          acl.append("{");
157 +        // put the value of each Rule in the result
158          for(int i=0; i < _acl.size(); i++) {
159              acl.append((ACLRule) _acl.get(i));
160              acl.append(",");
161          }
162 +        // put the default mode in the result
163          if(_defaultMode) {
164              acl.append("DEFAULT=ALLOW");
165          }
# Line 144 | Line 172 | public class ACL implements Serializable {
172  
173   //---PRIVATE METHODS---
174  
175 +    /**
176 +     * Converts an IP address in String format into
177 +     * a short array of length 4. Any wildcards, *,
178 +     * found in the IP address are represented by
179 +     * a -1. If the given String is not an IP address
180 +     * null is returned instead.
181 +     *
182 +     * @param ip The IP address in String format
183 +     * @return The IP address in a short[]
184 +     */
185 +    private short[] ipStringToShort(String ip) {
186 +        // default to expecting it to be an IP
187 +        // we will try to disprove this :)
188 +        short[] ipaddr = {-1, -1, -1, -1};
189 +        int i = 0;
190 +        String s = "";
191 +        // tokenize the String on fullstops, so we can break
192 +        // up the quads of an IP (if it's an IP!)
193 +        StringTokenizer st = new StringTokenizer(ip, ".");
194 +        while(st.hasMoreTokens() && i++ < 4) {
195 +            s = st.nextToken();
196 +            // if it's a wildcard, we'll skip to the next one
197 +            // as no more checks are required
198 +            if(s.equals("*")) {
199 +                continue;
200 +            }
201 +            // attempt to parse it into a short
202 +            try {
203 +                short n = Short.parseShort(s);
204 +                // if it's an int but outside of the
205 +                // valid range, it can't be an IP
206 +                if(n < 0 || n > 255) {
207 +                    // give up checking further
208 +                    return null;
209 +                }
210 +                ipaddr[i-1] = n;
211 +            }
212 +            // if it didn't parse as a short it can't be an IP
213 +            catch (NumberFormatException e) {
214 +                // give up checking further
215 +                return null;
216 +            }
217 +        }
218 +        // we've done 4 parts, so if there's any
219 +        // more this can't be an IP
220 +        if(st.hasMoreTokens()) {
221 +            return null;
222 +        }
223 +        // if we've done less than 4, see if the last one
224 +        // was a wildcard - if it isn't then it's not an IP
225 +        //   -- this allows 129.12.*
226 +        if(i < 4 && !s.equals("*")) {
227 +            return null;
228 +        }
229 +        // if we had one or less entries it can't be an IP
230 +        //   -- this disallows * matching as an IP due
231 +        //      to the rule above
232 +        if(i <= 1) {
233 +            return null;
234 +        }
235 +        return ipaddr;
236 +    }
237 +    
238 +    /**
239 +     * Compares two short arrays. The first array can contain a -1,
240 +     * which will always match any value -- it's a wildcard.
241 +     * They must be the same length to match.
242 +     *
243 +     * @param first The first array to compare (with -1 wildcard if required)
244 +     * @param second The second array to compare
245 +     * @result the result of the comparison
246 +     */
247 +    private boolean compareShorts(short[] first, short[] second) {
248 +        if(first.length != second.length) {
249 +            return false;
250 +        }
251 +        for(int i=0; i < first.length; i++) {
252 +            if(first[i] == -1) {
253 +                continue;
254 +            }
255 +            if(first[i] != second[i]) {
256 +                return false;
257 +            }
258 +        }
259 +        return true;
260 +    }
261 +
262   //---ACCESSOR/MUTATOR METHODS---
263  
264   //---ATTRIBUTES---
# Line 183 | Line 298 | public class ACL implements Serializable {
298           *
299           * @param allow whether this is an ALLOW or DENY rule
300           * @param expression what this rule matches
301 +         * @param ipaddr the IP address wildcard this rule matches if it's an IP rule
302 +         * @param iprule whether this is an IP rule
303           */
304 <        private ACLRule(boolean allow, String expression) {
304 >        private ACLRule(boolean allow, String expression, short[] ipaddr, boolean iprule) {
305              _allow = allow;
306              _expression = expression;
307 +            _ipaddr = ipaddr;
308 +            _iprule = iprule;
309          }
310          
311          /**
# Line 212 | Line 331 | public class ACL implements Serializable {
331           * What this rule matches.
332           */
333          private String _expression;
334 +        
335 +        /**
336 +         * The IP wildcard, only valid if this
337 +         * is an IP rule.
338 +         */
339 +        private short[] _ipaddr;
340 +        
341 +        /**
342 +         * Whether this is an IP rule.
343 +         */
344 +        private boolean _iprule;
345          
346      }
347  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines