--- experimental/server/ACL/ACL.java 2001/12/31 19:19:03 1.9 +++ experimental/server/ACL/ACL.java 2002/01/08 13:31:34 1.12 @@ -17,7 +17,7 @@ import java.io.Serializable; * the relevant check method. * * @author $Author: tdb $ - * @version $Id: ACL.java,v 1.9 2001/12/31 19:19:03 tdb Exp $ + * @version $Id: ACL.java,v 1.12 2002/01/08 13:31:34 tdb Exp $ */ public class ACL implements Serializable { @@ -26,7 +26,7 @@ public class ACL implements Serializable { /** * The current CVS revision of this class */ - public static final String REVISION = "$Revision: 1.9 $"; + public static final String REVISION = "$Revision: 1.12 $"; /** * static to be used when adding an ALLOW rule to the ACL. @@ -76,60 +76,16 @@ public class ACL implements Serializable { * param expression what this rule matches using wildcards */ public void add(boolean allow, String expression) { - // default to expecting it to be an IP - // we will try to disprove this :) - boolean ip = true; - short[] ipaddr = {-1, -1, -1, -1}; - int i = 0; - String s = ""; - // tokenize the expression on fullstops, so we can break - // up the quads of an IP (if it's an IP!) - StringTokenizer st = new StringTokenizer(expression, "."); - while(st.hasMoreTokens() && i++ < 4) { - s = st.nextToken(); - // if it's a wildcard, we'll skip to the next one - // as no more checks are required - if(s.equals("*")) { - continue; - } - // attempt to parse it into a short - try { - short n = Short.parseShort(s); - // if it's an int but outside of the - // valid range, it can't be an IP - if(n < 0 || n > 255) { - ip = false; - // give up checking further - break; - } - ipaddr[i-1] = n; - } - // if it didn't parse as an int it can't be an IP - catch (NumberFormatException e) { - ip = false; - // give up checking further - break; - } + // try and convert the expression into an IP address + short[] ipaddr = ipStringToShort(expression); + // a result of null means it's not an IP address + // add either a name rule or an IP rule + if(ipaddr != null) { + _acl.add(new ACLRule(allow, expression, ipaddr, true)); } - // we've done 4 parts, so if there's any - // more this can't be an IP - if(st.hasMoreTokens()) { - ip = false; + else { + _acl.add(new ACLRule(allow, expression, ipaddr, false)); } - // if we've done less than 4, see if the last one - // was a wildcard - if it isn't then it's not an IP - // -- this allows 129.12.* - if(i < 4 && !s.equals("*")) { - ip = false; - } - // if we had one or less entries it can't be an IP - // -- this disallows * matching as an IP due - // to the rule above - if(i <= 1) { - ip = false; - } - // add the rule to our array - _acl.add(new ACLRule(allow, expression, ipaddr, ip)); } /** @@ -143,7 +99,7 @@ public class ACL implements Serializable { public boolean check(String address) { for(int i=0; i < _acl.size(); i++) { ACLRule rule = (ACLRule) _acl.get(i); - if(StringUtils.wildcardCheck(address, rule._expression)) { + if(StringUtils.wildcardMatch(address, rule._expression)) { return rule._allow; } } @@ -171,13 +127,14 @@ public class ACL implements Serializable { ACLRule rule = (ACLRule) _acl.get(i); if(rule._iprule) { // if this is an IP rule do a short comparison - if(compareShorts(ipaddr, rule._ipaddr)) { + // must specify the wildcarded rule first + if(compareShorts(rule._ipaddr, ipaddr)) { return rule._allow; } } else { // if not do a full blown String comparsion - if(StringUtils.wildcardCheck(hostname, rule._expression)) { + if(StringUtils.wildcardMatch(hostname, rule._expression)) { return rule._allow; } } @@ -219,37 +176,71 @@ public class ACL implements Serializable { * Converts an IP address in String format into * a short array of length 4. Any wildcards, *, * found in the IP address are represented by - * a -1. + * a -1. If the given String is not an IP address + * null is returned instead. * * @param ip The IP address in String format * @return The IP address in a short[] */ private short[] ipStringToShort(String ip) { + // default to expecting it to be an IP + // we will try to disprove this :) short[] ipaddr = {-1, -1, -1, -1}; + int i = 0; + String s = ""; + // tokenize the String on fullstops, so we can break + // up the quads of an IP (if it's an IP!) StringTokenizer st = new StringTokenizer(ip, "."); - for(int i=0; i < 4 && st.hasMoreTokens(); i++) { + while(st.hasMoreTokens() && i++ < 4) { + s = st.nextToken(); + // if it's a wildcard, we'll skip to the next one + // as no more checks are required + if(s.equals("*")) { + continue; + } + // attempt to parse it into a short try { - ipaddr[i] = Short.parseShort(st.nextToken()); + short n = Short.parseShort(s); + // if it's an int but outside of the + // valid range, it can't be an IP + if(n < 0 || n > 255) { + // give up checking further + return null; + } + ipaddr[i-1] = n; } - catch(NumberFormatException e) { - // do nothing? - // we just want to leave it as -1 - // -- actually, maybe we want to do more checks in here? - // although in this code context it'll probably be ok, - // it might be worth verifying wildcards and that the - // number is in range... + // if it didn't parse as a short it can't be an IP + catch (NumberFormatException e) { + // give up checking further + return null; } } + // we've done 4 parts, so if there's any + // more this can't be an IP + if(st.hasMoreTokens()) { + return null; + } + // if we've done less than 4, see if the last one + // was a wildcard - if it isn't then it's not an IP + // -- this allows 129.12.* + if(i < 4 && !s.equals("*")) { + return null; + } + // if we had one or less entries it can't be an IP + // -- this disallows * matching as an IP due + // to the rule above + if(i <= 1) { + return null; + } return ipaddr; } /** - * Compares two short arrays. The array can contain a -1, which - * will always match any value -- it's a wildcard. They must be - * the same length to match. At the moment the order of the - * parameters does not matter. + * Compares two short arrays. The first array can contain a -1, + * which will always match any value -- it's a wildcard. + * They must be the same length to match. * - * @param first The first array to compare + * @param first The first array to compare (with -1 wildcard if required) * @param second The second array to compare * @result the result of the comparison */ @@ -258,13 +249,13 @@ public class ACL implements Serializable { return false; } for(int i=0; i < first.length; i++) { - // -- might want to consider specify which is the wildcard one? - if(first[i] == -1 || second[i] == -1) { + if(first[i] == -1) { continue; } if(first[i] != second[i]) { return false; } + } return true; }