All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.xins.server.AccessRuleList Maven / Gradle / Ivy

There is a newer version: 3.0
Show newest version
/*
 * $Id: AccessRuleList.java,v 1.53 2010/09/29 17:21:48 agoubard Exp $
 *
 * See the COPYRIGHT file for redistribution and use restrictions.
 */
package org.xins.server;

import java.util.StringTokenizer;

import org.xins.common.MandatoryArgumentChecker;
import org.xins.common.Utils;
import org.xins.common.text.ParseException;

/**
 * Access rule list.
 *
 * 

Descriptor format

* *

An access rule list descriptor, a character string, can be * converted to produce an {@link AccessRuleList} object. A valid descriptor * consists of a list of access rule descriptors (see class * {@link AccessRule}) and/or access rule file descriptors (see class * {@link AccessRuleFile}), separated by semi-colon characters (';'). * Optionally, the rules can have any amount of whitespace (space-, tab-, * newline- and carriage return-characters), before and after them. The last * descriptor cannot end with a semi-colon. * *

Descriptor examples

* *

An example of an access rule list descriptor is: * *

allow 194.134.168.213/32 *; *
deny 194.134.168.213/24 _*; *
allow 194.134.168.213/24 *; *
file /var/conf/file1.acl; *
deny 0.0.0.0/0 *
* *

The above access control list grants the IP address 194.134.168.213 * access to all functions. Then in the second rule it denies * access to all IP addresses in the range 194.134.168.0 to 194.134.168.255 to * all functions that start with an underscore ('_'). Then it * allows access for those IP addresses to all other functions, then it * applies the rules in the /var/conf/file1.acl file and finally * all other IP addresses are denied access to any of the functions. * * @version $Revision: 1.53 $ $Date: 2010/09/29 17:21:48 $ * @author Ernst de Haan * * @since XINS 1.0.0 */ public final class AccessRuleList implements AccessRuleContainer { /** * An empty access rule list. This field is never null. */ static final AccessRuleList EMPTY = new AccessRuleList(new AccessRuleContainer[0]); /** * The list of rules. Cannot be null. */ private AccessRuleContainer[] _rules; /** * The string representation of this instance. Cannot be null. */ private String _asString; /** * Flag that indicates whether this object is disposed. */ private boolean _disposed; /** * Creates a new AccessRuleList object. The passed * {@link AccessRuleContainer} array is assumed to be owned by the * constructor. * * @param rules * the list of rules, not null and should not contain any * duplicate or null elements; if one of these latter 2 * constraints are violated, the behaviour is undefined. * * @throws NullPointerException * if rules == null. */ private AccessRuleList(AccessRuleContainer[] rules) throws NullPointerException { // Count number of rules (may throw NPE) int ruleCount = rules.length; // Build string representation and log StringBuffer buffer = new StringBuffer(ruleCount * 40); if (ruleCount > 0) { String s = rules[0].toString(); buffer.append(s); Log.log_3429(0, s); for (int i = 1; i < ruleCount; i++) { s = rules[i].toString(); buffer.append(';'); buffer.append(s); Log.log_3429(i, s); } } _asString = buffer.toString(); // Store the rules _rules = rules; } /** * Parses the specified character string to construct a new * AccessRuleList object, with the specified watch interval * for referenced files. * *

If the specified interval is 0, then no watching will be * performed. * * @param descriptor * the access rule list descriptor, the character string to parse, * cannot be null. * * @param interval * the interval used to check the ACL files for modification, in * seconds, must be >= 0. * * @return * an {@link AccessRuleList} instance, never null. * * @throws IllegalArgumentException * if descriptor == null || interval < 0. * * @throws ParseException * if there was a parsing error. * * @since XINS 1.1.0 */ public static final AccessRuleList parseAccessRuleList(String descriptor, int interval) throws IllegalArgumentException, ParseException { // Check preconditions MandatoryArgumentChecker.check("descriptor", descriptor); if (interval < 0) { throw new IllegalArgumentException("interval (" + interval + ") < 0"); } // First trim whitespace from the descriptor descriptor = descriptor.trim(); // Tokenize the descriptor, separator is semi-colon StringTokenizer tokenizer = new StringTokenizer(descriptor, ";"); int ruleCount = tokenizer.countTokens(); // Parse all tokens AccessRuleContainer[] rules = new AccessRuleContainer[ruleCount]; for (int i = 0; i < ruleCount; i++) { // Remove leading and trailing whitespace from the next token String token = tokenizer.nextToken().trim(); // Parse and add the rule if (token.startsWith("allow") || token.startsWith("deny")) { rules[i] = AccessRule.parseAccessRule(token); } else if (token.startsWith("file")) { rules[i] = new AccessRuleFile(token, interval); } else { String detail = "Failed to parse access rule list. " + "Expected token \"" + token + "\" to start with " + "\"allow\", \"deny\" or \"file\"."; throw new ParseException(detail); } } return new AccessRuleList(rules); } /** * Counts the number of rules in this list. * * @return * the number of rules, always >= 0. */ public int getRuleCount() { return _rules.length; } /** * Determines if the specified IP address is allowed to access the * specified function, returning a Boolean object or * null. * *

This method finds the first matching rule and then returns the * allow property of that rule (see * {@link AccessRule#isAllowRule()}). If there is no matching rule, then * null is returned. * * @param ip * the IP address, cannot be null. * * @param functionName * the name of the function, cannot be null. * * @param conventionName * the name of the calling convention to match, can be null. * * @return * {@link Boolean#TRUE} if the specified IP address is allowed to access * the specified function, {@link Boolean#FALSE} if it is disallowed * access or null if no match is found. * * @throws IllegalStateException * if this object is disposed (since XINS 1.3.0). * * @throws IllegalArgumentException * if ip == null || functionName == null. * * @throws ParseException * if the specified IP address is malformed. * * @since XINS 2.1. */ public Boolean isAllowed(String ip, String functionName, String conventionName) throws IllegalStateException, IllegalArgumentException, ParseException { // Check state if (_disposed) { String detail = "This AccessRuleList is disposed."; Utils.logProgrammingError(detail); throw new IllegalStateException(detail); } // Check preconditions MandatoryArgumentChecker.check("ip", ip, "functionName", functionName); int ruleCount = _rules.length; for (int i = 0; i < ruleCount; i++) { AccessRuleContainer rule = _rules[i]; String ruleString = rule.toString(); Boolean allowed = rule.isAllowed(ip, functionName, conventionName); if (allowed != null) { // Choose between 'allow' and 'deny' boolean allow = allowed.booleanValue(); // Log this match // XXX: Should this logging really be done in this class? if (allow) { Log.log_3550(ip, functionName, conventionName, i, ruleString); } else { Log.log_3551(ip, functionName, conventionName, i, ruleString); } return allowed; } } return null; } /** * Disposes this access rule. All claimed resources are freed as much as * possible. * *

Once disposed, the {@link #isAllowed} method should no longer be * called. */ public void dispose() { // Check state if (_disposed) { String detail = "This AccessRule is already disposed."; Utils.logProgrammingError(detail); throw new IllegalStateException(detail); } // Do not dispose the EMPTY list if (this == EMPTY) { return; } // Mark this object as disposed _disposed = true; // Dispose the current rules int count = _rules == null ? 0 : _rules.length; for (int i = 0; i < count; i++) { AccessRuleContainer rule = _rules[i]; if (rule != null) { try { rule.dispose(); } catch (Throwable exception) { Utils.logIgnoredException(exception); } } } _rules = null; } /** * Returns a character string representation of this object. The returned * string is in the form: * *

type a.b.c.d/m pattern;type a.b.c.d/m pattern
* * where type is either "allow" or * "deny", a.b.c.d is the base IP address, m * is the mask, and pattern is the function name simple pattern. * * @return * a character string representation of this access rule, never * null. */ public String toString() { return _asString; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy