| 1 | //---PACKAGE DECLARATION--- | 
 
 
 
 
 | 2 | //package uk.org.iscream.cms.server.util; | 
 
 
 
 
 | 3 |  | 
 
 
 
 
 | 4 | //---IMPORTS--- | 
 
 
 
 
 | 5 | import uk.org.iscream.cms.server.util.*; | 
 
 
 
 
 | 6 | import java.util.ArrayList; | 
 
 
 
 
 | 7 | import java.net.InetAddress; | 
 
 
 
 
 | 8 | import java.io.Serializable; | 
 
 
 
 
 | 9 |  | 
 
 
 
 
 | 10 | /** | 
 
 
 
 
 | 11 | * Access Control List for use primarily | 
 
 
 
 
 | 12 | * with the ACLServerSocket. It could, however | 
 
 
 
 
 | 13 | * have other uses as it has a fairly generic | 
 
 
 
 
 | 14 | * behaviour. Rules are added using the add | 
 
 
 
 
 | 15 | * method, and then checks can be made using | 
 
 
 
 
 | 16 | * the relevant check method. | 
 
 
 
 
 | 17 | * | 
 
 
 
 
 | 18 | * @author  $Author$ | 
 
 
 
 
 | 19 | * @version $Id$ | 
 
 
 
 
 | 20 | */ | 
 
 
 
 
 | 21 | public class ACL implements Serializable { | 
 
 
 
 
 | 22 |  | 
 
 
 
 
 | 23 | //---FINAL ATTRIBUTES--- | 
 
 
 
 
 | 24 |  | 
 
 
 
 
 | 25 | /** | 
 
 
 
 
 | 26 | * The current CVS revision of this class | 
 
 
 
 
 | 27 | */ | 
 
 
 
 
 | 28 | public static final String REVISION = "$Revision$"; | 
 
 
 
 
 | 29 |  | 
 
 
 
 
 | 30 | /** | 
 
 
 
 
 | 31 | * static to be used when adding an ALLOW rule to the ACL. | 
 
 
 
 
 | 32 | */ | 
 
 
 
 
 | 33 | public static final boolean ALLOW = true; | 
 
 
 
 
 | 34 |  | 
 
 
 
 
 | 35 | /** | 
 
 
 
 
 | 36 | * static to be used when adding a DENY rule to the ACL. | 
 
 
 
 
 | 37 | */ | 
 
 
 
 
 | 38 | public static final boolean DENY = false; | 
 
 
 
 
 | 39 |  | 
 
 
 
 
 | 40 | //---STATIC METHODS--- | 
 
 
 
 
 | 41 |  | 
 
 
 
 
 | 42 | //---CONSTRUCTORS--- | 
 
 
 
 
 | 43 |  | 
 
 
 
 
 | 44 | /** | 
 
 
 
 
 | 45 | * Construct a new Access Control List. The default | 
 
 
 
 
 | 46 | * mode is to ALLOW anything that isn't explicitly | 
 
 
 
 
 | 47 | * blocked by a rule. | 
 
 
 
 
 | 48 | */ | 
 
 
 
 
 | 49 | public ACL() { | 
 
 
 
 
 | 50 | // default to ACL.ALLOW | 
 
 
 
 
 | 51 | this(ACL.ALLOW); | 
 
 
 
 
 | 52 | } | 
 
 
 
 
 | 53 |  | 
 
 
 
 
 | 54 | /** | 
 
 
 
 
 | 55 | * Construct a new Access Control List with a given | 
 
 
 
 
 | 56 | * default mode. This mode specifies what should | 
 
 
 
 
 | 57 | * happen if a check does not match any rules. | 
 
 
 
 
 | 58 | * | 
 
 
 
 
 | 59 | * @param defaultMode the default mode for non-matched checks | 
 
 
 
 
 | 60 | */ | 
 
 
 
 
 | 61 | public ACL(boolean defaultMode) { | 
 
 
 
 
 | 62 | _defaultMode = defaultMode; | 
 
 
 
 
 | 63 | } | 
 
 
 
 
 | 64 |  | 
 
 
 
 
 | 65 | //---PUBLIC METHODS--- | 
 
 
 
 
 | 66 |  | 
 
 
 
 
 | 67 | /** | 
 
 
 
 
 | 68 | * Add a new rule to the ACL immediately after the | 
 
 
 
 
 | 69 | * previous rule. The rule can either be an ACL.ALLOW | 
 
 
 
 
 | 70 | * rule, or an ACL.DENY rule. The expression can | 
 
 
 
 
 | 71 | * contain a wildcard (a * only). Rules can only be | 
 
 
 
 
 | 72 | * added to the end of the list. | 
 
 
 
 
 | 73 | * | 
 
 
 
 
 | 74 | * param allow whether this is an ALLOW or DENY rule | 
 
 
 
 
 | 75 | * param expression what this rule matches using wildcards | 
 
 
 
 
 | 76 | */ | 
 
 
 
 
 | 77 | public void add(boolean allow, String expression) { | 
 
 
 
 
 | 78 | _acl.add(new ACLRule(allow, expression)); | 
 
 
 
 
 | 79 | } | 
 
 
 
 
 | 80 |  | 
 
 
 
 
 | 81 | /** | 
 
 
 
 
 | 82 | * Check to see if a string is permitted by the | 
 
 
 
 
 | 83 | * ACL. Useful for testing, and non-Socket uses | 
 
 
 
 
 | 84 | * of this class. | 
 
 
 
 
 | 85 | * | 
 
 
 
 
 | 86 | * @param address the string to check | 
 
 
 
 
 | 87 | * @return whether the address was permitted by the ACL | 
 
 
 
 
 | 88 | */ | 
 
 
 
 
 | 89 | public boolean check(String address) { | 
 
 
 
 
 | 90 | for(int i=0; i < _acl.size(); i++) { | 
 
 
 
 
 | 91 | ACLRule rule = (ACLRule) _acl.get(i); | 
 
 
 
 
 | 92 | if(StringUtils.wildcardCheck(address, rule._expression)) { | 
 
 
 
 
 | 93 | return rule._allow; | 
 
 
 
 
 | 94 | } | 
 
 
 
 
 | 95 | } | 
 
 
 
 
 | 96 | return _defaultMode; | 
 
 
 
 
 | 97 | } | 
 
 
 
 
 | 98 |  | 
 
 
 
 
 | 99 | /** | 
 
 
 
 
 | 100 | * Check to see if an InetAddress is permitted | 
 
 
 
 
 | 101 | * by the ACL. Perfect for Socket uses of this | 
 
 
 
 
 | 102 | * class. It should be made clear that this will | 
 
 
 
 
 | 103 | * check both the hostname AND IP address against | 
 
 
 
 
 | 104 | * each rule in turn. The hostname will always be | 
 
 
 
 
 | 105 | * checked BEFORE the IP address. | 
 
 
 
 
 | 106 | * | 
 
 
 
 
 | 107 | * @param address the InetAddress to check | 
 
 
 
 
 | 108 | * @return whether the InetAddress was permitted by the ACL | 
 
 
 
 
 | 109 | */ | 
 
 
 
 
 | 110 | public boolean check(InetAddress address) { | 
 
 
 
 
 | 111 | for(int i=0; i < _acl.size(); i++) { | 
 
 
 
 
 | 112 | ACLRule rule = (ACLRule) _acl.get(i); | 
 
 
 
 
 | 113 | if(StringUtils.wildcardCheck(address.getHostName(), rule._expression)) { | 
 
 
 
 
 | 114 | return rule._allow; | 
 
 
 
 
 | 115 | } | 
 
 
 
 
 | 116 | if(StringUtils.wildcardCheck(address.getHostAddress(), rule._expression)) { | 
 
 
 
 
 | 117 | return rule._allow; | 
 
 
 
 
 | 118 | } | 
 
 
 
 
 | 119 | } | 
 
 
 
 
 | 120 | return _defaultMode; | 
 
 
 
 
 | 121 | } | 
 
 
 
 
 | 122 |  | 
 
 
 
 
 | 123 | /** | 
 
 
 
 
 | 124 | * Gets the ACL as a String for debugging. | 
 
 
 
 
 | 125 | * | 
 
 
 
 
 | 126 | * @return A String representation of this ACL. | 
 
 
 
 
 | 127 | */ | 
 
 
 
 
 | 128 | public String getStringACL() { | 
 
 
 
 
 | 129 | String acl = ""; | 
 
 
 
 
 | 130 | for(int i=0; i < _acl.size(); i++) { | 
 
 
 
 
 | 131 | ACLRule rule = (ACLRule) _acl.get(i); | 
 
 
 
 
 | 132 | if(rule._allow) { | 
 
 
 
 
 | 133 | acl += "ALLOW:" + rule._expression + " "; | 
 
 
 
 
 | 134 | } | 
 
 
 
 
 | 135 | else { | 
 
 
 
 
 | 136 | acl += "DENY:" + rule._expression + " "; | 
 
 
 
 
 | 137 | } | 
 
 
 
 
 | 138 | } | 
 
 
 
 
 | 139 | if(_defaultMode) { | 
 
 
 
 
 | 140 | acl += "DEFAULT:ALLOW"; | 
 
 
 
 
 | 141 | } | 
 
 
 
 
 | 142 | else { | 
 
 
 
 
 | 143 | acl += "DEFAULT:DENY"; | 
 
 
 
 
 | 144 | } | 
 
 
 
 
 | 145 | return acl; | 
 
 
 
 
 | 146 | } | 
 
 
 
 
 | 147 |  | 
 
 
 
 
 | 148 | /** | 
 
 
 
 
 | 149 | * Overrides the {@link java.lang.Object#toString() Object.toString()} | 
 
 
 
 
 | 150 | * method to provide clean logging (every class should have this). | 
 
 
 
 
 | 151 | * | 
 
 
 
 
 | 152 | * This uses the uk.org.iscream.cms.server.util.FormatName class | 
 
 
 
 
 | 153 | * to format the toString() | 
 
 
 
 
 | 154 | * | 
 
 
 
 
 | 155 | * @return the name of this class and its CVS revision | 
 
 
 
 
 | 156 | */ | 
 
 
 
 
 | 157 | public String toString() { | 
 
 
 
 
 | 158 | return FormatName.getName( | 
 
 
 
 
 | 159 | _name, | 
 
 
 
 
 | 160 | getClass().getName(), | 
 
 
 
 
 | 161 | REVISION); | 
 
 
 
 
 | 162 | } | 
 
 
 
 
 | 163 |  | 
 
 
 
 
 | 164 | //---PRIVATE METHODS--- | 
 
 
 
 
 | 165 |  | 
 
 
 
 
 | 166 | //---ACCESSOR/MUTATOR METHODS--- | 
 
 
 
 
 | 167 |  | 
 
 
 
 
 | 168 | //---ATTRIBUTES--- | 
 
 
 
 
 | 169 |  | 
 
 
 
 
 | 170 | /** | 
 
 
 
 
 | 171 | * This is the friendly identifier of the | 
 
 
 
 
 | 172 | * component this class is running in. | 
 
 
 
 
 | 173 | * eg, a Filter may be called "filter1", | 
 
 
 
 
 | 174 | * If this class does not have an owning | 
 
 
 
 
 | 175 | * component,  a name from the configuration | 
 
 
 
 
 | 176 | * can be placed here.  This name could also | 
 
 
 
 
 | 177 | * be changed to null for utility classes. | 
 
 
 
 
 | 178 | */ | 
 
 
 
 
 | 179 | private String _name = null; | 
 
 
 
 
 | 180 |  | 
 
 
 
 
 | 181 | /** | 
 
 
 
 
 | 182 | * The ACL is stored in this ArrayList. | 
 
 
 
 
 | 183 | */ | 
 
 
 
 
 | 184 | private ArrayList _acl = new ArrayList(); | 
 
 
 
 
 | 185 |  | 
 
 
 
 
 | 186 | /** | 
 
 
 
 
 | 187 | * The default mode of this ACL. | 
 
 
 
 
 | 188 | */ | 
 
 
 
 
 | 189 | private boolean _defaultMode; | 
 
 
 
 
 | 190 |  | 
 
 
 
 
 | 191 | //---STATIC ATTRIBUTES--- | 
 
 
 
 
 | 192 |  | 
 
 
 
 
 | 193 | //---INNER CLASSES--- | 
 
 
 
 
 | 194 |  | 
 
 
 
 
 | 195 | /** | 
 
 
 
 
 | 196 | * Wrapper class for an ACL rule. | 
 
 
 
 
 | 197 | */ | 
 
 
 
 
 | 198 | private class ACLRule implements Serializable { | 
 
 
 
 
 | 199 |  | 
 
 
 
 
 | 200 | /** | 
 
 
 
 
 | 201 | * Construct an ACL rule. | 
 
 
 
 
 | 202 | * | 
 
 
 
 
 | 203 | * @param allow whether this is an ALLOW or DENY rule | 
 
 
 
 
 | 204 | * @param expression what this rule matches | 
 
 
 
 
 | 205 | */ | 
 
 
 
 
 | 206 | private ACLRule(boolean allow, String expression) { | 
 
 
 
 
 | 207 | _allow = allow; | 
 
 
 
 
 | 208 | _expression = expression; | 
 
 
 
 
 | 209 | } | 
 
 
 
 
 | 210 |  | 
 
 
 
 
 | 211 | /** | 
 
 
 
 
 | 212 | * Whether this is an ALLOW or DENY rule. | 
 
 
 
 
 | 213 | */ | 
 
 
 
 
 | 214 | private boolean _allow; | 
 
 
 
 
 | 215 |  | 
 
 
 
 
 | 216 | /** | 
 
 
 
 
 | 217 | * What this rule matches. | 
 
 
 
 
 | 218 | */ | 
 
 
 
 
 | 219 | private String _expression; | 
 
 
 
 
 | 220 |  | 
 
 
 
 
 | 221 | } | 
 
 
 
 
 | 222 |  | 
 
 
 
 
 | 223 | } |